这个相机旋转算法有什么问题?

4
我正在尝试为我正在开发的小游戏实现3D图形,但摄像机旋转效果不太对。对于摄像机,我使用球坐标系,其中alpha是方位角(图片中的theta),beta是90度减去极角(图片中的90 - phi):
在xy平面或z坐标较小的对象视野看起来似乎很好,但是当看向z轴时,物体会变形。这是一个例子,以(0, 0, 500)为中心观察半径为100的球体:
另一个例子,以(0, 0, 500)为中心观察半径为100的球体,从(0, 0, 0)观察:
我几乎可以确定投影算法没有问题,应该是摄像机的旋转出了问题。下面是我用于摄像机旋转算法的代码。distance()方法返回从一个坐标到另一个坐标的距离。point是我要旋转的点(x, y, z)坐标,camera是摄像机位置的(x, y, z)坐标,alpha是方位角,beta是90度减去极角。最终,我希望点被旋转以便相对于摄像机系统定位。
point.x -= camera.x;
point.y -= camera.y;
point.z -= camera.z;

double alpha = Math.atan2(point.y, point.x) - cameraAlpha;
double beta = Math.atan2(point.z, Math.sqrt(point.x * point.x + point.y * point.y)) - cameraBeta;

point = new Coordinate(point.distance(new Coordinate(0, 0, 0)) * Math.cos(alpha) * Math.cos(beta), point.distance(new Coordinate(0, 0, 0)) * Math.sin(alpha) * Math.cos(beta), point.distance(new Coordinate(0, 0, 0)) * Math.sin(beta));

投影算法的其余部分模拟了眼睛中的镜头功能。由于y和z是对称的,我怀疑这部分不是问题所在。750是我正在绘制的小应用程序的高度和宽度。

if (point.x < 0){

    return null;

}else{

    return new Point(375 + (int) (point.y * 750 / point.x), 375 + (int) (point.z * 750 / point.x));

}

我已经花了好几个小时来解决这个问题,但一直没有成功。非常感谢任何能帮助我的人!感谢所有阅读这篇文章的人。


1
还有更多的代码吗?比如你是如何为相机构建矩阵的? - weston
1
你已经展示了如何计算一个点,但是这个点如何扭曲视图呢?我认为你应该发布投影算法。你使用OpenGL吗? - weston
这是投影算法的一部分(相对于相机移动点)的方法体。我正在使用标准的Java库和图形来绘制到屏幕上。 - user2605633
好的,但矩阵数学不需要库。你可以从查看“look at”的实现中获得一些提示。 - weston
使用四元数。http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#Quaternions 我建议阅读整个页面。它几乎包含了你需要了解的所有关于3D旋转的知识。 - Joonazan
显示剩余4条评论
1个回答

0

Java的Math函数使用弧度而不是角度。在您的第一个示例中,调试输出显示相机beta为-89,但实际上您希望它为-pi/2。

更好的方法是完全避免三角学,通过使用向量来完成所有操作。我认为,在编写游戏的编程竞赛中禁止使用图形库是非常不可能的。 "没有外部资源"可能意味着资产收集或“制作自己的flappy bird”套件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接