1
\$\begingroup\$

enter image description here

C2 and P1 are known points. Radius of circle C2 is also constant and known. I am trying to find point T to eventually construct line p1-t, which is tangent to circle c2.

I have made an attempt involving bisecting c2-p1 at M, and performing trigonometric operations to find measure of angle TMC2. Then, I found the difference in x and y coordinates from m.x and m.y using a polar form to cartesian (polar: angle tmc2 and length of tm = c2m = 1/2 c2P). After this, I normalized vectors c2P and added the difference in x, normalized the vector perpendicular to c2p and added the difference in y.

This approach seems very convoluted for such a simple task. Are there any basic vector operations to save time and processing power?

Thank you

\$\endgroup\$
3
  • \$\begingroup\$ There are infinite number of circles that you can make that will result in T be tangent if all you have is C2 and P1 as points. Is P1 really just a point, or is it a line? If its a line and you are just trying to find where T is on the line, you can solve it. But if P1 is just a point, you can pick and infinite number of T's and then construct a circle that will make the line (T-P1) tangent to the circle. \$\endgroup\$
    – default
    Commented Feb 21, 2017 at 19:18
  • \$\begingroup\$ The radius of the circle is constant and known as well. \$\endgroup\$
    – Danyil Bee
    Commented Feb 21, 2017 at 20:23
  • \$\begingroup\$ @Steven that is impossible, since c2-t-p1 is a triangle, and c2t is perp. to tp1 because tp1 is a tangent. \$\endgroup\$
    – Danyil Bee
    Commented Feb 22, 2017 at 3:33

2 Answers 2

2
\$\begingroup\$

It's pretty easy with some trigonometry.

Here's a hand drawn image of your problem:

enter image description here

OTP angle is a right angle.

Calculating l is done with the pythagorean theorem:

l = sqrt(d^2 - r^2)

You first want to calculate alpha. This is where the trigonometry part comes in.

tan(alpha) = r / l
alpha = atan2(r, l)

After you have alpha, you need to calculate the angle of PT relative to the coordinate system (let' call it beta). This is done by calculating the angle of PO (let's call it gamma) then subtracting alpha from it:

vector := O - P // vector pointing from P to O
gamma = atan2(vector.y, vector.x)
beta := gamma - alpha

Then finally you convert it to a directional vector with a length l and you add P to it

x := cos(beta) * l + P.x
y := sin(beta) * l + P.y
\$\endgroup\$
6
  • \$\begingroup\$ Thank you for your efforts. May you further explain "calculating the angle of PT(a line) relative to the coordinate system?" An issue that I came across in my solution was "Translating" to a global coordinate system. This seems to have solved this issue, but I do not understand why. \$\endgroup\$
    – Danyil Bee
    Commented Feb 21, 2017 at 21:18
  • \$\begingroup\$ @Danyil If you imagine a coordinate system with an origin in P, then a direction vector with an angle 0° points in the positive x direction. Because d is going from P to O, you can imagine it as a direction vector and you can calculate it's angle relative to the coordinate system. \$\endgroup\$
    – Bálint
    Commented Feb 21, 2017 at 21:35
  • \$\begingroup\$ @Steven to consider the case where intersects the circle, we'd need to ignore OP's condition that it is tangent to the circle. \$\endgroup\$ Commented Feb 22, 2017 at 4:13
  • \$\begingroup\$ @DrewCummins I'm not suggesting ℓ is not tangent to the circle; I'm pointing out that the angle between OT and OP isn't a square angle. Doesn't that preclude calculating the length of ℓ via pythagorean? \$\endgroup\$
    – Steven
    Commented Feb 22, 2017 at 17:23
  • \$\begingroup\$ @Steven Given that is tangent to the circle, the line segment OT is necessarily perpendicular to . OTP therefore is a right triangle. There is the degenerate case where P is on the circle, in which case T = P. @Bálint's and my answer both handle this case. \$\endgroup\$ Commented Feb 22, 2017 at 18:21
1
\$\begingroup\$

You can solve this without trigonometric functions, too.

Since the vector u = T - C is perpendicular to the vector v = T - P, the dot product u . v = 0. You also know the lengths of 2 sides of a right triangle (the radius r and ||C - P||).

This allows you to write 2 equations in the 2 unknown elements of T, which you can then solve:

(T-C) . (T-P) = 0
        |T-P| = |C-P| - r^2

where |X| is the squared length of the vector X.

But this might be annoying to solve, so you can further exploit that in 2D, the vector [x,y] is perpendicular to the vector [-y,x]. And so we can instead write the equation:

T = P + u' t = C + u r

where u' is [-uy,ux] and t = ||T-P|| = sqrt(|C-P| - r^2)--which we have to solve for u. This gives us:

ux = (r * (Px - Cx) - t * (Py - Cy))/(r^2 + t^2)
uy = (r * (Py - Cy) + t * (Px - Cx))/(r^2 + t^2)

and therefore:

Tx = Cx + ux * r
Ty = Cy + uy * r

There is an unfortunate caveat--one other vector is perpendicular to [x,y] at [y,-x], which is a clockwise rotation instead of counterclockwise. There are simple tests you can use to decide which to go with, but one or the other might suit you in practice.

This all involves only one sqrt call and so it may be less computationally expensive than Baliant's answer.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .