axes separated by angles - math

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.

Related

How to find a point in 3-D at an arbitrary perpendicular line given distance to the point

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)

Position of a point in a circle

Hello again first part is working like a charm, thank you everyone.
But I've another question...
As I've no interface, is there a way to do the same thing with out not knowing the radius of the circle?
Should have refresh the page CodeMonkey solution is exactly what I was looking for...
Thank you again.
============================
First I'm not a developer, I'm a simple woodworker that left school far too early...
I'm trying to make one of my tool to work with an autonomous robot.
I made them communicate by reading a lot of tutorials.
But I have one problem I cant figure out.
Robot expect position of the tool as (X,Y) but tool's output is (A,B,C)
A is the distance from tool to north
B distance to east
C distance at 120 degree clockwise from east axe
the border is a circle, radius may change, and may or may not be something I know.
I've been on that for 1 month, and I can't find a way to transform those value into the position.
I made a test with 3 nails on a circle I draw on wood, and if I have the distance there is only one position possible, so I guess its possible.
But how?
Also, if someone as an answer I'd love pseudo code not code so I can practice.
If there is a tool to make a drawing I can use to make it clearer can you point it out to me?
Thank you.
hope it helps :
X, Y are coordinate from center, Da,Db, Dc are known.
Trying to make it more clear (sorry its so clear in my head).
X,Y are the coordinate of the point where is the tool (P).
Center is at 0,0
A is the point where vertical line cut the circle from P, with Da distance P to A;
B is the point where horizontal line cuts the circle fom P, with Db distance P to B.
C is the point where the line at 120 clockwise from horizontal cuts the circle from P, with Dc distance P to C.
Output from tool is an array of int (unit mm): A=123, B=114, C=89
Those are the only informations I have
thanks for all the ideas I'll try them at home later,
Hope it works :)
Basic geometry. I decided to give up having the circle at the origin. We don't know the center of the circle yet. What you do have, is three points on that circle. Let's try having the tool's position, given as P, as the new (0,0). This thus resolves to finding a circle given three points: (0, Da); (Db,0), and back off at 120° at Dc distance.
Pseudocode:
Calculate a line from A to B: we'll call it AB. Find AB's halfway point. Calculate a line perpendicular to AB, through that midpoint (e.g. the cross product of AB and a unit Z axis finds the perpendicular vector).
Calculate a line from B to C (or C to A works just as well): we'll call it BC. Find BC's halfway point. Calculate a line perpendicular to BC, through that midpoint.
Calculate where these two lines cross. This will be the origin of your circle.
Since P is at (0,0), the negative of your circle's origin will be your tool's coordinates relative to the circle's origin. You should be able to calculate anything you need relative to that, now.
Midpoint between two points: X=(X1+X2)/2. Y=(Y1+Y2)/2.
The circle's radius can be calculated using, e.g. point A and the circle's origin: R=sqrt(sqr((Ax-CirX)+sqr(Ay-CirY))
Distance from the edge: circle's radius - tool's distance from the circle's center via Pythagorean Theorem again.
Assume you know X and Y. R is the radius of the circle.
|(X, Y + Da)| = R
|(X + Db, Y)| = R
|(X - cos(pi/3) * Dc, Y - cos(pi/6) * Dc)| = R
Assuming we don't know the radius R. We can still say
|(X, Y + Da)|^2 = |(X + Db, Y)|^2
=> X^2 + (Y+Da)^2 = (X+Db)^2 + Y^2
=> 2YDa + Da^2 = 2XDb + Db^2 (I)
and denoting cos(pi/3)*Dc as c1 and cos(pi/6)*Dc as c2:
|(X, Y + Da)|^2 = |(X - c1, Y - c2)|^2
=> X^2 + Y^2 + 2YDa + Da^2 = X^2 - 2Xc1 + c1^2 + Y^2 - 2Yc2 + c2^2
=> 2YDa + Da^2 = - 2Xc1 + c1^2 - 2Yc2 + c2^2
=> Y = (-2Xc1 + c1^2 + c2^2 - Da^2) / 2(c2+Da) (II)
Putting (II) back in the equation (I) we get:
=> (-2Xc1 + c1^2 + c2^2 - Da^2) Da / (c2+Da) + Da^2 = 2XDb + Db^2
=> (-2Xc1 + c1^2 + c2^2 - Da^2) Da + Da^2 * (c2+Da) = 2XDb(c2+Da) + Db^2 * (c2+Da)
=> (-2Xc1 + c1^2 + c2^2) Da + Da^2 * c2 = 2XDb(c2+Da) + Db^2 * (c2+Da)
=> X = ((c1^2 + c2^2) Da + Da^2 * c2 - Db^2 * (c2+Da)) / (2Dbc2 + 2Db*Da + 2Dac1) (III)
Knowing X you can get Y by calculating (II).
You can also make some simplifications, e.g. c1^2 + c2^2 = Dc^2
Putting this into Python (almost Pseudocode):
import math
def GetXYR(Da, Db, Dc):
c1 = math.cos(math.pi/3) * Dc
c2 = math.cos(math.pi/6) * Dc
X = ((c1**2 + c2**2) * Da + Da**2 * c2 - Db * Db * (c2 + Da)) / (2 * Db * c2 + 2 * Db * Da + 2 * Da * c1)
Y = (-2*X*c1 + c1**2 + c2**2 - Da**2) / (2*(c2+Da))
R = math.sqrt(X**2 + (Y+Da)**2)
R2 = math.sqrt(Y**2 + (X+Db)**2)
R3 = math.sqrt((X - math.cos(math.pi/3) * Dc)**2 + (Y - math.cos(math.pi/6) * Dc)**2)
return (X, Y, R, R2, R3)
(X, Y, R, R2, R3) = GetXYR(123.0, 114.0, 89.0)
print((X, Y, R, R2, R3))
I get the result (X, Y, R, R2, R3) = (-8.129166703588021, -16.205081335032794, 107.1038654949096, 107.10386549490958, 107.1038654949096)
Which seems reasonable if both Da and Db are longer than Dc, then both coordinates are probably negative.
I calculated the Radius from three equations to cross check whether my calculation makes sense. It seems to fulfill all three equations we set up in the beginning.
Your problem is know a "circumscribed circle". You have a triangle define by 3 distances at given angles from your robot position, then you can construct the circumscribed circle from these three points (see Circumscribed circle from Wikipedia - section "Other properties"). So you know the diameter (if needed).
It is also known that the meeting point of perpendicular bisector of triangle sides is the center of the circumscribed circle.
Let's a=Da, b=Db. The we can write a system for points A and B at the circumference:
(x+b)^2 + y^2 = r^2
(y+a)^2 + x^2 = r^2
After transformations we have quadratic equation
y^2 * (4*b^2+4*a^2) + y * (4*a^3+4*a*b^2) + b^4-4*b^2*r^2+a^4+2*a^2*b^2 = 0
or
AA * y^2 + BB * y + CC = 0
where coefficients are
AA = (4*b^2+4*a^2)
BB = (4*a^3+4*a*b^2)
CC = b^4-4*b^2*r^2+a^4+2*a^2*b^2
So calculate AA, BB, CC coefficients, find solutions y1,y2 of quadratic eqiation, then get corresponding x1, x2 values using
x = (a^2 - b^2 + 2 * a * y) / (2 * b)
and choose real solution pair (where coordinate is inside the circle)
Quick checking:
a=1,b=1,r=1 gives coordinates 0,0, as expected (and false 1,-1 outside the circle)
a=3,b=4,r=5 gives coordinates (rough) 0.65, 1.96 at the picture, distances are about 3 and 4.
Delphi code (does not check all possible errors) outputs x: 0.5981 y: 1.9641
var
a, b, r, a2, b2: Double;
aa, bb, cc, dis, y1, y2, x1, x2: Double;
begin
a := 3;
b := 4;
r := 5;
a2 := a * a;
b2:= b * b;
aa := 4 * (b2 + a2);
bb := 4 * a * (a2 + b2);
cc := b2 * b2 - 4 * b2 * r * r + a2 * a2 + 2 * a2 * b2;
dis := bb * bb - 4 * aa * cc;
if Dis < 0 then begin
ShowMessage('no solutions');
Exit;
end;
y1 := (- bb - Sqrt(Dis)) / (2 * aa);
y2 := (- bb + Sqrt(Dis)) / (2 * aa);
x1 := (a2 - b2 + 2 * a * y1) / (2 * b);
x2 := (a2 - b2 + 2 * a * y2) / (2 * b);
if x1 * x1 + y1 * y1 <= r * r then
Memo1.Lines.Add(Format('x: %6.4f y: %6.4f', [x1, y1]))
else
if x2 * x2 + y2 * y2 <= r * r then
Memo1.Lines.Add(Format('x: %6.4f y: %6.4f', [x2, y2]));
From your diagram you have point P that you need it's X & Y coordinate. So we need to find Px and Py or (Px,Py). We know that Ax = Px and By = Py. We can use these for substitution if needed. We know that C & P create a line and all lines have slope in the form of y = mx + b. Where the slope is m and the y intercept is b. We don't know m or b at this point but they can be found. We know that the angle of between two vectors where the vectors are CP and PB gives an angle of 120°, but this does not put the angle in standard position since this is a CW rotation. When working with circles and trig functions along with linear equations of slope within them it is best to work in standard form. So if this line of y = mx + b where the points C & P belong to it the angle above the horizontal line that is parallel to the horizontal axis that is made by the points P & B will be 180° - 120° = 60° We also know that the cos angle between two vectors is also equal to the dot product of those vectors divided by the product of their magnitudes.
We don't have exact numbers yet but we can construct a formula: Since theta = 60° above the horizontal in the standard position we know that the slope m is also the tangent of that angle; so the slope of this line is tan(60°). So let's go back to our linear equation y = tan(60°)x + b. Since b is the y intercept we need to find what x is when y is equal to 0. Since we still have three undefined variables y, x, and b we can use the points on this line to help us here. We know that the points C & P are on this line. So this vector of y = tan(60°)x + b is constructed from (Px, Py) - (Cx, Cy). The vector is then (Px-Cx, Py-Cy) that has an angle of 60° above the horizontal that is parallel to the horizontal axis. We need to use another form of the linear equation that involves the points and the slope this time which happens to be y - y1 = m(x - x1) so this then becomes y - Py = tan(60°)(x - Px) well I did say earlier that we could substitute so let's go ahead and do that: y - By = tan(60°)(x - Ax) then y - By = tan(60°)x - tan(60°)Ax. And this becomes known if you know the actual coordinate points of A & B. The only thing here is that you have to convert your angle of 120° to standard form. It all depends on what your known and unknowns are. So if you need P and you have both A & B are known from your diagram the work is easy because the points you need for P will be P(Ax,By). And since you already said that you know Da, Db & Dc with their lengths then its just a matter of apply the correct trig functions with the proper angle and or using the Pythagorean Theorem to find the length of another leg of the triangle. It shouldn't be all that hard to find what P(x,y) is from the other points. You can use the trig functions, linear equations, the Pythagorean theorem, vector calculations etc. If you can find the equation of the line that points C & P knowing that P has A's x value and has B's y value and having the slope of that line that is defined by the tangent above the horizontal which is 180° - phi where phi is the angle you are giving that is CW rotation and theta would be the angle in standard position or above the horizontal you have a general form of y - By = tan(180° - phi)(x - Ax) and from this equation you can find any point on that line.
There are other methods such as using the existing points and the vectors that they create between each other and then generate an equilateral triangle using those points and then from that equilateral if you can generate one, you can use the perpendicular bisectors of that triangle to find the centroid of that triangle. That is another method that can be done. The only thing you may have to consider is the linear translation of the line from the origin. Thus you will have a shift in the line of (Ax - origin, By - origin) and to find one set the other to 0 and vise versa. There are many different methods to find it.
I just showed you several mathematical techniques that can help you to find a general equation based on your known(s) and unknown(s). It just a matter of recognizing which equations work in which scenario. Once you recognize the correct equations for the givens; the rest is fairly easy. I hope this helps you.
EDIT
I did forget to mention one thing; and that is the line of CP has a point on the edge of the circle defined by (cos(60°), sin(60°)) in the 1st quadrant. In the third quadrant you will have a point on this line and the circle defined by (-cos(60°), -sin(60°)) provided that this line goes through the origin (0,0) where there is no y nor x intercepts and if this is the case then the point on the circle at either end and the origin will be the radius of that circle.

Standard form of ellipse

I'm getting ellipses as level curves of a fit dataset. After selecting a particular ellipse, I would like to report it as a center point, semi-major and minor axes lengths, and a rotation angle. In other words, I would like to transform (using mathematica) my ellipse equation from the form:
Ax^2 + By^2 + Cx + Dy + Exy + F = 0
to a more standard form:
((xCos[alpha] - ySin[alpha] - h)^2)/(r^2) + ((xSin[alpha] + yCos[alpha] - k)^2)/(s^2) = 1
where (h,k) is the center, alpha is the rotation angle, and r and s are the semi-axes
The actual equation I'm attempting to transform is
1.68052 x - 9.83173 x^2 + 4.89519 y - 1.19133 x y - 9.70891 y^2 + 6.09234 = 0
I know the center point is the fitted maximum, which is:
{0.0704526, 0.247775}
I posted a version of this answer on Math SE since it benefits a lot from proper mathematical typesetting. The example there is simpler as well, and there are some extra details.
The following description follows the German Wikipedia article Hauptachsentransformation. Its English counterpart, according to inter-wiki links, is principal component analysis. I find the former article a lot more geometric than the latter. The latter has a strong focus on statistical data, though, so it might be useful for you nevertheless.
Rotation
Your ellipse is described as
[A E/2] [x] [x]
[x y] * [E/2 B] * [y] + [C D] * [y] + F = 0
First you identify the rotation. You do this by identifying the eigenvalues and eigenvectors of this 2×2 matrix. These eigenvectors will form an orthogonal matrix describing your rotation: its entries are the Sin[alpha] and Cos[alpha] from your formula.
With your numbers, you get
[A E/2] [-0.74248 0.66987] [-10.369 0 ] [-0.74248 -0.66987]
[E/2 B] = [-0.66987 -0.74248] * [ 0 -9.1715] * [ 0.66987 -0.74248]
The first of the three factors is the matrix formed by the eigenvectors, each normalized to unit length. The central matrix has the eigenvalues on the diagonal, and the last one is the transpose of the first. If you multiply the vector (x,y) with that last matrix, then you will change the coordinate system in such a way that the mixed term vanishes, i.e. the x and y axes are parallel to the main axes of your ellipse. This is just what happens in your desired formula, so now you know that
Cos[alpha] = -0.74248 (-0.742479398678 with more accuracy)
Sin[alpha] = 0.66987 ( 0.669868899516)
Translation
If you multiply the row vector [C D] in the above formula with the first of the three matrices, then this effect will exactly cancel the multiplication of (x, y) by the third matrix. Therefore in that changed coordinate system, you use the central diagonal matrix for the quadratic term, and this product for the linear term.
[-0.74248 0.66987]
[1.68052, 4.89519] * [-0.66987 -0.74248] = [-4.5269 -2.5089]
Now you have to complete the square independently for x and y, and you end up with a form from which you can read the center coordinates.
-10.369x² -4.5269x = -10.369(x + 0.21829)² + 0.49408
-9.1715y² -2.5089y = -9.1715(y + 0.13677)² + 0.17157
h = -0.21829 (-0.218286476695)
k = -0.13677 (-0.136774259156)
Note that h and k describe the center in the already rotated coordinate system; to obtain the original center you'd multiply again with the first matrix:
[-0.74248 0.66987] [-0.21829] [0.07045]
[-0.66987 -0.74248] * [-0.13677] = [0.24778]
which fits your description.
Scaling
The completed squares above contributed some more terms to the constant factor F:
6.09234 + 0.49408 + 0.17157 = 6.7580
Now you move this to the right side of the equation, then divide the whole equation by this number so that you get the = 1 from your desired form. Then you can deduce the radii.
1 -10.369
-- = ------- = 1.5344
r² -6.7580
1 -9.1715
-- = ------- = 1.3571
s² -6.7580
r = 0.80730 (0.807304599162099)
s = 0.85840 (0.858398019487315)
Verifying the result
Now let's check that we didn't make any mistakes. With the parameters we found, you can piece together the equation
((-0.74248*x - 0.66987*y + 0.21829)^2)/(0.80730^2)
+ (( 0.66987*x - 0.74248*y + 0.13677)^2)/(0.85840^2) = 1
Move the 1 to the left side, and multiply by -6.7580, and you should end up with the original equation. Expanding that (with the extra precision versions printed in parentheses), you'll get
-9.8317300000 x^2
-1.1913300000 x y
+1.6805200000 x
-9.7089100000 y^2
+4.8951900000 y
+6.0923400000
which is a perfect match for your input.
If you have h and k, you can use Lagrange Multipliers to maximize / minimize the function (x-h)^2+(y-k)^2 subject to the constraint of being on the ellipse. The maximum distance will be the major radius, the minimum distance the minor radius, and alpha will be how much they are rotated from horizontal.

Distance from origin to plane (shortest)

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.

Finding intersect in triangle from a vector originating from a particular side

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.

Resources