add Lane-Riesenfeld subdivision for lab2

This commit is contained in:
2026-02-24 22:49:28 -05:00
parent 52036af25f
commit 81930753bb

View File

@@ -20,6 +20,7 @@ def ibspline(inputA, inputB=None):
global save_message_xloc global save_message_xloc
global num_sample global num_sample
global curve_degree, knot_vector, add_cp_mode # added for Bspline 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. # de Boor's algorithm to evaluate a point on a B-spline.
# Returns (x, y) coordinate at parameter t # 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) plt.plot(vX, vY, 'ob', picker=True, pickradius=5)
return return
# Redraw the entire plot # Redraw the entire plot
def redrawPlot(vX, vY): def redrawPlot(vX, vY):
global text_message, ax global text_message, ax
@@ -187,6 +189,58 @@ def ibspline(inputA, inputB=None):
# CallbackS # 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 # callback of add cp
def addCPButtonCallback(event): def addCPButtonCallback(event):
global add_cp_mode global add_cp_mode
@@ -265,6 +319,7 @@ def ibspline(inputA, inputB=None):
def createButtons(left_pos, button_width, button_height): def createButtons(left_pos, button_width, button_height):
global ax_add_button, add_button global ax_add_button, add_button
global ax_save_button, save_button global ax_save_button, save_button
global ax_lr_button, lr_button
# Colors # Colors
inactive_color = 'lightgray' inactive_color = 'lightgray'
@@ -276,6 +331,13 @@ def ibspline(inputA, inputB=None):
add_button.color = inactive_color add_button.color = inactive_color
add_button.hovercolor = 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 # Save
ax_save_button = plt.axes([left_pos, 0.6, button_width, button_height]) ax_save_button = plt.axes([left_pos, 0.6, button_width, button_height])
save_button = Button(ax_save_button, "Save") 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 # not enable all buttons as smooth needs subdivision first
def enableButtons(): def enableButtons():
global add_button, save_button global add_button, save_button, lr_button
add_button.color = 'white' add_button.color = 'white'
add_button.hovercolor = 'green' add_button.hovercolor = 'green'
lr_button.color = 'white'
lr_button.hovercolor = 'green'
save_button.color = 'white' save_button.color = 'white'
save_button.hovercolor = 'green' save_button.hovercolor = 'green'
plt.draw() plt.draw()