Calculating the angles of the rotation giving the vertices - rotation

I have 4 points (black A, black B, black C and black D) which are the vertices of the rotated red square.
Is it possible to determine what were the three angles (x angle, y angle and z angle) used to rotate the red square into the black square?
In this case, the angles were:
X = 1rad
Y = 0.2rad
Z = 0.3rad
EDIT: I just have the four black points, not the red ones.
The only thing I know about the red square is that it is a square

There is method to find affine matrix needed to transform point set into another one.
Having natrix, you can find angles.
Description for 2D case is here, 3D case is similar.
M * A = B
where
| xa xb xc xd|
A =| ya yb yc yd|
| za zb zc zd|
| 1 1 1 1 |
| xa' xb' xc' xd'|
B =| ya' yb' yc' yd'|
| za' zb' zc' zd'|
| 1 1 1 1 |
To find unknown M, we can multiply both sides of the expression by inverse of A matrix
M * A * Inv(A) = B * Inv(A)
M = B * Inv(A)
But solution is unique for non-complanar point quadruplet - in your case points lie in the same plane, so if solution exists, it is really a family of solutions and you have to choose arbitrary one. (Perhaps angles will be defined unambiguously)

Related

Intersection points between 2 discs in 3d

i am trying to find a algorithm or a way to find the intersection between two circle on a sphere (in 3d). For example if i have two circles center at two pointsA(latitude1,longitude1) and B(latidude2,longitude2)
assuming that they intersect, how can i find the intersection between those two circles? is there an algorithm to do that?
Thank you
Convert from latitude/longitude to 3D Cartesian
coordinates.
For each circle, find the equation nx x + ny y + nz z = d of the
plane whose intersection with the sphere is the circle. Assuming
that the sphere is centered at the origin, the normal vector
(nx, ny, nz) is the circle center (cx, cy, cz) (projected or
not) after normalization.
(cx, cy, cz)
(nx, ny, nz) = -----------------
||(cx, cy, cz)||
2
The distance d is computed using Pythagoras. Let r be the radius
of the circle and R be the radius of the sphere.
2 2 2
R = d + r
_______ _______________
| 2 2 |
d = \|R - r = \|(R + r) (R - r)
The second expression is preferred for numerical stability.
If we know only the length r' on the surface of the sphere from
the projected center of the circle to the circle, then compute
d = R cos(r'/R)
r = R sin(r'/R).
We actually don’t need r in this case.
Find the intersection of the two planes, a
line.
Find the intersection of the line and the sphere, between zero and two
points.
Convert the points to
latitude/longitude.

Inverting 3d rotation sequence

I have a transformation matrix constructed as
H = Rz * Ry * Rx. So rotations are performed in xyz order.
Now, given rotation angles around x, y, and z axes, is there a way to find rotation angles to perform inverse operation, such that
v = Rz * Ry * Rx * v0
v0 = Rz' * Ry' * Rx' * v
Just for completion sake. In the end I extracted the Euler angles from transformation matrix as described in:
Computing Euler angles from a rotation matrix - Gregory G. Slabaugh
If your matrices are purely rotation (i.e. no translation), the inverse is simply the transpose:
R-1 = RT
If your transformation includes translation like so:
A =
| R T |
| 0 1 |
Then use the transpose of the rotation matrix as above and for the translation portion, use:
T-1 = -RTT
Then
A-1 =
| R-1 T-1 |
| 0 1 |
Also note that you will have to do the inverse rotations in the inverse order:
v0 = Rx-1 * Ry-1 * Rz-1 * v

Applying different transformations to a polygon given a describing transformation matrix

I have a 2D polygon and a 2D transformation matrix M that I use to transform the vertices of the polygon. The matrix may describe...
rotation around z axis,
scaling along x and y,
sheering along x and y axis,
translation along x and y axis.
Since we are in 2D the transformation matrix is of type 3x3. Here as an example a translation matrix by vector t and a rotation by angle a:
M_t = |1 0 t2| M_r = | cos(a) sin(a) 0|
|0 1 t1| |-sin(a) cos(a) 0|
|0 0 1 | | 0 0 1|
In my custom framework I don't have any access to the matrix values but can apply other matrixes in a row:
vertice = ( M_r * M_t ) * vertice
The above formula rotates the vertice around (0, 0) by angle a and then translates it by vector t. I know that matrix multiplications aren't commutative. So the order of multiplications is important.
My problem is now that I want to get a transformation matrix N that reflects a rotation R around the new center of the polygon, followed by a translation T, after applying an unknown transformation matrix M. Or in other words: I want to rotate and translate the polygon relative to its position and rotation given by M.
I can imagine this way of doing it, incorporating an unknown rotation and translation as part of M:
N = R * M * T
My questions are:
Is that mathematically correct?
What about an unknown sheering and scaling as part of M?
Is there a better way of doing this?

circle-circle collision

I am going to develop a 2-d ball game where two balls (circles) collide. Now I have the problem with determining the colliding point (in fact, determining whether they are colliding in x-axis/y-axis). I have an idea that when the difference between the y coordinate of 2 balls is greater than the x coordinate difference then they collide in their y axis, otherwise, they collide in their x axis. Is my idea correct? I implemented this thing in my games. Normally it works well, but sometimes, it fails. Can anyone tell me whether my idea is right? If not, then why, and is any better way?
By collision in the x axis, I mean the circle's 1st, 4th, 5th, or 8th octant, y axis means the circle's 2nd, 3rd, 6th, or 7th octant.
Thanks in advance!
Collision between circles is easy. Imagine there are two circles:
C1 with center (x1,y1) and radius r1;
C2 with center (x2,y2) and radius r2.
Imagine there is a line running between those two center points. The distance from the center points to the edge of either circle is, by definition, equal to their respective radii. So:
if the edges of the circles touch, the distance between the centers is r1+r2;
any greater distance and the circles don't touch or collide; and
any less and then do collide.
So you can detect collision if:
(x2-x1)^2 + (y2-y1)^2 <= (r1+r2)^2
meaning the distance between the center points is less than the sum of the radii.
The same principle can be applied to detecting collisions between spheres in three dimensions.
Edit: if you want to calculate the point of collision, some basic trigonometry can do that. You have a triangle:
(x1,y1)
|\
| \
| \ sqrt((x2-x1)^2 + (y2-y1)^2) = r1+r2
|y2-y1| | \
| \
| X \
(x1,y2) +------+ (x2,y2)
|x2-x1|
The expressions |x2-x1| and |y2-y1| are absolute values. So for the angle X:
|y2 - y1|
sin X = -------
r1 + r2
|x2 - x1|
cos X = -------
r1 + r2
|y2 - y1|
tan X = -------
|x2 - x1|
Once you have the angle you can calculate the point of intersection by applying them to a new triangle:
+
|\
| \
b | \ r2
| \
| X \
+-----+
a
where:
a
cos X = --
r2
so
a = r2 cos X
From the previous formulae:
|x2 - x1|
a = r2 -------
r1 + r2
Once you have a and b you can calculate the collision point in terms of (x2,y2) offset by (a,b) as appropriate. You don't even need to calculate any sines, cosines or inverse sines or cosines for this. Or any square roots for that matter. So it's fast.
But if you don't need an exact angle or point of collision and just want the octant you can optimize this further by understanding something about tangents, which is:
0 <= tan X <= 1 for 0 <= X <= 45 degrees;
tan X >= 1 for 45 <= X <= 90
0 >= tan X >= -1 for 0 >= X => -45;
tan X <= -1 for -45 >= X => -90; and
tan X = tan (X+180) = tan (X-180).
Those four degree ranges correspond to four octants of the cirlce. The other four are offset by 180 degrees. As demonstrated above, the tangent can be calculated simply as:
|y2 - y1|
tan X = -------
|x2 - x1|
Lose the absolute values and this ratio will tell you which of the four octants the collision is in (by the above tangent ranges). To work out the exact octant just compare x1 and x2 to determine which is leftmost.
The octant of the collision on the other single is offset (octant 1 on C1 means octant 5 on C2, 2 and 6, 3 and 7, 4 and 8, etc).
As cletus says, you want to use the sum of the radii of the two balls. You want to compute the total distance between the centers of the balls, as follows:
Ball 1: center: p1=(x1,y1) radius: r1
Ball 2: center: p2=(x2,y2) radius: r2
collision distance: R= r1 + r2
actual distance: r12= sqrt( (x2-x1)^2 + (y2-y1)^2 )
A collision will happen whenever (r12 < R). As Artelius says, they shouldn't actually collide on the x/y axes, they collide at a particular angle. Except, you don't actually want that angle; you want the collision vector. This is the difference between the centers of the two circles when they collide:
collision vector: d12= (x2-x1,y2-y1) = (dx,dy)
actual distance: r12= sqrt( dx*dx + dy*dy )
Note that you have already computed dx and dy above when figuring the actual distance, so you might as well keep track of them for purposes like this. You can use this collision vector for determining the new velocity of the balls -- you're going to end up scaling the collision vector by some factors, and adding that to the old velocities... but, to get back to the actual collision point:
collision point: pcollision= ( (x1*r2+x2*r1)/(r1+r2), (y1*r2+y2*r1)/(r1+r2) )
To figure out how to find the new velocity of the balls (and in general to make more sense out of the whole situation), you should probably find a high school physics book, or the equivalent. Unfortunately, I don't know of a good web tutorial -- suggestions, anyone?
Oh, and if still want to stick with the x/y axis thing, I think you've got it right with:
if( abs(dx) > abs(dy) ) then { x-axis } else { y-axis }
As for why it might fail, it's hard to tell without more information, but you might have a problem with your balls moving too fast, and passing right by each other in a single timestep. There are ways to fix this problem, but the simplest way is to make sure they don't move too fast...
This site explains the physics, derives the algorithm, and provides code for collisions of 2D balls.
Calculate the octant after this function calculates the following: position of collision point relative to centre of mass of body a; position of collision point relative to centre of mass of body a
/**
This function calulates the velocities after a 2D collision vaf, vbf, waf and wbf from information about the colliding bodies
#param double e coefficient of restitution which depends on the nature of the two colliding materials
#param double ma total mass of body a
#param double mb total mass of body b
#param double Ia inertia for body a.
#param double Ib inertia for body b.
#param vector ra position of collision point relative to centre of mass of body a in absolute coordinates (if this is
known in local body coordinates it must be converted before this is called).
#param vector rb position of collision point relative to centre of mass of body b in absolute coordinates (if this is
known in local body coordinates it must be converted before this is called).
#param vector n normal to collision point, the line along which the impulse acts.
#param vector vai initial velocity of centre of mass on object a
#param vector vbi initial velocity of centre of mass on object b
#param vector wai initial angular velocity of object a
#param vector wbi initial angular velocity of object b
#param vector vaf final velocity of centre of mass on object a
#param vector vbf final velocity of centre of mass on object a
#param vector waf final angular velocity of object a
#param vector wbf final angular velocity of object b
*/
CollisionResponce(double e,double ma,double mb,matrix Ia,matrix Ib,vector ra,vector rb,vector n,
vector vai, vector vbi, vector wai, vector wbi, vector vaf, vector vbf, vector waf, vector wbf) {
double k=1/(ma*ma)+ 2/(ma*mb) +1/(mb*mb) - ra.x*ra.x/(ma*Ia) - rb.x*rb.x/(ma*Ib) - ra.y*ra.y/(ma*Ia)
- ra.y*ra.y/(mb*Ia) - ra.x*ra.x/(mb*Ia) - rb.x*rb.x/(mb*Ib) - rb.y*rb.y/(ma*Ib)
- rb.y*rb.y/(mb*Ib) + ra.y*ra.y*rb.x*rb.x/(Ia*Ib) + ra.x*ra.x*rb.y*rb.y/(Ia*Ib) - 2*ra.x*ra.y*rb.x*rb.y/(Ia*Ib);
double Jx = (e+1)/k * (Vai.x - Vbi.x)( 1/ma - ra.x*ra.x/Ia + 1/mb - rb.x*rb.x/Ib)
- (e+1)/k * (Vai.y - Vbi.y) (ra.x*ra.y / Ia + rb.x*rb.y / Ib);
double Jy = - (e+1)/k * (Vai.x - Vbi.x) (ra.x*ra.y / Ia + rb.x*rb.y / Ib)
+ (e+1)/k * (Vai.y - Vbi.y) ( 1/ma - ra.y*ra.y/Ia + 1/mb - rb.y*rb.y/Ib);
Vaf.x = Vai.x - Jx/Ma;
Vaf.y = Vai.y - Jy/Ma;
Vbf.x = Vbi.x - Jx/Mb;
Vbf.y = Vbi.y - Jy/Mb;
waf.x = wai.x - (Jx*ra.y - Jy*ra.x) /Ia;
waf.y = wai.y - (Jx*ra.y - Jy*ra.x) /Ia;
wbf.x = wbi.x - (Jx*rb.y - Jy*rb.x) /Ib;
wbf.y = wbi.y - (Jx*rb.y - Jy*rb.x) /Ib;
}
I agree with provided answers, they are very good.
I just want to point you a small pitfall: if the speed of balls is high, you can just miss the collision, because circles never intersect for given steps.
The solution is to solve the equation on the movement and to find the correct moment of the collision.
Anyway, if you would implement your solution (comparisons on X and Y axes) you'd get the good old ping pong! http://en.wikipedia.org/wiki/Pong
:)
The point at which they collide is on the line between the midpoints of the two circles, and its distance from either midpoint is the radius of that respective circle.

how do I find the angle of rotation of the major axis of an ellipse given its bounding rectangle?

I have an ellipse centered at (0,0) and the bounding rectangle is x = [-5,5], y = [-6,6]. The ellipse intersects the rectangle at (-5,3),(-2.5,6),(2.5,-6),and (5,-3)
I know nothing else about the ellipse, but the only thing I need to know is what angle the major axis is rotated at.
seems like the answer must be really simple but I'm just not seeing it... thanks for the help!
If (0, 0) is the center, than equation of Your ellipse is:
F(x, y) = Ax^2 +By^2 + Cxy + D = 0
For any given ellipse, not all of the coefficients A, B, C and D are uniquely determined. One can multiply the equation by any nonzero constant and obtain new equation of the same ellipse.
4 points You have, give You 4 equations, but since those points are two pairs of symmetrical points, those equations won't be independent. You will get 2 independent equations. You can get 2 more equations by using the fact, that the ellipse is tangent to the rectangle in hose points (that's how I understand it).
So if F(x, y) = Ax^2 +By^2 + Cxy + D Your conditions are:
dF/dx = 0 in points (-2.5,6) and (2.5,-6)
dF/dy = 0 in points (-5,3) and (5,-3)
Here are four linear equations that You get
F(5, -3) = 5^2 * A + (-3)^2 * B + (-15) * C + D = 0
F(2.5, -6) = (2.5)^2 * A + (-6)^2 * B + (-15) * C + D = 0
dF(2.5, -6)/dx = 2*(2.5) * A + (-6) * C = 0
dF(5, -3)/dy = 2*(-3) * B + 5 * C = 0
After a bit of cleaning:
25A + 9B - 15C + D = 0 //1
6.25A + 36B - 15C + D = 0 //2
5A - 6C = 0 //3
- 6B + 5C = 0 //4
Still not all 4 equations are independent and that's a good thing. The set is homogeneous and if they were independent You would get unique but useless solution A = 0, B = 0, C = 0, D = 0.
As I said before coefficients are not uniquely determined, so You can set one of the coefficient as You like and get rid of one equation. For example
25A + 9B - 15C = 1 //1
5A - 6C = 0 //3
- 6B + 5C = 0 //4
From that You get: A = 4/75, B = 1/27, C = 2/45 (D is of course -1)
Now, to get to the angle, apply transformation of the coordinates:
x = ξcos(φ) - ηsin(φ)
y = ξsin(φ) + ηcos(φ)
(I just couldn't resist to use those letters :) )
to the equation F(x, y) = 0
F(x(ξ, η), y(ξ, η)) = G(ξ, η) =
A (ξ^2cos^2(φ) + η^2sin^2(φ) - 2ξηcos(φ)sin(φ))
+ B (ξ^2sin^2(φ) + η^2cos^2(φ) + 2ξηcos(φ)sin(φ))
+ C (ξ^2cos(φ)sin(φ) - η^2cos(φ)sin(φ) + ξη(cos^2(φ) - sin^2(φ))) + D
Using those two identities:
2cos(φ)sin(φ) = sin(2φ)
cos^2(φ) - sin^2(φ) = cos(2φ)
You will get coefficient C' that stands by the product ξη in G(ξ, η) to be:
C' = (B-A)sin(2φ) + Ccos(2φ)
Now your question is: For what angle φ coefficient C' disappears (equals zero)
There is more than one angle φ as there is more than one axis. In case of the main axis B' > A'
The gradient of the ellipse is identical to the gradient of the intersects with the bounding rectangle along one side of the ellipse. In your case, that's the line from (-2.5,6) to (5,-3), the top side of your ellipse. That line has a vertical drop of 9 and a horizontal run of 7.5.
So we end up with the following right-angled triangle.
(-2.5,6)
*-----
|\x
| \
| \
9 | \
| \
| x\
+------* (5,-3)
7.5
The angle we're looking for is x which is the same in both locations.
We can calculate it as:
-1
tan (9/7.5)
which gives us an angle of -50.19 degrees
Set the angle of the ellipse = 0
Calculate the 4 points of intersection
Work out the error between the calculated intersection points and the desired ones (i.e. sum the 4 distances).
If error is too large use the secant method or Newton-Rhapson to work out a new angle for the ellipse and go to 2.
I used a similar approach to work out another ellipse problem:
http://successfulsoftware.net/2008/07/18/a-mathematical-digression/
http://successfulsoftware.net/2008/08/25/a-mathematical-digression-revisited/
See also:
http://en.wikipedia.org/wiki/Secant_method
http://en.wikipedia.org/wiki/Newton_Rhapson

Resources