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.
Related
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
I have a line AB. I would like to draw a line BC, perpendicular to AB. I know xyz of the points A and B, I also know the distance N between B and C. How can I find an arbitrary point C which fits into the given parameters? The calculations should be done in 3-D. Any point, perpendicular to AB can be the point C, if its distance to B equals N.
An almost identical question is given here, but I would like to know how the same thing is done in 3-D: How do you find a point at a given perpendicular distance from a line?
The calculation that works for me in 2-D was given in the link above:
dx = A.x-B.x
dy = A.y-B.y
dist = sqrt(dx*dx + dy*dy)
dx /= dist
dy /= dist
C.x = B.x + N*dy
C.y = B.y - N*dx
I tried adding Z axis to it like this:
dz = A.z - B.z
dist = sqrt(dx*dx + dy*dy + dz*dz)
dz /=dist
C.z = .... at this point it becomes a mystery to me
If I put something like "C.z - N*dz" into C.z, the distance is accurate only in some rotation angles, I would like to know the correct solution. I can imagine that in 3-D it is calculated in a completely different manner.
Clarification
Point C is not unique. It can be any point on a circle with its
centre at B and radius N. The circle is perpendicular to AB
If the desired point C can be any of the infinitely-many points fitting your requirements, here is one method.
Choose any vector that is not parallel or anti-parallel to vector AB. You could try the vector (1, 0, 0), and if that is parallel you could use (0, 1, 0) instead. Then take the cross-product of vector AB and the chosen vector. That cross-product is perpendicular to vector AB. Divide that cross-product by its length then multiply by the desired length N. Finally extend that vector from point B to find your desired point C.
Here is code in Python 3 that follows that algorithm. This code is somewhat non-pythonic to make it easier to convert to other languages. (If I really did this for myself I would use the numpy module to avoid coordinates completely and shorten this code.) But it does treat the points as tuples of 3 values: many languages will require you to handle each coordinate separately. Any real-life code would need to check for "near zero" rather than "zero" and to check that the sqrt calculation does not result in zero. I'll leave those additional steps to you. Ask if you have more questions.
from math import sqrt
def pt_at_given_distance_from_line_segment_and_endpoint(a, b, dist):
"""Return a point c such that line segment bc is perpendicular to
line segment ab and segment bc has length dist.
a and b are tuples of length 3, dist is a positive float.
"""
vec_ab = (b[0]-a[0], b[1]-a[1], b[2]-a[2])
# Find a vector not parallel or antiparallel to vector ab
if vec_ab[1] != 0 or vec_ab[2] != 0:
vec = (1, 0, 0)
else:
vec = (0, 1, 0)
# Find the cross product of the vectors
cross = (vec_ab[1] * vec[2] - vec_ab[2] * vec[1],
vec_ab[2] * vec[0] - vec_ab[0] * vec[2],
vec_ab[0] * vec[1] - vec_ab[1] * vec[0])
# Find the vector in the same direction with length dist
factor = dist / sqrt(cross[0]**2 + cross[1]**2 + cross[2]**2)
newvec = (factor * cross[0], factor * cross[1], factor * cross[2])
# Find point c such that vector bc is that vector
c = (b[0] + newvec[0], b[1] + newvec[1], b[2] + newvec[2])
# Done!
return c
The resulting output from the command
print(pt_at_given_distance_from_line_segment_and_endpoint((1, 2, 3), (4, 5, 6), 2))
is
(4.0, 6.414213562373095, 4.585786437626905)
What I am trying to do is if I place two objects [A and B] at certain positions, how can I find where C should be? The velocities are not the same. Object A's velocity is 30 m/s, Object B's is 20 m/s.
In the picture, I have drawn that the velocities are the same. It should give you a general idea of what I am trying to do, though.
I have been messing around with this, but I do not even know where to start.
Thank you in advanced to all of you who reply.
First, write two equations expressing the x position of each point at time t.
xpos_a(t) = original_xpos_a + xvelocity_a * t
xpos_b(t) = original_xpos_b + xvelocity_b * t
when the two points collide, their x positions will be equal. set xpos_a equal to xpos_b and solve for t.
original_xpos_a + xvelocity_a * t = original_xpos_b + xvelocity_b * t
xvelocity_a * t - xvelocity_b * t = original_xpos_b - original_xpos_a
t * (xvelocity_a - xvelocity_b) = original_xpos_b - original_xpos_a
t = (original_xpos_b - original_xpos_a) / (xvelocity_a - xvelocity_b)
there are three possible outcomes when you solve for t:
both points have identical original position and velocity. t = 0/0; the collision might occur at any time.
the points have identical velocty but different original positions. t = [some nonzero number]/0; the collision can never occur.
the points have different velocity and different original positions. t = some real number. If the points do collide, the collision can only occur at this time.
Perform these same steps for Y (and Z, if the problem is three dimensional). Compare the t values from each dimension. There are four possible outcomes:
any of the t values are "the collision can never occur". The collision will never occur.
two or more of the t values are real numbers that are not equal. The collision will never occur.
all t values are "the collision could occur at any time". The points are constantly colliding at every point on their trajectories.
all of the t values that are real numbers are equal to one another. The collision will occur at that time. (if that time is negative, the collision occurs before you started your simulation; you may or may not want to count this as, "the collision will never occur")
If you end up in the final category, take the time of collision and plug it into the xpos_a, ypos_a, zpos_a functions to get the spatial coordinates of the collision.
Given points A and B, and Vectors C (velocity of A) and D (velocity of B).
A = (x1, y1) >start point of A
B = (x2, y2) >start point of B
C = (q1, w1) >constant velocity of A
D = (q2, w2) >constant velocity of B
NOTE: x1, y1, x2, y2, q1, q2, w1, w2 are all constants
EDIT: Follow works given that A & C and b& D aren't co-linear (just find time of collision if they do collide as Kevin points out)
Do linearization(can't find a good reference) of them:
EQ1 => (x-x1)(w1/q1)=(y-y1) >> (x-x1)(w1/q1) + y1 = y <br>
EQ2 => (x-x2)(w2/q2)=(y-y2) >> (x-x2)(w2/q2) + y2 = y <br>
EQ1 => (w1/q1) * x + y1 - x1(w1/q1) = y
m1 * x +( b1 ) = y
EQ2 => (w2/q2) * x + y2 - x2(w2/q2) = y
m2 * x +( b2 ) = y
Solve EQ1 and EQ2 for x and y
x = (b2 - b1)/(m1 - m2)
y = m1 * x + b1 OR m2 * x + b2
The (x,y) referred to later ^
Solve for t1 or t2
t1 = (x-x1) / q1
t2 = (x-x2) / q2
Check if t1 and t2 is true for the ys
t1 ?= (y-y1) / w1
t2 ?= (y-y2) / w2
If they are the same, then yes they collide, at (x,y)
NOTE: Due to round off error unless everything is perfectly calcualted before hand, most likely nothing will collide
What is a formula to get a three dimensional vector B lying on the plane perpendicular to a vector A?
That is, given a vector A, what is a formula f(angle,modulus) which gives a vector that is perpendicular to A, with said modulus and rotated through an angle?
If the two vectors are perpendicular then their dot product is zero.
So: v1(x1, y1, z1), v2(x2, y2, z2).
=> x1 * x2 + y1 * y2 + z1 * z2 = 0
You know (x1, y1, z1). Put arbitrary x2 andy2 and you will receive the corresponding z2:
z1 * z2 = -x1 * x2 - y1 * y2
=> z2 = (-x1 * x2 - y1 * y2) / z1
Be aware if z1 is 0. Then you are in the plane.
function (a,b,c)
{
return (-b,a,0)
}
But this answer is not numerical stable when a,b are close to 0.
To avoid that case, use:
function (a,b,c)
{
return c<a ? (b,-a,0) : (0,-c,b)
}
The above answer is numerical stable, because in case c < a then max(a,b) = max(a,b,c), then vector(b,-a,0).length() > max(a,b) = max(a,b,c) , and since max(a,b,c) should not be close to zero, so is the vector. The c > a case is similar.
Calculate the cross product AxC with another vector C which is not collinear with A.
There are many possible directions in the plane perpendicular to A. If you don't really care, which one to pick, just create an arbitrary vector C not collinear with A:
if (A2 != 0 || A3 != 0)
C = (1, 0, 0);
else
C = (0, 1, 0);
B = A x C;
I believe that this should produce an arbitrary vector that is perpendicular to the given vector vec while remaining numerically stable regardless of the angle of vec (assuming that the magnitude of vec is not close to zero). Assume that Vec3D is a three dimensional vector of arbitrary numerical type.
Vec3D arbitrary_orthogonal(Vec3D vec)
{
bool b0 = (vec[0] < vec[1]) && (vec[0] < vec[2]);
bool b1 = (vec[1] <= vec[0]) && (vec[1] < vec[2]);
bool b2 = (vec[2] <= vec[0]) && (vec[2] <= vec[1]);
return cross(vec, Vec3D(int(b0), int(b1), int(b2)));
}
Informal explanation
Exactly 1 and only 1 of the bools get set; bN gets set if dimension N has magnitude strictly less than all subsequent dimensions and not greater than all previous dimensions. We then have a unit vector with a single non-zero dimension that corresponds to a dimension of minimum magnitude in vec. The cross product of this with vec is orthogonal to vec by defn of cross product. Consider now that the cross product is numerically unstable only when the two vectors are very closely aligned. Consider that our unit vector is large in only a single dimension and that that dimension corresponds to the dimension where vec was small. It's thus guaranteed to be loosely orthogonal to vec before taking the cross product, with least orthogonality in the case where all dimensions of vec are equal. In this least-orthogonal case, we're still quite orthogonal given that our unit vector has all but one dimension 0 whereas vec has all equal. We thus avoid the unstable case of taking the cross product of two nearly-aligned vectors.
q4w56's is almost there for a robust solution. Problems: 1) Doesn't take in account scaling. 2) Doesn't compare the magnitude between two variables when it should.
scale = |x| + |y| + |z|
if scale == 0:
return (0,0,0)
x = x/scale
y = y/scale
z = z/scale
if |x| > |y|:
return (z, 0,-x)
else:
return (0, z,-y)
Scaling is important when dealing with very large or very small numbers. Plus in general you are better off doing floating point operations on values between 0 and 1.
One way would be to find a rotation transform from the positive z-axis (or any other axis) to your given vector. Then transform <modulus * cos(angle), modulus * sin(angle), 0> using this transform.
def getPerpendicular(v1,modulus,angle):
v2 = vector(0,0,1)
v1_len = v2.length()
axis = v1.cross_product(v2)
sinAngle = axis.length() / v1_len # |u x v| = |u| * |v| * sin(angle)
cosAngle = v1.dot_product(v2) / v1_len # u . v = |u| * |v| * cos(angle)
axis = axis.normalize()
# atan2(sin(a), cos(a)) = a, -pi < a < pi
angle = math.atan2(sinAngle, cosAngle)
rotationMatrix = fromAxisAngle(axis, angle)
# perpendicular to v2
v3 = vector(modulus*cos(angle),modulus*sin(angle),0)
return rotationMatrix.multiply(v3);
To calculate the rotation matrix, see this article: WP: Rotation matrix from axis and angle
Another method would be to use quaternion rotation. It's a little more to wrap your head around, but it's less numbers to keep track of.
I'm trying to generate some axis vectors from parameters commonly used to specify crystallographic unit cells. These parameters consist of the length of the three axes: a,b,c and the angles between them: alpha,beta,gamma. By convention alpha is the angle between the b and c axes, beta is between a and c, and gamma between a and b.
Now getting vector representations for the first two is easy. I can arbitrarily set the the a axis to the x axis, so a_axis = [a,0,0]. I then need to rotate b away from a by the angle gamma, so I can stay in the x-y plane to do so, and b_axis = [b*cos(gamma),b*sin(gamma),0].
The problem is the third vector. I can't figure out a nice clean way to determine it. I've figured out some different interpretations but none of them have panned out. One is imagining the there are two cones around the axes axis_a and axis_b whose sizes are specified by the angles alpha and beta. The intersection of these cones create two lines, the one in the positive z direction can be used as the direction for axis_c, of length c.
Does someone know how I should go about determining the axis_c?
Thanks.
The angle alpha between two vectors u,v of known length can be found from their inner (dot) product <u,v>:
cos(alpha) = <u,v>/(||u|| ||v||)
That is, the cosine of alpha is the inner product of the two vectors divided by the product of their lengths.
So the z-component of your third can be any nonzero value. Scaling any or all of the axis vectors after you get the angles right won't change the angles, so let's assume (say) Cz = 1.
Now the first two vectors might as well be A = (1,0,0) and B = (cos(gamma),sin(gamma),0). Both of these have length 1, so the two conditions to satisfy with choosing C are:
cos(alpha) = <B,C>/||C||
cos(beta) = <A,C>/||C||
Now we have only two unknowns, Cx and Cy, to solve for. To keep things simple I'm going to just refer to them as x and y, i.e. C = (x,y,1). Thus:
cos(alpha) = [cos(gamma)*x + sin(gamma)*y]/sqrt(x^2 + y^2 + 1)
cos(beta) = x/(sqrt(x^2 + y^2 + 1)
Dividing the first equation by the second (assuming beta not a right angle!), we get:
cos(alpha)/cos(beta) = cos(gamma) + sin(gamma)*(y/x)
which is a linear equation to solve for the ratio r = y/x. Once you have that, substituting y = rx in the second equation above and squaring gives a quadratic equation for x:
cos^2(beta)*((1+r^2)x^2 + 1) = x^2
cos^2(beta) = (1 - cos^2(beta)*(1 + r^2))x^2
x^2 = cos^2(beta)/[(1 - cos^2(beta)*(1 + r^2))]
By squaring the equation we introduced an artifact root, corresponding to choosing the sign of x. So check the solutions for x you get from this in the "original" second equation to make sure you get the right sign for cos(beta).
Added:
If beta is a right angle, things are simpler than the above. x = 0 is forced, and we have only to solve the first equation for y:
cos(alpha) = sin(gamma)*y/sqrt(y^2 + 1)
Squaring and multiplying away the denominator gives a quadratic for y, similar to what we did before. Remember to check your choice of a sign for y:
cos^2(alpha)*(y^2 + 1) = sin^2(gamma)*y^2
cos^2(alpha) = [sin^2(gamma) - cos^2(alpha)]*y^2
y^2 = cos^2(alpha)/[sin^2(gamma) - cos^2(alpha)]
Actually if one of the angles alpha, beta, gamma is a right angle, it might be best to label that angle gamma (between the first two vectors A,B) to simplify the computation.
Here is a way to find all Cx, Cy, Cz (first two are the same as in the other answer), given that A = (Ax,0,0), B = (Bx, By, 0), and assuming that |C| = 1
1) cos(beta) = AC/(|A||C|) = AxCx/|A| => Cx = |A|cos(beta)/Ax = cos(beta)
2) cos(alpha) = BC/(|B||C|) = (BxCx+ByCy)/|B| => Cy = (|B|cos(alpha)-Bx cos(beta))/By
3) To find Cz let O be the point at (0,0,0), T the point at (Cx,Cy,Cz), P be the projection of T on Oxy and Q be the projection of T on Ox. So P is the point at (Cx,Cy,0) and Q is the point at (Cx,0,0). Thus from the right angle triangle OQT we get
tan(beta) = |QT|/||OQ| = |QT|/Cx
and from the right triangle TPQ we get |TP|^2 + |PQ|^2 = |QT|^2. So
Cz = |TP| = sqrt(|QT|^2 - |PQ|^2) = sqrt( Cx^2 tan(beta)^2 - Cy^2 )
I'm not sure if this is correct but I might as well take a shot. Hopefully I won't get a billion down votes...
I'm too lazy to scale the vectors by the necessary amounts, so I'll assume they are all normalized to have a length of 1. You can make some simple modifications to the calculation to account for the varying sizes. Also, I'll use * to represent the dot product.
A = (1, 0, 0)
B = (cos(g), sin(g), 0)
C = (Cx, Cy, Cz)
A * C = cos(beta) //This is just a definition of the dot product. I'm assuming that the magnitudes are 1, so I can skip that portion, and you said that beta was the angle between A and C.
A * C = Cx //I did this by multiplying each corresponding value, and the Cy and Cz were ignored because they were being multiplied by 0
cos(beta) = Cx //Combine the previous two equations
B * C = cos(alpha)
B * C = Cx*cos(g) + Cy*sin(g) = cos(beta) * cos(g) + Cy*sin(g)
(cos(alpha) - cos(beta) * cos(g))/(sin(g)) = Cy
To be honest, I'm not sure how to get the z component of vector C, but I would expect it to be one more relatively easy step. If I can figure it out, I'll edit my post.