我制作了一个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次,并且它在开始旋转之前显示我想要它的确切内容,但是一旦它开始旋转,就会出现一些无法识别的混乱通常只有一条水平线。
我用来旋转的方法不对吗?有没有更好的方法呢?
答案 0 :(得分:0)
围绕3轴旋转三维矢量并不像人们想象的那样微不足道。您可能要做的事情是使用所谓的Euler Angles旋转。您应该熟悉matrices以使用3d空间。我检查了你的轮换,他们应该工作正常。但是你应该记住以下几点:当你绕一个角度旋转时。以下旋转受前一轮旋转的影响。您也在旋转旋转轴。 为了避免这种行为,一个丑陋的可能性是绕自由轴旋转。当你首先围绕x轴旋转时。您可以反向旋转y轴,然后围绕此y'旋转您的点。当您围绕z旋转时,您需要使用反转的x和y旋转旋转z轴,然后围绕此z'旋转。当您这样做时,您可以随时围绕您的世界坐标系旋转。你应该使用一些数学库来实现这一目标。它让您的生活更轻松。当你想自己编码时。你需要一个适当的矩阵类,矩阵和向量的乘法以及一些反演方法。
答案 1 :(得分:0)
您的方法似乎采取了合理的一般形式。看起来您正在相对于当前相机位置旋转线端点,这是正确的,并且您正在执行的三个特定旋转 也可以正确(但请参见下文)。
但是,三个Math.toRadians()
调用无法执行任何有用的操作,因为您忽略了它们的结果。此外,表达式ax *= 90
及其配偶看起来非常可疑:ax
,ay
和az
是否真的表示为四分之一圆的分数?这似乎令人怀疑,如果是这种情况,那么你会希望乘以Math.PI/2
并跳过toRadians()
。另一方面,如果它们以度数表示,那么rotate()
的以下版本对于ax
,ay
和{{的一个合理定义是正确的1}}和一些可能的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
的正确性有点怀疑。特别要注意的是,您不能单独累积单独的x,y和z旋转增量,因为生成的聚合旋转在很大程度上取决于执行增量旋转的顺序。此外,即使az
,ax
和ay
正确描述了相机的方向,也不太可能将相同的旋转应用于世界,这是您真正想要做的事情。 / p>
尽管如此,我还没有看到任何理由说明为什么你的代码会像你描述的那样扭曲模型。我不认为它会应用你想要的旋转(即使我的建议修复),但失真的原因可能在其他地方。