add Lane-Riesenfeld subdivision for lab2
This commit is contained in:
@@ -20,6 +20,7 @@ def ibspline(inputA, inputB=None):
|
||||
global save_message_xloc
|
||||
global num_sample
|
||||
global curve_degree, knot_vector, add_cp_mode # added for Bspline
|
||||
global ax_lr_button, lr_button # added for Lane-Riesenfeld
|
||||
|
||||
# de Boor's algorithm to evaluate a point on a B-spline.
|
||||
# Returns (x, y) coordinate at parameter t
|
||||
@@ -119,6 +120,7 @@ def ibspline(inputA, inputB=None):
|
||||
plt.plot(vX, vY, 'ob', picker=True, pickradius=5)
|
||||
return
|
||||
|
||||
|
||||
# Redraw the entire plot
|
||||
def redrawPlot(vX, vY):
|
||||
global text_message, ax
|
||||
@@ -187,6 +189,58 @@ def ibspline(inputA, inputB=None):
|
||||
|
||||
# CallbackS
|
||||
|
||||
# Lane-Riesenfeld subdivision callback
|
||||
def lrSubdivideCallback(event):
|
||||
global vX, vY, curve_degree, knot_vector
|
||||
|
||||
if len(vX) == 0: return
|
||||
|
||||
# Check if knot vector is uniform
|
||||
is_uniform = True
|
||||
if len(knot_vector) > 1:
|
||||
diff = knot_vector[1] - knot_vector[0]
|
||||
for i in range(1, len(knot_vector) - 1):
|
||||
if abs((knot_vector[i+1] - knot_vector[i]) - diff) > 1e-5:
|
||||
is_uniform = False
|
||||
break
|
||||
|
||||
if not is_uniform:
|
||||
outputPlotMessage("Error: LR-Subdivide requires uniform knot distances.")
|
||||
plt.draw()
|
||||
return
|
||||
|
||||
n = curve_degree
|
||||
m = len(vX)
|
||||
points = list(zip(vX, vY))
|
||||
|
||||
# Step 1: Double the points (P0, P0, P1, P1, ...)
|
||||
doubled_points = []
|
||||
for p in points:
|
||||
doubled_points.append(p)
|
||||
doubled_points.append(p)
|
||||
|
||||
# Step 2: Apply moving average n times
|
||||
for _ in range(n):
|
||||
smoothed_points = []
|
||||
# Average adjacent points
|
||||
for i in range(len(doubled_points) - 1):
|
||||
px = (doubled_points[i][0] + doubled_points[i+1][0]) / 2.0
|
||||
py = (doubled_points[i][1] + doubled_points[i+1][1]) / 2.0
|
||||
smoothed_points.append((px, py))
|
||||
doubled_points = smoothed_points
|
||||
|
||||
# Update vX and vY
|
||||
vX = [p[0] for p in doubled_points]
|
||||
vY = [p[1] for p in doubled_points]
|
||||
|
||||
# update knot : maintain uniformity but increase density
|
||||
new_m = len(vX)
|
||||
knot_vector = list(range(1, new_m + curve_degree + 1))
|
||||
|
||||
outputPlotMessage(f"LR-Subdivide applied. (m={len(vX)})")
|
||||
redrawPlot(vX, vY)
|
||||
return
|
||||
|
||||
# callback of add cp
|
||||
def addCPButtonCallback(event):
|
||||
global add_cp_mode
|
||||
@@ -265,6 +319,7 @@ def ibspline(inputA, inputB=None):
|
||||
def createButtons(left_pos, button_width, button_height):
|
||||
global ax_add_button, add_button
|
||||
global ax_save_button, save_button
|
||||
global ax_lr_button, lr_button
|
||||
|
||||
# Colors
|
||||
inactive_color = 'lightgray'
|
||||
@@ -276,6 +331,13 @@ def ibspline(inputA, inputB=None):
|
||||
add_button.color = inactive_color
|
||||
add_button.hovercolor = inactive_color
|
||||
|
||||
# LR-Subdivide
|
||||
ax_lr_button = plt.axes([left_pos, 0.7, button_width, button_height])
|
||||
lr_button = Button(ax_lr_button, "LR-Sub")
|
||||
lr_button.on_clicked(lrSubdivideCallback)
|
||||
lr_button.color = inactive_color
|
||||
lr_button.hovercolor = inactive_color
|
||||
|
||||
# Save
|
||||
ax_save_button = plt.axes([left_pos, 0.6, button_width, button_height])
|
||||
save_button = Button(ax_save_button, "Save")
|
||||
@@ -288,10 +350,12 @@ def ibspline(inputA, inputB=None):
|
||||
|
||||
# not enable all buttons as smooth needs subdivision first
|
||||
def enableButtons():
|
||||
global add_button, save_button
|
||||
global add_button, save_button, lr_button
|
||||
|
||||
add_button.color = 'white'
|
||||
add_button.hovercolor = 'green'
|
||||
lr_button.color = 'white'
|
||||
lr_button.hovercolor = 'green'
|
||||
save_button.color = 'white'
|
||||
save_button.hovercolor = 'green'
|
||||
plt.draw()
|
||||
|
||||
Reference in New Issue
Block a user