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

OpenGL多线绘制异常:循环仅生成单条线的问题排查

解决你的OpenGL连线问题

我看了你的代码,问题主要出在两个地方:坐标列表的生成逻辑错误,以及画线的循环嵌套完全没必要。咱们一步步来修正:

1. 先修正坐标列表pos的生成

你现在生成pos的方式完全搞错了,[[[a, b] for a in pos_x] for b in pos_y]会创建一个三维列表,每个元素都是重复的组合,根本不是你需要的“每个点的(x,y)坐标对”。正确的做法是把pos_x和pos_y里的对应元素配对,改成这样:

pos = list(zip(pos_x, pos_y))

这样pos里的每个元素就是(x, y)的元组,直接就能用来取坐标。

2. 修正画线的循环逻辑

你原来的嵌套循环for n in range(lol-1)完全多余,而且会导致同一个终点被重复添加多次。GL_LINES的规则是每两个连续的顶点组成一条线段,所以我们只需要遍历每个点,连接它和下一个点就行。另外,如果你要画闭合的图形(比如正八边形),别忘了把最后一个点和第一个点连起来。

修正后的画线代码应该是这样:

glBegin(GL_LINES)
glColor3f(0.0, 1.0, 0.0)
# 连接相邻的点
for m in range(lol):
    # 当前点
    x1, y1 = pos[m]
    # 下一个点,最后一个点的下一个是第一个点
    x2, y2 = pos[(m+1) % lol]
    glVertex2f(x1, y1)
    glVertex2f(x2, y2)
glEnd()

把glBegin(GL_LINES)和glEnd()放在循环外面,这样所有线段都在同一个批次里绘制,效率更高,逻辑也更清晰。

3. 其他小问题修正

  • 你原来的glClear只在初始化时调用了一次,要是后面加旋转的话,画面会重叠,应该把glClear放到主循环里。
  • 绘制点的时候,也可以把所有点放在同一个glBegin(GL_POINTS)里,不用循环一次就调用一次glBegin/glEnd。

完整修正后的代码

import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
import numpy as np
import math as mt

pos_x = []
pos_y = []
pos= []
lol = 8

def point_pos(p, r):
    for i in range(p):
        t = 2 * mt.pi * i / p
        x = r * mt.cos(t)
        pos_x.append(x)
        y = r * mt.sin(t)
        pos_y.append(y)
    # 正确生成坐标列表
    pos = list(zip(pos_x, pos_y))
    
    # 绘制所有点
    glBegin(GL_POINTS)
    glColor3f(1.0, 0.0, 0.0)  # 把点设为红色,和绿色的线区分开
    for x, y in pos:
        glVertex2f(x, y)
    glEnd()
    
    # 绘制所有连线
    glBegin(GL_LINES)
    glColor3f(0.0, 1.0, 0.0)
    for m in range(lol):
        x1, y1 = pos[m]
        x2, y2 = pos[(m+1) % lol]
        glVertex2f(x1, y1)
        glVertex2f(x2, y2)
    glEnd()

def main():
    pygame.init()
    display = (800,600)
    pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
    gluPerspective(90, (display[0]/display[1]), 0.1, 50.0)
    glTranslatef(0.0,0.0, -5)
    
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        
        # 每次循环都清除缓冲区,避免画面重叠
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        point_pos(lol, 2)
        pygame.display.flip()
        pygame.time.wait(10)

main()

这样运行之后,你就能看到一个由红色点和绿色线组成的正八边形了。如果要画3D的正八面体,那还需要调整坐标生成的逻辑(加入z轴),不过先把2D的连线问题解决,再扩展到3D会更顺利~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:11:14