How can I determine where the circle is to be positioned?

SLSCoder

New member
Joined
Aug 24, 2021
Messages
21
I am trying to draw a graph of a series of circles like the image below.
The circles are a result of data so the number of circles and their diameters depend on that data.
That is to say, the image below is 1 case. The number of circles, their diameters and their vertical positions can change from one graph to another. This is a software app. written in PHP.

Vertically the circles are positioned by avg relational to the scale on the left (10 to -10).
The circles are ordered by diameter from largest to smallest.
I start with the largest circle and place it in the center on the x scale.
From there I place the next to the right, the next to the left, the next to the right, etc.

I need to place each circle so that its edge almost touches the closest edge of another circle that has already been placed. For example, lift's lower left edge would almost touch forklift's upper right edge and tilt's lower left edge should almost touch lift's upper right edge.
If any circle could be moved left or right without touching any other circle it should be in the center of the x scale.
Brakes (below) should be in the center on the x scale because it cannot touch any other circle anywhere on the x scale.
Steering's lower right edge should almost touch forklifts' upper left edge.

Once they're all placed relative to each other all of them need to move left until the furthest left edge almost touches the left edge of the graph.
In the case below steering would almost touch the left edge of the white box.

I've spent hours trying to figure out how to do this. I cannot and almost gave up.
I'm not a mathematician. I aced geometry in high school and advanced algebra in college but that was about a hundred years ago and my memory fails me.
I do have access to Python if needed.

Any help in accomplishing what I'm trying to do would be greatly appreciated.
1750936284226.png
 
Last edited:
I have this function in php.
You should pretty easily be able to see what the math functions in it do.
I'd really like to know if this function is correct.
/*
This function determines whether 2 circles intersect or not.
param c1 is the first circle array: ["x" => center x, "y" => center y, "r" => radius];
param c2 is the second circle array: ["x" => center x, "y" => center y, "r" => radius];
return:
-1 = no intersection
0 = intersection on 1 point
1 = intersection on multiple points
*/
function ck2CirclesIntersect($c1, $c2) {
$d = round(sqrt(pow(($c2["x"] - $c1["x"]), 2) + pow(($c2["y"] - $c1["y"]), 2)));
if($d > $c1["r"] + $c2["r"]) return -1;
else if($d == $c1["r"] + $c2["r"]) return 0;
else return 1;
}
 
I used to design simple websites when I was a kid using PHP\displaystyle \text{PHP} and MySQL\displaystyle \text{MySQL} and sometimes I included JavaScript\displaystyle \text{JavaScript}. I will not pretend that I can understand your code fully but I have some ideas. Today I developed a program in Java\displaystyle \text{Java} from scratch which has a built-in Swing\displaystyle \text{Swing} library that allows me to draw shapes. For now my code is simple, it only asks the user how many circles he wants to be displayed. Say the user chose 5\displaystyle 5, then five circles will be drawn randomly in the window. For now each one of them has a diameter of 1\displaystyle 1 and collision between them could happen. I am very lazy to work on other people problems, but I can develop my code slowly to match the complete idea of yours. Then it is a piece of cake to convert it to PHP\displaystyle \text{PHP}.

To not let the circles collide is a little bit challenging. It will take me sometime to beat it, so I advise you to not depend on me. From time to time, I will post my progress. Here I provided two screen shots of a user who entered FIVE\displaystyle \bold{FIVE}.

circles.png

💪💀💀


circles_2.png
 
I am trying to draw a graph of a series of circles like the image below.
The circles are a result of data so the number of circles and their diameters depend on that data.
That is to say, the image below is 1 case. The number of circles, their diameters and their vertical positions can change from one graph to another. This is a software app. written in PHP.

Vertically the circles are positioned by avg relational to the scale on the left (10 to -10).
The circles are ordered by diameter from largest to smallest.
I start with the largest circle and place it in the center on the x scale.
From there I place the next to the right, the next to the left, the next to the right, etc.

I need to place each circle so that its edge almost touches the closest edge of another circle that has already been placed. For example, lift's lower left edge would almost touch forklift's upper right edge and tilt's lower left edge should almost touch lift's upper right edge.
If any circle could be moved left or right without touching any other circle it should be in the center of the x scale.
Brakes (below) should be in the center on the x scale because it cannot touch any other circle anywhere on the x scale.
Steering's lower right edge should almost touch forklifts' upper left edge.

Once they're all placed relative to each other all of them need to move left until the furthest left edge almost touches the left edge of the graph.
In the case below steering would almost touch the left edge of the white box.

I've spent hours trying to figure out how to do this. I cannot and almost gave up.
I'm not a mathematician. I aced geometry in high school and advanced algebra in college but that was about a hundred years ago and my memory fails me.
I do have access to Python if needed.

Any help in accomplishing what I'm trying to do would be greatly appreciated.
View attachment 39492
Hi @SLSCoder,

Reading your first post, I struggled to see how anybody might help you unless they were familiar with this "app" you are using (about which you provided precious little detail). I also struggled to understand exactly what help it was you were hoping to get but, if I (eventually) understood correctly what you needed, it seemed to me that your second post suggested that you already had all the information you required.

My conclusion, if correct (and I can't guarantee that it is), was that all you were really asking was how to "position" any two circles which you wished to bring together to a point of tangency, so I went off and prepared a couple of pictures that might illustrate my suggested solution for you. When I next looked in, I noticed that another member had since posted a reply containing some program code. Now that may be of more use to you, I don't know because I have absolutely no expertise in php or Python (or java) scripting, but it didn't appear to directly address the issue I was thinking might answer your query, so I decided to go ahead and post this for your consideration.

You mentioned you "
aced geometry in high school" but have forgotten most of it so I think the best place to start may be a little revision on the Maths involved in the Geometry of a circle. Below is a slide I have put together for use when teaching Circles to HS students. Please have a look at it and ensure you understand it; any problems in that respect and I'm sure someone will be happy to explain further (you might wish to save the image so you can open it full size on your own device)...

2025-06-27 (2).png

So, any circle may be described by this general equation:- (xa)2+(yb)2=r2(x-a)^2+(y-b)^2=r^2
(where: the centre of the circle lies at the point: (a, b) and its radius is: r.)

Now, you appear to have access to the x & y coordinates of you circles and their radii (from how I read your 2nd post) and all you want to do is bring them "together" (touching each other) as you describe.

If we start with your first circle, its x-coordinate will place it somewhere along the x-axis ("
in the center on the x scale" you say). Both its y-coordinate and that of the next circle you wish to place are determined by their "avg" values. (I don't know whether this is some 'average' value or 'avg' stands for something else altogether; it doesn't matter, the 'avg' number is clearly each circle's centre's y-coordinate.)
So all you need to do is find the x-coordinate of the second circle such that its circumference touches that of the first one.

Am I right so far?

(Continued in the next post, as there's a damn nuisance of 10k characters per post!)
 
Last edited:
I have created the following example to illustrate the process. I used specific numbers (a Pythagorean triple) to keep the arithmetic simple but this will work for any circles' data and the more decimal numbers you work to, the better looking your result(s) will be.

I started with a first circle, called (say) "forklift", whose "
avg" I set to 10. I then decided (randomly) that the "centre" of the graph would lie at 15 along the x-axis, so the centre of this circle would lie at (15, 10) and I also set its radius to be 9 units. I then plotted this circle in Desmos in blue (as shown below). I then plotted a second circle called "lift" (in red) whose radius is 4 units with its centre lying at the point (38, 15) because its "avg" is 15 (and it lies off to the right of "forklift").

In order to make "lift" touch "forklift" (the way I think you want it to) all you need to do is find the x-coordinate for "lift" that will move it to the position shown when it is re-drawn in green (qv). Both circles' y-coordinates are fixed (by their "avg" values) and you know the radii of each, so, given the x-coordinate of one, it's a simple matter to calculate an x-coordinate for the second to make their circumferences tangential.

You simply add their radii together (which will give the distance you want their centers to be apart) and find the difference between their "
avg" values (ie: their y-coordinates). Then you take the square of the first number and subtract the square of the second and find the square root of the result.

Looking at the picture, you can see that their radii add to 13 (9 + 4) and the difference between their "
avg's" is 5 (15 - 10) so...13252=16925=144 and 144=1213^2-5^2=169-25=144\text{ and }\sqrt{144}=12
Therefore, the difference between the x-coordinates of their centres needs to be 12.

So re-plotting "lift" (in green) with its centre at (27, 15) brings it into contact with "forklift" just as desired.

Note that the x-coordinate of "lift" is now 12 greater than that of "forklift" whilst their y-coordinates remain unchanged (at 10 & 15 respectively).


Positioning Circles.png

This "method" will work just as effectively regardless of whether the second circle is to the left or right of or above or below the first one; you only need to calculate the required difference between their x-coordinates to make them "touch" each other.

Note too that, once you have arranged all your circles in the desired (relative) positions, all you then need to do is look at the leftmost circle and determine how far its x-coordinate is from the "
left edge of the graph" and then subtract that amount from the x-coordinate of all the circles to move them all, en masse, to the required final position.

You may wish to save this picture too (just right-click it and choose: "
Save image as...") so you can view it full-size on your own device (and zoom into it to see any areas in more detail) but you can also visit the Desmos page where I created it and, if you wish, play around with different values for the circles and their centres.

You can access the Desmos page here. You should there see that I entered, at the LHS, the equations for the three circles (followed by the points for their centres) in blue, red & green; if you alter an equation you may need to change its centre's point too.

The subsequent entries (in black) were just there to create the lines (of the right-angled triangle) and should probably just be deleted before you try changing anything about the circles.

Please let us know if this goes any way toward solving your problem. If not, then I'm afraid you may just have to wait until @logistic_guy gets around to developing his code for you but I'd like to hear you thoughts on what I've suggested anyway?

Hope that helps. 😊
 
Last edited:
I used to design simple websites when I was a kid using PHP\displaystyle \text{PHP} and MySQL\displaystyle \text{MySQL} and sometimes I included JavaScript\displaystyle \text{JavaScript}. I will not pretend that I can understand your code fully but I have some ideas. Today I developed a program in Java\displaystyle \text{Java} from scratch which has a built-in Swing\displaystyle \text{Swing} library that allows me to draw shapes. For now my code is simple, it only asks the user how many circles he wants to be displayed. Say the user chose 5\displaystyle 5, then five circles will be drawn randomly in the window. For now each one of them has a diameter of 1\displaystyle 1 and collision between them could happen. I am very lazy to work on other people problems, but I can develop my code slowly to match the complete idea of yours. Then it is a piece of cake to convert it to PHP\displaystyle \text{PHP}.

To not let the circles collide is a little bit challenging. It will take me sometime to beat it, so I advise you to not depend on me. From time to time, I will post my progress. Here I provided two screen shots of a user who entered FIVE\displaystyle \bold{FIVE}.

View attachment 39495

💪💀💀


View attachment 39496
I haven't used java swing in some time. This is interesting. I can't really see your code.
I did solve the problem though. The number, diameter and position of the circles depend on existing data that comes from a database.

Thanks for your response.
 
Hi @SLSCoder,

Reading your first post, I struggled to see how anybody might help you unless they were familiar with this "app" you are using (about which you provided precious little detail). I also struggled to understand exactly what help it was you were hoping to get but, if I (eventually) understood correctly what you needed, it seemed to me that your second post suggested that you already had all the information you required.

My conclusion, if correct (and I can't guarantee that it is), was that all you were really asking was how to "position" any two circles which you wished to bring together to a point of tangency, so I went off and prepared a couple of pictures that might illustrate my suggested solution for you. When I next looked in, I noticed that another member had since posted a reply containing some program code. Now that may be of more use to you, I don't know because I have absolutely no expertise in php or Python (or java) scripting, but it didn't appear to directly address the issue I was thinking might answer your query, so I decided to go ahead and post this for your consideration.

You mentioned you "
aced geometry in high school" but have forgotten most of it so I think the best place to start may be a little revision on the Maths involved in the Geometry of a circle. Below is a slide I have put together for use when teaching Circles to HS students. Please have a look at it and ensure you understand it; any problems in that respect and I'm sure someone will be happy to explain further (you might wish to save the image so you can open it full size on your own device)...


So, any circle may be described by this general equation:- (xa)2+(yb)2=r2(x-a)^2+(y-b)^2=r^2
(where: the centre of the circle lies at the point: (a, b) and its radius is: r.)

Now, you appear to have access to the x & y coordinates of you circles and their radii (from how I read your 2nd post) and all you want to do is bring them "together" (touching each other) as you describe.

If we start with your first circle, its x-coordinate will place it somewhere along the x-axis ("
in the center on the x scale" you say). Both its y-coordinate and that of the next circle you wish to place are determined by their "avg" values. (I don't know whether this is some 'average' value or 'avg' stands for something else altogether; it doesn't matter, the 'avg' number is clearly each circle's centre's y-coordinate.)
So all you need to do is find the x-coordinate of the second circle such that its circumference touches that of the first one.

Am I right so far?

(Continued in the next post, as there's a damn nuisance of 10k characters per post!)
Obviously I wasn't very clear. Sorry about that.
Yes I had all the data. It's pulled from a database. I also already had the diameter and the vertical position of each circle.
All I needed was to set the horizontal position of each circle after the first (which is centered) so that no 2 circles collided.
I did solve the problem. I start by sorting them by diameter largest to smallest. Then I center the first horizontally.
Then I separate left from right based on if the circle to be set is odd in the list so I have left circles and right circles.
As I place them one at a time I I look for potential collision with any that have been set. If none it goes in the center horizontally.
If so, I place the circle to be placed just past the far (left or right) edge of the circle it might collide with.
Then in a loop I move it back 1 pixel until I see a collision on 1 point per the function I show above.
The circle has a very small border that is invisible so that sets it 'almost' in collision with the one already set.

I appreciate all your help here. I'll study it. Maybe it will help me make the functionality more efficient.
 
I haven't used java swing in some time. This is interesting. I can't really see your code.
I did solve the problem though. The number, diameter and position of the circles depend on existing data that comes from a database.

Thanks for your response.
My code at this stage is garbage as it is just a way to let me start from somewhere. Therefore, you don't need it. I am so interested to know how did you solve the problem! How did you know that the code in post #2\displaystyle 2 was either correct or not correct. And if it was not correct, how did you fix it? Can you also share the data that these circles depend on?

I know that you are a very busy person. But if you got a free time, and it was okay for you to explain to me what was the exact problem you faced at the beginning (I know that part of it you don't know how to position the circles) and how did you discover the solution to fix it.

I also will be so glad if you can explain the code in post #2\displaystyle 2 and how it works!

💪😸😸
 
Hi @SLSCoder,

Reading your first post, I struggled to see how anybody might help you unless they were familiar with this "app" you are using (about which you provided precious little detail). I also struggled to understand exactly what help it was you were hoping to get but, if I (eventually) understood correctly what you needed, it seemed to me that your second post suggested that you already had all the information you required.

My conclusion, if correct (and I can't guarantee that it is), was that all you were really asking was how to "position" any two circles which you wished to bring together to a point of tangency, so I went off and prepared a couple of pictures that might illustrate my suggested solution for you. When I next looked in, I noticed that another member had since posted a reply containing some program code. Now that may be of more use to you, I don't know because I have absolutely no expertise in php or Python (or java) scripting, but it didn't appear to directly address the issue I was thinking might answer your query, so I decided to go ahead and post this for your consideration.

You mentioned you "
aced geometry in high school" but have forgotten most of it so I think the best place to start may be a little revision on the Maths involved in the Geometry of a circle. Below is a slide I have put together for use when teaching Circles to HS students. Please have a look at it and ensure you understand it; any problems in that respect and I'm sure someone will be happy to explain further (you might wish to save the image so you can open it full size on your own device)...


So, any circle may be described by this general equation:- (xa)2+(yb)2=r2(x-a)^2+(y-b)^2=r^2
(where: the centre of the circle lies at the point: (a, b) and its radius is: r.)

Now, you appear to have access to the x & y coordinates of you circles and their radii (from how I read your 2nd post) and all you want to do is bring them "together" (touching each other) as you describe.

If we start with your first circle, its x-coordinate will place it somewhere along the x-axis ("
in the center on the x scale" you say). Both its y-coordinate and that of the next circle you wish to place are determined by their "avg" values. (I don't know whether this is some 'average' value or 'avg' stands for something else altogether; it doesn't matter, the 'avg' number is clearly each circle's centre's y-coordinate.)
So all you need to do is find the x-coordinate of the second circle such that its circumference touches that of the first one.

Am I right so far?

(Continued in the next post, as there's a damn nuisance of 10k characters per post!)
Isn't radius diamater/2? If not my solution doesn't work. They look right though.
I have created the following example to illustrate the process. I used specific numbers (a Pythagorean triple) to keep the arithmetic simple but this will work for any circles' data and the more decimal numbers you work to, the better looking your result(s) will be.

I started with a first circle, called (say) "forklift", whose "
avg" I set to 10. I then decided (randomly) that the "centre" of the graph would lie at 15 along the x-axis, so the centre of this circle would lie at (15, 10) and I also set its radius to be 9 units. I then plotted this circle in Desmos in blue (as shown below). I then plotted a second circle called "lift" (in red) whose radius is 4 units with its centre lying at the point (38, 15) because its "avg" is 15 (and it lies off to the right of "forklift").

In order to make "lift" touch "forklift" (the way I think you want it to) all you need to do is find the x-coordinate for "lift" that will move it to the position shown when it is re-drawn in green (qv). Both circles' y-coordinates are fixed (by their "avg" values) and you know the radii of each, so, given the x-coordinate of one, it's a simple matter to calculate an x-coordinate for the second to make their circumferences tangential.

You simply add their radii together (which will give the distance you want their centers to be apart) and find the difference between their "
avg" values (ie: their y-coordinates). Then you take the square of the first number and subtract the square of the second and find the square root of the result.

Looking at the picture, you can see that their radii add to 13 (9 + 4) and the difference between their "
avg's" is 5 (15 - 10) so...13252=16925=144 and 144=1213^2-5^2=169-25=144\text{ and }\sqrt{144}=12
Therefore, the difference between the x-coordinates of their centres needs to be 12.

So re-plotting "lift" (in green) with its centre at (27, 15) brings it into contact with "forklift" just as desired.

Note that the x-coordinate of "lift" is now 12 greater than that of "forklift" whilst their y-coordinates remain unchanged (at 10 & 15 respectively).



This "method" will work just as effectively regardless of whether the second circle is to the left or right of or above or below the first one; you only need to calculate the required difference between their x-coordinates to make them "touch" each other.

Note too that, once you have arranged all your circles in the desired (relative) positions, all you then need to do is look at the leftmost circle and determine how far its x-coordinate is from the "
left edge of the graph" and then subtract that amount from the x-coordinate of all the circles to move them all, en masse, to the required final position.

You may wish to save this picture too (just right-click it and choose: "
Save image as...") so you can view it full-size on your own device (and zoom into it to see any areas in more detail) but you can also visit the Desmos page where I created it and, if you wish, play around with different values for the circles and their centres.

You can access the Desmos page here. You should there see that I entered, at the LHS, the equations for the three circles (followed by the points for their centres) in blue, red & green; if you alter an equation you may need to change its centre's point too.

The subsequent entries (in black) were just there to create the lines (of the right-angled triangle) and should probably just be deleted before you try changing anything about the circles.

Please let us know if this goes any way toward solving your problem. If not, then I'm afraid you may just have to wait until @logistic_guy gets around to developing his code for you but I'd like to hear you thoughts on what I've suggested anyway?

Hope that helps. 😊
WOW! I think your solution beats mine by a lot. I don't have to 'scoot' it left or right, just use math.
I think I can skip some of it because I determine the diameter from the width of the graph (which I didn't tell you I have sorry) and the count.
That is, I have the diameter so I have radius (dia/2 correct?).

I'll have to work through the math but I like it.
I'll see if I can implement it and let you know what I come up with.
Thanks very much.
 
I have created the following example to illustrate the process. I used specific numbers (a Pythagorean triple) to keep the arithmetic simple but this will work for any circles' data and the more decimal numbers you work to, the better looking your result(s) will be.

I started with a first circle, called (say) "forklift", whose "
avg" I set to 10. I then decided (randomly) that the "centre" of the graph would lie at 15 along the x-axis, so the centre of this circle would lie at (15, 10) and I also set its radius to be 9 units. I then plotted this circle in Desmos in blue (as shown below). I then plotted a second circle called "lift" (in red) whose radius is 4 units with its centre lying at the point (38, 15) because its "avg" is 15 (and it lies off to the right of "forklift").

In order to make "lift" touch "forklift" (the way I think you want it to) all you need to do is find the x-coordinate for "lift" that will move it to the position shown when it is re-drawn in green (qv). Both circles' y-coordinates are fixed (by their "avg" values) and you know the radii of each, so, given the x-coordinate of one, it's a simple matter to calculate an x-coordinate for the second to make their circumferences tangential.

You simply add their radii together (which will give the distance you want their centers to be apart) and find the difference between their "
avg" values (ie: their y-coordinates). Then you take the square of the first number and subtract the square of the second and find the square root of the result.

Looking at the picture, you can see that their radii add to 13 (9 + 4) and the difference between their "
avg's" is 5 (15 - 10) so...13252=16925=144 and 144=1213^2-5^2=169-25=144\text{ and }\sqrt{144}=12
Therefore, the difference between the x-coordinates of their centres needs to be 12.

So re-plotting "lift" (in green) with its centre at (27, 15) brings it into contact with "forklift" just as desired.

Note that the x-coordinate of "lift" is now 12 greater than that of "forklift" whilst their y-coordinates remain unchanged (at 10 & 15 respectively).



This "method" will work just as effectively regardless of whether the second circle is to the left or right of or above or below the first one; you only need to calculate the required difference between their x-coordinates to make them "touch" each other.

Note too that, once you have arranged all your circles in the desired (relative) positions, all you then need to do is look at the leftmost circle and determine how far its x-coordinate is from the "
left edge of the graph" and then subtract that amount from the x-coordinate of all the circles to move them all, en masse, to the required final position.

You may wish to save this picture too (just right-click it and choose: "
Save image as...") so you can view it full-size on your own device (and zoom into it to see any areas in more detail) but you can also visit the Desmos page where I created it and, if you wish, play around with different values for the circles and their centres.

You can access the Desmos page here. You should there see that I entered, at the LHS, the equations for the three circles (followed by the points for their centres) in blue, red & green; if you alter an equation you may need to change its centre's point too.

The subsequent entries (in black) were just there to create the lines (of the right-angled triangle) and should probably just be deleted before you try changing anything about the circles.

Please let us know if this goes any way toward solving your problem. If not, then I'm afraid you may just have to wait until @logistic_guy gets around to developing his code for you but I'd like to hear you thoughts on what I've suggested anyway?

Hope that helps. 😊

OK I've worked this much out so far:
DiameterPercent: ((array index.Count/GndTotal) * .85) rounded 2 decimals
Diameter: DiameterPercent * GraphWidth
CircleRadius: Diameter/2
CircleYMiddle: (LabelHeight * LabelIndexInScale) + (LabelHeight/2);
CircleTop: CircleMiddle - Radius

We have the radius and the top of each circle.
We need to place them horizontally so that they touch but don't intersect (if collision is possible).

GraphWidth: 700
LabelHeight: 37.7
ScaleCount: 21 (-10 to 10)
YCenter: 350 (700/2)

Circles:
Forklift: array index: 0, count: 21, avg: 1, diameter: 196, top: 261.5, center(130.8, 350)
Lift: array index: 1, count: 11, avg: 4, diameter: 105, top: 193.6
steering: array index: 2, count: 11, avg: 4, diameter: 105, top: 193.6
Brakes: array index: 3, count: 10, avg: -3, diameter: 91, top: 193.6
Tilt: array index: 4, count: 10, avg: 6, diameter: 91, top: 193.6
GndTotal: 62

From here reference to a circle is indicated by its index
rad1 = 98, rad2 = 52.2 -> 98 + 52.2 = 150.2
y1 = 359.5, y2 = 141.4 -> 359.5 - 141.4 = 218.3 (is that right?)
y1² = 129,240.25, y2² = 19,993.96 -> 129,240.25 - 19,993.96 = 109,246.29
√109,246.29 = 330.52

You lost me on the last step. How do I find the x coord of 2?
 
From here reference to a circle is indicated by its index
rad1 = 98, rad2 = 52.2 -> 98 + 52.2 = 150.2
y1 = 359.5, y2 = 141.4 -> 359.5 - 141.4 = 218.3 (is that right?)
y1² = 129,240.25, y2² = 19,993.96 -> 129,240.25 - 19,993.96 = 109,246.29
√109,246.29 = 330.52
You lost me on the last step. How do I find the x coord of 2?
Thank you for responding (so many just don't bother! 😢 lol).

I'm afraid your list of variables (that I presume are specific to the scripting language in your app) are too many and varied for me to get my head around at this time of night so I won't attempt to provide you with an answer in terms of those variables. I'll just try to simplify what I already said but, reading you latest posts, I'm now concerned that I may have misinterpreted exactly what you are trying to achieve.

I thought you wanted to re-position your circles such that their circumferences actually touched each other but I'm now wondering whether you simply wish to have their edges aligned. So I will attempt show the formula you would need to employ for each case.


My formulae deal only with the x & y coordinates of the circles and their radii.

I am assuming that you can directly (or with simple manipulation) access the radius of any circle (yes, the radius is the diameter divided by 2) and the coordinates of its centre point (the y-coordinate being the y-coordinate of its "top" minus its radius if its top's coordinates are all you can directly access).

I believe that the height (ie: the y-coordinate of the centre point) of every circle is fixed (by their "
avg" value? Or by top - radius?) so in order to position any two circles you only need to consider what their x-coordinates should be.

Since circle centres have fixed y-coordinates, you only need to consider the difference between their x-coordinates.


Case 1. If you wish to render any two circles such that their circumferences touch each other (what I originally assumed) then you would use this formula:-

Δx=(radius+radius)2(yy)2\color{#348543}\Delta x\color{black}=\sqrt{(\color{#2D70B3}\text{radius}\color{black}+\color{#C3433F}\text{radius}\color{black})^2-(\color{#C3433F}y\color{black}-\color{#2D70B3}y\color{black})^2}
You are adding together their radii and squaring that sum, then finding the difference between their heights (centres' y-coordinates) and squaring that result, then subtracting the second number from the first and finding the square root of that answer.


This gives you the desired difference between the x-coordinates of the two circles' centres (Δx\displaystyle \color{#348543}\Delta x).

Once you have calculated Δx\displaystyle \color{#348543}\Delta x, you can add* it to the x-coordinate of the first circle to get the the (new) x-coordinate of the second circle and this will re-position the second circle as shown below.
* You will, of course, subtract Δx\displaystyle \color{#348543}\Delta x if the second circle is to lie to the left of the first.



Tangential circumferences.png
(I have just used colours throughout to identify circles, their radii & centre coordinates.)




Case 2. If, on the other hand, you simply wish to move the red circle such that its circumference is aligned vertically with the blue one's (ie: there's no "overlap") then Δx\displaystyle \color{#348543}\Delta x simply becomes the sum of their radii and so...

Δx=radius+radius\color{#348543}\Delta x\color{black}=\color{#2D70B3}\text{radius}\color{black}+\color{#C3433F}\text{radius}\color{black}
Which will produce the result shown below...

Aligned circumferences.png
Hope that helps. 😊
 
To summarize (if I've understood anything correctly, lol)

You need to access your starting data and work out for every circle what the (final) radius and the coordinates of its centre are to be on your graph (after 'scaling' them to fit your available graph width?).
(You can give them all the same x-coordinate to start with if you like; ideally, perhaps, half the width of your graph, ie: the middle of the x-axis.)

Then place them in order (by diameter?) and decide which are to be left or right of the largest.

Then deal with them in pairs.

Starting with the two largest, use the (appropriate) formula from the last post to now find the required difference (Δx\displaystyle \Delta x) in their x-coordinates. Add that difference to the x-coordinate of the largest to find the x-coordinate of the second largest.

Then repeat for the largest and the third largest but subtract Δx\displaystyle \Delta x this time (because it is to lie to the left of the largest.

Then repeat for the second largest and the fourth largest and so on....
 
Circles:
Forklift: array index: 0, count: 21, avg: 1, diameter: 196, top: 261.5, center(130.8, 350) Shouldn't this be (350, 130.8)???
And how do you get 130.8? Shouldn't it be 261.5 -
1962\displaystyle \frac{196}{2} = 261.5 - 98 = 163.5?

Lift: array index: 1, count: 11, avg: 4, diameter: 105, top: 193.6 And its centre is?
steering: array index: 2, count: 11, avg: 4, diameter: 105, top: 193.6 Centre?
Brakes: array index: 3, count: 10, avg: -3, diameter: 91, top: 193.6 Centre?
Tilt: array index: 4, count: 10, avg: 6, diameter: 91, top: 193.6 Centre?
GndTotal: 62

From here reference to a circle is indicated by its index
rad1 = 98, rad2 = 52.2 -> 98 + 52.2 = 150.2
y1 = 359.5, y2 = 141.4 -> 359.5 - 141.4 = 218.3 (is that right?) No, (359.5 - 141.4 = 218.1 not 218.3) but now you introduce completely different y values from previous ones (above)! (And centre of 2 is now below that of 1!!!)
y1² = 129,240.25, y2² = 19,993.96 -> 129,240.25 - 19,993.96 = 109,246.29
√109,246.29 = 330.52 This is the difference in the x values (Δx\displaystyle \Delta x) so just add it. (Or subtract it to go leftwards.)

You lost me on the last step. How do I find the x coord of 2?

Circle1 is centred at (x1, 359.2) and Circle2 at (x1+330.52, 141.4)
but your figures have left me all very confused! 🤷‍♂️
 
I hate to admit - I was wrong. I hate that lol. Where I got 130.8 I do not know.

A circle's y matches the y of the 'label' in the scale to the left (the numbers).
So circle 1 y = (label height (37.7) * number of labels (10)) - (label height/2) to put it in the middle of the correct label.
X was determined by starting past the edge of the furthest already set that the circle to set could intersect and then scooting 1 toward center until it touches the 'furthest' that was already set. Hope that makes sense.
I"ll change that to use your formula. Your first case was correct. I want them to just touch.
Actually there's an invisible border around each circle so visually they won't quite touch - perfect.

These are the coords my app came up with. Visually this looks right.
Circles:
idx: 0 forklift: cnt: 21 avg: 1 rad: 99 x: 350 y: 360.54
idx: 1 lift: cnt: 11 avg: 4 rad: 53 x: 451 y: 246.64
idx: 2 steering: cnt: 11 avg: 4 rad: 53 x: 249 y: 246.64
idx: 3 brakes: cnt: 10 avg: -3 rad: 46 x: 350 y: 512.39
idx: 4 tilt: cnt: 10 avg: 6 rad: 46 x: -505 y: 170.71
GndTotal: 62

I think I've got your formula now so I'll use that and see what happens.
I'll let you know what I find.
Thanks again for your responses.
 
MAGIC! It worked! Thank You!
The functions are easy to figure: Math.sqrt =square root, Math.pow = to the power of (in this case 2).
arTest is your blue circle, arSet is your red circle.
This functionality loops through all the indexes from 1 to end (4 in this case) so in this case your formula is calculated 4 times.
arSet.XCenter = arTest.XCenter + (Math.sqrt(Math.pow((arTest.ChtRad + arSet.ChtRad),2) - Math.pow((arSet.YChtMid - arTest.YChtMid), 2)));
arSet.XCenter = arTest.XCenter - (Math.sqrt(Math.pow((arTest.ChtRad + arSet.ChtRad),2) - Math.pow((arSet.YChtMid - arTest.YChtMid), 2)));

Oh, FYI - I watch Highlander pretty much every night. I just hate that my wife thinks Adrian Paul is 'hot' - lol.

1751279778490.png

Your formula alleviated this much code including that 'while' loop which had to keep executing until 'intersect'.
Your formula was exactly what I was looking for here. Again, thanks much!

arSet.ChtRight = arTest.ChtLeft - 2;
arSet.XCenter = arSet.ChtLeft + arSet.ChtRad;
arSet.ChtLeft = arSet.XCenter - arSet.ChtRad;
c1 = {x:arTest.XCenter,y:arTest.YChtMid,r:arTest.ChtRad};
c2 = {x:arSet.XCenter,y:arSet.YChtMid,r:arSet.ChtRad};
nIntersect = ck2CirclesIntersect(c1, c2);
nMoveLeft = 0;
while(nIntersect == -1) {
c2.x += 1;
nMoveLeft += 1;
nIntersect = ck2CirclesIntersect(c1, c2);
}
arSet.ChtLeft += nMoveLeft;
arSet.XCenter += nMoveLeft;
arSet.ChtRight += nMoveLeft;
 
MAGIC! It worked! Thank You!
The functions are easy to figure: Math.sqrt =square root, Math.pow = to the power of (in this case 2).
arTest is your blue circle, arSet is your red circle.
This functionality loops through all the indexes from 1 to end (4 in this case) so in this case your formula is calculated 4 times.
arSet.XCenter = arTest.XCenter + (Math.sqrt(Math.pow((arTest.ChtRad + arSet.ChtRad),2) - Math.pow((arSet.YChtMid - arTest.YChtMid), 2)));
arSet.XCenter = arTest.XCenter - (Math.sqrt(Math.pow((arTest.ChtRad + arSet.ChtRad),2) - Math.pow((arSet.YChtMid - arTest.YChtMid), 2)));

Oh, FYI - I watch Highlander pretty much every night. I just hate that my wife thinks Adrian Paul is 'hot' - lol.

View attachment 39515

Your formula alleviated this much code including that 'while' loop which had to keep executing until 'intersect'.
Your formula was exactly what I was looking for here. Again, thanks much!

arSet.ChtRight = arTest.ChtLeft - 2;
arSet.XCenter = arSet.ChtLeft + arSet.ChtRad;
arSet.ChtLeft = arSet.XCenter - arSet.ChtRad;
c1 = {x:arTest.XCenter,y:arTest.YChtMid,r:arTest.ChtRad};
c2 = {x:arSet.XCenter,y:arSet.YChtMid,r:arSet.ChtRad};
nIntersect = ck2CirclesIntersect(c1, c2);
nMoveLeft = 0;
while(nIntersect == -1) {
c2.x += 1;
nMoveLeft += 1;
nIntersect = ck2CirclesIntersect(c1, c2);
}
arSet.ChtLeft += nMoveLeft;
arSet.XCenter += nMoveLeft;
arSet.ChtRight += nMoveLeft;
Glad I was able to help and you finally got it sorted. (Looks impressive )👍

Both Adrian Paul and Christopher Lambert are complete imposters! Neither of them has a drop of Scottish blood in them.
(Ah'd hae baith ther heids aff in twa shakes o' ma claymore if they ever dared to come here! 🤣)
 
complete imposters! lol
I don't know how to set your response as 'correct answer'.
I'm writing some more on your topic that may be of interest (though it is somewhat critical) so look back in about an hour; I hope to have it finished by then.
 
Last edited:
I hate to admit - I was wrong. I hate that lol. Where I got 130.8 I do not know.

A circle's y matches the y of the 'label' in the scale to the left (the numbers).
So circle 1 y = (label height (37.7) * number of labels (10)) - (label height/2) to put it in the middle of the correct label.
X was determined by starting past the edge of the furthest already set that the circle to set could intersect and then scooting 1 toward center until it touches the 'furthest' that was already set. Hope that makes sense.
I"ll change that to use your formula. Your first case was correct. I want them to just touch.
Actually there's an invisible border around each circle so visually they won't quite touch - perfect.

These are the coords my app came up with. Visually this looks right.
Circles:
idx: 0 forklift: cnt: 21 avg: 1 rad: 99 x: 350 y: 360.54
idx: 1 lift: cnt: 11 avg: 4 rad: 53 x: 451 y: 246.64
idx: 2 steering: cnt: 11 avg: 4 rad: 53 x: 249 y: 246.64
idx: 3 brakes: cnt: 10 avg: -3 rad: 46 x: 350 y: 512.39
idx: 4 tilt: cnt: 10 avg: 6 rad: 46 x: -505 y: 170.71

GndTotal: 62

I think I've got your formula now so I'll use that and see what happens.
I'll let you know what I find.
Thanks again for your responses.
Hi again,

I've been reading (and re-reading) your posts and there appears (to me) to be something very wrong in the state of Denmark. I still can't get your numbers to "add up"!

Just for the heck of it, I thought I might run through the numbers you supplied above (I've coloured them blue, qv). It occurred to me (big mistake!) that I might just slot them into an Excel spreadsheet (to save me doing repetitive calculations) but it turned out that doing so became really quite complicated because it required several rather complex formulae and a number of conditional statements to handle all the vagaries of your presentation but, I persevered and eventually produced the table shown below.

However, before I even reached the complicated parts of the table construction, I immediately came up against several anomalies in your numbers! None of your y values were consistent with the circle positions you appeared to be aiming for. You give 360 for idx0 but then 246 for both idx1 & 2 which would place them lower in the graph than idx0 (when they should be above it). Similarly, you quote 512 for idx3 which places it above idx0 when it ought to be directly underneath it! You give idx4 the lowest y-value of the lot when it should actually be the highest circle and you also give it a (huge) negative x-coordinate (-505) which would whizz it right off the graph to the left! (Exit stage left followed by a bear, lol)
(You'll have to forgive my Shakespearean references, they just pop into my head as I write. 🤷‍♂️)

So it was back to re-reading your posts to try to figure out wtf was going on here.

First thing I noticed was "
So circle 1 y = (label height (37.7) * number of labels (10)) - (label height/2) to put it in the middle of the correct label." and this didn't make any sense to me at all. You have 21 labels (1 to10, -1 to -10 plus zero) so if each label has a height (on the graph) of 37.7 that makes the graph 791.7 from top to bottom which seems a very odd arrangement. It's 700 wide (you tell us) so I would have expected it to be 700 tall too (giving a label height of 33⅓; still not a great number to work with) or better still, maybe, use a label height that's a nice round number like 20 or 50 (or any other multiple of ten; 40 would make the graph 840 high).

And your "system" for calculating the y-value linked to the "
avg" value and the label height seemed inauspicious too. Why this multiplying by the number of labels (which is 21 not 10) and there should be no need to subtract "label height/2". The middle of the zero label is 0 on the y-axis, so the middle of labe1 1 is at 37.7 and label 2 at 75.4 (37.7 x 2) and so on...

So, when I couldn't get your numbers to produce the right results I just calculated (what I reckoned to be) the correct y-values myself.

Here is the table I ended up with...


Correxct Entries Table.png

I will go on to write more in a further post (below) to avoid any problem with character limits and I will explain more about the table's construction and the graph it produced but, in the meantime, here also is the graph I got (from my table)...

Correxct Entries+Scale.png

more to follow...
 
Last edited:
Top