OpenGL中点圆绘制算法:解决for循环内while无限循环问题
问题解决:OpenGL中点圆算法无限循环与多内圆绘制问题
问题描述
我正在PyCharm中使用OpenGL实现中点圆绘制算法,目标是在一个大圆内绘制8个分属不同区域的内圆(目前先尝试实现4个)。我编写了两个函数分别绘制大圆与内圆,但运行后仅显示一个内圆——for循环遍历区域列表时,第一个迭代中的while循环执行完成后,后续迭代无法进入绘制逻辑,导致仅显示第一个内圆。
错误原因分析
- 核心算法变量未重置:
x、y、d这些中点圆算法的关键变量被定义在for循环外部,第一个内圆绘制完成后,变量状态被保留,后续循环的while x <= y条件直接不满足,无法启动新的内圆绘制流程。 - 变量拼写错误:第四个区域的偏移变量写成了
center_x(美式拼写),与前面统一的centre_x(英式拼写)不一致,导致该区域内圆中心未正确偏移。
修正后的代码
from OpenGL.GL import * from OpenGL.GLUT import * from OpenGL.GLU import * def circle_points(x, y, centre_x, centre_y): glVertex2f(x + centre_x, y + centre_y) glVertex2f(x + centre_x, -y + centre_y) glVertex2f(-x + centre_x, y + centre_y) glVertex2f(-x + centre_x, -y + centre_y) glVertex2f(y + centre_x, x + centre_y) glVertex2f(y + centre_x, -x + centre_y) glVertex2f(-y + centre_x, -x + centre_y) glVertex2f(-y + centre_x, x + centre_y) # 绘制大圆 def draw_circle(r): glPointSize(2) glBegin(GL_POINTS) glColor3f(1.0, 1.0, 1.0) x = 0 y = r d = 1 - r # 决策参数 centre_x, centre_y = 250, 250 # 大圆中心 while x <= y: circle_points(x, y, centre_x, centre_y) if d >= 0: d = d + 2 * (x - y) + 1 x += 1 y -= 1 else: d = d + 2 * x + 1 x += 1 glEnd() # 绘制内圆 def draw_inner_circles(r): glPointSize(2) glBegin(GL_POINTS) glColor3f(1.0, 1.0, 1.0) # 用元组存储各区域的坐标偏移,简化逻辑 zones = [('up', 0, r), ('down', 0, -r), ('right', r, 0), ('left', -r, 0)] for _, offset_x, offset_y in zones: # 每个内圆绘制前重置算法变量 x = 0 y = r d = 1 - r centre_x, centre_y = 250 + offset_x, 250 + offset_y while x <= y: circle_points(x, y, centre_x, centre_y) if d >= 0: d = d + 2 * (x - y) + 1 x += 1 y -= 1 else: d = d + 2 * x + 1 x += 1 glEnd() def iterate(): glViewport(0, 0, 500, 500) glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(0.0, 500, 0.0, 500, 0.0, 1.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() def showScreen(): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() iterate() glColor3f(1.0, 1.0, 1.0) draw_circle(200) draw_inner_circles(100) glutSwapBuffers() glutInit() glutInitDisplayMode(GLUT_RGBA) glutInitWindowSize(500, 500) glutInitWindowPosition(0, 0) wind = glutCreateWindow(b"OpenGL Coding Practice") glutDisplayFunc(showScreen) glutMainLoop()
修正说明
- 重置算法变量:将
x、y、d的初始化代码移到for循环内部,确保每个内圆绘制时都从算法初始状态(x=0, y=r, d=1-r)开始,避免前一次绘制的变量状态干扰后续循环。 - 修复变量拼写错误:统一使用
centre_x变量名,确保第四个区域内圆的中心偏移正确。 - 优化区域逻辑:用元组列表存储各区域的坐标偏移,替代冗余的条件判断,提升代码可读性和可扩展性(后续扩展到8个区域时,只需添加对应的偏移元组即可)。
内容的提问来源于stack exchange,提问作者Anonymous Stranger
相关产品推荐
相关产品推荐

