Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在三维空间中围绕轴心点旋转点_Java_Vector_3d_Rotation_Render - Fatal编程技术网

Java 在三维空间中围绕轴心点旋转点

Java 在三维空间中围绕轴心点旋转点,java,vector,3d,rotation,render,Java,Vector,3d,Rotation,Render,我已经制作了一个Java程序,可以在3d空间中显示投影到2d视图上的线条,到目前为止,它运行得非常好。我试图使“世界”基本上围绕相机的位置绕任意轴旋转,但现在我遇到了一些问题 public void rotate(){ float ax = main.angleX; //main = camera float ay = main.angleY; float az = main.angleZ; for(Line3d line : lines){ //all line

我已经制作了一个Java程序,可以在3d空间中显示投影到2d视图上的线条,到目前为止,它运行得非常好。我试图使“世界”基本上围绕相机的位置绕任意轴旋转,但现在我遇到了一些问题

public void rotate(){
    float ax = main.angleX; //main = camera
    float ay = main.angleY;
    float az = main.angleZ;
    for(Line3d line : lines){ //all lines in the world
        Vector3d start = Vector3d.Vector3dPMinus(line.start, main.getPoint()); //vetor value of starting point of line - camera's position
        Vector3d end = Vector3d.Vector3dPMinus(line.end, main.getPoint());
        start.rotate(ax, ay, az);
        end.rotate(ax, ay, az); //rotate each vector
        line.start = Point3d.pointFromVector3d(start).add(main.getPoint());
        line.end = Point3d.pointFromVector3d(end).add(main.getPoint()); //vectors back into points
    }
}
旋转功能:

public Vector3d rotate(float ax, float ay, float az){
    Math.toRadians(ax *= 90);
    Math.toRadians(ay *= 90);
    Math.toRadians(az *= 90);
    y = (float) (y * Math.cos(ax) - z * Math.sin(ax));
    z = (float) (y * Math.sin(ax) + z * Math.cos(ax));
    x = (float) (x * Math.cos(ay) + z * Math.sin(ay));
    z = (float) (z * Math.cos(ay) - x * Math.sin(ay));
    x = (float) (x * Math.cos(az) - y * Math.sin(az));
    y = (float) (x * Math.sin(az) + y * Math.cos(az));
    return this;
}
我已经设定它每秒绕x轴旋转3次,它在开始旋转之前显示出我想要的东西,但是一旦它开始旋转,就会出现一些无法识别的混乱,通常只有一条水平线


我用的旋转方法不对吗?有更好的方法吗?

三维矢量围绕3轴旋转并不像人们想象的那么简单。你可能正试图做的事情就是用所谓的。您应该熟悉如何使用三维空间。我检查了你的旋转,应该很好。但是你应该记住以下几点:当你围绕一个角度旋转时。以下旋转受上一个旋转的影响。您也在旋转旋转轴。
为了避免这种行为,一个丑陋的可能性是绕自由轴旋转。当你先绕x轴旋转时。将y轴反向旋转,然后围绕y'旋转点。当您围绕z旋转时,您需要使用反转的x和y旋转旋转z轴,然后围绕此z'旋转。当你这样做的时候,你总是可以围绕你的世界坐标系旋转。你真的应该使用一些数学库来实现这一点。它让你的生活更轻松。当你想自己编写代码的时候。您需要一个适当的矩阵类,它包含矩阵和向量的乘法以及一些求逆方法。

您的方法似乎采用了合理的一般形式。看起来您正在相对于当前摄影机位置旋转直线端点,这是正确的,并且您正在执行的三个特定旋转也可能是正确的(但请参见下文)

但是,这三个
Math.toRadians()
调用不能做任何有用的事情,因为您忽略了它们的结果。此外,表达式
ax*=90
及其配偶看起来非常可疑:
ax
ay
az
是否真的表示为四分之一圆的分数?这似乎有点可疑,如果是这样的话,那么您将需要乘以
Math.PI/2
并跳过
toRadians()
。另一方面,如果它们以度表示,则以下版本的
rotate()
对于
ax
ay
az
,以及一些可能的
Vector3D
实现的合理定义是正确的:

public Vector3d rotate(double ax, double ay, double az){
    ax = Math.toRadians(ax);
    ay = Math.toRadians(ay);
    az = Math.toRadians(az);
    y = (float) ( y * Math.cos(ax) - z * Math.sin(ax));
    z = (float) ( y * Math.sin(ax) + z * Math.cos(ax));
    x = (float) ( x * Math.cos(ay) + z * Math.sin(ay));
    z = (float) (-x * Math.sin(ay) + z * Math.cos(ay));
    x = (float) ( x * Math.cos(az) - y * Math.sin(az));
    y = (float) ( x * Math.sin(az) + y * Math.cos(az));
    return this;
}
不过,总的来说,我也有点怀疑这方面的
ax
ay
az
的正确性。特别是,请注意,不能单独累积单独的x、y和z旋转增量,因为生成的聚合旋转在很大程度上取决于增量旋转的执行顺序。此外,即使
ax
ay
az
正确地描述了相机的方向,也不太可能对世界应用相同的旋转是您真正想要做的


尽管前面提到了所有这些,但是我看不出有任何原因可以解释为什么您的代码会像您描述的那样扭曲模型。我认为它不会应用您想要的旋转(即使使用我建议的修复),但失真的原因可能在其他地方。

您说要绕任何轴旋转世界,但您的代码似乎试图绕特定于相机的轴执行旋转。也许是围绕相机的视角方向?如果是这样的话,为什么不旋转相机呢?我意识到ax*=90的问题,ax,ay和az实际上是四分之一圆的分数。我把Math.toRadians改为手动操作,但有一个小问题。它或多或少适用于沿z轴旋转,尽管越来越小/更远(idk),但对于x轴,它不能正确显示,对于y轴,它只是完全消失。