apophysis7x/Plugin/ripple.c
xyrus02 95a2f54683 ADMIN: migration complete
git-svn-id: https://svn.code.sf.net/p/apophysis7x/svn/trunk@1 a5d1c0f9-a0e9-45c6-87dd-9d276e40c949
2013-07-28 08:58:33 +00:00

102 lines
2.7 KiB
C

typedef struct
{
// variables
double ripple_frequency,
ripple_velocity,
ripple_amplitude,
ripple_centerx,
ripple_centery,
ripple_phase,
ripple_scale;
// private stuff
double f, a, p, s, is,
vxp, pxa, pixa;
} Variables;
#define _USE_MATH_DEFINES
#include "apoplugin.h"
APO_PLUGIN("ripple");
APO_VARIABLES(
// wave function frequency
VAR_REAL(ripple_frequency, 2.0),
// wave velocity
VAR_REAL(ripple_velocity, 1.0),
// wave amplitude
VAR_REAL(ripple_amplitude, 0.5),
// origin of the ripple (x,y)
VAR_REAL(ripple_centerx, 0.0),
VAR_REAL(ripple_centery, 0.0),
// wave phase / interpolation coefficient
VAR_REAL(ripple_phase, 0.0),
// ripple scale
VAR_REAL(ripple_scale, 1.0)
);
int PluginVarPrepare(Variation* vp)
{
// some variables are settled in another range for edit comfort
// - transform them
VAR(f) = VAR(ripple_frequency) * 5;
VAR(a) = VAR(ripple_amplitude) * 0.01;
VAR(p) = VAR(ripple_phase) * M_2PI - M_PI;
// scale must not be zero
VAR(s) = VAR(ripple_scale) == 0 ? EPS : VAR(ripple_scale);
// we will need the inverse scale
VAR(is) = 1 / VAR(s);
// pre-multiply velocity+phase, phase+amplitude and (PI-phase)+amplitude
VAR(vxp) = VAR(ripple_velocity) * VAR(p);
VAR(pxa) = VAR(p) * VAR(a);
VAR(pixa) = (M_PI - VAR(p)) * VAR(a);
// done
return TRUE;
}
inline double lerp(double a, double b, double p) { return a + (b - a) * p; }
int PluginVarCalc(Variation* vp)
{
//align input x, y to given center and multiply with scale
double x = (FTx * VAR(s)) - VAR(ripple_centerx),
y = (FTy * VAR(s)) + VAR(ripple_centery);
// calculate distance from center but constrain it to EPS
double d = MAX(EPS, sqrt(sqr(x) * sqr(y)));
// normalize (x,y)
double nx = x / d,
ny = y / d;
// calculate cosine wave with given frequency, velocity
// and phase based on the distance to center
double wave = cos(VAR(f) * d - VAR(vxp));
// calculate the wave offsets
double d1 = wave * VAR(pxa) + d,
d2 = wave * VAR(pixa) + d;
// we got two offsets, so we also got two new positions (u,v)
double u1 = (VAR(ripple_centerx) + nx * d1),
v1 = (-VAR(ripple_centery) + ny * d1);
double u2 = (VAR(ripple_centerx) + nx * d2),
v2 = (-VAR(ripple_centery) + ny * d2);
// interpolate the two positions by the given phase and
// invert the multiplication with scale from before
FPx = VVAR * (lerp(u1, u2, VAR(p))) * VAR(is);
FPy = VVAR * (lerp(v1, v2, VAR(p))) * VAR(is);
// done
return TRUE;
}