From: Jason Pearson on
Hi Roger,
Thanks very much for taking the time to explain this in greater detail. Perhaps I'm missing something obvious, but how did you derive the algebraic formulas for the values of s and c? You show these formulas as:

s = ((q2-q1)*r+(p2-p1)*(r2-r1))/d2;
c = ((p2-p1)*r-(q2-q1)*(r2-r1))/d2;

I have drawn out the diagram as you suggest, sliding the tangent down until it intersects with C1. I have also drawn a horizontal line from C1 across to above/below C2, and a vertical line from the end of that horizontal to C2. This gives me two right triangles which share a hypotenuse (d).

From your formulas, I am assuming that these triangles somehow figure into your calculations, since for one triangle, the length of the horizontal would be (q2-q1), and the length of the vertical would be (p2-p1). And for the other triangle, the length of one leg would be r, and the length of the other leg would be (r2-r1).

Since these are the basic components of your formulas, I am assuming that there is some geometrical law that I am forgetting or never learned that says that, for two right triangles that share a hypotenuse (h), and whose legs are of length L1,W1,L2,W2, if the combined angle that they form is a, then sin(a) = ((H2*L1)+(H1*L2))/(h^2). And that cos(a) = ((H2*L1)-(H1*L2))/(h^2).

Am I inferring correctly that these are the geometrical laws upon which you are drawing? If so, do these laws/theorems have a specific name that I could Google so I can better understand why they are true (and how to tweak them for, say, an internal tangent)?

Thank you for any help that you could provide. You humbly pleaded age for any errors, and I will plead extreme rustiness in return! It has been over twenty-five years since I actively used my geometry/trig skills, and I've forgotten a lot...

Best wishes,

Jason Pearson

> Here is an explanation of the quantities I used in step one as per your request. Call the centers of the two circles C1 =(p1,q1) and C2 = (p2,q2) and the two corresponding points of tangency T1 = (x1,y1) and T2 = (x2,y2). Then d2 is the square of the distance between the centers, while r is the distance between T1 and T2. You can see this latter by sliding the line segment connecting T1 and T2 to a parallel line segment running through C1 and apply pythagoras theorem. The quantity s is the sine of the angle measured counterclockwise from the x-axis to the above line segment (parallel to line T1T2) while c is the cosine of that angle. This angle is the sum of the angle from the x-axis to the line C1C2 and the angle from C1C2 to the above segment. Then x1, y1, x2, and y2 are obtained in the obvious way from that.
>
> Let me know if this explanation is too brief and I'll go into more detail.
>
> Roger Stafford
From: Roger Stafford on
"Jason Pearson" <jason.c.pearson.xyxy(a)gmail.replace> wrote in message <i3dh1g$i8g$1(a)fred.mathworks.com>...
> Hi Roger,
> Thanks very much for taking the time to explain this in greater detail. Perhaps I'm missing something obvious, but how did you derive the algebraic formulas for the values of s and c? You show these formulas as:
>
> s = ((q2-q1)*r+(p2-p1)*(r2-r1))/d2;
> c = ((p2-p1)*r-(q2-q1)*(r2-r1))/d2;
>
> I have drawn out the diagram as you suggest, sliding the tangent down until it intersects with C1. I have also drawn a horizontal line from C1 across to above/below C2, and a vertical line from the end of that horizontal to C2. This gives me two right triangles which share a hypotenuse (d).
>
> From your formulas, I am assuming that these triangles somehow figure into your calculations, since for one triangle, the length of the horizontal would be (q2-q1), and the length of the vertical would be (p2-p1). And for the other triangle, the length of one leg would be r, and the length of the other leg would be (r2-r1).
>
> Since these are the basic components of your formulas, I am assuming that there is some geometrical law that I am forgetting or never learned that says that, for two right triangles that share a hypotenuse (h), and whose legs are of length L1,W1,L2,W2, if the combined angle that they form is a, then sin(a) = ((H2*L1)+(H1*L2))/(h^2). And that cos(a) = ((H2*L1)-(H1*L2))/(h^2).
>
> Am I inferring correctly that these are the geometrical laws upon which you are drawing? If so, do these laws/theorems have a specific name that I could Google so I can better understand why they are true (and how to tweak them for, say, an internal tangent)?
>
> Thank you for any help that you could provide. You humbly pleaded age for any errors, and I will plead extreme rustiness in return! It has been over twenty-five years since I actively used my geometry/trig skills, and I've forgotten a lot...
>
> Best wishes,
>
> Jason Pearson
- - - - - - - - - - -
I was afraid I might have hand-waved over that stuff too fast. I think you have the two right triangles I had in mind, but I'll start from the beginning.

Assume for our purposes that r2 > r1 and that the center C2 is above and to the right of C1. Assume further that we are talking about the tangent line being to the left of the two circles. Then draw the line through C1 parallel to the T1T2 line and call point U where it intersects with line C2T2. Finally drop a line vertically down from C2 until it intersects a horizontal line from C1 and call that intersection V. Then, as you said, triangles C1UC2 and C1VC2 are right triangles that share a common hypotenuse in segment C1C2 which is of length d = sqrt(d2) (in the code.) Since C2U is of length r2-r1, then C1U must be of length r = sqrt(d^2-(r2-r1)^2), (again as in the code.)

Call angle VC1C2 alpha and call angle C2C1U beta. Because these are right triangles we have

sin(alpha) = C2V/C1C2 = (q2-q1)/d
cos(alpha) = C1V/C1C2 = (p2-p1)/d
sin(beta) = C2U/C1C2 = (r2-r1)/d
cos(beta) = C1U/C1C2 = r/d

Recall that I said that s and c are to be the sine and cosine respectively of the sum of these two angles alpha and beta, so using the trig summation formulas we have

s = sin(alpha+beta) = sin(alpha)*cos(beta) + cos(alpha)*sin(beta)
= (q2-q1)/d*r/d + (p2-p1)/d*(r2-r1)/d = ((q2-q1)*r+(p2-p1)*(r2-r1))/d2
c = cos(alpha+beta) = cos(alpha)*cos(beta) - sin(alpha)*sin(beta)
= (p2-p1)/d*r/d - (q2-q1)/d*(r2-r1)/d = ((p2-p1)*r-(q2-q1)*(r2-r1))/d2

which are carried out in the code.

Finally for angle VC1T1 = alpha + beta + pi/2 we have

x1 = p1 + r1*cos(alpha+beta+pi/2)
= p1 - r1*sin(alpha+beta) = p1 - r1*s
y1 = q1 + r1*sin(alpha+beta+pi/2)
= q1 + r1*cos(alpha+beta) = q1 + r1*c
x2 = p2 + r2*cos(alpha+beta+pi/2) = p2 - r2*s
y2 = q2 + r2*sin(alpha+beta+pi/2) = q2 + r2*c

Of course a rigorous proof of this would take into consideration other possible orientations of the circles and having r2 < r1. It's a lot of additional work but it all comes out fine. Some of the angles would then be negative but the same formulas still give the proper answer. For our purposes here it should probably suffice to generate random circles in all possible orientations and relative sizes, and check the results with appropriate plots, which is what I did for a check back in March of 2009 when I wrote those formulas.

As you guessed earlier in this thread, it is possible to make small changes in these formulas to get the other three possible tangents to the circles: the outside one to the right, the one that is to the left of C1 and to the right of C2, and the one that is to the right of C1 and left of C2. However, I'll confess I never did bother to work them out. I encourage you to see if you can do it yourself after being armed with all the above techniques. If you do, be sure to write plotting routines that test them thoroughly in all possible orientations if you want to make serious use of them. It will also be good practice for writing matlab code in general.

Roger Stafford
From: Jason Pearson on
Roger,
Thank you for this wonderfully clear response. This makes perfect sense, and it does, indeed, equip me with the necessary tools to experiment with code variations to produce the different tangents that I want. I'm using these calculations to correctly locate the curved portions of the shapes for a dynamic Sankey flow diagram (en.wikipedia.org/wiki/Sankey_diagram), which I am initially coding in Processing (www.processing.org) and then exporting as a Java applet. If it works out as I hope, I'll send you a copy or link to see the final result.
Thank you again!
Best,
Jason Pearson

"Roger Stafford" <ellieandrogerxyzzy(a)mindspring.com.invalid> wrote in message <i3do0l$8pk$1(a)fred.mathworks.com>...
> "Jason Pearson" <jason.c.pearson.xyxy(a)gmail.replace> wrote in message <i3dh1g$i8g$1(a)fred.mathworks.com>...
> > Hi Roger,
> > Thanks very much for taking the time to explain this in greater detail. Perhaps I'm missing something obvious, but how did you derive the algebraic formulas for the values of s and c? You show these formulas as:
> >
> > s = ((q2-q1)*r+(p2-p1)*(r2-r1))/d2;
> > c = ((p2-p1)*r-(q2-q1)*(r2-r1))/d2;
> >
> > I have drawn out the diagram as you suggest, sliding the tangent down until it intersects with C1. I have also drawn a horizontal line from C1 across to above/below C2, and a vertical line from the end of that horizontal to C2. This gives me two right triangles which share a hypotenuse (d).
> >
> > From your formulas, I am assuming that these triangles somehow figure into your calculations, since for one triangle, the length of the horizontal would be (q2-q1), and the length of the vertical would be (p2-p1). And for the other triangle, the length of one leg would be r, and the length of the other leg would be (r2-r1).
> >
> > Since these are the basic components of your formulas, I am assuming that there is some geometrical law that I am forgetting or never learned that says that, for two right triangles that share a hypotenuse (h), and whose legs are of length L1,W1,L2,W2, if the combined angle that they form is a, then sin(a) = ((H2*L1)+(H1*L2))/(h^2). And that cos(a) = ((H2*L1)-(H1*L2))/(h^2).
> >
> > Am I inferring correctly that these are the geometrical laws upon which you are drawing? If so, do these laws/theorems have a specific name that I could Google so I can better understand why they are true (and how to tweak them for, say, an internal tangent)?
> >
> > Thank you for any help that you could provide. You humbly pleaded age for any errors, and I will plead extreme rustiness in return! It has been over twenty-five years since I actively used my geometry/trig skills, and I've forgotten a lot...
> >
> > Best wishes,
> >
> > Jason Pearson
> - - - - - - - - - - -
> I was afraid I might have hand-waved over that stuff too fast. I think you have the two right triangles I had in mind, but I'll start from the beginning.
>
> Assume for our purposes that r2 > r1 and that the center C2 is above and to the right of C1. Assume further that we are talking about the tangent line being to the left of the two circles. Then draw the line through C1 parallel to the T1T2 line and call point U where it intersects with line C2T2. Finally drop a line vertically down from C2 until it intersects a horizontal line from C1 and call that intersection V. Then, as you said, triangles C1UC2 and C1VC2 are right triangles that share a common hypotenuse in segment C1C2 which is of length d = sqrt(d2) (in the code.) Since C2U is of length r2-r1, then C1U must be of length r = sqrt(d^2-(r2-r1)^2), (again as in the code.)
>
> Call angle VC1C2 alpha and call angle C2C1U beta. Because these are right triangles we have
>
> sin(alpha) = C2V/C1C2 = (q2-q1)/d
> cos(alpha) = C1V/C1C2 = (p2-p1)/d
> sin(beta) = C2U/C1C2 = (r2-r1)/d
> cos(beta) = C1U/C1C2 = r/d
>
> Recall that I said that s and c are to be the sine and cosine respectively of the sum of these two angles alpha and beta, so using the trig summation formulas we have
>
> s = sin(alpha+beta) = sin(alpha)*cos(beta) + cos(alpha)*sin(beta)
> = (q2-q1)/d*r/d + (p2-p1)/d*(r2-r1)/d = ((q2-q1)*r+(p2-p1)*(r2-r1))/d2
> c = cos(alpha+beta) = cos(alpha)*cos(beta) - sin(alpha)*sin(beta)
> = (p2-p1)/d*r/d - (q2-q1)/d*(r2-r1)/d = ((p2-p1)*r-(q2-q1)*(r2-r1))/d2
>
> which are carried out in the code.
>
> Finally for angle VC1T1 = alpha + beta + pi/2 we have
>
> x1 = p1 + r1*cos(alpha+beta+pi/2)
> = p1 - r1*sin(alpha+beta) = p1 - r1*s
> y1 = q1 + r1*sin(alpha+beta+pi/2)
> = q1 + r1*cos(alpha+beta) = q1 + r1*c
> x2 = p2 + r2*cos(alpha+beta+pi/2) = p2 - r2*s
> y2 = q2 + r2*sin(alpha+beta+pi/2) = q2 + r2*c
>
> Of course a rigorous proof of this would take into consideration other possible orientations of the circles and having r2 < r1. It's a lot of additional work but it all comes out fine. Some of the angles would then be negative but the same formulas still give the proper answer. For our purposes here it should probably suffice to generate random circles in all possible orientations and relative sizes, and check the results with appropriate plots, which is what I did for a check back in March of 2009 when I wrote those formulas.
>
> As you guessed earlier in this thread, it is possible to make small changes in these formulas to get the other three possible tangents to the circles: the outside one to the right, the one that is to the left of C1 and to the right of C2, and the one that is to the right of C1 and left of C2. However, I'll confess I never did bother to work them out. I encourage you to see if you can do it yourself after being armed with all the above techniques. If you do, be sure to write plotting routines that test them thoroughly in all possible orientations if you want to make serious use of them. It will also be good practice for writing matlab code in general.
>
> Roger Stafford
From: Jason Pearson on
Roger,
I have completed the first phase of code development for the Sankey flow creator, using your excellent advice on tangents as a basis. I'm quite pleased with the results.
If you would like me to send you a ZIP of the resulting Java applet, just let me know. I tried to decipher your email address, but it gave me an error. Feel free to email me on mine - just remove the xy stuff and replace the domain suffix with the obvious.
Best,
Jason Pearson