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.