You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenGL圆变换后正射投影、透视投影及相机旋转实现求助

问题解答

Q1:变换后圆在xy平面的正射投影

推导过程

  1. 原圆参数方程(θ∈[0, 2π)):
    x₀ = 40 + 20cosθ
    y₀ = 40 + 20sinθ
    z₀ = 0
    
  2. 绕X轴逆时针转30°的旋转矩阵作用后坐标:
    x₁ = x₀ = 40 + 20cosθ
    y₁ = y₀ * cos30° - z₀ * sin30° = (40 + 20sinθ) * (√3/2)
    z₁ = y₀ * sin30° + z₀ * cos30° = (40 + 20sinθ) * 0.5
    
  3. 沿Z轴正方向平移20单位后最终坐标:
    x = x₁ = 40 + 20cosθ
    y = y₁ = 20√3 + 10√3 sinθ
    z = z₁ + 20 = 40 + 10sinθ
    
  4. 正射投影到xy平面直接丢弃z坐标,最终投影为椭圆,标准方程为:
    ((x - 40)/20)² + ((y - 20√3)/(10√3))² = 1
    
    椭圆中心为(40, 20√3),x方向半轴长20,y方向半轴长10√3。

Q2:透视投影求解与实现代码

投影规则推导

三个坐标轴点(100, 0, 0)、(0, 100, 0)、(0, 0, 100)构成的平面方程为x + y + z = 100。相机位于原点,透视投影为原点出发的射线穿过圆上点,与该平面的交点:

  • 设圆上任意点坐标为(x, y, z),射线参数方程为t(x, y, z), t>0
  • 代入平面方程得t = 100/(x+y+z)
  • 最终投影点坐标为(100x/(x+y+z), 100y/(x+y+z), 100z/(x+y+z))

可运行实现代码(含相机沿Z轴旋转效果)

from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
from math import *

# 相机绕Z轴旋转角度
cam_rotate = 0.0
# 变换后圆的圆心坐标
target_x, target_y, target_z = 40, 40 * cos(radians(30)), 40 * sin(radians(30)) + 20

def circle():
    posx, posy = 40,40
    sides = 80
    radius = 20
    glBegin(GL_POLYGON)
    for i in range(sides):
        cosine = radius * cos(i*2*pi/sides) + posx
        sine  = radius * sin(i*2*pi/sides) + posy
        glVertex3f(cosine, sine, 0)
    glEnd()

def iterate():
    global cam_rotate
    glViewport(0, 0, 800, 800)
    # 设置透视投影
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(60, 1, 0.1, 1000)
    
    # 设置视图变换+模型变换
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    # 相机绕Z轴旋转
    glRotatef(cam_rotate, 0, 0, 1)
    # 相机位于原点,看向变换后的圆心,向上向量为原Z轴(0,0,1)
    gluLookAt(0, 0, 0, target_x, target_y, target_z, 0, 0, 1)
    # 圆的变换:先绕X轴转30度,再沿Z轴平移20
    glTranslatef(0, 0, 20)
    glRotatef(30, 1, 0, 0)
    # 每帧旋转角度+0.5度
    cam_rotate += 0.5

def showScreen():
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    iterate()
    glColor3f(1.0, 0.0, 0.0)
    circle()
    glutSwapBuffers()

glutInit()
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(800, 800)
glutInitWindowPosition(200, 200)
wind = glutCreateWindow("Perspective Projection Demo")
# 开启深度测试
glEnable(GL_DEPTH_TEST)
glClearColor(1.0, 1.0, 1.0, 1.0)
glutDisplayFunc(showScreen)
glutIdleFunc(showScreen)
glutMainLoop()

内容的提问来源于stack exchange,提问作者XGB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 02:15:03