1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
| // Base amplitude and frequency
float baseAmplitude = chf("amplitude");
float baseFrequency = chf("frequency");
// Randomness sliders for frequency and amplitude
float frequencyRandomness = chf("frequency_randomness");
float amplitudeNoiseScale = chf("amplitude_noise_scale");
float amplitudeChangeRate = chf("amplitude_change_rate");
// Use @Time to get a smoother phase animation with sub-frame precision
float phaseShift = chf("phase_shift") + @Time * chf("phase_shift_rate");
// Phase stretching parameters
float phaseStretch = chf("phase_stretch");
float phaseRandomness = chf("phase_randomness");
// Taper distance parameter
float taperDistance = chf("taper_distance");
// Mirror plane axis parameter - this should be a unit vector
vector mirrorAxis = normalize(chv("mirror_axis"));
// Determine the number of points and initialize path length
int numPoints = @numpt;
float pathLength = 0;
// Calculate the total path length
for (int i = 1; i < numPoints; i++) {
vector pos0 = point(0, "P", i - 1);
vector pos1 = point(0, "P", i);
pathLength += distance(pos0, pos1);
}
// Add the distance from the last point to the first to close the circle
vector posLast = point(0, "P", numPoints - 1);
vector posFirst = point(0, "P", 0);
pathLength += distance(posLast, posFirst);
// Apply the sine deformation with varying amplitude along the path
for (int pt = 0; pt < numPoints; pt++) {
vector pos = point(0, "P", pt);
float traveled = 0;
// Calculate the distance traveled along the path up to this point
for (int i = 1; i <= pt; i++) {
vector pos0 = point(0, "P", i - 1);
vector pos1 = point(0, "P", i);
traveled += distance(pos0, pos1);
}
// Normalize the traveled distance
float normalizedTraveled = traveled / pathLength;
// Calculate noise values for amplitude and frequency
float amplitudeNoise = noise(normalizedTraveled * amplitudeChangeRate) * amplitudeNoiseScale;
float freqNoise = noise(pt * 654.321); // A different seed multiplier for frequency
float randomFrequency = baseFrequency + freqNoise * frequencyRandomness;
// Stretch and randomize the phase using noise
float stretchNoise = noise(normalizedTraveled * phaseRandomness);
float stretchedFrequency = randomFrequency * (1 + stretchNoise * phaseStretch);
// Random amplitude is base amplitude plus noise influence
float randomAmplitude = baseAmplitude + amplitudeNoise;
// Calculate the sine value with random frequency and phase shift
float sineValue = randomAmplitude * sin((normalizedTraveled * stretchedFrequency * 2 * PI) + phaseShift);
// Calculate distance to the mirror plane
float distanceToPlane = abs(dot(pos - @P[0], mirrorAxis));
// Taper factor based on distance to the mirror plane
float taperFactor = 1.0;
if (distanceToPlane < taperDistance) {
taperFactor = pow((taperDistance - distanceToPlane) / taperDistance, 2);
}
// Apply deformation with tapering
vector normal = {0, 1, 0}; // Assuming Y is up
pos += normal * sineValue * taperFactor;
// Set the point position with the new deformed position
setpointattrib(0, "P", pt, pos, "set");
}
|