Constructing a triangle using heading and fixed distances? - math

I want to construct a triangle in the real world to represent a 2D "viewing frustum" using the user's coordinates, heading (degrees currently facing from true north), and fixed distances that represent how far they can see.
I was imagining drawing a line of K1 distance from the user's point in the direction of the heading and marking a temporary point, then drawing a perpendicular line at that point to the previous line and marking 2 points on each side of the perpendicular line K2 distance away from the point.
This would give me the 3 points that I need. For those who are great at math, first is this possible and second can you give me some pointers on how to approach this? Thanks.

In cartesian co-ordinates:
Assume:
+Y axis is north.
K2 is distance from "temp point" to the two points you're creating
Current position is (Cx, Cy)
Heading (H) is angle clockwise from the Y-axis.
Temporary point is (Tx, Ty)
Remaining two points are (Px, Py) and (Qx, Qy)
Then:
Tx = Cx + K1 * sin(H)
Ty = Cy + K1 * cos(H)
Px = Tx - K2 * cos(H)
Py = Ty + K2 * sin(H)
Qx = Tx + K2 * cos(H)
Qy = Ty - K2 * sin(H)
When computing (Tx, Ty), you use sin(H) with the x-coord and cos(H) with the y-coord because the angle is being measured from the Y-axis. When computing (Px, Py) and (Qx, Qy) you use the fact that if (a, b) is some vector, then any multiple of (-a, b) is a vector perpendicular to the first. Hence the (sin(H), cos(H)) turns into (-sin(H), cos(H)) and (cos(H), -sin(H)). This falls out of the definition of dot product in 2-D cartesian space and the coordinate-free fact that the dot product of perpendicular vectors is zero.

Related

closest point on a box to a line

I have drawn a 2D representation of the problem, but I will eventually have to solve this in 3 dimensions.
A line is drawn from an origin point to infinity, in a direction given by pitch and yaw. There is an axis-aligned box "in front of" the point.
I want to get the coordinates of the point on box that is closest to the line, or, if it intersects, closest to the origin point.
I.e., if the line were 'turned' towards the box, which point of the box would intersect with the line first?
Make parametric represenation of the ray with base point P0, direction vector D and parameter t
P = P0 + t * D
Get t for intersections of the ray with rectangle edges like this (similar in 3d):
Rect.Right = X0 + t * D.X
Find what intersection occurs first (smaller t), check coordinates of intersection. If inside edge - point found. If not, analyze intersection parameters with edgr continuations to determine what corner (perhaps edge in 3d) is the closest
Note that in 2d case you need to check only two possible edges - depending on ray direction. For example - left and bottom for your right picture. When you see that intersections are out of edges - check what of two corners is closer. The same for 3d - but intersection is possible for three faces and closest for more edges or corners.
Let the position of the point be (x0,y0,z0) and the box have corners (x1,y1,z1) and (x2,y2,z2) with x1 < x2, y1 < y2, z1 < z2. In terms of yaw ψ and pitch θ a unit vector along the line will be give by
(u,v,w) = (cos ψ sin θ, sin ψ, cos ψ cos θ)
The line is (x0,y0,z0) + t (u,v,w)
Finding intersection with one of the plane containing a face of the box is trivial. Say to find the intersection with the plane x=x1, just requires solving
x0 + u t = x1 so t = (x1-x0)/u. Once found its easy to check if the intersection is contained in the face.
The tricky situation happens if the line does not intersect the faces. Here we have a pair of skew lines, and wish to find the closest pair of points one on each line.
Consider the closest point to the edge from (x1,y1,z1) to (x2,y1,z1).
We want to find the parameter s,t such that that the points
(x0,y0,z0)+s(u,v,w)
(x1,y1,z1)+t(1,0,0)
are the closest. The segment joining these points must be perpendicular to both lines. A vector along that line is the cross product
N = (u,v,w) X (1,0,0) = (0,w,-v)
Now consider the plane through (x1,y1,z1) spanned by (1,0,0) and N, this has normal
N2 = (1,0,0) X N
= (1,0,0) X (0,w,-v)
= (0,v,w)
and the plane is defined by
P . N2 = (x1,y1,z1) . N2
Take a point on our ray
( (x0,y0,z0)+s(u,v,w) ) . N2 = (x1,y1,z1) . N2
(x0,y0,z0) . N2 + s (u,v,w) . N2 = (x1,y1,z1) . N2
s (u,v,w) . N2 = ((x1,y1,z1)-(x0,y0,z0)) . N2
s (v^2+w^2) = (y1-y0) v + (z1-z0) w
so
s = [ (y1-y0) v + (z1-z0) w ] / (v^2+w^2)
We can repeat the above for each edge on the box, find the closest points and select the smallest.

Panning via normal vector and plane

I have got a camera and the direction it is looking at. Therefore I can create a plane out of this direction vector if I take it as a normal vector. So now I want to move my camera which should be on this plane along the plane. Everything's in 3D but I couldn't come up with an idea how to do so. How can I implement the navigational method of panning - so moving in this specific plane?
To pan your camera to the left and to the right you need to know not only lookAt direction, but also up direction for the camera. Then you can calculate cross product of lookAt and upAxis and this gives you direction to the right, negated vector gives you direction to the left.
Definition: A vector N that is orthogonal to every vector in a plane is called a normal vector to the plane.
An equation of the plane containing the point (x0, y0, z0) with normal vector N = (A, B, C), is A(x − x0) + B(y − y0) + C(z − z0) = 0.
Note: The equation of any plane can be expressed as Ax + By + Cz = D.
This is called the standard form of the equation of a plane. From the eqn you can get any other point you want on the plane.
Example: A plane passing through the point P = (1, 6, 4) and the normal vector, R = (2, - 3, - 1). Then the eqn is,
2(x-1) - 3(y-6) - (z-4) = 0
=> 2x - 3y - z = -20

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

Find a vector tangent to a circle

I need to move a point by vectors of fixed norm around a central circle.
So to do this, I need to calculate the circle tangent vector to apply to my point.
Here is a descriptive graph :
So I know p1 coordinates, circle radius and center, and the vector norm d. I need to find p2 (= finding the vector v orientation).
I put on the graph some ideas I got to find it : p1' is p1 projected on the circle. And t is the tangent vector to C in p1'.
That should be easy, but I'm too weak in maths to figure how to implement this. So I would like an idea of the implementation this (language agnostic is okay, javascript is cool).
Extra cool if you can also get me how to implement clockwise and counter clockwise movement with this.
Edit : Obtained this
let vx = cx - p1x,
vy = cy - p1y,
norm = Math.sqrt((vx * vx) + (vy * vy)),
p2x = p1x - (vy * d / norm),
p2y = p1y + (vx * d / norm);
But there is still a quirk : using this on time, the point is slowly getting away from the center of the circle, performing a spiral.
Obtain vector Center of circle - point P1. Let's call this vector
v1.
Tangent vector 't' is perpendicular to v1. If v1=(vx, vy) then
t=(-vy,vx) . Just swap values and a sign (I wrote -vy, it could also be -vx, but not both -vy,-vx).
Setting one direction or the order is just using t2= -t1= (vy, -vx), or (-vy, vx)
For movements you must use normalized (||v|| = 1) vectors.

Rotation matrix that minimizes distance

Let's say I have two points in 3D space (a and b) and a fixed axis/unit vector called n.
I want to create a rotation matrix that minimizes the euclidan distance between point a (unrotated) and the rotated point b.
E.g:
Q := matrix_from_axis_and_angle (n, alpha);
find the unknown alpha that minimizes sqrt(|a - b*Q|)
Btw - If a solution/algorithm can be easier expressed with unit-quaternions go ahead and use them. I just used matrices to formulate my question because they're more widely used.
Oh - I know there are some degenerated cases ( a or b lying exactly in line with n ect.) These can be ignored. I'm just looking for the case where a single solution can be calculated.
sounds fairly easy. Assume unit vector n implies rotation around a line parallel to n through point x0. If x0 != the origin, translate the coordinate system by -x0 to get points a' and b' relative to new coordinate system origin 0, and use those 2 points instead of a and b.
1) calculate vector ry = n x a
2) calculate unit vector uy = unit vector in direction ry
3) calculate unit vector ux = uy x n
You now have a triplet of mutually perpendicular unit vectors ux, uy, and n, which form a right-handed coordinate system. It can be shown that:
a = dot(a,n) * n + dot(a,ux) * ux
This is because unit vector uy is parallel to ry which is perpendicular to both a and n. (from step 1)
4) Calculate components of b along unit vectors ux, uy. a's components are (ax,0) where ax = dot(a,ux). b's components are (bx,by) where bx = dot(b,ux), by = dot(b,uy). Because of the right-handed coordinate system, ax is always positive so you don't actually need to calculate it.
5) Calculate theta = atan2(by, bx).
Your rotation matrix is the one which rotates by angle -theta relative to coordinate system (ux,uy,n) around the n-axis.
This yields degenerate answers if a is parallel to n (steps 1 and 2) or if b is parallel to n (steps 4, 5).
I think you can rephrase the question to:
what is the distance from a point to a 2d circle in 3d space.
the answer can be found here
so the steps needed are as following:
rotating the point b around a vector n gives you a 2d circle in 3d space
using the above, find the distance to that circle (and the point on the circle)
the point on the circle is the rotated point b you are looking for.
deduce the rotated angle
...or something ;^)
The distance will be minimized when the vector from a to the line along n lines up with the vector from b to the line along n.
Project a and b into the plane perpendicular to n and solve the problem in 2 dimensions. The rotation you get there is the rotation you need to minimize the distance.
Let P be the plane that is perpendicular to n.
We can find the projection of a into the P-plane, (and similarly for b):
a' = a - (dot(a,n)) n
b' = b - (dot(b,n)) n
where dot(a,n) is the dot-product of a and n
a' and b' lie in the P-plane.
We've now reduced the problem to 2 dimensions. Yay!
The angle (of rotation) between a' and b' equals the angle (of rotation) needed to swing b around the n-axis so as to be closest to a. (Think about the shadows b would cast on the P-plane).
The angle between a' and b' is easy to find:
dot(a',b') = |a'| * |b'| * cos(theta)
Solve for theta.
Now you can find the rotation matrix given theta and n here:
http://en.wikipedia.org/wiki/Rotation_matrix
Jason S rightly points out that once you know theta, you must still decide to rotate b clockwise or counterclockwise about the n-axis.
The quantity, dot((a x b),n), will be a positive quantity if (a x b) lies in the same direction as n, and negative if (a x b) lies in the opposite direction. (It is never zero as long as neither a nor b is collinear with n.)
If (a x b) lies in the same direction as n, then b has to be rotated clockwise by the angle theta about the n-axis.
If (a x b) lies in the opposite direction, then b has to be rotated clockwise by the angle -theta about the n-axis.

Resources