Find intersection by knowing a point, direction, circle position and radius (2D) - math

#Problem
Hey I wondered how we can find the intersection between a point with a vector direction, assuming that the point is in the circle.
In Other words, how can I find where the particle will hit the circle circumference when I know the following: Circle position, radius, Particle Position and direction (velocity).
#Implementation
I am currently creating a flight radar, all flights are stored in a Queue and I need to sort the queue based on the time untill the flight leaves the cirlce (Radar Radius)
So I need to return a Point, thus I can just get the distance and calculate the time based on distance and velocity.

At first subtract center cordinates to simplify calculations (now circle center is coordinate origin)
x11 = x1 - x0
y11 = y1 - y0
Point position against time is
x = x11 + vx * t
y = y11 + vy * t
where vx, vy are components of velocity
Point is at circumference when
x^2 + y^2 = R^2
so
(x11 + vx * t)^2 + (y11 + vy * t)^2 = R^2
(vx^2+vy^2)*t^2 + (2*vx*x11+2*vy*y11)*t + (x11^2+y11^2-R^2) = 0
This is quadratic equation for unknown t. Solve it, find roots - none for outside moving, one for single touch case, two roots for regular intersection - larger one is needed time of intersection t_int
Substitute t into point position equations and get coordinates:
x_int = x1 + t_int * vx
y_int = y1 + t_int * vy

Related

How to efficiently compute the future position of a point that will move in a box and bounce on its walls (2D)?

I have a simple maths/physics problem here: In a Cartesian coordinate system, I have a point that moves in time with a known velocity. The point is inside a box, and bounces orthognally on its walls.
Here is a quick example I did on paint:
What we know: The red point position, and its velocity which is defined by an angle θ and a speed. Of course we know the dimensions of the green box.
On the example, I've drawn in yellow its approximate trajectory, and let's say that after a determined period of time which is known, the red point is on the blue point. What would be the most efficient way to compute the blue point position?
I've tought about computing every "bounce point" with trigonometry and vector projection, but I feel like it's a waste of resources because trigonometric functions are usually very processor hungry. I'll have more than a thousand points to compute like that so I really need to find a more efficient way to do it.
If anyone has any idea, I'd be very grateful.
Apart from programming considerations, it has an interesting solution from geometric point of view. You can find the position of the point at a specific time T without considering its temporal trajectory during 0<t<T
For one minute, forget the size and the boundaries of the box; and assume that the point can move on a straight line for ever. Then the point has constant velocity components vx = v*cos(θ), vy = v*sin(θ) and at time T its virtual porition will be x' = x0 + vx * T, y' = y0 + vy * T
Now you need to map the virtual position (x',y') into the actual position (x,y). See image below
You can recursively reflect the virtual point w.r.t the borders until the point comes back into the reference (initial) box. And this is the actual point. Now the question is how to do these mathematics? and how to find (x,y) knowing (x',y')?
Denote by a and b the size of the box along x and y respectively. Then nx = floor(x'/a) and ny = floor(y'/b) indicates how far is the point from the reference box in terms of the number of boxes. Also dx = x'-nx*a and dy = y'-ny*b introduces the relative position of the virtual point inside its virtual box.
Now you can find the true position (x,y): if nx is even, then x = dx else x = a-dx; similarly if ny is even, then y = dy else y = b-dy. In other words, even number of reflections in each axis x and y, puts the true point and the virtual point in the same relative positions, while odd number of reflections make them different and complementary.
You don't need to use trigonometric function all the time. Instead get normalized direction vector as (dx, dy) = (cos(θ), sin(θ))
After bouncing from vertical wall x-component changes it's sign dx = -dx, after bouncing from horizontal wall y-component changes it's sign dy = -dy. You can see that calculations are blazingly simple.
If you (by strange reason) prefer to use angles, use angle transformations from here (for ball with non-zero radius)
if ((ball.x + ball.radius) >= window.width || (ball.x - ball.radius) <= 0)
ball.theta = M_PI - ball.theta;
else
if ((ball.y + ball.radius) >= window.height || (ball.y - ball.radius) <= 0)
ball.theta = - ball.theta;
To get point of bouncing:
Starting point (X0, Y0)
Ray angle Theta, c = Cos(Theta), s = Sin(Theta);
Rectangle coordinates: bottom left (X1,Y1), top right (X2,Y2)
if c >= 0 then //up
XX = X2
else
XX = X1
if s >= 0 then //right
YY = Y2
else
YY = Y1
if c = 0 then //vertical ray
return Intersection = (X0, YY)
if s = 0 then //horizontal ray
return Intersection = (XX, Y0)
tx = (XX - X0) / c //parameter when vertical edge is met
ty = (YY - Y0) / s //parameter when horizontal edge is met
if tx <= ty then //vertical first
return Intersection = (XX, Y0 + tx * s)
else //horizontal first
return Intersection = (X0 + ty * c, YY)

Sliding Two Points Along Perpendicular Slope By Distance

For my current project, a user taps 2 locations on the X,Y plane. Once the two points are tapped, the user should then click and drag to extend 2 new points starting at the original 2 locations into a perfect rectangle (90 degree corners).
The math seems super simple, I just can't seem to get the right configuration to slide these two points along the perpendicular slope (by a certain distance).
My current attempt is to find the perpendicular slope and slide it by X distance (the distance the user has dragged), but I'm stuck on translating the perp. slope by distance.
You have points A and B. Difference vector
D = (Dx, Dy) = (Bx - Ax, By - Ay)
Normalized (unit) vector
Len = Sqrt(Dx*Dx + Dy*Dy)
(dx, dy) = (Dx / Len, Dy / Len)
Perpendicular unit vector
(px, py) = (-dy, dx)
Shift by distance L
pL = (px * L, py * L)
So shifted A will have coordinates
(a'x, a'y) = (Ax +/- px * L, Bx +/- py * L)
+ or - for two possible shift directions

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.

How to check if an infinite line intersects a rectangular prism in 3d space?

If I have a line segment defined by two points p1, p2, and then a rectangular prism defined by (x,y,z) (lowest corner point) with length/width/height (l, w, h), how can I check if the line will intersect the prism? And also get the point of intersection if there is one?
Does anyone know?
Thanks
Seems that your prism is axis-aligned box (rectangular parallelepiped).
So use any algorithm intended for line clipping - for example, 3D-version of Liang-Barsky algorithm
In short - make parametric equation for line segment
X = X1 + t * (X2 - X1)
Y = Y1 + t * (Y2 - Y1)
Z = Z1 + t * (Z2 - Z1)
find parameters t for intersection with faces: substitute X = x or X = x + l in equation, find t, check if point with this t lies inside face rectangle

algorithm for finding out pixel coordinates on a circumference of a circle

how do i find out pixel value at certain degree on the circumference of a circle if I know the pixel co-ordinates of the center of the circle, radius of the circle ,and perpendicular angle.
Basically, I am trying to draw the hands of a clock at various times ( 1 o clock , 2 o clock etc )
Let h be the hour as a floating point number (h=2.25 would be 02:15, etc.) between 0 and 12. (cX,cY) are the coordinates of the center. hLength and mLength are the lengths of the hour and min hands.
// Hour hand
hAngle = 2.0*Pi*h/12.0; // 0..12 mapped to 0..2*Pi
hX = cX + hLength * sin(hAngle);
hY = cY - hLength * cos(hAngle);
// Min hand
mAngle = 2.0*Pi*h; // 0..1 mapped to 0..2*Pi, etc.
mX = cX + mLength * sin(mAngle);
mY = cY - mLength * cos(mAngle);
Where the centre of the circle is (X0, Y0), the radius is R and the angle with the x-axis is theta:
X1 = (R * cos theta) + X0
and
Y1 = (R * sin theta) + Y0
If (x1,y1) is a point on the circumference and (x,y) is the center, then x1 = x + r * cos(angle) and y1 = y + r * sin(angle)
if center is at x0, y0, and 0,0 iz at bottom-left corner, then 1 o'clock is at x0 + rsin(2π/3), y0+rcos(2π/3).
Draw lines from the center to coordinates computed with sin for the y coordinates and cos for the x coordinates (both multiplied by the length of the hand).
Wikipedia has more information on how sin and cos "work".

Resources