Calculating intersection point of two tangents on one circle? - math

I tried using a raycasting-style function to do it but can't get any maintainable results. I'm trying to calculate the intersection between two tangents on one circle. This picture should help explain:
I've googled + searched stackoverflow about this problem but can't find anything similar to this problem. Any help?

Well, if your variables are:
C = (cx, cy) - Circle center
A = (x1, y1) - Tangent point 1
B = (x2, y2) - Tangent point 2
The lines from the circle center to the two points A and B are CA = A - C and CB = B - C respectively.
You know that a tangent is perpendicular to the line from the center. In 2D, to get a line perpendicular to a vector (x, y) you just take (y, -x) (or (-y, x))
So your two (parametric) tangent lines are:
L1(u) = A + u * (CA.y, -CA.x)
= (A.x + u * CA.y, A.y - u * CA.x)
L2(v) = B + v * (CB.y, -CB.x)
= (B.x + v * CB.y, B.x - v * CB.x)
Then to calculate the intersection of two lines you just need to use standard intersection tests.

The answer by Peter Alexander assumes that you know the center of the circle, which is not obvious from your figure http://oi54.tinypic.com/e6y62f.jpg.
Here is a solution without knowing the center:
The point C (in your figure) is the intersection of the tangent at A(x, y) with the line L perpendicular to AB, cutting AB into halves. A parametric equation for the line L can be derived as follows:
The middle point of AB is M = ((x+x2)/2, (y+y2)/2), where B(x2, y2). The vector perpendicular to AB is N = (y2-y, x-x2). The vector equation of the line L is hence
L(t) = M + t N, where t is a real number.

Related

closest point on a box to a line

I have drawn a 2D representation of the problem, but I will eventually have to solve this in 3 dimensions.
A line is drawn from an origin point to infinity, in a direction given by pitch and yaw. There is an axis-aligned box "in front of" the point.
I want to get the coordinates of the point on box that is closest to the line, or, if it intersects, closest to the origin point.
I.e., if the line were 'turned' towards the box, which point of the box would intersect with the line first?
Make parametric represenation of the ray with base point P0, direction vector D and parameter t
P = P0 + t * D
Get t for intersections of the ray with rectangle edges like this (similar in 3d):
Rect.Right = X0 + t * D.X
Find what intersection occurs first (smaller t), check coordinates of intersection. If inside edge - point found. If not, analyze intersection parameters with edgr continuations to determine what corner (perhaps edge in 3d) is the closest
Note that in 2d case you need to check only two possible edges - depending on ray direction. For example - left and bottom for your right picture. When you see that intersections are out of edges - check what of two corners is closer. The same for 3d - but intersection is possible for three faces and closest for more edges or corners.
Let the position of the point be (x0,y0,z0) and the box have corners (x1,y1,z1) and (x2,y2,z2) with x1 < x2, y1 < y2, z1 < z2. In terms of yaw ψ and pitch θ a unit vector along the line will be give by
(u,v,w) = (cos ψ sin θ, sin ψ, cos ψ cos θ)
The line is (x0,y0,z0) + t (u,v,w)
Finding intersection with one of the plane containing a face of the box is trivial. Say to find the intersection with the plane x=x1, just requires solving
x0 + u t = x1 so t = (x1-x0)/u. Once found its easy to check if the intersection is contained in the face.
The tricky situation happens if the line does not intersect the faces. Here we have a pair of skew lines, and wish to find the closest pair of points one on each line.
Consider the closest point to the edge from (x1,y1,z1) to (x2,y1,z1).
We want to find the parameter s,t such that that the points
(x0,y0,z0)+s(u,v,w)
(x1,y1,z1)+t(1,0,0)
are the closest. The segment joining these points must be perpendicular to both lines. A vector along that line is the cross product
N = (u,v,w) X (1,0,0) = (0,w,-v)
Now consider the plane through (x1,y1,z1) spanned by (1,0,0) and N, this has normal
N2 = (1,0,0) X N
= (1,0,0) X (0,w,-v)
= (0,v,w)
and the plane is defined by
P . N2 = (x1,y1,z1) . N2
Take a point on our ray
( (x0,y0,z0)+s(u,v,w) ) . N2 = (x1,y1,z1) . N2
(x0,y0,z0) . N2 + s (u,v,w) . N2 = (x1,y1,z1) . N2
s (u,v,w) . N2 = ((x1,y1,z1)-(x0,y0,z0)) . N2
s (v^2+w^2) = (y1-y0) v + (z1-z0) w
so
s = [ (y1-y0) v + (z1-z0) w ] / (v^2+w^2)
We can repeat the above for each edge on the box, find the closest points and select the smallest.

Determine vertex in a "Isosceles Right Triangle"

Hi I have geometrical problem which is driving me crazy. I want to determine the location of one vertex in a "Isosceles Right Triangle" (alpha = 45°; beta = 45°; gamma = 90°).
E.g. in this illustration:
I have a,b,c,h and the location of A and B (and of cause the angle). The only thing thats missing is C in x,y terms. Can someone support me on this?
Here is code that works only for the 45°-45°-90° triangle--it would need to be modified for other triangles.
Note that all you need are the coordinates of A and B. c is then the distance between those two points, h is c/2, and both a and b are c/sqrt(2). This Python code returns a 2-tuple (Cx, Cy) giving the coordinates of C, assuming you want C to be oriented counterclockwise from the vector AB. If you want clockwise, replace the plus sign with a minus sign in the calculation that defines inclinationAC. This uses only basic trigonometry, showing each step--there are other methods, as Ed Heal says in his comment, but this should be more easily understood by most people.
from math import sqrt, hypot, pi, cos, sin, atan2
def corner_right_isoceles(Ax, Ay, Bx, By):
"""Return the coordinates of the right-angle corner of a right
isosceles triangle if the other two vertices are the points
(Ax, Ay) and (Bx, By). The returned corner is counterclockwise
from the vector AB.
"""
c = hypot(By - Ay, Bx - Ax)
b = c / sqrt(2)
inclinationAB = atan2(By - Ay, Bx - Ax)
inclinationAC = inclinationAB + pi / 4
Cx = Ax + b * cos(inclinationAC)
Cy = Ay + b * sin(inclinationAC)
return Cx, Cy
Here is another version, which is a bit simpler and with that also much more efficient to calculate. The idea is that h is exactly half of c in this triangle:
dx = Bx - Ax
dy = By - Ay
Cx = Ax + 0.5 * (dx - dy)
Cy = Ay + 0.5 * (dy + dx)

Position of a point in a circle

Hello again first part is working like a charm, thank you everyone.
But I've another question...
As I've no interface, is there a way to do the same thing with out not knowing the radius of the circle?
Should have refresh the page CodeMonkey solution is exactly what I was looking for...
Thank you again.
============================
First I'm not a developer, I'm a simple woodworker that left school far too early...
I'm trying to make one of my tool to work with an autonomous robot.
I made them communicate by reading a lot of tutorials.
But I have one problem I cant figure out.
Robot expect position of the tool as (X,Y) but tool's output is (A,B,C)
A is the distance from tool to north
B distance to east
C distance at 120 degree clockwise from east axe
the border is a circle, radius may change, and may or may not be something I know.
I've been on that for 1 month, and I can't find a way to transform those value into the position.
I made a test with 3 nails on a circle I draw on wood, and if I have the distance there is only one position possible, so I guess its possible.
But how?
Also, if someone as an answer I'd love pseudo code not code so I can practice.
If there is a tool to make a drawing I can use to make it clearer can you point it out to me?
Thank you.
hope it helps :
X, Y are coordinate from center, Da,Db, Dc are known.
Trying to make it more clear (sorry its so clear in my head).
X,Y are the coordinate of the point where is the tool (P).
Center is at 0,0
A is the point where vertical line cut the circle from P, with Da distance P to A;
B is the point where horizontal line cuts the circle fom P, with Db distance P to B.
C is the point where the line at 120 clockwise from horizontal cuts the circle from P, with Dc distance P to C.
Output from tool is an array of int (unit mm): A=123, B=114, C=89
Those are the only informations I have
thanks for all the ideas I'll try them at home later,
Hope it works :)
Basic geometry. I decided to give up having the circle at the origin. We don't know the center of the circle yet. What you do have, is three points on that circle. Let's try having the tool's position, given as P, as the new (0,0). This thus resolves to finding a circle given three points: (0, Da); (Db,0), and back off at 120° at Dc distance.
Pseudocode:
Calculate a line from A to B: we'll call it AB. Find AB's halfway point. Calculate a line perpendicular to AB, through that midpoint (e.g. the cross product of AB and a unit Z axis finds the perpendicular vector).
Calculate a line from B to C (or C to A works just as well): we'll call it BC. Find BC's halfway point. Calculate a line perpendicular to BC, through that midpoint.
Calculate where these two lines cross. This will be the origin of your circle.
Since P is at (0,0), the negative of your circle's origin will be your tool's coordinates relative to the circle's origin. You should be able to calculate anything you need relative to that, now.
Midpoint between two points: X=(X1+X2)/2. Y=(Y1+Y2)/2.
The circle's radius can be calculated using, e.g. point A and the circle's origin: R=sqrt(sqr((Ax-CirX)+sqr(Ay-CirY))
Distance from the edge: circle's radius - tool's distance from the circle's center via Pythagorean Theorem again.
Assume you know X and Y. R is the radius of the circle.
|(X, Y + Da)| = R
|(X + Db, Y)| = R
|(X - cos(pi/3) * Dc, Y - cos(pi/6) * Dc)| = R
Assuming we don't know the radius R. We can still say
|(X, Y + Da)|^2 = |(X + Db, Y)|^2
=> X^2 + (Y+Da)^2 = (X+Db)^2 + Y^2
=> 2YDa + Da^2 = 2XDb + Db^2 (I)
and denoting cos(pi/3)*Dc as c1 and cos(pi/6)*Dc as c2:
|(X, Y + Da)|^2 = |(X - c1, Y - c2)|^2
=> X^2 + Y^2 + 2YDa + Da^2 = X^2 - 2Xc1 + c1^2 + Y^2 - 2Yc2 + c2^2
=> 2YDa + Da^2 = - 2Xc1 + c1^2 - 2Yc2 + c2^2
=> Y = (-2Xc1 + c1^2 + c2^2 - Da^2) / 2(c2+Da) (II)
Putting (II) back in the equation (I) we get:
=> (-2Xc1 + c1^2 + c2^2 - Da^2) Da / (c2+Da) + Da^2 = 2XDb + Db^2
=> (-2Xc1 + c1^2 + c2^2 - Da^2) Da + Da^2 * (c2+Da) = 2XDb(c2+Da) + Db^2 * (c2+Da)
=> (-2Xc1 + c1^2 + c2^2) Da + Da^2 * c2 = 2XDb(c2+Da) + Db^2 * (c2+Da)
=> X = ((c1^2 + c2^2) Da + Da^2 * c2 - Db^2 * (c2+Da)) / (2Dbc2 + 2Db*Da + 2Dac1) (III)
Knowing X you can get Y by calculating (II).
You can also make some simplifications, e.g. c1^2 + c2^2 = Dc^2
Putting this into Python (almost Pseudocode):
import math
def GetXYR(Da, Db, Dc):
c1 = math.cos(math.pi/3) * Dc
c2 = math.cos(math.pi/6) * Dc
X = ((c1**2 + c2**2) * Da + Da**2 * c2 - Db * Db * (c2 + Da)) / (2 * Db * c2 + 2 * Db * Da + 2 * Da * c1)
Y = (-2*X*c1 + c1**2 + c2**2 - Da**2) / (2*(c2+Da))
R = math.sqrt(X**2 + (Y+Da)**2)
R2 = math.sqrt(Y**2 + (X+Db)**2)
R3 = math.sqrt((X - math.cos(math.pi/3) * Dc)**2 + (Y - math.cos(math.pi/6) * Dc)**2)
return (X, Y, R, R2, R3)
(X, Y, R, R2, R3) = GetXYR(123.0, 114.0, 89.0)
print((X, Y, R, R2, R3))
I get the result (X, Y, R, R2, R3) = (-8.129166703588021, -16.205081335032794, 107.1038654949096, 107.10386549490958, 107.1038654949096)
Which seems reasonable if both Da and Db are longer than Dc, then both coordinates are probably negative.
I calculated the Radius from three equations to cross check whether my calculation makes sense. It seems to fulfill all three equations we set up in the beginning.
Your problem is know a "circumscribed circle". You have a triangle define by 3 distances at given angles from your robot position, then you can construct the circumscribed circle from these three points (see Circumscribed circle from Wikipedia - section "Other properties"). So you know the diameter (if needed).
It is also known that the meeting point of perpendicular bisector of triangle sides is the center of the circumscribed circle.
Let's a=Da, b=Db. The we can write a system for points A and B at the circumference:
(x+b)^2 + y^2 = r^2
(y+a)^2 + x^2 = r^2
After transformations we have quadratic equation
y^2 * (4*b^2+4*a^2) + y * (4*a^3+4*a*b^2) + b^4-4*b^2*r^2+a^4+2*a^2*b^2 = 0
or
AA * y^2 + BB * y + CC = 0
where coefficients are
AA = (4*b^2+4*a^2)
BB = (4*a^3+4*a*b^2)
CC = b^4-4*b^2*r^2+a^4+2*a^2*b^2
So calculate AA, BB, CC coefficients, find solutions y1,y2 of quadratic eqiation, then get corresponding x1, x2 values using
x = (a^2 - b^2 + 2 * a * y) / (2 * b)
and choose real solution pair (where coordinate is inside the circle)
Quick checking:
a=1,b=1,r=1 gives coordinates 0,0, as expected (and false 1,-1 outside the circle)
a=3,b=4,r=5 gives coordinates (rough) 0.65, 1.96 at the picture, distances are about 3 and 4.
Delphi code (does not check all possible errors) outputs x: 0.5981 y: 1.9641
var
a, b, r, a2, b2: Double;
aa, bb, cc, dis, y1, y2, x1, x2: Double;
begin
a := 3;
b := 4;
r := 5;
a2 := a * a;
b2:= b * b;
aa := 4 * (b2 + a2);
bb := 4 * a * (a2 + b2);
cc := b2 * b2 - 4 * b2 * r * r + a2 * a2 + 2 * a2 * b2;
dis := bb * bb - 4 * aa * cc;
if Dis < 0 then begin
ShowMessage('no solutions');
Exit;
end;
y1 := (- bb - Sqrt(Dis)) / (2 * aa);
y2 := (- bb + Sqrt(Dis)) / (2 * aa);
x1 := (a2 - b2 + 2 * a * y1) / (2 * b);
x2 := (a2 - b2 + 2 * a * y2) / (2 * b);
if x1 * x1 + y1 * y1 <= r * r then
Memo1.Lines.Add(Format('x: %6.4f y: %6.4f', [x1, y1]))
else
if x2 * x2 + y2 * y2 <= r * r then
Memo1.Lines.Add(Format('x: %6.4f y: %6.4f', [x2, y2]));
From your diagram you have point P that you need it's X & Y coordinate. So we need to find Px and Py or (Px,Py). We know that Ax = Px and By = Py. We can use these for substitution if needed. We know that C & P create a line and all lines have slope in the form of y = mx + b. Where the slope is m and the y intercept is b. We don't know m or b at this point but they can be found. We know that the angle of between two vectors where the vectors are CP and PB gives an angle of 120°, but this does not put the angle in standard position since this is a CW rotation. When working with circles and trig functions along with linear equations of slope within them it is best to work in standard form. So if this line of y = mx + b where the points C & P belong to it the angle above the horizontal line that is parallel to the horizontal axis that is made by the points P & B will be 180° - 120° = 60° We also know that the cos angle between two vectors is also equal to the dot product of those vectors divided by the product of their magnitudes.
We don't have exact numbers yet but we can construct a formula: Since theta = 60° above the horizontal in the standard position we know that the slope m is also the tangent of that angle; so the slope of this line is tan(60°). So let's go back to our linear equation y = tan(60°)x + b. Since b is the y intercept we need to find what x is when y is equal to 0. Since we still have three undefined variables y, x, and b we can use the points on this line to help us here. We know that the points C & P are on this line. So this vector of y = tan(60°)x + b is constructed from (Px, Py) - (Cx, Cy). The vector is then (Px-Cx, Py-Cy) that has an angle of 60° above the horizontal that is parallel to the horizontal axis. We need to use another form of the linear equation that involves the points and the slope this time which happens to be y - y1 = m(x - x1) so this then becomes y - Py = tan(60°)(x - Px) well I did say earlier that we could substitute so let's go ahead and do that: y - By = tan(60°)(x - Ax) then y - By = tan(60°)x - tan(60°)Ax. And this becomes known if you know the actual coordinate points of A & B. The only thing here is that you have to convert your angle of 120° to standard form. It all depends on what your known and unknowns are. So if you need P and you have both A & B are known from your diagram the work is easy because the points you need for P will be P(Ax,By). And since you already said that you know Da, Db & Dc with their lengths then its just a matter of apply the correct trig functions with the proper angle and or using the Pythagorean Theorem to find the length of another leg of the triangle. It shouldn't be all that hard to find what P(x,y) is from the other points. You can use the trig functions, linear equations, the Pythagorean theorem, vector calculations etc. If you can find the equation of the line that points C & P knowing that P has A's x value and has B's y value and having the slope of that line that is defined by the tangent above the horizontal which is 180° - phi where phi is the angle you are giving that is CW rotation and theta would be the angle in standard position or above the horizontal you have a general form of y - By = tan(180° - phi)(x - Ax) and from this equation you can find any point on that line.
There are other methods such as using the existing points and the vectors that they create between each other and then generate an equilateral triangle using those points and then from that equilateral if you can generate one, you can use the perpendicular bisectors of that triangle to find the centroid of that triangle. That is another method that can be done. The only thing you may have to consider is the linear translation of the line from the origin. Thus you will have a shift in the line of (Ax - origin, By - origin) and to find one set the other to 0 and vise versa. There are many different methods to find it.
I just showed you several mathematical techniques that can help you to find a general equation based on your known(s) and unknown(s). It just a matter of recognizing which equations work in which scenario. Once you recognize the correct equations for the givens; the rest is fairly easy. I hope this helps you.
EDIT
I did forget to mention one thing; and that is the line of CP has a point on the edge of the circle defined by (cos(60°), sin(60°)) in the 1st quadrant. In the third quadrant you will have a point on this line and the circle defined by (-cos(60°), -sin(60°)) provided that this line goes through the origin (0,0) where there is no y nor x intercepts and if this is the case then the point on the circle at either end and the origin will be the radius of that circle.

Distance from a point toward another point

Given point a point a (x1,y1) and a point c (x3,y3) we can calculate a slope m. Assuming we have a distance d I'm a bit stuck trying to figure out how to find a point b (x2,y2) which is d distance from x1,y1 in the direction of c.
Does anyone know how to calculate this? I thought about using the midpoint function but it's not quite there.
Help?
You can work out the full distance between a and c with:
__________________________________
df = / (x3-x1)*(x3-x1) + (y3-y1)*(y3-y1)
\/
This uses the standard "root of the sum of squares" method.
Then, if the actual partial distance you want is dp, the point can be found at (x2,y2) with:
x2 = x1 + dp/df * (x3-x1)
y2 = y1 + dp/df * (y3-y1)
which is simply moving the correct proportion dp/df in both dimensions.
You can get the direction from A to B by the following:
D = B - A
Then, you may normalize the direction (which means it is magnitude 1, or length 1):
N = D / D.Length
where
D.Length = sqrt(D.X * D.X + D.Y * D.Y)
To find a point on the line given by A and B, X units away from A in the direction of B, you would use the following:
Final = A + N * X

Calculate a Vector that lies on a 3D Plane

I have a 3D Plane defined by two 3D Vectors:
P = a Point which lies on the Plane
N = The Plane's surface Normal
And I want to calculate any vector that lies on the plane.
Take any vector, v, not parallel to N, its vector cross product with N ( w1 = v x N ) is a vector that is parallel to the plane.
You can also take w2 = v - N (v.N)/(N.N) which is the projection of v into plane.
A point in the plane can then be given by x = P + a w, In fact all points in the plane can be expressed as
x = P + a w2 + b ( w2 x N )
So long as the v from which w2 is "suitable".. cant remember the exact conditions and too lazy to work it out ;)
If you want to determine if a point lies in the plane rather than find a point in the plane, you can use
x.N = P.N
for all x in the plane.
If N = (xn, yn, zn) and P = (xp, yp, zp), then the plane's equation is given by:
(x-xp, y-yp, z-zp) * (xn, yn, zn) = 0
where (x, y, z) is any point of the plane and * denotes the inner product.
And I want to calculate any vector
that lies on the plane.
If I understand correctly You need to check if point belongs to the plane?
http://en.wikipedia.org/wiki/Plane_%28geometry%29
You mast check if this equation: nx(x − x0) + ny(y − y0) + nz(z − z0) = 0 is true for your point.
where: [nx,ny,nz] is normal vector,[x0,y0,z0] is given point, [x,y,z] is point you are checking.
//edit
Now I'm understand Your question. You need two linearly independent vectors that are the planes base. Sow You need to fallow Michael Anderson answerer but you must add second vector and use combination of that vectors. More: http://en.wikipedia.org/wiki/Basis_%28linear_algebra%29

Resources