首页 > 解决方案 > 带有权重的 OpenGL B-Spline 未正确渲染

问题描述

我正在开发一个在 OpenGL 中使用 B-Splines 的项目。

据我所知,B 样条本身可以工作,但我还想在 1-10 范围内为我的控制点添加一些权重,以使样条更接近具有更高权重的点。

我现在遇到的问题是,当我向某个点添加一些权重时,样条曲线总是会超出该点,而不是稍微靠近一点。

现在我到目前为止所尝试的是按照本文中描述的方式来实现我的程序。本文的最后一个主题描述了如何使用权重实现 B-Splines,但它对我不起作用。

这就是我向控制点添加权重的方式。

我用鼠标单击创建一个控制点,并添加权重值为 1 作为第三个向量参数

def onMouseButton(win, button, action, mods):
    global degree
    global M
    global currentpoint
    global shift
    global yposition
    shift = 0
        if button == glfw.MOUSE_BUTTON_LEFT:
            if action == glfw.PRESS:
                p = np.array(glfw.get_cursor_pos(win))
                p[0] = (p[0] - WIDTH/2) / (WIDTH/2)
                p[1] = 1 - (p[1] / (HEIGHT/2))
                p = np.append(p, 1.0)
                controlpoints.append(p)

然后我将选定的控制点除以其旧权重以将其设置回 1,然后我将该点乘以它的新权重。Currentpoint 是我选择添加权重的点。

def onMouseMove(win, xpos, ypos):
    global shift
    global currentpoint
    global yposition

    if shift == 1:
        for x in controlpoints:
            if np.array_equal(x, currentpoint):
                weight = yposition - ypos
                if weight >= 10:
                    weight = 10
                if weight <= 1:
                    weight = 1
                x[0] /= x[2]
                x[1] /= x[2]
                x[2] = weight
                x[0] *= x[2]
                x[1] *= x[2]
                calcSpline()

这就是我尝试渲染样条曲线的方式。对于渲染,我想忽略增加的权重。

def render():
    weightpoints = []
    for x in controlpoints:
        a = x[0]/x[2]
        b = x[1]/x[2]
        element = [a, b]
        element = np.array(element)
        weightpoints.append(element)
    # draw black control polygon
    draw(GL_LINE_STRIP, weightpoints, [0.0, 0.0, 0.0])
    #draw red control points
    draw(GL_POINTS, weightpoints, [1.0, 0.0, 0.0])
    #draw red control points
    draw(GL_LINE_STRIP, splinepoints, [0.0, 0.0, 1.0])
    # recalculate spline curve
    calcSpline()
    # draw blue bspline deboor points
    draw(GL_POINTS, splinepoints, [0.0, 1.0, 1.0])

def draw(mode, points, color):
    # draws objects
    glPointSize(3)
    glEnable(GL_POINT_SMOOTH)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    glBegin(mode)
    glColor(color[0], color[1], color[2])
    for p in points:
        glVertex2f(p[0], p[1])
    glEnd()

更新

这就是我计算样条曲线的方式。deboor 算法和 findR 函数应该是正确的,因为我从讲座中获得了它们。

def calcSpline():
    # calculates spline curve with deboor
    calcKnotVector()
    del splinepoints[:]
    if len(controlpoints) >= degree:
        t = 0
        while t <= knotvector[-1]:
            r = findR(t)
            b = deBoor(controlpoints, knotvector, t, r, degree - 1)
            splinepoints.append(b)
            t += 1 /float(M - 1)
            t -= 0.0000000001

我预计样条线会更接近所选点,但它总是在它上方增长。

标签: pythonopenglbsplineopengl-compat

解决方案


更新

感谢Nico Schertler,我让程序运行并正常工作。我做错的是创建和使用 3D 控制点,包括它们的重量,但我再次考虑了这些点,将我的 3D 矢量转换为 2D 点,这是我犯的一个错误。

这是重做的绘图功能:

def draw(mode, points, color):
    # draws objects
    glPointSize(5)
    glLineWidth(3)
    glEnable(GL_POINT_SMOOTH)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    glBegin(mode)
    glColor(color[0], color[1], color[2])
    for x, y, w in points:
        glVertex2f(x / w, y / w)
    glEnd()

其余代码没有改变。

:)


推荐阅读