# Drawing multiple objects with calculations related to the previous object

I need help figuring out how to figure out something.

So I have hardcoded two circles and an external and internal tangent line. Here is the code:

``````PVector c1, c2; //center of circles
PVector t1, t2; //tangent points of external tangent
PVector t3, t4; //tangent points of internal tangent

float etheta, itheta //angles to calculate tangent points
float c1c2; //length of the vector between the two centers

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

c1 = new PVector(150, 150);
c2 = new PVector (300, 300);
r1 = 70;
r2 = 55;
}

void draw() {
//draw the circles
ellipse(c1.x, c1.y, 2*r1, 2*r1);
ellipse(c2.x, c2.y, 2*r2, 2*r2);

float c1c2= PVector.dist(c1, c2);

//calculate the angle for the external tangent
etheta = atan2(c2.y-c1.y, c2.x-c1.x)+acos((r1-r2)/c1c2)+PI;

//calculate the angle for the internal tangent points
itheta =atan2(c2.y-c1.y, c2.x-c1.x)+asin((r1+r2)/c1c2)-(PI/2);

//calculate the two external tangent points
t1 = new PVector(c1.x+(r1*cos(etheta)), c1.y+(r1*sin(etheta)));
t2 = new PVector(c2.x+(r2*cos(etheta)), c2.y+(r2*sin(etheta)));

//calculate the internal tangent points
t3 = new PVector(c1.x+(r1*cos(itheta)), c1.y+(r1*sin(itheta)));
t4 = new PVector(c2.x+(r2*cos(itheta+PI)), c2.y+(r2*sin(itheta+PI)));

//draw the lines
line(t1.x, t1.y, t2.x, t2.y);
line(t3.x, t3.y, t4.x, t4.y);
}
``````

This gives me two circles with two tangent lines. Now, I want a third circle. I can code a third one in manually that I call â€śc3â€ť and recalculate the tangent points between c3 and c2 and then I can end up with this image:

My question is if I want to automate it so that I can draw 20 circles or a random number of circles each with tangent lines to the previous circle how do I need to go about doing this? I can stumble through figuring it out, I just need to be pointed in the right direction. Like do I need to use ArrayLists or 2D Arrays? Something else? Or is this even easier than I realize?

No arrays needed unless you want the full list available at the end. Just reuse your variables:

``````choose c0 = (x0, y0)
draw c0
for( int i=1; i<20; i++ ) {
calculate c1 = (x1, y1) from c0
draw c1 and tangent lines
c0 = c1;    // throws away c0 (Java "forgets" about it)
}
``````

If you want to make sure that your circles are not on top of each other, then you might want to keep a list of the previous circles and loop to choose a new one until it doesnâ€™t overlap any of the previous. Depends on your artistic goal.

Even if you kept the past ones in a list, you would still have a variable (c0) pointing to the most recent circle and use it to compute the next one.

2 Likes

Great! This was what I neededâ€”it was more simple than I thought. Here it is with 10:

And if I wanted to have a list in the end of circles, so that perhaps I might draw the lines not only to the previous circle but letâ€™s say the 2nd one or whichever or my choosing, would I make a PVector array?

And how would I make sure one circle isnâ€™t on top of another? I would assume it has to do with calculating the distance between two centers and making sure that is more than the sum of the radii but I donâ€™t really know how to have it rechoose numbers if those conditions arenâ€™t satisfied?

1 Like

For past circles, you would want both the center and the radius, so you could either have two lists or you could make a class that contains all the circle information you want to save:

``````class Circle {
float x, y, r;
Circle( float x_, float y_, float r_ ) {
x = x_;  y = y_;  r = r_;
}
}
``````

and keep of list of them. Then generate your new circles as you said, comparing their distance vs the sum of their radii:

``````boolean overlapped;
do {
overlapped = false;
generate new circle
for each old circle in your list:
if distance between old circle and new circle < sum of radii:
overlapped = true
} while( overlapped is true );