3D - 使用四元数围绕矢量旋转点
3D - Rotating point around vector using quaternions
所以我有一个点 (x,y,z) 和一个向量 (x1,y1,z1),我想在 3D space 中围绕向量旋转点。根据我的阅读,我应该能够使用这样的四元数来做到这一点:
(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))
我是这样实现的:
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;
问题是,当我使用上面的代码制作动画(围绕矢量旋转球体)时,我得到的不是圆形而是螺旋形,球体很快就结束了与矢量相同的位置:
现在通过单击按钮自行完成移动,如下所示:
btn2.setOnAction(新事件处理程序() {
@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);
}
});
我认为问题出在新坐标的计算上,过了一会儿它们最终在矢量上的某个地方,但是在重新检查数学的次数超过我数不清的时候,我正式迷路了。谁能告诉我我遗漏了什么或哪里出错了?
哦,算了,毕竟是计算错误(虽然我发誓我检查了一千多次..)
而不是:
double y_f = k_a2*c_m+a_m*k_c2+k_b2*d_m-k_d2*b_m;
它应该是:
double y_f = k_a2*c_m+a_m*k_c2-k_b2*d_m+k_d2*b_m;
所以我有一个点 (x,y,z) 和一个向量 (x1,y1,z1),我想在 3D space 中围绕向量旋转点。根据我的阅读,我应该能够使用这样的四元数来做到这一点:
(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))
我是这样实现的:
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;
问题是,当我使用上面的代码制作动画(围绕矢量旋转球体)时,我得到的不是圆形而是螺旋形,球体很快就结束了与矢量相同的位置:
现在通过单击按钮自行完成移动,如下所示:
btn2.setOnAction(新事件处理程序() {
@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);
}
});
我认为问题出在新坐标的计算上,过了一会儿它们最终在矢量上的某个地方,但是在重新检查数学的次数超过我数不清的时候,我正式迷路了。谁能告诉我我遗漏了什么或哪里出错了?
哦,算了,毕竟是计算错误(虽然我发誓我检查了一千多次..) 而不是:
double y_f = k_a2*c_m+a_m*k_c2+k_b2*d_m-k_d2*b_m;
它应该是:
double y_f = k_a2*c_m+a_m*k_c2-k_b2*d_m+k_d2*b_m;