admin管理员组

文章数量:1332976

import numpy as np
import matplotlib.pyplot as plt

class BSpline2D:
    def __init__(self, degree, knots, control_points):
        self.degree = degree
        self.knots = np.array(knots)
        self.control_points = np.array(control_points)

    def get_knot_at(self, i):
        n = len(self.knots)
        return self.knots[(i % n + n) % n]

    def evaluate(self, t):
        span = self.find_span(t)
        coeff = self.basis_functions(span, t)
        point = np.zeros(2)  # Assuming 2D control points
        for i in range(self.degree + 1):
            point += coeff[i] * self.get_control_point_at(span - self.degree + i)
        return point

    def find_span(self, u):
        return np.searchsorted(self.knots, u) - 1

    def basis_functions(self, i, u):
        coeff = [1.0]
        left = [0.0] * (self.degree + 1)
        right = [0.0] * (self.degree + 1)

        for j in range(1, self.degree + 1):
            left[j] = u - self.get_knot_at(i + 1 - j)
            right[j] = self.get_knot_at(i + j) - u
            saved = 0.0
            for r in range(j):
                temp = coeff[r] / (right[r + 1] + left[j - r])
                coeff[r] = saved + temp * right[r + 1]
                saved = temp * left[j - r]
            coeff.append(saved)
        return coeff

    def get_control_point_at(self, i):
        n = len(self.control_points)
        return self.control_points[(i % n + n) % n]

def plot_bspline_2d(spline, resolution=100):
    t_values = np.linspace(spline.knots[0], spline.knots[-1], resolution)
    curve_points = [spline.evaluate(t) for t in t_values]

    # Extract x, y for plotting
    curve_points = np.array(curve_points)
    x, y = curve_points[:, 0], curve_points[:, 1]

    # Extract control points
    control_points = np.array(spline.control_points)
    cx, cy = control_points[:, 0], control_points[:, 1]

    # Plot
    plt.figure()
    plt.plot(x, y, label='B-Spline Curve', color='blue')
    plt.scatter(cx, cy, color='red', label='Control Points')
    plt.plot(cx, cy, linestyle='dotted', color='red', label='Control Polygon')
    plt.legend()
    plt.xlabel("X")
    plt.ylabel("Y")
    plt.title("2D B-Spline Curve")
    plt.axis("equal")
    plt.show()

# Example usage:
degree = 2
knots = [1, 2, 3, 4, 5]
control_points = [
    [0.0, 0.0],
    [1.0, 0.0],
    [1.0, 1.0],
    [0.0, 1.0]
]

spline = BSpline2D(degree, knots, control_points)
plot_bspline_2d(spline)

I have this code in Python, it's supposed to be a closed B-Spline implementation. As you can see on this image, it's wrong:

I shouldn't really change the size of the knot vector, or the control points. I would like to know how to fix the issue seen on the image. Currently I try to wrap the indices using modulo operators both for the knots, and the control points. (If over or underindexing happens, it should handle that correctly.)

本文标签: geometryWhat39s wrong with this closed BSpline implementationStack Overflow