Spirals Made Easy

In these notes you will learn:

  • How to plot shapes using polar coordinates.
  • How to avoid gaps between consecutive points of a plot.

Polar Coordinates

The usual \((x, y)\) coordinates we’ve been using are called Cartesian coordinates.

Polar coordinates are a different, and sometimes very useful, way of plotting points. A polar coordinate point is written \((r, \theta)\), where \(r\) is the point’s distance from the origin. If you then draw a line segment from the point to the origin, \(\theta\) is the angle (in radians) it makes with the x-axis.

Since Processing only plots its shapes using Cartesian coordinates, we will need to convert polar coordinates into Cartesian coordinates using these two equations:

\[x = r \cos(\theta)\]\[y = r \sin(\theta)\]

So, for example, the polar coordinate point \((100, \frac{\pi}{6})\) is the Cartesian coordinate point \((100\cos \frac{\pi}{6}, 100\sin \frac{\pi}{6}) = (86.60254, 50.0)\).

Note

For this course you don’t need to undertand why these equations convert polar coordinates to Cartesian coordinates. You can just take it on faith that they work correctly.

Circles

float rotations = 0;

void setup() {
    size(500, 500);
    smooth();
    noStroke();
    fill(255, 0, 0);
}

void draw() {
    background(255);
    float r = dist(250, 250, mouseX, mouseY);

    translate(250, 250);
    for(float theta = 0; theta < rotations; ++theta) {
        float x = r * cos(radians(theta));
        float y = r * sin(radians(theta));
        ellipse(x, y, 3, 3);
    }

    rotations += 2;
    if (rotations > 360) {
        rotations = 0;
    }
}

Plotting Without Gaps

void setup() {
  size(500, 500);

  smooth();
  // noStroke();
  stroke(255, 0, 0);
  fill(255, 0, 0);
}

void draw() {
  background(255);
  float r = dist(250, 250, mouseX, mouseY);

  translate(250, 250);

  // calculate the first point
  float prevX = r * cos(radians(0));
  float prevY = r * sin(radians(0));

  float incr = 1;
  for (float theta = incr; theta <= 360; theta += incr) {
    float x = r * cos(radians(theta));
    float y = r * sin(radians(theta));
    line(x, y, prevX, prevY);
    prevX = x;
    prevY = y;
  }
}

Spirals

  • Archimedean spiral
float rotations = 0;

void setup() {
  size(500, 500);

  smooth();
  noStroke();
  fill(255, 0, 0);
}

void draw() {
  background(255);

  translate(250, 250);
  for (float theta = 0; theta < rotations; ++theta) {
    float r = theta / 15;
    float x = r * cos(radians(theta));
    float y = r * sin(radians(theta));
    ellipse(x, y, 3, 3);
  }

  rotations += 2;
  if (rotations > 5 * 360) {
    rotations = 0;
  }
}

Polar Roses

void setup() {
    size(500, 500);

    smooth();
    stroke(255, 0, 0);
    fill(255, 0, 0);
}

void draw() {
    background(255);

    translate(250, 250);

    // calculate the first point
    float prevX = 0;
    float prevY = 0;
    ellipse(prevX, prevY, 3, 3);

    float incr = 1;
    for(float theta = incr; theta <= 180; theta += incr) {
        float r = 200 * sin(400 * theta);
        float x = r * cos(radians(theta));
        float y = r * sin(radians(theta));
        line(x, y, prevX, prevY);
        prevX = x;
        prevY = y;
        ellipse(x, y, 3, 3);
    }
}

Questions

  1. Explain how polar coordinates specify points on the screen.

  2. In the program that draws a spiral in an animated way, the variable rotations is declared as a global variable at the top of the program, e.g.:

    float rotations = 0;
    
    void setup() {
       // ...
    }
    
    void draw() {
       // ...
    }
    

    However, the only placed rotations is used is inside the draw() function. So, would the program still work the same way if we declared rotations as a local variable in draw() like this?

    void setup() {
       // ...
    }
    
    void draw() {
       float rotations = 0;
       // ...
    }