Search code examples
javaanimationgraphics3dquaternions

3D - Rotating point around vector using quaternions


So i have a point (x,y,z) and a vector (x1,y1,z1) and i want to rotate the point around the vector in a 3D space. From what i read I should be able to do so using quaternions like this:

(0,new_x,new_y,new_z) = K^-1 * I * K

where K = (cos(fi/2), sin(fi/2)*(x1,y1,z1)) (where (x1,y1,z1) is a normalized vector)

I = (0,(x,y,z)) K^-1 = (cos(fi/2), -sin(fi/2)*(x1,y1,z1))

I implemented it like this:

    Point3D n = new Point3D(x1,y1,z1);
    n=n.normalize();
    double a=Math.cos(Math.toRadians(45)); //fi is 90
    double b= Math.sin(Math.toRadians(45));
    double k_a = a;
    double k_b = b*n.getX();
    double k_c=b*n.getY();
    double k_d = b*n.getZ(); //K points 
    double k_a2=k_a; //K^-1 points
    double k_b2=-k_b;
    double k_c2 = -k_c;
    double k_d2= -k_d;
    //I*K
    double a_m = -((x*k_b)+(y*k_c)+(z*k_d));
    double b_m= k_a*x+y*k_d+0*k_b-z*k_c;        
    double c_m = k_a*y+0*k_c+k_b*z-x*k_d;
    double d_m = k_a*z+0*k_d+x*k_c-y*k_b;
    //K^-1 * what we got above aka the final coordinates 
    double a_f = k_a2*a_m -b_m*k_b2-c_m*k_c2-d_m*k_d2; //should and is 0
    double x_f= k_a2*b_m+a_m*k_b2+k_c2*d_m-k_d2*c_m;
    double y_f = k_a2*c_m+a_m*k_c2+k_b2*d_m-k_d2*b_m;
    double z_f = k_a2*d_m+a_m*k_d2+k_b2*c_m-k_c2*b_m;

The problem is, that when i use the above code for a animation (rotating a sphere around a vector), instead of a circle i get a spiral, where the sphere quickly ends up in the same place as the vector: enter image description here

The move it self is done with a button click for now like this:

btn2.setOnAction(new EventHandler() {

        @Override
        public void handle(ActionEvent e) {
            Point3D n = calc(x,y,z,x1,y1,z1); //a call to the method calculating K^-1*I*K shown above           
             Sphere sphere= new Sphere(10); //I know, drawing a new one everytime is a waste, but i wanted to be sure the translate wasnt at fault since im new at javaFX
             sphere.setMaterial(new PhongMaterial(Color.CORAL));
             sphere.setTranslateX(n.getX());
             sphere.setTranslateY(n.getY());
             sphere.setTranslateZ(n.getZ());
             x=n.getX();
             y=n.getY();
             z=n.getZ();
             content.group.getChildren().remove(0);
             content.group.getChildren().add(0, sphere);
        }
    });

I think the problem is in the calculation of the new coordinates, after a bit they end up somewhere on the vector, but after rechecking the math more times than i can count, im officially lost. Can anyone tell me what i am missing or where i went wrong?


Solution

  • Oh nevermind, it was an calculation mistake afterall (though i swear i checked it over a thousand times..) instead of:

    double y_f = k_a2*c_m+a_m*k_c2+k_b2*d_m-k_d2*b_m;
    

    its supposed to be:

     double y_f = k_a2*c_m+a_m*k_c2-k_b2*d_m+k_d2*b_m;