如何使用 OpenGL 在 Python 中使球体遵循 8 条路径?

问题描述 投票:0回答:1

我必须为我的计算机图形学课制作一个球体以无限符号的形状移动。

我想我已经成功地在下面的 Python 程序中重新创建了球体的精确运动,如任务图表所示。

这些是结果:

The sphere following a path in the shape of the number eight

这是我的问题:

我的程序需要做某些事情才能完成此任务:

  1. 我必须画两个球体模型。一个位于 (-8,4,0),另一个位于 (7,-3,0)。我这样做是为了将球体放置在与原点不同的两个坐标周围。

  2. 我让第一个模型围绕坐标(-8,4,0)旋转,直到它完成半循环。之后,我将其更改为原点位于 (7,-3,0) 的第二个模型,并且它会一直旋转,直到完成整个循环。一旦发生这种情况,我再次将其更改为第一个模型并执行整个循环半。它再次重复,从而遵循无限符号的轨迹。

这就是我在 python 程序中所做的

run = True
angle = 0
x_position = -8
y_position = 4
points_matrix = generate_sphere_points(x0=x_position, y0=y_position, z0=0)
points_matrix2 = generate_sphere_points(x0=-x_position-1, y0=-y_position+1, z0=0)
index = False
matrices_points = [points_matrix, points_matrix2]
delta_angle = -4
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    draw_world_axes()
    glLineWidth(1)
    glTranslatef(x_position, y_position, 0)
    glRotatef(angle, 0, 0, 1)
    plot_parametric_mesh(matrices_points[index])
    pygame.display.flip()
    pygame.time.wait(10)

    if angle <= -180 or angle >= 180:
        index = not index
        x_position = -x_position - 1
        y_position = -y_position + 1
        delta_angle *= -1

    angle += delta_angle

pygame.quit()

虽然它有效,但我认为你只需要一个球体模型。但是,我还没有弄清楚如何使球体甚至物体围绕与原点 (0,0,0) 不同的坐标旋转,而不会在创建该物体时移动该物体。我知道你可以使用

glRotatef()*glTranslatef()
使对象绕原点旋转,但我想要的是它绕我指定的坐标旋转。

在这种情况下,制作一个围绕一个坐标旋转的球体模型,然后将其中心切换到另一个坐标,并在整个 8 环中重复。

有谁知道如何仅使用变换矩阵(translatef 和rotatef)使球体围绕坐标旋转,而不必更改其参数方程中的球体中心,并且仅使用球体的一个模型来完成8 个循环而不是交换两个模型?

python matrix opengl rotation
1个回答
0
投票

我认为您正在寻找的是利萨如曲线。这可以通过对两个轴应用不同角度的变换来创建。如果两个角度相同,就会得到一个圆。如果一个角是另一个角的两倍,则得到 8:

import pygame
from OpenGL.GL import *
import math

pygame.init()
display = (400, 400)
screen = pygame.display.set_mode(display, pygame.DOUBLEBUF | pygame.OPENGL)
clock = pygame.time.Clock()

run = True
angle1 = 0
angle2 = 0
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    x = math.cos(angle1) * 0.8
    y = math.sin(angle2) * 0.4
    glTranslatef(x, y, 0)
    angle1 += 0.01
    angle2 += 0.02
    glBegin(GL_QUADS)
    glVertex2f(-0.1, -0.1)
    glVertex2f(0.1, -0.1)
    glVertex2f(0.1, 0.1)
    glVertex2f(-0.1, 0.1)
    glEnd()

    clock.tick(100)
    pygame.display.flip()

pygame.quit()
© www.soinside.com 2019 - 2024. All rights reserved.