0% found this document useful (0 votes)
11 views3 pages

Import Numpy As NP

des
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views3 pages

Import Numpy As NP

des
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 3

import numpy as np

import matplotlib.pyplot as plt


from math import comb

# ==========================
# Utilidades matemáticas
# ==========================

def bezier_curve(control_points, num=200):


"""
Evalúa una curva Bézier (grado n-1) usando la forma de Bernstein.
control_points: array de shape (n, 2)
num: número de muestras en [0,1]
"""
P = np.asarray(control_points, dtype=float)
n = P.shape[0] - 1
t = np.linspace(0.0, 1.0, num)

# Coeficientes binomiales
C = np.array([comb(n, i) for i in range(n+1)], dtype=float)

# Potencias de t y (1-t)
T = np.array([t**i for i in range(n+1)])
U = np.array([(1 - t)**(n - i) for i in range(n+1)])

# Base de Bernstein para cada i en 0..n y cada t


B = C[:, None] * T * U # shape (n+1, num)

# Curva: sum_i B_i(t) * P_i


curve = B.T @ P # shape (num, 2)
return curve, t

def make_open_uniform_knot_vector(n_ctrl, degree):


"""
Vector nudo abierto y uniforme.
n_ctrl: número de puntos de control
degree: grado p
"""
p = degree
m = n_ctrl + p + 1 # número de nudos
# p+1 ceros, n_ctrl - p - 1 intermedios uniformes, p+1 unos
knots = np.zeros(m)
knots[p : m - p] = np.linspace(0, 1, m - 2*p)
knots[m - p :] = 1.0
return knots

def de_boor(k, x, t, c, p):


"""
Algoritmo de De Boor para evaluar B-spline.
k: índice tal que t[k] <= x < t[k+1]
x: parámetro en [t[p], t[-p-1]]
t: vector nudo
c: puntos de control (array Nx2)
p: grado
"""
d = [c[i + k - p].astype(float).copy() for i in range(0, p + 1)]
for r in range(1, p + 1):
for j in range(p, r - 1, -1):
i = j + k - p
denom = t[i + p + 1 - r] - t[i]
if denom == 0:
alpha = 0.0
else:
alpha = (x - t[i]) / denom
d[j] = (1.0 - alpha) * d[j - 1] + alpha * d[j]
return d[p]

def bspline_curve(control_points, degree=3, num=300):


"""
Evalúa una B-spline abierta y uniforme.
control_points: array de shape (n,2)
degree: grado p (por defecto cúbica)
num: número de muestras
"""
P = np.asarray(control_points, dtype=float)
n_ctrl = P.shape[0]
p = degree
if n_ctrl <= p:
raise ValueError("Se requieren más puntos de control que el grado (n_ctrl >
degree).")

knots = make_open_uniform_knot_vector(n_ctrl, p)

# Rango válido de x: [t[p], t[-p-1]]


low, high = knots[p], knots[-p-1]
xs = np.linspace(low, high, num, endpoint=False) # evitar tocar el último nudo

C = np.array([de_boor(np.searchsorted(knots, x) - 1, x, knots, P, p) for x in


xs])
return C, xs, knots

# ============================
# Ejemplo 1: Bézier cúbica
# ============================
bezier_ctrl = np.array([
[0.0, 0.0],
[0.5, 1.2],
[1.2, -0.8],
[2.0, 0.8]
])

curve_bz, tbz = bezier_curve(bezier_ctrl, num=400)

plt.figure(figsize=(7, 5))
# Control polygon
plt.plot(bezier_ctrl[:, 0], bezier_ctrl[:, 1], marker='o', linestyle='--',
linewidth=1.0, label='Polígono de control')
# Curve
plt.plot(curve_bz[:, 0], curve_bz[:, 1], linewidth=2.0, label='Curva Bézier (grado
3)')
plt.title("Curva Bézier cúbica")
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
plt.axis('equal')
plt.grid(True)
plt.show()
# ============================
# Ejemplo 2: B-spline cúbica
# ============================
bspline_ctrl = np.array([
[0.0, 0.0],
[0.5, 1.0],
[1.2, 1.2],
[2.0, 0.2],
[2.5, 0.8],
[3.0, 0.0],
[3.4, 1.0]
])

curve_bs, tbs, knots = bspline_curve(bspline_ctrl, degree=3, num=600)

plt.figure(figsize=(7, 5))
plt.plot(bspline_ctrl[:, 0], bspline_ctrl[:, 1], marker='o', linestyle='--',
linewidth=1.0, label='Polígono de control')
plt.plot(curve_bs[:, 0], curve_bs[:, 1], linewidth=2.0, label='B-spline cúbica
(abierta, uniforme)')
plt.title("Curva B-spline cúbica (control local)")
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
plt.axis('equal')
plt.grid(True)
plt.show()

# Impresión breve de info útil (opcional)


print("Vector nudo (B-spline):", np.round(knots, 3))

You might also like