Python 无法垂直旋转3D相机,请转换图像
我最近写了一个简单的程序,将3D空间中的点投影到屏幕上, 并创建了一个多边形类来演示这一点。除了一些视觉上的小故障,我对它相当满意 它的工作原理是计算每个点相对于相机的角度差和相机所面对的角度差。它分别在水平面和垂直面上执行此操作。 当计算从相机到点的水平距离(用于计算垂直角度)时,我乘以Python 无法垂直旋转3D相机,请转换图像,python,python-3.x,3d,pygame,perspectivecamera,Python,Python 3.x,3d,Pygame,Perspectivecamera,我最近写了一个简单的程序,将3D空间中的点投影到屏幕上, 并创建了一个多边形类来演示这一点。除了一些视觉上的小故障,我对它相当满意 它的工作原理是计算每个点相对于相机的角度差和相机所面对的角度差。它分别在水平面和垂直面上执行此操作。 当计算从相机到点的水平距离(用于计算垂直角度)时,我乘以cos(abs(self.angle[0]-self.camera.angle[0])来计算投影距离,而不是欧几里德距离 然而,有一个突出的问题,那就是当向上或向下旋转相机时,它会向上或向下平移整个屏幕,而不会
cos(abs(self.angle[0]-self.camera.angle[0])
来计算投影距离,而不是欧几里德距离
然而,有一个突出的问题,那就是当向上或向下旋转相机时,它会向上或向下平移整个屏幕,而不会改变透视图。这意味着,只有当相机完全水平时,一切看起来都应该是这样。否则,事情会变得有点扭曲(向上看和向下看是最好的方式)
这是一个多边形的侧面图像(看起来正常),然后直接从上面往下看(非常扭曲)。它应该像是从直接的角度来看的,但事实并非如此
正常:
扭曲的:
我已经尝试了几个小时,试图找出我可以做什么来解决这个问题,但真的不确定,我想得到一些帮助。我在下面隐藏了我的代码,没有太多的事情发生,所以我希望你能理解它
您可以使用WASD四处移动,并使用箭头键旋转相机。空格和LSHIFT分别向上和向下移动
导入系统
导入pygame
输入数学
从pygame.locals导入*
pygame.init()
宽度=800
高度=600
比率=宽度/高度
SCREEN=pygame.display.set_模式((宽度、高度))
CLOCK=pygame.time.CLOCK()
FPS=60
pygame.display.set_标题('3D测试')
#颜色#
黑色=(0,0,0)
蓝色=(0,0255)
青色=(0,255,255)
暗绿色=(0,64,0)
暗灰色=(64,64,64)
灰色=(128128128)
绿色=(0,128,0)
石灰=(0,255,0)
洋红=(255,0255)
褐红色=(128,0,0)
NAVYBLUE=(0,0,128)
奥利弗=(128128,0)
紫色=(128,0,128)
红色=(255,0,0)
银=(192192192)
TEAL=(0,128,128)
白色=(255,255,255)
黄色=(255,255,0)
# #-------------------# #
类摄像机:
定义初始化(自):
self.position=[0,5,-20]
self.angle=[90,-15]
self.fov=45
自身移动速度=0.2
self.look\u速度=2
def环顾四周(自我):
keys=pygame.key.get_pressed()
如果键[K_RIGHT]:
自转角[0]-=自转角速度
如果键[K_左]:
自转角[0]+=self.look\u速度
如果键[K_UP]:
自转角[1]+=self.look\u速度
如果键[K_向下]:
自转角[1]-=自转角速度
如果自转角[0]<-180:
自转角[0]+=360
elif自转角[0]>180:
自转角[0]=360
自转角[1]=最小值(最大值(自转角[1],-90),90)
def移动(自我):
keys=pygame.key.get_pressed()
如果键[K#w]:#向前移动
self.position[0]+=math.cos(数学弧度(self.angle[0]))*self.move\u速度
self.position[2]+=math.sin(数学弧度(self.angle[0]))*self.move\u速度
如果键[K#s]:#向后移动
self.position[0]-=数学cos(数学弧度(self.angle[0]))*self.move\u速度
self.position[2]=math.sin(math.radians(self.angle[0]))*self.move\u速度
如果键[K#U a]:#向左移动
self.position[2]+=math.cos(数学弧度(self.angle[0]))*self.move\u速度
self.position[0]=math.sin(math.radians(self.angle[0]))*self.move\u速度
如果键[K#d]:#向右移动
self.position[2]=math.cos(数学弧度(self.angle[0]))*self.move\u速度
self.position[0]+=math.sin(数学弧度(self.angle[0]))*self.move\u速度
如果键[K_空格]:#向上移动
自身位置[1]+=自身移动速度
如果键[K#L Shift]:#向下移动
自身位置[1]-=自身移动速度
def更新(自我):
self.move()
self.环顾四周
课程点:
def _u初始(自身、摄像头、位置):
self.camera=camera
self.position=位置
self.angle=[0,0]
self.update_angle()
def更新角度(自身):
#获取相机和点之间的水平角度
自角度[0]=数学度(数学atan2(自位置[2]-自相机位置[2],
self.position[0]-self.camera.position[0]))
水平距离=数学海波(自身位置[0]-自身摄像机位置[0],
self.position[2]-self.camera.position[2])
垂直距离=自身位置[1]-自身摄像机位置[1]
#获取相机和点之间的垂直角度
自身角度[1]=数学角度(数学角度)2(垂直距离,
cos(数学弧度(abs(self.angle[0]-self.camera.angle[0]))*水平距离)
def更新(自我):
self.update_angle()
def获取屏幕位置(自身):
#计算相机与点的角度差
视角=[self.camera.angle[0]-self.angle[0],
self.camera.angle[1]-self.angle[1]]
#计算点相对于相机的相对位置(在屏幕上)
相对位置=[视角角度[0]/self.camera.fov,
视角[1]/(self.camera.fov/比率)]
#根据屏幕大小缩放相对位置
位置=[int((相对位置[0]+0.5)*宽度),int((相对位置[1]+0.5)*高度)]
返回位置
类多边形:
定义初始化(自我,