manipulating distance between two vectors - vector

I am having a hard time manipulating the distance between two points.
Given x y z coordinates for A and B, and knowing their distance, how can I increase or decrease this distance keeping the angle between the 2 points?
Say point A is at 0, 0, 0 and point B is at 3, 3, 0.
I am able to calculate the distance between the two points to be 4.242.
I need to be able to "push" point B further on the same tangent by X. Any ideas?
Thanks in advance.

Subtract A from B to get the vector D representing the distance and direction from A to B
D = B - A
Multiply D by your scalar x to push it further from A along the same direction: (I'm changing your X to x to emphasize that it is a scalar).
D' = xD
Get the new point B' that is in the same direction from A as B is, but is further away (assuming x > 1):
B' = A + D'

Related

What is the Correct Way to Scale then Rotate a set of Points?

I have 4 points, point A(x1, y1), point B(x2, y1), and point C(x2, y2), point D(x2, y3) creating two scales: Scale1 yRange(B, D), Scale2 yRange(B, C).
I want to scale the y axis only, so that point D is scaled down to point C, so that the angle between CAB is a certain degree. Then I want to rotate the scaled point C around point B a certain degree, obtaining point E. Then I want to find the real value of point E on the un-scaled coordinate grid where original point D is located. I think I need to use affine transformations, but all examples are rotate first, then scale. But I need to scale first, then rotate. How do I find this new value? I know how to perform rotations alone and a bit of scaling alone, but not together.
Maybe I am confused, after I perform the scaling and rotation, I would not need to scale back, because the new value of E equates to F? I know there are plenty of examples, but I can not wrap my head around this...
Here is my objective. I have the 3 points A, B and D. I want to scale so that DAB equates to let's say 60 degrees, creating point C, then perform several point rotations on C inside the scaled grid. I ultimately want to find the value of F, and the other rotated points, which lies in geometrical positions inside the original unscaled grid that I can not calculate unless I scale the 3 original points to said degree first. The scaled grid contains the correct ratio I need in order to rotate my points. I need to do all my rotations inside the scaled grid, without losing values, but changing aspect ratio, and then take those new points inside the scaled grid and plot them in the unscaled grid, which will then lose correct aspect ratios, which is fine.
Coding in python.
Here's a Python3 program that I think does what you want:
import math
# Use a negative angle since we're rotating clockwise
rotate_C_angle = math.radians(-60)
A = [0, 0]
B = [100, 0]
D = [100, 250]
# Create point D such that angle CAB = target_angle_CAB
target_angle_CAB = math.radians(60)
C = [B[0], B[0] * math.tan(target_angle_CAB)]
# What do we scale B by in order to get C
scale_factor = C[1] / D[1]
# Rotate C around B by rotate_C_angle
# (translate C by -Bx, then rotate, then translate back)
E = [
C[0] - C[1] * math.sin(rotate_C_angle),
C[1] * math.cos(rotate_C_angle)
]
# Scale E back
F = [E[0], E[1] / scale_factor]
This is assuming that A is at the origin. If it isn't then subtract Ax from all the x coordinates and Ay from the y coordinates, then do the calculations before translating back again.
Whether you need to scale back E to F depends on what you're doing. What happens here assumes that the scaling transformation along y does not get rotated.

Finding 2 vectors knowing their cross product and one constraint

I have to find two vectors in 3D space, a and b such a x b = c where c is known. I also know one constraint, let's say that a_y = 0
So I have to look for these 2 vectors on (c_x)x+(c_y)y+(c_z)z=0 plane, for vector a I can simplify it to (c_x)x+(c_z)z=0
for vector b since it's perpendicular to a as well it has to be in intersection of (a_x)x+(a_z)z=0 plane and (c_x)x+(c_y)y+(c_z)z=0 plane. After adding cross product equation to that I have 4 equations and 5 unknowns (a_x,a_z,b_x,b_y,b_z). How can I solve this?
Thanks in advance.
EDIT: Maybe explaining what I need these for will help out somehow.
I have camera direction vector and I need vector that points to the right of screen, and second one that points up.
problem definition
A,B=?
C=!
Ay=!
A x B = C
implicated properties of dot and cross product due to perpendicularity:
(A.C) = 0
(B.C) = 0
|A|.|B| = |C|
set length for one of the vectors to any known constant like 1
|A|=1
|B|=|C|
This is also mentioned by John Moeller in his comment
Compute A
So length of |A|=1 and dot product of (A.C)=0 as they are perpendicular so:
Ax^2 + Ay^2 + Az^2 = 1
Ax.Cx + Ay.Cy + Az.Cz = 0
This is system of 2 equations and 2 unknowns so solve it. It will lead to 2 solutions chose one that is nonzero.
Compute B
We know that B is perpendicular to C so (B.C)=0 so put the constrains together:
A x B = C
Bx.Cx + By.Cy + Bz.Cz = 0
Bx^2 + By^2 + Bz^2 = Cx^2 + Cy^2 + Cz^2
If you expand the cross product you will get 5 equations and 3 unknowns. So solve the system (chose any 3 of the non trivial equations).
PS It seems this is to generate your NEH matrix analogy
So if that is the case all 3 vectors are perpendicular to each other while one points to specific direction (Up or North ...) and the sizes are usually 1 for all vectors.
So let assume D vector is the known aligning vector:
A'= C x D
B = C x A'
A = C x B
You can change the order of operands to obtain the directions you need. If the D is not known then you can use (1,0,0) or (0,1,0) or (0,0,1) instead chose one that is non parallel with C ... or have biggest (C.D). Also take a look at:
How to find view point coordinates?
[Notes]
dot product: (A.B)=Ax.Bx+Ay.By+Az.Cz
cross product: A x B
length: |A| = sqrt (Ax^2 + Ay^2 + Az^2)

Check if 4 points in space are corner points of a rectangle

I have 4 points in space A(x,y,z), B(x,y,z), C(x,y,z) and D(x,y,z). How can I check if these points are the corner points of a rectangle?
You must first determine whether or not the points are all coplanar, since a rectangle is a 2D geometric object, but your points are in 3-space. You can determine they are coplanar by comparing cross products as in:
V1 = (B-A)×(B-C)
V2 = (C-A)×(C-D)
This will give you two vectors which, if A, B, C, and D are coplanar are linearly dependent. By considering what Wolfram has to say on vector dependence, we can test the vectors for linear dependence by using
C = (V1∙V1)(V2∙V2) - (V1∙V2)(V2∙V1)
If C is 0 then the vectors V1 and V2 are linearly dependent and all the points are coplanar.
Next compute the distances between each pair of points. There should be a total of 6 such distances.
D1 = |A-B|
D2 = |A-C|
D3 = |A-D|
D4 = |B-C|
D5 = |B-D|
D6 = |C-D|
Assuming none of these distances are 0, these points form a rectangle if and only if the vertices are coplanar (already verified) and these lengths can be grouped into three pairs where elements of each pair have the same length. If the figure is a square, two sets of the pairs will have be the same length and will be shorter than the remaining pair.
Update: Reading this again, I realize the the above could define a parallelogram, so an additional check is required to check that the square of the longest distance is equal to the sum of the squares of the two shorter distances. Only then will the parallelogram also be a rectangle.
Keep in mind all of this is assuming infinite precision and within a strictly mathematical construct. If you're planning to code this up, you will need to account for rounding and accept a degree of imprecision that's not really a player when speaking in purely mathematical terms.
Check if V1=B-A and V2=D-A are orthogonal using the dot product. Then check if
C-A == V1+V2
within numerical tolerances. If both are true, the points are coplanar and form a rectangle.
Here a function is defined to check whether the 4 points represents the rectangle or not .
from math import sqrt
def Verify(A, B, C, D, epsilon=0.0001):
# Verify A-B = D-C
zero = sqrt( (A[0]-B[0]+C[0]-D[0])**2 + (A[1]-B[1]+C[1]-D[1])**2 + (A[2]-B[2]+C[2]-D[2])**2 )
if zero > epsilon:
raise ValueError("Points do not form a parallelogram; C is at %g distance from where it should be" % zero)
# Verify (D-A).(B-A) = 0
zero = (D[0]-A[0])*(B[0]-A[0]) + (D[1]-A[1])*(B[1]-A[1]) + (D[2]-A[2])*(B[2]-A[2])
if abs(zero) > epsilon:
raise ValueError("Corner A is not a right angle; edge vector dot product is %g" % zero)
else:
print('rectangle')
A = [x1,y1,z1]
print(A)
B = [x2,y2,z2]
C = [x3,y3,z3]
D = [x4,y4,z4]
Verify(A, B, C, D, epsilon=0.0001)

How to locate a point in z axis given surface location x,y and z and the distance from the first point?

I have location of a point P1 in x, y and z form. I want to find another point which is directly below this point (in z axis) at a distance d. This means that x & y co ordinates of P2 will be the same as that of P1. How to find the coordinates of P2 (z value)?
Maybe the most correct way would be to define a vector for the original point and one for the difference to the other point. Let a, b, c, represent the x, y, z coordinates for the known point and d is the distance of point 2 below point 1, then something like
v1 = {a, b, c}
diff = {0, 0, d}
and then subtract the two
v2 = v1 - diff
However, to merely get the coordinates of course all you really need to do is to define
v2 = {a, b, c-d}

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