How to do linear interpolation? - math

I have line segment with start s(x1,y1) and end e(x2,y2). I have calculated distance between s and e by using euclidean distance
d = sqrt((x1-x2)(x1-x2) + (y1-y2)(y1-y2))
How to find out point on the line segment at distance d1 (0 < d1< d)?

The main theme of linearity is that everything is proportional.
d1 is d1/d fraction of the way from 0 to d.
Therefore, the point, p, that you are looking for is the same fraction of
the way from s to e. So let r = d1/d. Then
p = (x1 + r*(x2-x1), y1 + r*(y2-y1))
Notice that when r equals 0, p is (x1 + 0*(x2-x1), y1 + 0*(y2-y1)) = (x1, y1) = s. And when r equals 1, p is e = (x2, y2). As r goes from 0 to 1, p goes from s to t linearly -- that is, as a linear function of r.

parametric Line is defined like this:
x(t)=x1+(x2-x1)*t;
y(t)=y1+(y2-y1)*t;
where t is parameter in range <0.0,1.0>
if t=0.0 then the result is giving point (x1,y1)
if t=1.0 then the result is giving point (x2,y2)
So if you need point at d distance from start then:
D=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
x(d)=x1+(x2-x1)*d/D;
y(d)=y1+(y2-y1)*d/D;
where D is line length
and d is distance from start point

Related

How to determine if a line passes through a plane of 4 points (2d)

I'm currently trying to write a program to determine if a line is going through the area of a square of 4 points and I'm searching for a formula. I only found solutions for 3-dimensional planes with vectors and tried to apply them to my situation by calculating with pen and paper but I always seem to hit a dead end when a third value is being needed.
I think the best way to approach it is to calculate the distance of the line to the square. Which would be 0 if it is passing through (a part of it) obviously. But I can't seem to find the right words for the google and stack overflow search since this seems too basic to not have been answered before.
If anyone has a link or a suggestion on how to calculate this I would be really thankful.
For my formula testing I've been working with these simple values:
Line:
l = (0 , 0) + s * (10, 10)
Points of the Square:
A (5, 5)
B (6, 5)
C (6, 6)
D (5, 6)
EDIT:
Using the function of the reply I marked as the answer I got it to work. A problem I had was getting the correct input for the function. The variables a, b and c. This is how I got them in the end:
var a = 1 / x2
var b = -(1 / y2)
var c = y1/y2 - x1/x2
Here's an idea on how you can approach the this problem.
First, what does line passing through a square means in a coordinate system?
Line L passes through square ABCD if and only if L separates the diagonally opposite sides on ABCD (A&C or B&D). Now the problem simplifies to checking whether two given points are separated by a given line.
Let the equation of the line L be ax + by + c = 0. Define a function f(x,y) = ax + by + c. Point A=(x1,y1) and C=(x2,y2) are separated by line L if f(x1,y1) and f(x2,y2) have opposite signs. Additionally if they have the same sign it means for point are on the same side of the line.
Here's the Python code for the above idea:
# Function to check if two points
# lie on the opposite side of the line
def pointsAreOnOppositeSideOfLine(a, b, c, x1, y1, x2, y2):
fx1 = 0 # Variable to store a * x1 + b * y1 - c
fx2 = 0 # Variable to store a * x2 + b * y2 - c
fx1 = a * x1 + b * y1 - c
fx2 = a * x2 + b * y2 - c
# If fx1 and fx2 have same sign
if ((fx1 * fx2) <= 0):
return True
return False

What is the equation stands for in geometry(intuitively)?

I am writing a bilinear interpolation method.
This method can be abstract by solve the equation A*x = b, A is a 4x4 matrix below:
1 x1 y1 x1*y1
1 x2 y2 x2*y2
1 x3 y3 x3*y3
1 x4 y4 x4*y4
Here, (x1, y1), (x2, y2), (x3, y3) and (x4, y4) is four points containing the dst interpolation point.
My problem is when det(A) = 0(then x! = A-1*b), what is the quadrangle looks like?
The determinant becomes 0 when one of the rows or columns can be expressed as a linear combination of the others. Using columns, this equation must hold for some constants a, b, c for each of the four points:
a*1 + b*x + c*y + xy = 0
This is the equation a hyperbola with asymptotes parallel to the axis, so the determinant is zero if and only if the four points fall on the same hyperbola.
For example, if you pick the rectangle (-2, -1), (-1, -2), (1, 2), (2, 1) the determinant will be zero since the points fall on the hyperbola defined by t → (t, 2/t).
Another way to look at it: you are free to pick any 3 points. The three points define a unique hyperbola. The determinant is 0 if and only if you pick the fourth point from that hyperbola.
Joni's answer above is entirely correct, but here's a physical interpretation that you might like:
Picture a square as a well-behaved quadrilateral defined by the following four points: 1 = (0,0), 2 = (1,0), 3 = (1, 1), and 4 = (0, 1).
If you start skewing it by anchoring points 1 and 2 but tugging point 3 to the right in such a way that the sides remain the same length, but the angle between the x-axis and the line segment between points 2 and 3 changes from 90 degrees to 180 and the angle between the x-axis and the line segment between points 1 and 4 changes from 90 degrees to 0, the determinant will approach zero as the angle increases. When you have points 1 = (0,0), 2 = (1, 0), 3 = (2,0), and 4 = (1,0) the quad will be collapsed to a line segment and the determinant will be zero.
You can run this experiment with your matrix and see if I'm correct.

Get the point that corresponds to 1/3rd the distance from p1 to p2

So for example, if we have p1 = (x1,y1) and p2 = (x2,y2) and I want to find the point that corresponds to 1/3rd the distance from p1 and p2 that lies in the line formed by p1 and p2, then what formula would I use? Having a brainfart right now.
Use Section Formula . Read here.
You have to find a point(x,y) that divides line in ratio 1:3 .
x = (x2+3*x1)/4
y = (y2+3*y1)/4
If the line segment is of distance d units then point (x,y) lies at distance d/3 from (x1,y1) and
distance 2d/3 from point (x2,y2)
If A is the vector to the first point, and B is the vector to the second point, then the point you want is
(2A + B) / 3
This works because the point one third of the way between A and B, vectorially, is the vector A + one third of the vector between A and B:
That is A + 1/3(B-A)
Algebra does the rest.
Same one as for any other position:
p(t) = a*(1-t) + b*t
where 0 <= t <= 1 gives all points on a line between vectors "a" and "b"/
In your case
p = (x1, y1)* (1-1/3) + (x2,y2) * 1/3
which is how some other answers look like.
The point p3 = (x3, y3) 1/3rd of the distance is:
x3 = (2 * x1 + x2) / 3
y3 = (2 * y1 + y2) / 3

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

Find point of intersection between two vectors in MATLAB

I have a very simple MATLAB question. What is the easiest way to find the point of intersection between two vectors. I am not familiar with the various MATLAB functions -- it seems like there should be one for this.
For example, if I have one vector from (0,0) to (6,6) and another vector from (0,6) to (6,0), I need to determine that they intersect at (3,3).
One solution is to use the equations derived in this tutorial for finding the intersection point of two lines in 2-D (update: this is an internet archive link since the site no longer exists). You can first create two matrices: one to hold the x coordinates of the line endpoints and one to hold the y coordinates.
x = [0 0; 6 6]; %# Starting points in first row, ending points in second row
y = [0 6; 6 0];
The equations from the above source can then be coded up as follows:
dx = diff(x); %# Take the differences down each column
dy = diff(y);
den = dx(1)*dy(2)-dy(1)*dx(2); %# Precompute the denominator
ua = (dx(2)*(y(1)-y(3))-dy(2)*(x(1)-x(3)))/den;
ub = (dx(1)*(y(1)-y(3))-dy(1)*(x(1)-x(3)))/den;
And you can now compute the intersection point of the two lines:
xi = x(1)+ua*dx(1);
yi = y(1)+ua*dy(1);
For the example in the question, the above code gives xi = 3 and yi = 3, as expected. If you want to check that the intersection point lies between the endpoints of the lines (i.e. they are finite line segments), you just have to check that the values ua and ub both lie between 0 and 1:
isInSegment = all(([ua ub] >= 0) & ([ua ub] <= 1));
A couple more points from the tutorial I linked to above:
If the denominator den is 0 then the two lines are parallel.
If the denominator and numerator for the equations for ua and ub are 0 then the two lines are coincident.
Well, you really have two points on two different lines, and you want to find the intersection. The easiest way is to find the equations of the two lines and then calculate the intersection.
The equation of a line is given by y = mx + b where m is the slope and b is the y-intercept. For one line you have two points which gives two equations. So, you can solve for the constants m and b. This gives the following two equations:
0 = 0*m + 1*b % Using the first point x=y=0 into y=m*x+b
6 = 6*m + 1*b % Using the second point x=y=6
Or in matrix form:
[ 0 ] = [ 0 1 ]* [ m ]
[ 6 ] [ 6 1 ] [ b ]
For the first line the constants can be calculated in MATLAB by
C1 = inv([0 1;6 1]*[1;0]; % m=C1(1) and b=C(2)
Now that you have the equation for the two lines you can solve for the intersection by solving the following system of equations (which are obtained by manipulating the equation for a line):
m_1*x-y = -b_1
m_2*x-y = -b_2
All that is left is to write the above system of equations in matrix form and solve:
[x] = inv [m_1 -1] * [-b_1]
[y] [m_2 -1] [-b_2]
Or in MATLAB syntax:
I = inv([m_1 -1; m_2 -1])*[-b_1;-b_2]; % I is the intersection.
Notes
As per gnovice's comment if the lines are actually line segments you need to check if the intersection is between the end points of the line segments.
If the two slopes are equal, m_1 = m_2, then there will either be no intersection or infinitely many intersections.
For a general multi-dimensional solution, what you're actually doing is solving a series of linear systems.
First you need to reduce the equations to linear form: Ax+By=C (expand dimensions as necessary)
For two-points:
y - y1 = (y2 - y1) / (x2 - x1) * (x - x1)
y - y1 = (y2 - y1) / (x2 - x1) * x - (y2 - y1) / (x2 - x1) * x1
(y1 - y2) / (x2 - x1) * x + y - y1 = (y1 - y2) / (x2 - x1) * x1
(y1 - y2) / (x2 - x1) * x + y = (y1 - y2) / (x2 - x1) * x1 + y1
(y1 - y2) * x + (x2 - x1) * y = (y1 - y2) * x1 + (x2 - x1) * y1
A = (y1 - y2)
B = (x2 - x1)
C = (y1 - y2) * x1 + (x2 - x1) * y1 = A * x1 + B * y1
For your example:
x1 = 0, x2 = 6, y1 = 0, y2 = 6
A1 = (0 - 6) = -6
B1 = (6 - 0) = 6
C1 = A1 * 0 + B1 * 0 = 0
x1 = 0, x2 = 6, y1 = 6, y2 = 0
A2 = (6 - 0) = 6
B2 = (6 - 0) = 6
C2 = A2 * 0 + B2 * 6 = 6 * 6 = 36
Then, form a matrix, with A B and C in rows:
[A1 B1 C1]
[A2 B2 C2]
[-6 6 0]
[ 6 6 36]
Now reduce to reduced echelon form using the Matlab function rref(matrix):
[ 1 0 3]
[ 0 1 3]
As you can guess, the last column is your intersection point. This is expandable to as many dimensions as necessary. If your reduced echelon form has something other than the identity matrix for the front part of it, your vectors either do not have a unique intersection point, or have no intersection point, depending on the form of the matrix.
dim = 2;
% Do other stuff, ending with rref(matrix)
if (matrix(:,1:dim) == eye(dim))
% Matrix has unique solution.
solution = (matrix(:,dim+1))'
else
% No unique solution.
end
In two dimensions, the variations are:
Linear solution, indicating solution is a line of form x + By = C:
[ 1 B C]
[ 0 0 0]
No solution, indicating the lines do not cross, where C2 <> 0:
[ 1 B C1]
[ 0 0 C2]
The other results are confusing, verbose and incomplete, IMO. So here's my two cents - also potentially confusing and verbose.
If you are sure that your lines are not skew-parallel or parallel, the following is all you need:
% Let each point be def as a 3x1 array
% Let points defining first line be : p1, q1
% Let points defining second line be : p2, q2
L = p1-p2;
M = p1-q1;
N = p2-q2;
A = [M N];
T = pinv(A)*L;
h = p1-T(1)*(p1-q1); % h is a 3x1 array representing the actual pt of intersection
Yeah, the Moore-Penrose pseudoinverse is a powerful thing. The explanation for the approach is: You want to find the weights or the scaling factors of the 'direction vectors' (M and N are direction vectors), that linearly combine M and N to give L.
A full description is presented below. It presents a simple exception detection scheme, and their handling is left to the user. (The minimum distance between two line algorithms is from Wikipedia; the comparison of direction cosines (DCS) to check vector attitudes is common knowledge.)
% Let each point be def as a 3x1 array
% Let points defining first line be : p1, q1
% Let points defining second line be: p2, q2
% There are two conditions that prevent intersection of line segments/lines
% in L3 space. 1. parallel 2. skew-parallel (two lines on parallel planes do not intersect)
% Both conditions need to be identified and handled in a general algorithm.
% First check that lines are not parallel, this is done by comparing DCS of
% the line vectors
% L, M, N ARE DIRECTION VECTORS.
L = p1-p2;
M = p1-q1;
N = p2-q2;
% Calculate a normalized DCS for comparison. If equal, it means lines are parallel.
MVectorMagnitude = sqrt(sum(M.*M,2)); % The rowsum is just a generalization for N-D vectors.
NVectorMagnitude=sqrt(sum(N.*N,2)); % The rowsum is just a generalization for N-D vectors.
if isequal(M/MVectorMagnitude,N/NVectorMagnitude) % Compare the DCS for equality
fprintf('%s\n', 'lines are parallel. End routine')
end;
% Now check that lines do not exist on parallel planes
% This is done by checking the minimum distance between the two lines. If there's a minimum distance, then the lines are skew.
a1 = dot(M,L); b1 = dot(M,M); c1 = dot(M,N);
a2 = dot(N,L); b2 = dot(N,M); c2 = dot(N,N);
s1 = -(a1*c2 - a2*c1)/(b1*c2-b2*c1);
s2 = -(a1*b2 - a2*b1)/(b1*c2-b2*c1);
Sm = (L + s1*M - s2*N);
s = sqrt(sum(Sm.*Sm,2));
if ~isequal(s,0) % If the minimum distance between two lines is not zero, then the lines do not intersect
fprintf('%s\n','lines are skew. End routine')
end;
% Here's the actual calculation of the point of intersection of two lines.
A = [M N];
T = pinv(A)*L;
h = p1-T(1)*(p1-q1); % h is a 3x1 array representing the actual pt of intersection.
So the pinv approach will give you results even when your M and N vectors are skew (but not parallel, because inv(A'.A) is required to exist). You can use this to determine the minimum distance between two parallel lines or between two parallel planes - to do this, define k = p2+T(2)*(p2-q2), and then the required distance is h-k. Also note that h and k are the points on the lines that are closest to each other IFF lines are skew.
So the use of the pseudoinverse and projection spaces gives us a concise algorithm for:
Determining the point of intersection of two lines (not parallel, and not skew)
Determining the minimum distance between two lines (not parallel)
Determining the points closest to each other on two skew lines.
Concise is not the same as time-efficient. A lot depends on your exact pinv function implementation - MATLAB uses svd which solves to a tolerance. Also, some results will only be approximately accurate in higher dimensions and higher order definitions of the measurement metric (or vector norms). Besides the obvious dimension independent implementation, this can be used in statistical regression analysis and algebraically maximizing likelihood of point estimates.

Resources