Hi, I want to create a simple animation that starts with a line and the line slowly curls into a spiral. I thought initially that I might be able to do this by making multiple curveVertex segments and rotating the coordinate system for part of the curve but it seems that the shape has to be finished before rotating coordinates. Is there a better way such as working in polar coordinates? That seems to complicate starting with a straight line. Here is the drawing I was starting with to test my idea:
int x1 = -100;
int y1 = 0;
int x2 = 100 ;
int y2 = 0;
int x_b = x1;
int y_b = y1;
int x_e = x2;
int y_e = y2;
int d = x1/2;
int d_c = 0;
int deg = 20;
size(400, 400);
noFill();
translate(width/2, height/2);
beginShape();
curveVertex(x_b, y_b);
curveVertex(x1, y1);
curveVertex(x1+d, y1);
curveVertex((x1+x2)/2+d_c, (y1+y2)/2+d_c);
curveVertex(x2-d, y2);
pushMatrix();
rotate(radians(deg));
curveVertex(x2, y2);
curveVertex(x_e, y_e);
popMatrix();
endShape();
void draw()
{
background(255);
int numSteps = 72; // how long shall we keep going?
noFill();
beginShape();
for (int i = 1; i <= numSteps; i++)
{
float t = i * 10.f; // every 10 degrees
float r = mouseX * i / 100.f; // arbitrary increase in radius, each step
float x = width/2 + r * cos(radians(t));
float y = height/2 + r * sin(radians(t));
curveVertex(x, y);
}
endShape();
}
Here is my take on this with simple trigonometry. You need to increase the radius and the number of turns as the time goes.
The code... (take a look after trying yourself!)
// The resolution of the line (number of points)
int steps = 150;
// Maximum number of spiral turns
int maxTurns = 5;
// Maximum radius of the spiral
int maxRadius = 200;
// Time value, used to control animation
float time = 0;
void setup() {
size(500, 500);
}
void draw() {
background(255);
// Move to the center of the canvas
translate(width / 2, height / 2);
// Increase the turns over time from [0, maxTurns]
float turns = ((cos(time) + 1) / 2) * maxTurns;
// Angle between each points
float anglePart = (TWO_PI * turns) / steps;
noFill();
strokeWeight(4);
beginShape();
for (int i = 0; i < steps; i++) {
// The radius is increasing over time
float radius = map(i, 0, steps - 1, 0, maxRadius);
// Angle of the current point
float angle = i * anglePart;
// Use trigonometric circle to plot points
curveVertex(cos(angle) * radius, sin(angle) * radius);
}
endShape();
// Increase the time, it's the animation speed
time += 0.01;
}
It was a good idea! This is another code that does a similar effect by rotating the coordinate system with rotate() and translate()
The code... (same thing, try it yourself first before seeing the solution)
// The resolution of the line (number of points)
int steps = 150;
// The length of the line
int lineLength = 500;
// Time value, used to control animation
float time = 0;
// The length of a curve segment
float segmentLength = (float) lineLength / steps;
void setup() {
size(800, 300);
}
void draw() {
background(255);
translate(width / 4, height / 4);
noFill();
// Oscilate with time
float timeCurvature = (cos(time) + 1) / 2.0;
for (int i = 0; i < steps; i++) {
// O to 1 value indicating how far we are from the origin of the curve
float farFromOrigin = (float) i / (steps - 1);
// Non uniform stroke weight
strokeWeight((1 - farFromOrigin) * 3 + 1);
// Draw a line
line(0, 0, segmentLength, 0);
// Rotate the coordinate system (it keeps the rotations since we are not calling push/pop)
rotate(exp(farFromOrigin / 2.0) * timeCurvature * TWO_PI / (50.0 * (1 - farFromOrigin + 0.1)));
// Then translate it
translate(segmentLength, 0);
}
// Increase the time, it's the animation speed
time += 0.01;
}