Formula to find intersection point of two lines - coordinates

How to find an point where line1 and lin2 intersect, if both lines are defined by x,y,alpha where x,y are coordinates of a point on a line and alpha is the angle between the line and x=const?
I tried applying sine theorem but it yields two answers (triangles can be built on both sides of a line). I can check which point forms correct slope with one of the points, but that is ugly.
I can switch to y=ax+b representation, but then I have special cases that I have to worry about. Vertical and horizontal lines should be differently to avoid division by zero in 1/sin(alpha) and 1/cos(alpha) cases.
I am not looking for an implementation in a certain language, just a formula.
These questions are not relevant because they deal with finite line segments, NOT lines.
Given two points and two vectors, find point of intersection
How do you detect where two line segments intersect?

Suppose line 1 is defined by [x1, y1] and alpha1 and line 2 by [x2, y2] and alpha2.
Suppose k1 = tan(alpha1) and k2 = tan(alpha2).
Then the formula for the x-coordinate of the intersection is
x = (y2 - y1 + k1 * x1 - k2 * x2) / (k1 - k2)
Note: Function tan is undefined for angles pi / 2 + k * pi (where k is an arbitrary integer), so:
if k1 is undefined, then x = x1 and y = y2 + k2 * (x1 - x2)
if k2 is undefined, then x = x2 and y = y1 + k1 * (x2 - x1)
(both are practically the same with exchange of indices 1 <--> 2).

For a line equation Y = aX + b, you can calculate a = tan(alpha).
So if line1 is defined as x, y and alpha, the equation is Y = tan(alpha) * X + b.
Now to find b, you need a point on your line. This point has coordinates (x, y).
y = ax + b
b = y - ax
So you line equation is:
Y = tan(alpha) * X + (y - tan(alpha) * x)
Now you only have to solve the lines equation:
Y = a1 * X + b1
Y = a2 * X + b2
Which is:
a1 * X + b1 = a2 * X + b2
(a1 - a2) * X = b2 - b1
X = (b2 - b1) / (a1 - a2)
Right now you can calculate Y too.
So if we replace, we obtain:
X = ((y2 - tan(alpha2) * x2) - (y1 - tan(alpha1) * x1)) / (tan(alpha1) - tan(alpha2)
Simplified:
X = (y2 - y1 - tan(alpha2) * x2 + tan(alpha1) * x1)) / (tan(alpha1) - tan(alpha2)
And then:
Y = tan(alpha1) * X + (y - tan(alpha1) * x

Related

Find a point coordinate between two points

Let's say I have two points P1(x1,y1,z1), and P2(x2,y2,z2).
I want to find P3(x3,y3,z3) between these two points. How can I find P3?
P3 can be anywhere between P1 and P2, hence I cannot use the mid-point formula. Figure shown below
You can use the idea of a weighted average of the two points.
P3 = p * P1 + (1 - p) * P2
or written out
x3 = p * x1 + (1 - p) * x2
y3 = p * y1 + (1 - p) * y2
z3 = p * z1 + (1 - p) * z2
where p is some number between 0 and 1.
So a p of 2/3, would give you a point 2/3 the way starting from P1 toward P2.

Solving nonlinear equations with "solve", incorrect solution

I am testing MATLAB capabilities in solving equations for a project that I intend to do, so I gave it a test run with something simple, but the results that it gives me are incorrect. I tried to solve two non-linear equations with two unknowns, one of the solutions is correct the other is not.
syms theta d x y
eq1 = d * cos(theta) == x;
eq2 = d * sin(theta) == y;
sol = solve(eq1, eq2, theta, d)
sol.theta
sol.d
The solutions for d are correct, but for theta I get:
-2*atan((x - (x^2 + y^2)^(1/2))/y)
-2*atan((x + (x^2 + y^2)^(1/2))/y)
And the correct answer for theta is simply atan(y/x)
Then when I evaluate these solutions with x = 1, y = 0, I get:
eval(sol.d)
eval(sol.theta)
d = 1, -1
theta = NaN, -3.1416
Solutions for d are correct, but theta in that scenario should be 0.
What am I doing wrong?
EDIT: solving it by hand it looks like this: Divide the y equation by the x equation
y/x = (d * sin(theta)) / (d * cos(theta))
y/x = sin(theta)/cos(theta)
y/x = tan(theta)
theta = atan(y/x)
Even if matlab solves it in some other way and gets a different expression, it should still yield the same final result when I use numbers and it PARTIALLY does.
For x = 1 and y = 0, theta should be 0, => this doesnt work, it gives NaN (explanation bellow)
for x = 1 and y = 1, theta should be 45 degrees => this works
for x = 0 and y = 1 theta should be 90 degrees => this works
And I just checked it again with the 45 and 90 degree values for x and y and it works, but for x = 1 and y = 0 it still gives NaN as one of the answers and that is because it gets a 0/0 from the way it is expressing it
-2*atan((x - (x^2 + y^2)^(1/2))/y)
-2*(1 - (1^2 + 0^2))^(1/2)/0
-2*(1 - 1)^(1/2)/0
0/0
but if its in the form of atan(y/x) the result is
theta = atan(0/1)
theta = atan(0)
theta = 0
Did you mean to solve this:
syms a b theta d real
eq1 = a==d * cos(theta) ;
eq2 = b==d * sin(theta) ;
[sol] = solve([eq1 eq2],[d theta] ,'IgnoreAnalyticConstraints', true,'Real',true,'ReturnConditions',true);
When solving the equations with symbolic x and y, the solver will find a solution with a certain condition, which can be obtained using the argument 'ReturnCondition':
syms x y theta d real
eq1 = d*cos(theta) == x;
eq2 = d*sin(theta) == y;
sol = solve([eq1; eq2],[d theta],'ReturnConditions',true);
This gives the following result for sol
>> sol.d
(x^2 + y^2)^(1/2)
-(x^2 + y^2)^(1/2)
>> sol.theta
2*pi*k - 2*atan((x - (x^2 + y^2)^(1/2))/y)
2*pi*k - 2*atan((x + (x^2 + y^2)^(1/2))/y)
>> sol.parameters
k
>> sol.conditions
y ~= 0 & in(k, 'integer')
y ~= 0 & in(k, 'integer')
As you can see, y = 0 does not fulfill this general solution given by the solver, resulting in your problem for y = 0. You can find solutions for y = 0 by either making y numeric instead of symbolic, or by adding an assumption:
syms x y theta d real
assume(y==0)
sol = solve([eq1; eq2],[d theta],'ReturnConditions',true);
I guess its easier to just set y=0 numeric, for this one condition, since there are already 4 possible solutions and conditions for the three lines above.

Trying to find 2D coordinates of point along straight line, given one coordinate

I have game object that moves along a path on a 2D plane, between 2 points (x1,y1) and (x2,y2). Occasionally it gets moved off the path and needs to be put back on it. When this happens I'll know the x-coordinate, but need to calculate the y-coordinate along the path given the x-coordinate.
Here's an illustration of what I mean:
You have a line segment, i.e., the set of all convex combinations of the given endpoints. You would like to find the coefficients that yield the convex combination (x3,y3), where y3 is unknown.
t (x1,y1) + (1-t) (x2,y2) = (x3,y3)
Since x3 is known, we obtain
t = (x3 - x2) / (x1 - x2)
and, thus,
y3 = ((x3-x2) y1 + (x1-x3) y2) / (x1 - x2)
The general equation of a line in 2D is a.x + b.y + c = 0 where the vector U = (-b, a) is a direction vector of the line.
Because (x1, y1) and (x2, y2) are on the line, you know that:
a.x1 + b.y1 + c = 0
a.x2 + b.y2 + c = 0
(x2-x1, y2-y1) is a direction vector of the line so:
-b = x2-x1 and a = y2-y1
So one equation of your line ax + by + c = 0 with :
a = y2-y1
b = x1-x2
c = -a.x1 - b.y1 = x1(y1-y2) + y1(x2-x1)
Knowing a, b, c and x3, you can easily find y3:
y3 = -(c + a.x3) / b
Pay attention nevertheless to the case where b = 0 (case of a vertical line)

How to find the third coordinate of an equilateral triangle?

If I have two points say A(x,y) & B(p,q), how can I find the coordinates of the third point on both sides of AB?
I have the formula for one side, but that cannot give the other one..
Need the formula for coordinates of third point on each sides.
Since you have the result on one side then it's easy to find the symmetrical point.
Let's say your result for the third point is C(r, s). You need to find D(t, w), the symmetrical point of C, with respect to the segment AB.
For this we consider the middle of AB: M(u, v) = (A(x, y) + B(p, q)) / 2;
We have the following equation: M(u, v) = (D(t, w) + C(r, s))/2.
We get D(t, w) = 2 * M(u, v) - C(r, s).
We further get: D(t, w) = A(x, y) + B(p, q) - C(r, s).
A possible solution, based on a rotation matrix R is:
A = [0 0];
B = [0 1];
AB = B-A;
theta = deg2rad(60);
R = [cos(theta) -sin(theta); sin(theta) cos(theta)];
C = A + AB*R';
X = [A;B;C; A];
plot(X(:, 1), X(:, 2));
axis equal

constant term in Matlab principal component regression (pcr) analysis

I am trying to learn principal component regression (pcr) with Matlab. I use this guide here: http://www.mathworks.fr/help/stats/examples/partial-least-squares-regression-and-principal-components-regression.html
it's really good, but I just cannot understand one step:
we do the PCA and the regression, nice and clear:
[PCALoadings,PCAScores,PCAVar] = princomp(X);
betaPCR = regress(y-mean(y), PCAScores(:,1:2));
And then we adjust the first coefficient:
betaPCR = PCALoadings(:,1:2)*betaPCR;
betaPCR = [mean(y) - mean(X)*betaPCR; betaPCR];
yfitPCR = [ones(n,1) X]*betaPCR;
How come that the coefficient needs to be 'mean(y) - mean(X)*betaPCR' for the constant one factor? Can you explain that to me?
Thanks in advance!
This is really a math question, not a coding question. Your PCA extracts a set of features and puts them in a matrix, which gives you PCALoadings and PCAScores. Pull out the first two principal components and their loadings, and put them in their own matrix:
W = PCALoadings(:, 1:2)
Z = PCAScores(:, 1:2)
The relationship between X and Z is that X can be approximated by:
Z = (X - mean(X)) * W <=> X ~ mean(X) + Z * W' (1)
The intuition is that Z captures most of the "important information" in X, and the matrix W tells you how to transform between the two representations.
Now you can do a regression of y on Z. First you have to subtract the mean from y, so that both the left and right hand sides have mean zero:
y - mean(y) = Z * beta + errors (2)
Now you want to use that regression to make predictions for y from X. Substituting from equation (1) into equation (2) gives you
y - mean(y) = (X - mean(X)) * W * beta
= (X - mean(X)) * beta1
where we have defined beta1 = W * beta (you do this in your third line of code). Rearranging:
y = mean(y) - mean(X) * beta1 + X * beta1
= [ones(n,1) X] * [mean(y) - mean(X) * beta1; beta1]
= [ones(n,1) X] * betaPCR
which works out if we define
betaPCR = [mean(y) - mean(X) * beta1; beta1]
as in your fourth line of code.