Aaaboy97
|
  |
| Joined: 05 Apr 2009 |
| Total Posts: 6612 |
|
|
| 24 Apr 2012 05:38 PM |
What is the equation for finding the angle between point a and b?
I've tried using this:
public static RotationMatrix pointToPoint(double[] a, double[] b) { double[] c = {b[0] - a[0], b[1] - a[1], b[2] - a[2]}; double rx = -Math.atan(c[1] / c[0]); double ry = Math.atan(c[2] / c[0]); return new RotationMatrix(a[0], a[1], a[2]).multiply(angleToMatrix(rx, ry, 0)); }
but this is incorrect.
What is the correct equation for finding the angle from point a to point b?
|
|
|
| Report Abuse |
|
|
1Ra
|
  |
| Joined: 02 May 2010 |
| Total Posts: 2400 |
|
|
| 24 Apr 2012 06:07 PM |
| Wouldn't an angle between 2 points always be 180, because you can always draw 1 line between 2 points? |
|
|
| Report Abuse |
|
|
Aaaboy97
|
  |
| Joined: 05 Apr 2009 |
| Total Posts: 6612 |
|
|
| 24 Apr 2012 06:09 PM |
@1ra
I'm trying to find the equivalent of:
CFrame.new(a, b):toEulerAnglesXYZ()
where a and b are the points in question |
|
|
| Report Abuse |
|
|
Aaaboy97
|
  |
| Joined: 05 Apr 2009 |
| Total Posts: 6612 |
|
|
| 24 Apr 2012 06:46 PM |
| I've been told to use the dot product and arccos but I don't understand how that gives 3 angles... |
|
|
| Report Abuse |
|
|
MrNicNac
|
  |
| Joined: 29 Aug 2008 |
| Total Posts: 26567 |
|
|
| 24 Apr 2012 07:06 PM |
Euclidean angles are quite tricky to get. Although there is a little method that can suffice based on points deriving from a matrix of nine values.
* [m00 m01 m02] * [m10 m11 m12] * [m20 m21 m22]*/ public final void rotate(matrix m) { // Assuming the angles are in radians. if (m.m10 > 0.998) { // singularity at north pole heading = Math.atan2(m.m02,m.m22); attitude = Math.PI/2; bank = 0; return; } if (m.m10 < -0.998) { // singularity at south pole heading = Math.atan2(m.m02,m.m22); attitude = -Math.PI/2; bank = 0; return; } heading = Math.atan2(-m.m20,m.m00); bank = Math.atan2(-m.m12,m.m11); attitude = Math.asin(m.m10); }
Note that really isn't mine, but I'm positive it might throw some insight. To me or you. = |
|
|
| Report Abuse |
|
|
Aaaboy97
|
  |
| Joined: 05 Apr 2009 |
| Total Posts: 6612 |
|
|
| 24 Apr 2012 07:08 PM |
@MrNicNac
I'm not trying mainly to get angles from a rotation matrix, I'm attempting to get the angles to point an object at point a to face point b |
|
|
| Report Abuse |
|
|
HotThoth
|
  |
 |
| Joined: 24 Aug 2010 |
| Total Posts: 1176 |
|
|
| 24 Apr 2012 07:24 PM |
If I understand what you're asking, then what you want to be looking up is basically polar coordinates. Take point a to be your origin, and then call "r" the vector from a to b in worldspace; you want to find the two angles phi and theta. (r, phi, and theta are all standard names for the three values in a polar coordinate tuple).
There is one last angle you could be rotating around, but it doesn't matter for your purposes [if I have a camera pointing at you, I can rotate the camera "barrel roll"-style and it will always be facing you; so this rotation axis isn't important for "facing"]. |
|
|
| Report Abuse |
|
|
Aaaboy97
|
  |
| Joined: 05 Apr 2009 |
| Total Posts: 6612 |
|
|
| 24 Apr 2012 08:05 PM |
@HotThoth
double[] c = {b[0] - a[0], b[1] - a[1], b[2] - a[2]}; double r = Math.sqrt(Math.pow(c[0], 2) + Math.pow(c[1], 2) + Math.pow(c[2], 2)); double[] d = {c[0]/r, c[1]/r, c[2]/r}; double theta = Math.atan2(Math.sqrt(Math.pow(d[0], 2) + Math.pow(d[1], 2)), d[2]); double phi = Math.atan2(d[1], d[0]);
Is this correct?
Which axis do theta and phi correspond with? |
|
|
| Report Abuse |
|
|
|
| 24 Apr 2012 08:11 PM |
I just learned last week in 2D space that the angle between two 2D vectors u and v is. According to Wikipedia, "The dot product is directly related to the cosine of the angle between two vectors in Euclidean space of any number of dimensions."
Wikipedia also seems to ignore dimensions, so this seems to be true any dimensional vectors.
cos theta = (u dot v) / (mag u * mag v)
Or
theta = arccos(u dot v / (mag u * mag v))
So, for between two Vector3's (from origin):
function angle(a,b) return math.acos( (a.x*b.x + a.y*b.y + a.z*b.z) / a.magnitude / b.magnitude) end |
|
|
| Report Abuse |
|
|
myrkos
|
  |
| Joined: 06 Sep 2010 |
| Total Posts: 8072 |
|
|
| 24 Apr 2012 08:12 PM |
| ^ Which is exactly what I said in the other thread I made... :D |
|
|
| Report Abuse |
|
|
myrkos
|
  |
| Joined: 06 Sep 2010 |
| Total Posts: 8072 |
|
| |
|
Aaaboy97
|
  |
| Joined: 05 Apr 2009 |
| Total Posts: 6612 |
|
|
| 24 Apr 2012 08:18 PM |
| But that returns one angle, which axis is it on, and how to you retrieve the other one? |
|
|
| Report Abuse |
|
|
Aaaboy97
|
  |
| Joined: 05 Apr 2009 |
| Total Posts: 6612 |
|
|
| 24 Apr 2012 08:20 PM |
| And also, what if you are finding the angle between 0, 0, 0 and another, that'll error. |
|
|
| Report Abuse |
|
|
myrkos
|
  |
| Joined: 06 Sep 2010 |
| Total Posts: 8072 |
|
|
| 24 Apr 2012 08:20 PM |
| It returns the angle between the two vectors. Set one of the vectors to an axis and you get the angle from that axis to the other vector. |
|
|
| Report Abuse |
|
|
Aaaboy97
|
  |
| Joined: 05 Apr 2009 |
| Total Posts: 6612 |
|
|
| 24 Apr 2012 08:26 PM |
If I try to find one angle of the line pointing from 1, 1, 1 to 5, 5, 5 I should get one of these:
> print(CFrame.new(Vector3.new(1, 1, 1), Vector3.new(5, 5, 5)):toEulerAnglesXYZ()) 2.3561944961548 -0.6154797077179 2.6179938316345
But that method returns 0.0 |
|
|
| Report Abuse |
|
|
myrkos
|
  |
| Joined: 06 Sep 2010 |
| Total Posts: 8072 |
|
|
| 24 Apr 2012 08:28 PM |
Because the angle between the two parallel vectors is 0.
(0,0,0) to (1,1,1) and (0,0,0) to (5,5,5) are parallel. |
|
|
| Report Abuse |
|
|
Aaaboy97
|
  |
| Joined: 05 Apr 2009 |
| Total Posts: 6612 |
|
|
| 24 Apr 2012 08:29 PM |
But what method do I use to find the three 2.3561944961548 -0.6154797077179 2.6179938316345
This is what I've been trying to figure out |
|
|
| Report Abuse |
|
|
myrkos
|
  |
| Joined: 06 Sep 2010 |
| Total Posts: 8072 |
|
|
| 24 Apr 2012 08:32 PM |
(1,1,1) - (5,5,5) gives you the vector from a to b, called c.
Use the function with c and (0,1,0) to get the angle form the x axis.
|
|
|
| Report Abuse |
|
|
Aaaboy97
|
  |
| Joined: 05 Apr 2009 |
| Total Posts: 6612 |
|
|
| 24 Apr 2012 08:34 PM |
| What do I use for the y and z axis? |
|
|
| Report Abuse |
|
|
myrkos
|
  |
| Joined: 06 Sep 2010 |
| Total Posts: 8072 |
|
|
| 24 Apr 2012 08:35 PM |
(1,0,0) for x (0,1,0) for y (0,0,1) for z
it's a tad bit obvious, but whatever |
|
|
| Report Abuse |
|
|
Aaaboy97
|
  |
| Joined: 05 Apr 2009 |
| Total Posts: 6612 |
|
|
| 24 Apr 2012 08:37 PM |
You just told me (0, 1, 0) is x axis.. but
function angle(a,b) return math.acos( (a.x*b.x + a.y*b.y + a.z*b.z) / a.magnitude / b.magnitude) end
local a = Vector3.new(1, 1, 1) local b = Vector3.new(5, 5, 5)
local c = a - b print(angle(Vector3.new(1, 0, 0), c)) print(angle(Vector3.new(0, 1, 0), c)) print(angle(Vector3.new(0, 0, 1), c))
that returns
2.1862760354653 2.1862760354653 2.1862760354653 |
|
|
| Report Abuse |
|
|
myrkos
|
  |
| Joined: 06 Sep 2010 |
| Total Posts: 8072 |
|
|
| 24 Apr 2012 08:39 PM |
| Don't you subtract to find dot product? |
|
|
| Report Abuse |
|
|
Aaaboy97
|
  |
| Joined: 05 Apr 2009 |
| Total Posts: 6612 |
|
|
| 24 Apr 2012 08:41 PM |
I thought you added...
with subtracting it gives
2.1862760354653 0.95531661812451 0.95531661812451 |
|
|
| Report Abuse |
|
|
stravant
|
  |
 |
| Joined: 22 Oct 2007 |
| Total Posts: 2893 |
|
|
| 24 Apr 2012 08:44 PM |
This is actually a really good problem for my studying for linear algebra, and turns out to be very easy, you actually need no trig at all:
The first thing that you need to recognize is that a rotation matrix is really a set of unit vectors which describe how the x/y/z axis would look if you were to rotate them through the rotation in question.
Now, consider the two "points" that you have as the unit vectors of the x and x' axis. Define: (x) := a.unit, (x') := b.unit. Now, it becomes trivial to find two rotations that represent the those axis. Just take the two Matrices:
Standard matrix A (rotation to point a from the standard x axis): y = (0,1,0)-(0,1,0)*(0,1,0):Dot((x)) A := { (x), y, (x):Cross(y) } Same idea for the second x' axis: y' = (0,1,0)-(0,1,0)*(0,1,0):Dot((x')) B := { (x'), y', (x'):Cross(y') }
(each component of the {} is one row or column of the matrix depending on if you're using row major or column major. If you don't know what those mean, just try both and use whichever works)
What I did is find a rotation where the standard x axis -> x/x', I use gramm-schmitt process in order to find some orthogonal next axis for the standard y axis to become, and the z axis becomes whatever vector is perpendicular to those two in the left-handed sense.
Now, you want to find the transform from A -> B, rather that I -> A, I -> B which is what we have right now. To do that you can just take: Take out input point "p", and represent it in the basis A: p = A*t => t = A:inverse()*p Now, apply the final transform B to t: out = B*t = B*A:inverse()*p out = (Transform)*p
So the transform is: B*A:inverse()
And that's the answer. It isn't quite what you're looking for, since it will choose a rather arbitrary rotation axis, not the "best" one, but it will correctly rotate things between those two axis defined by a and b.
I'll keep working on it later to try to solve it for the best rotation axis.
|
|
|
| Report Abuse |
|
|
HotThoth
|
  |
 |
| Joined: 24 Aug 2010 |
| Total Posts: 1176 |
|
|
| 25 Apr 2012 01:13 PM |
If you're trying to match the values you get from that RBX.Lua call, then you'll want Mr. NicNac's method.
Basically MNN's method is precisely what the call :ToEulerAnglesXYZ() does, except his isn't XYZ. His is YZX, which is pretty standard. So look up the XYZ variant (it's the same function, but with the values in your matrix rearranged a bit).
So to match RBX.Lua, you need two functions, you need to get the ToEulerAnglesXYZ(), and before you use that, you'll also need to get a matrix from points a and b (the CFrame.new(a, b) call).
To do that part, you take (b - a).unit, and since this is the lookDirection, we know this needs to be our matrix's negative z-axis. My guess is that then we try to make the y-axis of our matrix pointing straight up. We do this by taking (0, 1, 0) as our y-axis. But we want it to be perpendicular to the z-axis, so we take out whatever overlap there is, and make it a unit. Then we find x-axis by using cross product.
This gives us: z: (a - b).unit y: ((0, 1, 0) - z:Dot(0,1,0)*z).unit x: -z:Cross(y)
Cross product makes the resulting vector perpendicular to the input vectors, so we know that x is perpendicular to the other two, and our z is fixed, but we actually don't know that y is perpendicular, so we do one last cross product now for the y-axis.
y = z:Cross(x).
This gives us our x, y, and z axes. Note that this fails if you look straight up and down at something, so in that case, we probably take some other axis to use as what we try to make our y-axis point to. Probably x-axis? (So just replace (0, 1, 0)'s with (1, 0, 0)'s in that case.
So it's a long and rickety road, but doing both of those should get you the same values.
|
|
|
| Report Abuse |
|
|