Now the rotation works, i’ve tried rotating an object by 90 degrees, it rotates it but also makes an unexpected translation on the oX axis to the left. I’ve added a normalisation mehod for w,x,y,z components of the quaterion and corrected any code mistakes i found.
This is the method i use:
public class Point3DRotationQuaternions
{
public static ArrayList<Float> rotation3D(ArrayList<Float> points, double angle, int x, int y, int z)
{
ArrayList<Float> newpoints = points;
for (int i=0;i<points.size();i+=3)
{
float x_old = points.get(i).floatValue();
float y_old = points.get(i+1).floatValue();
float z_old = points.get(i+2).floatValue();
double[] initial = {1,0,0,0};
double[] total = new double[4];
double[] local = new double[4];
//components for local quaternion
//w
local[0] = Math.cos(0.5 * angle);
//x
local[1] = x * Math.sin(0.5 * angle);
//y
local[2] = y * Math.sin(0.5 * angle);
//z
local[3] = z * Math.sin(0.5 * angle);
//local = magnitude(local);
//components for final quaternion Q1*Q2
//w = w1w2 - x1x2 - y1y2 - z1z2
total[0] = local[0] * initial[0] - local[1] * initial[1] - local[2] * initial[2] - local[3] * initial[3];
//x = w1x2 + x1w2 + y1z2 - z1y2
total[1] = local[0] * initial[1] + local[1] * initial[0] + local[2] * initial[3] - local[3] * initial[2];
//y = w1y2 - x1z2 + y1w2 + z1x2
total[2] = local[0] * initial[2] - local[1] * initial[3] + local[2] * initial[0] + local[3] * initial[1];
//z = w1z2 + x1y2 - y1x2 + z1w2
total[3] = local[0] * initial[3] + local[1] * initial[2] - local[2] * initial[1] + local[3] * initial[0];
//new x,y,z of the 3d point using rotation matrix made from the final quaternion
float x_new = (float)((1 - 2 * total[2] * total[2] - 2 * total[3] * total[3]) * x_old
+ (2 * total[1] * total[2] - 2 * total[0] * total[3]) * y_old
+ (2 * total[1] * total[3] + 2 * total[0] * total[2]) * z_old);
float y_new = (float) ((2 * total[1] * total[2] + 2 * total[0] * total[3]) * x_old
+ (1 - 2 * total[1] * total[1] - 2 * total[3] * total[3]) * y_old
+ (2 * total[2] * total[3] + 2 * total[0] * total[1]) * z_old);
float z_new = (float) ((2 * total[1] * total[3] - 2 * total[0] * total[2]) * x_old
+ (2 * total[2] * total[3] - 2 * total[0] * total[1]) * y_old
+ (1 - 2 * total[1] * total[1] - 2 * total[2] * total[2]) * z_old);
newpoints.set(i, x_new);
newpoints.set(i+1, y_new);
newpoints.set(i+2, z_new);
}
return newpoints;
}
}
public static void main(String args[])
{
ArrayList<Float> list = new ArrayList<>();
list.add(new Float(0));
list.add(new Float(0));
list.add(new Float(-11));
ArrayList<Float> list1 = Point3DRotationQuaternions.rotation3D(list, Math.toRadians(90), 0, 1, 0);
for (int i=0;i<list1.size();i++)
System.out.print(list1.get(i)+" ");
}
Now the call looks like this rotation3D(points, Math.toRadians(90), 0, 1, 0).
To write these methods i used this article .
These are the vertexes for the figure i try to rotate:
//bottom base
old vertexes:
0.0 0.0 -9.0
0.0 0.0 -11.0
20.0 0.0 -11.0
20.0 0.0 -9.0
new vertexes:
-9.0 0.0 -1.9984014E-15
-11.0 0.0 -2.4424907E-15
-11.0 0.0 -20.0
-9.0 0.0 -20.0
//top base
old vertexes:
0.0 20.0 -11.0
0.0 20.0 -9.0
20.0 20.0 -9.0
20.0 20.0 -11.0
new vertexes:
-11.0 20.0 -2.4424907E-15
-9.0 20.0 -1.9984014E-15
-9.0 20.0 -20.0
-11.0 20.0 -20.0
//face
old vertexes:
0.0 20.0 -9.0
0.0 0.0 -9.0
20.0 0.0 -9.0
20.0 20.0 -9.0
new vertexes:
-9.0 20.0 -1.9984014E-15
-9.0 0.0 -1.9984014E-15
-9.0 0.0 -20.0
-9.0 20.0 -20.0
//back
old vertexes:
20.0 20.0 -9.0
20.0 0.0 -9.0
20.0 0.0 -11.0
20.0 20.0 -11.0
new vertexes:
-9.0 20.0 -20.0
-9.0 0.0 -20.0
-11.0 0.0 -20.0
-11.0 20.0 -20.0
//right side
old vertexes:
0.0 0.0 -11.0
0.0 20.0 -11.0
20.0 20.0 -11.0
20.0 0.0 -11.0
new vertexes:
-11.0 0.0 -2.4424907E-15
-11.0 20.0 -2.4424907E-15
-11.0 20.0 -20.0
-11.0 0.0 -20.0
//left base
old vertexes:
0.0 20.0 -9.0
0.0 20.0 -11.0
0.0 0.0 -11.0
0.0 0.0 -9.0
new vertexes:
-9.0 20.0 -1.9984014E-15
-11.0 20.0 -2.4424907E-15
-11.0 0.0 -2.4424907E-15
-9.0 0.0 -1.9984014E-15
You’re doing
total[0] = ...four times.