Starting from straight line and curling into a spiral

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();
1 Like
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();
}

Try tweaking and animating how r is calculated?

Ref: Logarithmic Spiral -- from Wolfram MathWorld

3 Likes

Hi @endymion,

Welcome to the forum! :wink:

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;
}

spiral_o

It was a good idea! :yum: This is another code that does a similar effect by rotating the coordinate system with rotate() and translate() :leafy_green:

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;
}

spiral_long_o

4 Likes

Wow thank you! That looks amazing.

1 Like