collision detection between two lines - math

This is a fairly simple question. I need need an equation to determine whether two 2 dimensional lines collide with each other. If they do I also need to know the X and Y position of the collision.

Put them both in general form. If A and B are the same then they're parallel. Otherwise, create two simultaneous equations and solve for x and y.

Let A and B represented by this parametric form : y = mx + b
Where m is the slope of the line
Now in the case of parallelism of A and B their slope should be equal
Else they will collide with each other at point T(x,y)
For finding the coordinates of point T you have to solve an easy equation:
A: y = mx + b
B: y = Mx + B
y(A) = y(B) means : mx + b = Mx + B which yields to x = (B - b)/(m - M) and by putting
the x to the line A we find y = ((m*(B - b))/(m - M)) + b
so : T : ((B - b)/(m - M) , ((m*(B - b))/(m - M)) + b)

Related

Get vertex value that shapes 90 degrees with triangle centroid

I have this triangle:
I'm trying to get the vertex value highlighted in the green circle in order to draw that red line. Is there any equation that I can use to extract that value?
The centroid vertex G = (x=5.5, y=1.5)
The other vertex B = (x=0, y=1)
and the last vertex C = (x=7, y=0)
Any help would be appreciated. I know it might be a 5th grade math but I can't think of a way to calculate this point.
If you throw away the majority of the triangle and just keep the vector B->G and the vector B->C then this problem shows itself to be a "vector projection" problem.
These are solved analytically using the dot product of the 2 vectors and are well documented elsewhere.
Took me 2 days to figure this out, you basically need to get the slopes for the base vector and the altitude vector (centroid), then solve this equation: y = m * x + b for both vectors (the base + altitude). Then you'll get 2 different equations that you need to use substitution to get the x first then apply that value to the 2nd equation to get the y. For more information watch this youtube tutorial:
https://www.youtube.com/watch?v=VuEbWkF5lcM
Here's the solution in PHP (pseudo) if anyone is interested:
//slope of base
$m1 = getSlope(baseVector);
//slope of altitude (invert and divide it by 1)
$m2 = 1/-$m1;
//points
$x1 = $baseVector->x;
$y1 = $baseVector->y;
//Centroid vertex
$x2 = $center['x'];
$y2 = $center['y'];
//altitude equation: y = m * x + b
//eq1: y1 = (m1 * x1) + b1 then find b1
$b1 = -($m1 * $x1) + $y1;
//equation: y = ($m1 * x) + $b1
//eq2: y2 = (m2 * x2) + b2 then find b2
$b2 = -($m2 * $x2) + $y2;
//equation: y = ($m2 * x) + $b2;
//substitute eq1 into eq2 and find x
//merge the equations (move the Xs to the left side and numbers on the right side)
$Xs = $m1 - $m2; //left side (number of Xs)
$Bs = $b2 - $b1; //right side
$x = $Bs / $Xs; //get x number
$y = ($m2 * $x) + $b2; //get y number

How to set a square root to only be whole

I cant seem to find any kind of answer to this, but if I have an equation like the square root of (X^2-4n) where 4n is a constant, how could I set x so the equation gives a whole number.
I know setting x to n+1 works, but I'm looking for an algorithm that would generate all solutions.
So, the problem is to find all pairs of integers (x, m) such that:
sqrt(x^2 - 4n) = m
We have:
x^2 - 4n = m^2
or
x^2 - mĖ†2 = 4n
so
(x + m)(x - m) = 4n
Now, 2 divides 4n and so it must divide (x+m) or (x-m). But if it divides any of them it will divide the other too. Thus a := (x+m)/2 and b := (x-m)/2 are both integers. Therefore
a*b = n
So, it is just a matter of factoring n as a*b in all possible ways and recover x and m from the equations above:
x = a + b.
m = a - b.
Your solution x = n+1 corresponds to the trivial factorization n = n*1 where a=n and b=1.
UPDATE
Here is an algorithm that prints all pairs (x, m)
[Initialize] a := n.
[Check] if n % a = 0 then
b := n / a.
print(a + b), print(a - b)
[Decrement] a := a - 1.
[End?] if a * a > n go to Step 2.

Find line that is tangent to 2 given circles

I've got a situation in which I have 2 circles (C1 and C2)
and i need to find the line equation for the line that is tangent to both of these circles.
So as far as i'm aware, given a single point (P1) and C2's point and radius it is possible to quite easily get 2 possible points of tangency for C2 and P1 to make 2 line equations. But as i don't have P1, only the knowledge that the point will be one of a possible 2 points on C1, i'm not sure how to calculate this.
I assume it will be something along the lines of getting the 2 tangent line equations of C1 that are equal to the same of C2.
Both circles can have any radius, they could be the same or they could be hugely different. They will also never overlap (they can still touch though). And I'm looking for the 2 possible internal tangents.
Oh, and also, visuals would be very helpful haha :)
Let O be the intersection point between the line through the centers and the tangent.
Let d be the distance between the centers and h1, h2 be the distances between O and the centers. By similarity, these are proportional to the radii.
Hence,
h1 / h2 = r1 / r2 = m,
h1 + h2 = d,
giving
h1 = m d / (1 + m),
h2 = d / (1 + m).
Then the coordinates of O are found by interpolating between the centers
xo = (h2.x1 + h1.x2) / d
yo = (h2.y1 + h1.y2) / d
and the angle of the tangent is that of the line through the centers plus or minus the angle between this line and the tangent,
a = arctan((y2 - y1)/(x2 - x1)) +/- arcsin(r1 / h1).
You can write the implicit equation of the tangent as
cos(a).y - sin(a).x = cos(a).yo - sin(a).xo.
(source: imag.fr)
So we are going to use a homothetic transformation. If the circles C and C' have respectively centres O and O', and radius r and r', then we know there exists a unique homothetic transformation with centre J and ratio a, such that :
a = |JO|/|JO'| = r/r'
Noting AB is the vector from A to B, and |z| the norm of a vector z.
Hence you get J, knowing that it is between O and O' which we both already know.
Then with u the projection of JR on JO', and v the decomposition on its orthogonal, and considering the sine s and cosine c of the angle formed by O'JR, we have
|u| = |JR| * c
|v| = |JR| * s
c^2 + s^2 = 1
And finally because the triangle JRO' is right-angled in R :
s = r' / |JO|'
Putting all of this together, we get :
J = O + OO' / |OO'| * a / (a+1)
if |OJ| == r and |O'J| == r' then
return the orthogonal line to (OO') passing through J
|JR| = āˆš( |JO'|^ - r'^2 )
s = r' / |JO'|
c = āˆš( 1 - s^2 )
u = c * |JR| * OO' / |OO'|
w = (-u.y, u.x) % any orthogonal vector to u
v = s * |JR| * w / |w|
return lines corresponding to parametric equations J+t*(u+v) and J+t*(u-v)

Given a list of coefficients, create a polynomial

I want to create a polynomial with given coefficients. This seems very simple but what I have found till now did not appear to be the thing I desired.
For example in such an environment;
n = 11
K = GF(4,'a')
R = PolynomialRing(GF(4,'a'),"x")
x = R.gen()
a = K.gen()
v = [1,a,0,0,1,1,1,a,a,0,1]
Given a list/vector v of length n (I will set this n and v at the begining), I want to get the polynomial v(x) as v[i]*x^i.
(Actually after that I am going to build the quotient ring GF(4,'a')[x] /< x^n-v(x) > after getting this v(x) from above) then I will say;
S = R.quotient(x^n-v(x), 'y')
y = S.gen()
But I couldn't write it.
This is a frequently asked question in many places so it is better to leave it here as an answer although the answer I have is so simple:
I just wrote R(v) and it gave me the polynomial:
sage
n = 11
K = GF(4,'a')
R = PolynomialRing(GF(4,'a'),"x")
x = R.gen()
a = K.gen()
v = [1,a,0,0,1,1,1,a,a,0,1]
R(v)
x^10 + a*x^8 + a*x^7 + x^6 + x^5 + x^4 + a*x + 1
Basically (that is, ignoring the specifics of your polynomial ring) you have a list/vector v of length n and you require a polynomial which is the sum of all v[i]*x^i. Note that this sum equals the matrix product V.X where V is a one row matrix (essentially equal to the vector v) and X is a column matrix consisting of powers of x. In Maxima you could write
v: [1,a,0,0,1,1,1,a,a,0,1]$
n: length(v)$
V: matrix(v)$
X: genmatrix(lambda([i,j], x^(i-1)), n, 1)$
V.X;
The output is
x^10+ax^8+ax^7+x^6+x^5+x^4+a*x+1

Deform a triangle along vector to get a specific angle

I am trying to create a binary tree from a lot of segments in 3d space sharing the same origin.
When merging two segments I want to have a specific angle between the lines to the child nodes.
The following image illustrates my problem. C shows the position of the parent node and A and B the child positions. N is the average vector of the vectors from C to A and C to B.
With a given angle, how can I determine point P?
Thanks for any help
P = C + t * ((A + B)/2 - C) t is unknown parameter
PA = A - P PA vector
PB = B - P PB vector
Tan(Fi) = (PA x PB) / (PA * PB) (cross product in the nominator, scalar product in the denominator)
Tan(Fi) * (PA.x*PB.x + PA.y*PB.y) = (PA.x*PB.y - PA.y*PB.x)
this is quadratic equation for t, after solving we will get two (for non-degenerate cases) possible positions of P point (the second one lies at other side of AB line)
Addition:
Let's ax = A.x - A point X-coordinate and so on,
abcx = (ax+bx)/2-cx, abcy = (ay+by)/2-cy
pax = ax-cx - t*abcx, pay = ay-cy - t*abcy
pbx = bx-cx - t*abcx, pby = by-cy - t*abcy
ff = Tan(Fi) , then
ff*(pax*pbx+pay*pby)-pax*pby+pay*pbx=0
ff*((ax-cx - t*abcx)*(bx-cx - t*abcx)+(ay-cy - t*abcy)*(by-cy - t*abcy)) -
- (ax-cx - t*abcx)*(by-cy - t*abcy) + (ay-cy - t*abcy)*(bx-cx - t*abcx) =
t^2 *(ff*(abcx^2+abcy^2)) +
t * (-2*ff*(abcx^2+abcy^2) + abcx*(by-ay) + abcy*(ax-bx) ) +
(ff*((ax-cx)*(bx-cx)+(ay-cy)*(by-cy)) - (ax-cx)*(by-cy)+(bx-cx)*(ay-cy)) =0
This is quadratic equation AA*t^2 + BB*t + CC = 0 with coefficients
AA = ff*(abcx^2+abcy^2)
BB = -2*ff*(abcx^2+abcy^2) + abcx*(by-ay) + abcy*(ax-bx)
CC = ff*((ax-cx)*(bx-cx)+(ay-cy)*(by-cy)) - (ax-cx)*(by-cy)+(bx-cx)*(ay-cy)
P.S. My answer is for 2d-case!
For 3d: It is probably simpler to use scalar product only (with vector lengths)
Cos(Fi) = (PA * PB) / (|PA| * |PB|)
Another solution could be using binary search on the vector N, whether P is close to C then the angle will be smaller and whether P is far from C then the angle will be bigger, being it suitable for a binary search.

Resources