Okay so I'm trying to get a separating axis theorem algorithm to work (for collision detection) and I need to find the minimal perpendicular vector between a point and a line. I'm not asking for the minimum perpendicular distance (which I know how to find) but rather the vector that would have the same magnitude as that distance and that goes from an arbitrary point and a point on the line. I know the location of the point, a point on the line, and a unit vector giving the direction of the line.
What I tried doing was first finding the minimal distance between the point and the line.
The next part is confusing but I:
1) Found the vector between the point and the point on the line I know
2) Found the vector between the point on the line and the point on the line plus the unit vector giving the direction of the line
3) Took the cross product of these two vectors (I'll call this cross product A)
4) Took the cross product of the unit vector giving the direction of the line and the vector from cross product A (I'll call this cross product B)
5) Normalized cross product B
6) Scaled cross product B by the minimal distance
Anyways that whole attempt failed miserably. Can anyone tell me how I am supposed to find this vector?
If I understood your question correctly, I believe this is what you're looking for:
P - point
D - direction of line (unit length)
A - point in line
X - base of the perpendicular line
P
/|
/ |
/ v
A---X----->D
(P-A).D == |X-A|
X == A + ((P-A).D)D
Desired perpendicular: X-P
where the period represents the dot product and |X-A| means magnitude.
From the above figure, you have:
q = p + s --> s = q - p = q - (p2-p1) = q + p1 - p2
==> s^ = |q - p2 - p1| / |s| (unitary vector)
Also: |s| = |q| sin c = |q|sin(b-a)
b = arcsin (qy / |q|); a = arcsin( p1y / |p1| )
where: |q| = (qx^2 + qy^2)^1/2
Related
Here, line segment ab is cast upward on arbitrary vector n where I do somethings to find the black point on the line segment cd. My question is, how do I find the point on ab that intersects with the inverted n vector coming down from the new point?
Looks like it will have the same x-coordinate as the black point (call this x). The slope of ab is m = (by - ay) / (bx - ax), so the y coordinate is mx + ay.
If the projection is parallel, by the Thales theorem the ratios are preserved.
|ae| / |ab| = |cf| / |cd| = r
which is known.
The searched point is, vectorially
e = a + r.ab = a + |cf|/|cd|.ab
I have a line and a few points and I need to determine which points are under and which are beyond the line. I tried to find a line that is in 90degrees angle with my line and crosses the points but i couldnt figure out whether the vectors orientation is up or down. Can you help? Thank you
You can find line equation and substitute points in thin equation.
Easy case: Let's line is not vertical, so it might be described by equation
y = a * x + b
for every query point (px, py) calculate value
S = py - a * px - b
When S is positive, point is above the line, when negative - below.
If your line is defined by base point B and direction vector D, you can determine - what semi-plane (against the line) query point P belongs to - using cross product sign
Sign (D x (P-B))
Note that in this case term "below" depends also on sign of X-component of vector D
How can i sort vectors by distance from point?
For example i have three vectors: A, B, C and the point
Example image with point and vectors
And the sorted result must be something like this: (A, C, B)
Okay, this is more of a math question, but let me explain it here anyways. Take a look at this picture:
Let's define a line segment by vector A for the start point and a for the vector running through that line segment which end at the arrows end. Same is valid for the other segments B and C respectively. The point P as coordinates as also a vector.
Now let's make linear algebra our friend, yet be programatically efficient.
:-)
At the example of segment a you can do this and with the other respectively:
With the dot product of a and AP (vector from A to P) you get the projection projA on a where the where P is closest.
If you set A+ (projA)*na (na is the the normalized a vector) you get the closest Point in the vector a of P.
Let's set dA = A+projA*na - P and with its length you get the closest distance to compare.
Instead of saving the distances, try to store and compare squared distance of dA, dB and dC and compare those instead. It will save you to compute the square root which might become very expensive.
Here is some pseudocode:
vector3 AP = P-A;
vector3 projA = a.dot(AP);
vector3 nA = a.normalized();
dA = A + projA*na - P;
dA2 = dA.x*dA.x + dA.y*dA.y + dA.z*dA.z;
-> Compare and sort them by that value
Hope it helps a bit...
So I was reading over something on this page (http://gamedeveloperjourney.blogspot.com/2009/04/point-plane-collision-detection.html)
The author mentioned
d = - D3DXVec3Dot(&vP1, &vNormal);
where vP1 is a point on the plane and vNormal is the normal to the plane. I'm curious as to how this gets you the distance from the world origin since the result will always be 0. In addition, just to be clear (since I'm still kind of hazy on the d part of a plane equation), is d in a plane equation the distance from a line through the world origin to the plane's origin?
In the generic case the distance between a point p and a plane can be computed by
<p - p0, normal>
where <a, b> is the dot product operation
<a, b> = ax*bx + ay*by + az*bz
and where p0 is a point on the plane.
When n is of unity length the dot product between a vector and it is the (signed) length of the projection of the vector on the normal
The formula you are reporting is just the special case when the point p is the origin. In this case
distance = <origin - p0, normal> = - <p0, normal>
This equality is formally wrong because the dot product is about vectors, not points... but still holds numerically. Writing down the explicit formula you get that
(0 - p0.x)*n.x + (0 - p0.y)*n.y + (0 - p0.z)*n.z
is the same as
- (p0.x*n.x + p0.y*n.y + p0.z*n.z)
Indeed a nice way to store a plane is to save the normal n and the value of k = <p0, n> where p0 is any point on the plane (the value of k is independent on which point you choose of the plane).
The result is not always zero. The result will only be zero if the plane goes through the origin. (Here let's assume the plane doesn't go through the origin.)
Basically, you are given a line from the origin to some point on the plane. (I.e. you have a vector from the origin to vP1). The problem with this vector is that most likely it's slanted and going to some far away place on the plane rather than to the closest point on the plane. So, if you simply took the length of vP1 you will get a distance that is too big.
What you need to do is get the projection of vP1 onto some vector that you know is perpendicular to the plane. That of course is vNormal. So take the dot product of vP1 and vNormal, and divide by the length of vNormal and you have the answer. (If they are kind enough to give you a vNormal that already is magnitude one, then no need to divide.)
You can work this out with Lagrange multipliers:
You know that the closest point on the plane must be of the form:
c = p + v
Where c is the closest point and v is a vector along the plane (which is thus orthogonal to n, the normal). You are trying for find the c with the smallest norm (or norm squared). So you are trying to minimized dot(c,c) subject to v being orthogonal to n (thus dot(v,n) = 0).
Thus, set up Lagrangian:
L = dot(c,c) + lambda * ( dot(v,n) )
L = dot(p+v,p+v) + lambda * ( dot(v,n) )
L = dot(p,p) + 2*dot(p,v) + dot(v,v) * lambda * ( dot(v,n) )
And take the derivative with respect to v (and set to 0) to get:
2 * p + 2 * v + lambda * n = 0
You can solve for lambda by in the equation above by dot producting both sides by n to get
2 * dot(p,n) + 2 * dot(v,n) + lambda * dot(n,n) = 0
2 * dot(p,n) + lambda = 0
lambda = - 2 * dot(p,n)
Note again that dot(n,n) = 1 and dot(v,n) = 0 (since v is in the plane and n is orthogonal to it). Then subtitute lambda back in to get:
2 * p + 2 * v - 2 * dot(p,n) * n = 0
and solve for v to get:
v = dot(p,n) * n - p
Then plug this back into c = p + v to get:
c = dot(p,n) * n
The length of this vector is |dot(p,n)| and the sign tells you whether the point is in the direction of the normal vector from the origin, or the reverse direction from the origin.
I know the coordinates of A, B and C.. I also know of a vector V originating from C..
I know that the vector intersects A and B, I just don't know how to find i.
Can anyone explain the steps involved in solving this problem?
Thanks alot.
http://img34.imageshack.us/img34/941/triangleprob.png
If you know A and B, you know equation for the line AB, and you said you know V, so you can form the equation for Line V.... Well i is only point that satisfies both those equations.
Equation for Line AB:
(bx-ax)(Y-ay) = (by-ay)(X-ax)
If you knpow the direction (or slope = m) of the vector, and any point that lies on the vector, then the equation of the line for vector V is
Y = mX = b
where m is the slope or direction of the line, and b is the y coordinate where it crosses thevertical y=axis (where X = 0)
if you know a point on the line (i.e., C = (s, t) then you solve for b by:
t = ms + b ==> b = t - ms,
so equation becomes
Y = mX + t-ms
i = C+kV
Lets call N the normal to the line A,B so N = [-(B-A).y, (B-A).x]
Also, for any point on the line:
(P-A)*N = 0 -- substitute from line 1 above:
(C+kV-A)*N = 0
(kV+C-A)*N = 0
kV*N + (C-A)*N = 0
kV*N = (A-C)*N
k = [(A-C)*N]/V*N
Now that we have k, plug it into line 1 above to get i.
Here I'm using * to represent dot product so expanding to regular multiplication:
k = ((A.x-C.x)*-(B.y-A.y) + (A.y-C.y)*(B.x-A.x)) / (V.x*-(B.y-A.y) + V.x*(B.x-A.x))
I.x = C.x + k*V.x
I.y = C.y + k*V.y
Unless I screwed something up....
Simple algebra. The hard part is often just writing down the basic equations, but once written down, the rest is easy.
Can you define a line that emanates from the point C = [c_x,c_y], and points along the vector V = [v_x,v_y]? A nice way to represent such a line is to use a parametric representation. Thus,
V(t) = C + t*V
In terms of the vector elements, we have it as
V(t) = [c_x + t*v_x, c_y + t*v_y]
Look at how this works. When t = 0, we get the point C back, but for any other value of t, we get some other point on the line.
How about the line segment that passes through A and B? One way to solve this problem would be to define a second line parametrically in the same fashion. Then solve for a system of two equations in two unknowns to find the intersection.
An easier approach is to look at the normal vector to the line segment AB. That vector is given as
N = [b_y - a_y , a_x - b_x]/sqrt((b_x - a_x)^2 + (b_y - a_y)^2)
Note that N is defined here to have a unit norm.
So now, when do we know if a point happens to lie along the line that connects A and B? This is easy now. That will happen when the dot product defined below is exactly zero.
dot(N,V(t) - A) = 0
Expand this, and solve for the parameter t. We can write it down using dot products.
t = dot(N,A-C)/dot(N,V)
Or, if you prefer,
t = (N_x*(a_x - c_x) + N_y*(a_y - c_y)) / (N_x*v_x + N_y*v_y))
And once we have t, substitute into the expression above for V(t). Lets see all of this work in practice. I'll pick some points A,B,C and a vector V.
A = [7, 3]
B = [2, 5]
C = [1, 0]
V = [1, 1]
Our normal vector N, after normalization, will look something like
N = [0.371390676354104, 0.928476690885259]
The line parameter, t, is then
t = 3.85714285714286
And we find the point of intersection as
C + t*V = [4.85714285714286, 3.85714285714286]
If you plot the points on a piece of paper it should all fit together, and all in only a few simple expressions.