- Review: Basic line
- Using sin and cos
- Items in a circle
- Drawing some items differently
- Animating the circle
- From circle to spiral
Review: Basic line
This code from Arranging a Line of Items draws a line of shapes. It uses the derivation strategy, to calculate a value for x directly from i each time through the loop.
function setup() {
createCanvas(windowWidth, windowHeight);
}
function draw() {
for (let i = 10; i < 20; i++) {
let x = 10 + 50 * i;
let y = 100;
circle(x, 100, 40);
}
}
Note: From here on, the definition of setup()
is not shown. Each of the following code samples assumes that the sketch also contains a setup()
function:
function setup() {
createCanvas(windowWidth, windowHeight);
}
Using sin
and cos
We can use the sin()
or cos()
functions to make the items swing between the top and bottom of the band, as the index value progresses.
function draw() {
for (let i = 0; i < 10; i++) {
let x = 20 + 50 * i;
let y = 100 + 50 * sin(i);
circle(x, y, 50);
}
}
function draw() {
for (let i = 0; i < 10; i++) {
let x = 20 + 50 * i;
let y = 100 + 50 * cos(i);
circle(x, y, 50);
}
}
Trying to use sin
(or cos
) for both x and y arranges the items on a diagonal line. This is true any time that x and y use the same equation, because then they will have the same value.
function draw() {
for (let i = 0; i < 10; i++) {
let x = 100 + 50 * sin(i);
let y = 100 + 50 * sin(i);
circle(x, y, 50);
}
}
The solution is to use cos
for x
and sin
for y
. These functions are cleverly designed so that using them together this way makes a circle.
Let’s look at just using sin
for y
(instead of x
), and compare that to the code a couple of sketches above that uses cos
for x
.
function draw() {
for (let i = 0; i < 10; i++) {
let x = 100 + 50 * cos(i);
let y = 100 + 50 * i;
circle(x, y, 50);
}
}
Combining cos
for x
with sin
for y
creates a circle.
function draw() {
for (let i = 0; i < 10; i++) {
let x = 100 + 50 * cos(i);
let y = 100 + 50 * sin(i);
circle(x, y, 50);
}
}
There’s two things that may be wrong with this circle, depending on your design intent: (1) it is too small relative to the items that are placed along its edge; and, the items are wrapped around the circle more than once.
The first problem can be addressed by changing the 50
in 50 * cos(i)
and 50 * sin(i)
to a larger number. We will also change the 100
in 100 + 50 * cos(i)
to a larger number, to move the center of the arrangement circle right so that the whole circle stays on the screen.
Items in a circle
By default, sin
and cos
repeat every . We need to insure that the number that we putting into them varies from 0 to by the time the loop is done. Since i
varies from 0 to (just under) 10, i * TWO_PI / 10
varies from 0 to (one step under) TWO_PI
.
function draw() {
for (let i = 0; i < 10; i++) {
let angle = i * TWO_PI / 10;
let x = 250 + 150 * cos(angle);
let y = 300 + 150 * sin(angle);
circle(x, y, 50);
}
}
Note: We could also have used map(i, 0, 10, 0, TWO_PI)
instead of i * TWO_PI / 10
.
Here is another way of doing this. angleMode(DEGREES)
causes sin
and cos
to repeat every 360, instead of every .
function draw() {
angleMode(DEGREES);
for (let i = 0; i < 10; i++) {
let angle = i * 360 / 10;
let x = 250 + 150 * cos(angle);
let y = 300 + 150 * sin(angle);
circle(x, y, 50);
}
}
Note: It is more standard to put angleMode(DEGREES)
in setup()
, because (1) it only needs to be done once, and (2) that way it will affect any calls to sin
and cos
that run in setup()
. Here, we are putting it in draw()
just because that’s the only part of the sketch that is shown in these examples.
Yet another way to do this is to increment the angle directly instead of computing it from the index position. This is useful if we know the number of degrees we want to leave between items, instead of the number of items.
function draw() {
angleMode(DEGREES);
for (let angle = 0; angle < 360; angle += 10) {
let x = 250 + 150 * cos(angle);
let y = 300 + 150 * sin(angle);
circle(x, y, 50);
}
}
Drawing some items differently
We can use a conditional in order to draw some items differently from others.
function draw() {
angleMode(DEGREES);
for (let i = 0; i < 360; i += 10) {
let angle = i;
let x = 250 + 150 * cos(angle);
let y = 300 + 150 * sin(angle);
if (i === 180) {
fill('black');
} else {
fill('white');
}
circle(x, y, 50);
}
}
angleMode(DEGREES);
for (let i = 0; i < 360; i += 10) {
let angle = i;
let x = 250 + 150 * cos(angle);
let y = 300 + 150 * sin(angle);
if (i === 180) {
fill('black');
} else {
fill('white');
}
if (i === 90) {
strokeWeight(5);
} else {
strokeWeight(1);
}
circle(x, y, 50);
}
function draw() {
angleMode(DEGREES);
for (let i = 0; i < 360; i += 10) {
let angle = i;
let radius = 150;
let x = 250 + radius * cos(angle);
let y = 300 + radius * sin(angle);
if (i % 40 === 0) {
fill('black');
} else {
fill('white');
}
if (i === 90) {
strokeWeight(5);
} else {
strokeWeight(1);
}
circle(x, y, 50);
}
}
Animating the circle
Incorporate the time (millis()
) into the equation, in order to animate the circle.
function draw() {
background(200);
angleMode(DEGREES);
for (let i = 0; i < 360; i += 10) {
let angle = i + millis() / 15;
let x = 250 + 150 * cos(angle);
let y = 300 + 150 * sin(angle);
if (i % 40 === 0) {
fill('black');
} else {
fill('white');
}
if (i === 90) {
strokeWeight(5);
} else {
strokeWeight(1);
}
circle(x, y, 50);
}
}
From circle to spiral
The circle sketches place each object the same distance from the center. sin
and cos
are defined to produce x, y pairs that are all a distance of 1.0 from the origin; multiplying them both by 150 makes everything a distance of 150 pixels from the origin. Instead of multiplying each sin
and cos
by 150, multiple them by larger and larger numbers as the angle increases. This creates a spiral.
function draw() {
angleMode(DEGREES);
for (let i = 0; i <= 360; i += 10) {
let angle = i;
let radius = map(i, 0, 360, 10, 200) + 100;
let x = 250 + radius * cos(angle);
let y = 300 + radius * sin(angle);
if (i % 40 === 0) {
fill('black');
} else {
fill('white');
}
if (i === 90) {
strokeWeight(5);
} else {
strokeWeight(1);
}
circle(x, y, 80);
}
}
Increasing the angle to 720 degrees to wrap around the circle twice ().
function draw() {
angleMode(DEGREES);
for (let i = 0; i < 720; i += 10) {
let angle = i;
let radius = map(i, 0, 360, 10, 200);
let x = 250 + radius * cos(angle);
let y = 300 + radius * sin(angle);
if (i % 40 === 0) {
fill('black');
} else {
fill('white');
}
if (i === 90) {
strokeWeight(5);
} else {
strokeWeight(1);
}
circle(x, y, 50);
}
}
©2020–2022 by Oliver Steele.