简体   繁体   中英

OpenGL B-Spline with weight isn`t rendered correctly

I'm working on a project with B-Splines in OpenGL.

The B-Spline itself works as far as I can say but I also want to add some weight to my control-points in a range of 1-10 in order to have the spline go closer to points with higher weight.

The problem that I have right now is that when I add some weight to a point the spline always goes way above that point instead of just getting a little bit closer.

Now what I have tried so far is to implement my program the way it is described in this article . The Last topic in this article describes how to implement B-Splines with weight but it doesn't work for me.

This is how I add weight to a control-point.

I create a control-point with a mouseclick and add weight with the value 1 as the third vector parameter

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)

Then I divide a selected controlpoint by its old weight to set it back to 1 and then I multiply the point by its new weight. Currentpoint is the point I have selected to add weight to.

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()

And this is how I try to render the spline For rendering I want to ignore the added weight.

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()

UPDATE

This is how I calculate the spline. The deboor alogrithm and the findR function should be correct scince I have them from a lecture foil.

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

I Expected the Spline to go closer to the selected point but instead it always grows above it.

UPDATE

Thanks to Nico Schertler I got the program running and working. What I did wrong was creating and working with 3D control points including their weight but I factored these points out again, turning my 3D Vectors into 2D points, which was a mistake made by me.

Here is the draw function redone:

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()

The rest of the code didn't change.

:)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM