Cardioids: Part 2

Avi Gupta
hackerLog
Published in
5 min readJan 20, 2019

As you can remember last time, in Cardioids Part 1, I would say that I would answer all of the questions in one week.
If you don’t know what a cardioid is or you haven’t seen part 1,
Click on the link here.

So, let’s get on with it, shall we?

My cardioid using my code from last time.

If you have read my article, you will know that this is a cardioid.

However, this is a cardioid with one lobe. If you saw the first gif in part 1, it means that the black circle rotates around the blue circle once.

This is what I mean:

Cardioid represented by a black circle spinning around a blue one. Courtesy of Wikipedia.

But what If I told you that the image below is also a cardioid?

A multi-bulb cardioid that I made with my code.

Yep, that is a cardioid with 2 lobes.

That means that it is like the first gif in part 1, but instead of the black circle rotating once, it rotates twice.

Pretty simple if you did look at part 1 or the GIF from Wikipedia. So one of the questions from part 1 has been solved:

What gives you more lobes?

in the code samples below, comments marked with //* indicate variables that you can play with to get different effects!

So first, we set up the initial variables. In this case, we have 3: r, b, and theta.

// initalize the variables
float r, b;// r is the radius, b defines how many lobes it has
float theta;// theta is the angle

Then, we set up the program.

// sets up the program
void setup() {
size(600, 600);
r = height * .25;
b = 3;// the number of lobes will always be b-1. this will produce 2 lobes*
theta = 0;// initializes theta*
background(0);// black background*
frameRate(1000);// sets the framerate*
pixelDensity(2);
}

Then, we start drawing. First, we make the basic structure for what the cardioid will look like:

// draws everything out
void draw() {
stroke(random(255), random(255), 255);// makes colorful dots *
strokeWeight(random(5));// the thickness of the stroke is up to 5
pushMatrix();// pushes the grid to a certain point
translate(width/2, height/2);// makes (0,0) at the center of the canvas *

Then, we set up the first set of polar coordinates.

// the first xy coordinates
float x = r*sin(theta/1);
float y = r*cos(theta/1);

Now, we set up the second set of polar coordinates.

// the second xy coordinates, making it b times the original xy
float x2 = r*sin(b*theta);
float y2 = r*cos(b*theta);

Then, we subtract both from each other.

// subtracts both from each other, making so that it produces a point at the xy coordinates: (r*sin((b-1)*theta), r*cos((b-1)*theta))  point((x2-x)/1, (y2-y)/1);//*

Then we increase theta, set r, and use the popMatrix(); function to make it so that (0,0) would be at the top left corner of the canvas again.

// subtracts both from each other, making so that it produces a point at the xy coordinates: (r*sin((b-1)*theta), r*cos((b-1)*theta))
point((x2-x)/1, (y2-y)/1);//*
theta+=0.5;//*
r = 90;//*
popMatrix();
}
// * -> play around with these variables

Full code for this problem on GitHub here.

So now we solve another problem:

What makes it smoother?

Well, all we have to do is decrease the intervals at which theta changes by. So we change this line:

theta+=0.5; //*

into this line:

theta+=0.01; //*

making it smoother.

Next question:

Can we make the cardioid larger if we want to?

Yes we can! All we have to do is increase r.

make r = 90; to r = 180; to make it larger. It works!

Now for the next question:

How do we make the cardioid with lines?

Well, we take this line:

point((x2-x)/1, (y2-y)/1);

And replace it with this line:

line(x, y, x2, y2);

And also make sure that the stroke thickness is thin, so we take this line:

strokeWeight(random(5));// the thickness of the stroke is up to 5

and replace it with this line:

strokeWeight(1);// the thickness of the stroke is only 1.

It looks like this in the end:

I wrote separate code for this. See it on GitHub here.

Okay, so now we are just on the last question:

How do we make the circles visible?

This took me a while, but I think I got it:

My cardioid circle made using processing.

As you can see, there is a little black circle in the middle, which counts. The green circle is the one spinning all around.

So how did we make this code?

first, we declare our variables.

// declare universal variables
float t = 0, r;
Point[] cardioidArray = new Point[0];// makes an array of class point. (will be pretty handy later)
Point prevCircle = null;

Then, we set up the main structure.

// set it up
void setup() {
size(600, 600);
background(20);
r = 50;
pixelDensity(2);
ellipseMode(CENTER);
frameRate(60);
}

Now, we draw out all of the components of it.
I first declared my internal variables:

// draw it
void draw(){
// x in r = x + x sin(theta)
float xc = r * 2;

// cardioid radius equation
float r2 = xc + xc * sin(t);
float x = r2 * sin(t) - r;
float y = r2 * cos(t);
strokeWeight(3);

Then, I make the green circle.

// green circle
noFill();
strokeWeight(1);
if(prevCircle != null) {
stroke(20,20,20);
ellipse(prevCircle.x, prevCircle.y, r*2, r*2);
}
stroke(0, 255, 0);
prevCircle = new Point(width/2 + r*2*sin(t), height/2 + r*2*cos(t));
ellipse(prevCircle.x, prevCircle.y, r*2, r*2);

Now, I make the blue cardioid. I do this by making an array of the class Point.

// blue cardioid points
cardioidArray = (Point[]) append(cardioidArray, new Point(width/2 + x, height/2 + y));

for(int i=0; i< cardioidArray.length; i++){
cardioidArray[i].render();// draws the cardioid
}

Finally, in void draw(), I increase the theta and make it so that the green circles clear after t = 360:

t+= 1;
if (t > 360){
background(20);
t = 0;
}
}

Now, we make class Point. This is easy to make, since it requires only an x and y variable for location.
We do final so the variable remains unchanged after declared:

class Point {
final float x,y;
Point(float x, float y){
this.x = x;
this.y = y;
}
// draw point
void render() {
strokeWeight(5);
stroke(0, 0, 255);
point(x,y);
}
}

Hence making the class point.

See the code for the cardioid with the circles here.

So really, all of these problems are really interesting to figure out and to do, since there are so many ways that we can edit a cardioid.

Signing out ‘till next time,

Avi

--

--

Avi Gupta
hackerLog

Named after the first 2 games I got on my xBox, Forza and Minecraft. Also, i have a blog. Real name is Avi.