3D rotation using 2 3D points.
Posted: Tue Sep 08, 2009 9:41 am
Is there a way in Irrlicht to find the rotation using 2 3D points.
I am using wiimote for my project and I calculate the 3D position of 2 IR led dots.
I use these 2 dots to find the rotations in 3D. Is there an easy way in Irrlicht to do this? (quaternions or sth).
Also I did the rotations in 2D using Johny Lees Affine transformation solver. I converted the float 4x4 to matrix4 and stored the values.
Sometimes the Z-rotation kicks to 258.xx . I really dont understand why this is happening.
Please see the code below.
float computeAngle(float dx, float dy)
{
float angle = 0;
if (dx == 0)
{
angle = (float)PI / 2;
}
else
{
if (dx > 0)
return (float)atan(dy / dx);
else
angle = (float)(atan(dy / dx) + PI);
}
return angle;
}
float distance2(float x1, float x2, float y1, float y2)
{
float dx = x1- x2;
float dy = y1-y2;
return (float)sqrt(dx*dx+dy*dy);
}
//I want to know if I am doing this properly here.
matrix4 solve2Dto4x4(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
{
float scale = distance2(x3,x4,y3,y4) / distance2(x1,x2,y1,y2);
float theta = computeAngle((x4 - x3), (y4 - y3)) - computeAngle((x2 - x1), (y2 - y1));
float tx1 = (x2 + x1) / 2;
float ty1 = (y2 + y1) / 2;
float tx2 = (x4 + x3) / 2;
float ty2 = (y4 + y3) / 2;
matrix4 result;
result.makeIdentity();
result(0, 0) = 1.0f;
result(1, 1) = 1.0f;
result(2, 2) = 1.0f;
result(3, 3) = 1.0f;
result(0,0) = (float)(scale * cos(theta));
result(1,0) = -(float)(scale * sin(theta));
result(3,0) = -tx1 * result(0,0) - ty1 * result(1,0) + tx2;
result(0,1) = (float)(scale * sin(theta));
result(1,1) = (float)(scale * cos(theta));
result(3,1) = -tx1 * result(0,1) - ty1 * result(1,1) + ty2;
return result;
}
==================================
The main code that uses this slove2Dto4x4()
matrix4
WiiInteraction::computeTransformation()
{
matrix4 transform;
if (normalizedPosition1.X < normalizedPosition2.X)
leftCursor = 1;
else
leftCursor = 2;
if(leftCursor == 1)
{
transform = solve2Dto4x4(old_normalizedPosition1.X, old_normalizedPosition1.Y, old_normalizedPosition2.X, old_normalizedPosition2.Y,
normalizedPosition1.X, normalizedPosition1.Y, normalizedPosition2.X, normalizedPosition2.Y);
}
else
{
transform = solve2Dto4x4(old_normalizedPosition2.X, old_normalizedPosition2.Y, old_normalizedPosition1.X, old_normalizedPosition1.Y,
normalizedPosition2.X, normalizedPosition2.Y, normalizedPosition1.X, normalizedPosition1.Y);
}
return transform;
}
if (wii.remoteL.IR.Dot[0].bVisible && wii.remoteL.IR.Dot[1].bVisible)
{
cout << "********Computing Transformation**************" << endl;
matrix4 m;
m.setRotationDegrees(handle1.iNode->getRotation());
//This returns the transformation matrix
matrix4 transform = wii.computeTransformation();
matrix4 n;
n.setRotationDegrees(transform.getRotationDegrees());
m *= n;
handle1.setRotation(m.getRotationDegrees());
if(isRingAttached == true)
{
currentRing.setRotation(m.getRotationDegrees());
}
}
I am using wiimote for my project and I calculate the 3D position of 2 IR led dots.
I use these 2 dots to find the rotations in 3D. Is there an easy way in Irrlicht to do this? (quaternions or sth).
Also I did the rotations in 2D using Johny Lees Affine transformation solver. I converted the float 4x4 to matrix4 and stored the values.
Sometimes the Z-rotation kicks to 258.xx . I really dont understand why this is happening.
Please see the code below.
float computeAngle(float dx, float dy)
{
float angle = 0;
if (dx == 0)
{
angle = (float)PI / 2;
}
else
{
if (dx > 0)
return (float)atan(dy / dx);
else
angle = (float)(atan(dy / dx) + PI);
}
return angle;
}
float distance2(float x1, float x2, float y1, float y2)
{
float dx = x1- x2;
float dy = y1-y2;
return (float)sqrt(dx*dx+dy*dy);
}
//I want to know if I am doing this properly here.
matrix4 solve2Dto4x4(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
{
float scale = distance2(x3,x4,y3,y4) / distance2(x1,x2,y1,y2);
float theta = computeAngle((x4 - x3), (y4 - y3)) - computeAngle((x2 - x1), (y2 - y1));
float tx1 = (x2 + x1) / 2;
float ty1 = (y2 + y1) / 2;
float tx2 = (x4 + x3) / 2;
float ty2 = (y4 + y3) / 2;
matrix4 result;
result.makeIdentity();
result(0, 0) = 1.0f;
result(1, 1) = 1.0f;
result(2, 2) = 1.0f;
result(3, 3) = 1.0f;
result(0,0) = (float)(scale * cos(theta));
result(1,0) = -(float)(scale * sin(theta));
result(3,0) = -tx1 * result(0,0) - ty1 * result(1,0) + tx2;
result(0,1) = (float)(scale * sin(theta));
result(1,1) = (float)(scale * cos(theta));
result(3,1) = -tx1 * result(0,1) - ty1 * result(1,1) + ty2;
return result;
}
==================================
The main code that uses this slove2Dto4x4()
matrix4
WiiInteraction::computeTransformation()
{
matrix4 transform;
if (normalizedPosition1.X < normalizedPosition2.X)
leftCursor = 1;
else
leftCursor = 2;
if(leftCursor == 1)
{
transform = solve2Dto4x4(old_normalizedPosition1.X, old_normalizedPosition1.Y, old_normalizedPosition2.X, old_normalizedPosition2.Y,
normalizedPosition1.X, normalizedPosition1.Y, normalizedPosition2.X, normalizedPosition2.Y);
}
else
{
transform = solve2Dto4x4(old_normalizedPosition2.X, old_normalizedPosition2.Y, old_normalizedPosition1.X, old_normalizedPosition1.Y,
normalizedPosition2.X, normalizedPosition2.Y, normalizedPosition1.X, normalizedPosition1.Y);
}
return transform;
}
if (wii.remoteL.IR.Dot[0].bVisible && wii.remoteL.IR.Dot[1].bVisible)
{
cout << "********Computing Transformation**************" << endl;
matrix4 m;
m.setRotationDegrees(handle1.iNode->getRotation());
//This returns the transformation matrix
matrix4 transform = wii.computeTransformation();
matrix4 n;
n.setRotationDegrees(transform.getRotationDegrees());
m *= n;
handle1.setRotation(m.getRotationDegrees());
if(isRingAttached == true)
{
currentRing.setRotation(m.getRotationDegrees());
}
}