Diferencia entre revisiones de «Curvas de Bézier Grupo 2»
(→Código y representación) |
(→Código y animación) |
||
| Línea 599: | Línea 599: | ||
=== '''Código y animación''' === | === '''Código y animación''' === | ||
| − | [[Archivo:animacion_ferrari_bezier.gif|500px|miniaturadeimagen|derecha|Animación del vector velocidad y el vector de la aceleración centrípeta del Ferrari mientras recorre la pista | + | [[Archivo:animacion_ferrari_bezier.gif|500px|miniaturadeimagen|derecha|Animación del vector velocidad (en rojo) y el vector de la aceleración centrípeta (en verde) del Ferrari mientras recorre la pista con forma de curva de Bézier para t∈(0,1)]] |
{{matlab|codigo= | {{matlab|codigo= | ||
Revisión del 19:55 9 dic 2024
| Trabajo realizado por estudiantes | |
|---|---|
| Título | Curvas de Bézier (Grupo 2) |
| Asignatura | Teoría de Campos |
| Curso | 2024-25 |
| Autores | Marta Escaso Camacho Maximiliano Rodríguez Ruiz Beatrice Laval González Alejandro Villaverde Carrascosa Daniel Pérez Cámara |
| Este artículo ha sido escrito por estudiantes como parte de su evaluación en la asignatura | |
Las curvas de Bézier son un sistema que se desarrolló sobre 1960 para el diseño aeronáutico, el trazado de dibujos técnicos y el diseño de automóviles. Fueron ideadas por el ingeniero francés Pierre Bézier y posteriormente desarrolladas por Paul de Casteljau. Hoy en día, estas curvas se han convertido en un estándar en la industria de la gráfica por computadora, el diseño industrial y la ingeniería, permitiendo crear formas fluidas y precisas. Las curvas de Bézier de orden [math]n[/math] están definidas por los puntos de control [math]P_0,P_1,...,P_n[/math] y se pueden expresar mediante la siguiente fórmula:
donde \(B_{i,n}(t)\) son los polinomios de Bernstein, dados por:
para \(t \in [0, 1]\), y donde \(\binom{n}{i}\) es el coeficiente binomial.
Contenido
- 1 Representación de la curva de Bézier cúbica para [math]n=3[/math], junto con la curva poligonal que conecta cuatro puntos de control coplanarios.
- 2 Representación del campo tangente [math]T(t)[/math] y del campo normal [math]N(t)[/math] en varios puntos de la curva.
- 3 Representación de la curvatura de la curva en función del parámetro [math]t[/math].
- 4 Animación del vector tangente, el vector normal y la circunferencia osculatriz asociados a cada punto de la curva de Bézier.
- 5 Representación de la curva de Bézier tridimensional, junto con la curva poligonal que conecta los cuatro puntos que están en el espacio tridimensional y no pertenecen al mismo plano.
- 6 Representación de los gráficos de la curvatura y de la torsión como funciones del parámetro [math]t[/math].
- 7 Animación que representa el triedro de Frenet que se mueve a lo largo de la curva.
- 8 Aplicación de una curva de Bézier al tramo de un circuito de [math]F_1[/math].
- 9 Aplicaciones de las curvas de Bézier en la ingeniería.
1 Representación de la curva de Bézier cúbica para [math]n=3[/math], junto con la curva poligonal que conecta cuatro puntos de control coplanarios.
En primer lugar se seleccionan cuatro puntos de control coplanarios ([math]P_0,P_1,P_2,P_3[/math]):
[math] \;\left\{\begin{matrix}P_0=(0,0) \\ P_1=(4,2) \\ P_2=(0,2) \\ P_3=(4,4) \end{matrix}\right.[/math]
Para calcular los puntos de la curva se utilizan los polinomios de Bernstein para cada valor de [math]i∈[/math] { [math]0,1,2,...,n[/math] } con [math]n=3[/math]:
[math] B_0=(1-t)^3 [/math]
[math] B_1=3(1-t)^2·t [/math]
[math] B_2=3(1-t)·t^2 [/math]
[math] B_3=t^3 [/math]
Se calcula la posición del punto en la curva mediante una combinación lineal de los puntos de control ponderados por los polinomios de Bernstein.
La imagen representa la gráfica de la curva de Bézier y la poligonal de control. Se puede observar cómo los puntos de control influyen en la forma de la curva, lo que permite adaptarla a distintas aplicaciones.
1.1 Código y representación
% Selección de puntos de control coplanarios
P0 = [0, 0, 0];
P1 = [4, 2, 0];
P2 = [0, 2, 0];
P3 = [4, 4, 0];
% Puntos para la curva de Bézier
numPuntos = 100;
% Valores de t entre 0 y 1
t = linspace(0, 1, numPuntos);
% Inicializar los puntos de la curva Bézier
puntosCurva = zeros(numPuntos, 3);
% Calcular los puntos de Bézier
for i = 1:numPuntos
% Polinomio de Bernstein
B0 = (1-t(i))^3;
B1 = 3 * (1-t(i))^2 * t(i);
B2 = 3 * (1-t(i)) * t(i)^2;
B3 = t(i)^3;
puntosCurva(i,:) = B0*P0 + B1*P1 + B2*P2 + B3*P3;
end
% Graficar la curva y la poligonal de control
figure;
hold on;
% Poligonal de control
plot3([ P0(1), P1(1), P2(1), P3(1) ], [ P0(2), P1(2), P2(2), P3(2) ], ...
[ P0(3), P1(3), P2(3), P3(3) ], 'bo--', 'LineWidth', 1.5);
% Curva de Bézier
plot3(puntosCurva(:,1), puntosCurva(:,2), puntosCurva(:,3), 'r-', 'LineWidth', 2.5);
% Se pone título a la gráfica
title('Curva de Bézier cúbica');
% Se pone nombre a los ejes
xlabel('Eje x');
ylabel('Eje y');
legend('Poligonal de control', 'Curva Bézier');
grid on;
hold off;
2 Representación del campo tangente [math]T(t)[/math] y del campo normal [math]N(t)[/math] en varios puntos de la curva.
2.1 Cálculo del Vector Tangente [math]T(t)[/math]:
El vector tangente [math]T(t)[/math] es la derivada de la curva \(B(t)\) respecto al parámetro [math]t[/math]:
donde la derivada del polinomio de Bernstein es:
El vector tangente se obtiene normalizando la derivada:
donde [math]||B'(t)||=\sqrt{(B'_x(t))^2 + (B'_y(t))^2} [/math]
2.2 Cálculo del Vector Normal [math]N(t)[/math]:
Como el vector normal es ortogonal al vector tangente, lo calculamos haciendo uso del tensor rotación [math]R[/math] con eje unitario y ángulo 90º ([math]\frac{\pi}{2}[/math] radianes).
La fórmula general para una rotación alrededor de un eje [math]e[/math] unitario con un ángulo [math]θ[/math] es:
Particularizando para [math] e_z=\begin{pmatrix} 0 \\ 0 \\ 1 \end{pmatrix} [/math]:
Para rotaciones en el plano XY, es decir, 2D:
2.3 Código y representación
% Vector de puntos de control coplanarios
P = [0, 0; 4, 2; 0, 2; 4, 4];
n = 3; % Orden de la curva de Bézier
% Puntos para la curva de Bézier
numPuntos = 100;
t = linspace(0, 1, numPuntos); % Valores de t entre 0 y 1
B = zeros(numPuntos, 2); % Inicializar B con la matriz nula
dB = zeros(numPuntos, 2); % Derivada de la curva
% Cálculo de la curva y derivada
for i = 0:n
coefBin = nchoosek(n, i); % Coeficiente binomial
Bernstein = coefBin * (t.^i) .* ((1-t).^(n-i)); % Polinomio de Bernstein
BernsteinDerivada = coefBin * (i * t.^(i-1) .* (1-t).^(n-i) - (n-i) * t.^i .* (1-t).^(n-i-1)); % Derivada
B = B + Bernstein' * P(i+1, :); % Curva de Bézier
dB = dB + BernsteinDerivada' * P(i+1, :); % Derivada
end
% Obtenemos el vector tangente
T = dB ./ vecnorm(dB, 2, 2);
% Definimos la matriz de rotación para 90º alrededor del eje Z
R = [0 -1; 1 0];
% Cálculo del vector normal usando R
N = (R * T')';
% Puntos de la curva para dibujar vectores tangentes y normales
puntos = round(linspace(1, numPuntos, 12)); % Seleccionamos 12 puntos
% Graficar la curva y la poligonal de control
figure;
hold on;
plot(P(:, 1), P(:, 2), 'bo--', 'LineWidth', 1.5); % Poligonal de control
plot(B(:, 1), B(:, 2), 'r-', 'LineWidth', 2.5); % Curva Bézier
% Graficar vectores tangentes y normales
quiver(B(puntos, 1), B(puntos, 2), T(puntos, 1), T(puntos, 2), 0.3, 'g', 'LineWidth', 1); % Tangentes (en verde)
quiver(B(puntos, 1), B(puntos, 2), N(puntos, 1), N(puntos, 2), 0.3, 'm', 'LineWidth', 1); % Normales (en magenta)
title('Campos tangente y normal');
xlabel('Eje x');
ylabel('Eje y');
legend('Poligonal de control', 'Curva Bézier', 'Tangentes', 'Normales');
grid on;
hold off;
3 Representación de la curvatura de la curva en función del parámetro [math]t[/math].
La curvatura es una medida del cambio de dirección del vector tangente a una curva, cuanto más rápido cambia este a medida que nos desplazamos a lo largo de la curva, se dice que es más grande la curvatura. Se puede expresar como una función del parámetro [math]t[/math], que generalmente parametriza la curva. En este apartado se usará su parametrización para representar el gráfico de la curvatura de la curva en los cuatro siguientes puntos: [math] P_0=(0,0)[/math] , [math]P_1=(4,2)[/math] , [math]P_2=(0,2)[/math] y [math]P_3=(4,4) [/math].
Se utilizarán los polinomios de Berstein para poder calcular la posición de cada punto de la curva que se define como: [math] B(t) = (x(t), y(t)) [/math]. Posteriormente será necesario calcular las derivadas de primer y segundo orden en función del parámetro [math]t[/math] tanto de [math]x[/math] como de [math]y[/math] y se calculará la curvatura mediante la siguiente fórmula:
3.1 Código y representación
% Selección de puntos de control coplanarios
P0 = [0, 0, 0];
P1 = [4, 2, 0];
P2 = [0, 2, 0];
P3 = [4, 4, 0];
% Puntos para la curva de Bézier
numPuntos = 100;
% Valores de t entre 0 y 1
t = linspace(0, 1, numPuntos);
% Inicializar los puntos de la curva Bézier
puntosCurva = zeros(numPuntos, n);
% Calcular los puntos de Bézier
for i = 1:numPuntos
% Polinomio de Bernstein
B0 = (1-t(i))^3;
B1 = 3 * (1-t(i))^2 * t(i);
B2 = 3 * (1-t(i)) * t(i)^2;
B3 = t(i)^3;
puntosCurva(i,:) = B0*P0 + B1*P1 + B2*P2 + B3*P3;
end
% Derivar las coordenadas de la curva con respecto a t
% Aproximación por diferencias finitas
dx = gradient(puntosCurva(:, 1), t); % Primera derivada de x
dy = gradient(puntosCurva(:, 2), t); % Primera derivada de y
d2x = gradient(dx, t); % Segunda derivada de x
d2y = gradient(dy, t); % Segunda derivada de y
% Calcular la curvatura usando la fórmula
curvatura = abs(dx .* d2y - dy .* d2x) ./ ((dx.^2 + dy.^2).^(3/2));
% Graficar la curvatura en función del parámetro t
plot(t, curvatura, 'r-', 'LineWidth', 2);
title('Curvatura de la curva de Bézier en función de t');
xlabel('Eje x');
ylabel('Eje y');
4 Animación del vector tangente, el vector normal y la circunferencia osculatriz asociados a cada punto de la curva de Bézier.
Para poder calcular el vector tangente, el vector normal y la circunferencia osculatriz a medida que nos movemos a lo largo de una curva de Bézier es importante entender cómo se define la curva y cómo obtener las propiedades geométricas pedidas a partir de las propiedades de las derivadas de la curva.
4.1 Curva de Bézier y su derivada
Como bien dice el enunciado, consideraremos una curva de Bézier de orden n definida por el conjunto de puntos de control {[math]P_0[/math], [math]P_1[/math], [math]P_2[/math], [math]P_3[/math]}. La fórmula paramétrica para una curva de Bézier de grado [math]n[/math] es: [math] B(t)=\sum_{i=0}^n B_{i,n}(t) P_i\ [/math] dónde [math]B_{i,n}(t)[/math] son los polinomios de Bernstein y [math]t[/math] es el parámetro que varía entre 0 y 1. Los polinomios están dados por: [math] B_{i,n}(t) = \binom{n}{i} t^i (1-t)^{n-i}\ [/math] para \(t \in [0, 1]\), y donde \(\binom{n}{i}\) es el coeficiente binomial.
En este caso se han usado los siguientes puntos: [math]P_0=(0,0,0)[/math], [math]P_1=(4,2,0)[/math], [math]P_2=(0,2,0)[/math] y [math]P_3=(4,4,0)[/math], por lo tanto, la curva de Bézier sería: [math]B(t) = (1 − t)^{3}·P_0 + 3(1 − t)^{2}·t·P_1 + (1 − t)^{2}·t^{2}·P_2 + t^{3}·P_3 [/math].
4.2 Vector Tangente (Primera Derivada)
El vector tangente en un punto [math]t[/math] es el vector que indica la dirección en la que se mueve la curva cuando [math]t[/math] cambia. Para obtenerlo, calcularemos la primera derivada de la curva de Bézier [math] B'(t)=\sum_{i=0}^{n-1} (P_{i+1} - P_i)·B_{i,n-1}(t)\ [/math]. Es decir, [math]B'(t) = 3(1 − t)^{2}·(P_1 - P_0) + 6(1 − t)·t·(P_2 - P_1) + 3t^{2}·(P_3 - P_2) [/math]. Sustituyendo según los valores: [math]B'(t) = 3(1 − t)^{2}·[4,2,0] + 6(1 − t)·t·[-4,0,,0] + 3t^{2}·[4,2,0] [/math].
El vector tangente [math]T(t)[/math] en el punto [math]t[/math] es simplemente la normalización de [math]B'(t)[/math]: [math]T(t) = \frac{B'(t)}{|B'(t)|}[/math] (unitario). Este vector apunta en la dirección de la tangente a la curva.
4.3 Vector Normal (Segunda Derivada)
El vector normal es perpendicular al vector tangente y apunta en la dirección en la que la curva se "curva". Para obtener el vector normal, primero necesitas la segunda derivada de la curva: [math] B''(t)=\sum_{i=0}^{n-2} (P_{i+2} - 2 P_{i+1} + P_i)·B_{i,n-2}(t)\ [/math].
Entonces, [math]B''(t) = 6(1 − t)·(P_1 - P_0) + 6[2(1 − t)-2t]·(P_2 - P_1) + 6t·(P_3 - P_2) [/math] y sustituyendo queda como: [math]B''(t) = 6(1 − t)·[4,2,0] + 6(2-4t)·[-4,0,0] + 6t·[4,2,0] [/math].
El vector normal [math]N(t)[/math] se obtiene a partir de la segunda derivada de la curva y la tangente: [math] N(t) = \frac{B''(t)}{|B''(t)|}[/math] (unitario). Es importante tener en cuenta que [math]N(t)[/math] apunta en la dirección de la curvatura de la curva, y está asociado con el cambio de dirección del vector tangente.
4.4 Circunferencia Osculatriz
La circunferencia osculatriz en un punto dado de la curva es el círculo que tiene la misma tangente y curvatura que la curva en ese punto. Para hallar la ecuación de esta circunferencia necesitamos calcular tres variables:
4.4.1 Centro de la circunferencia osculatriz:
Se puede obtener a partir de la curvatura y los vectores tangente y normal. Este centro está ubicado a una distancia [math]R[/math] del punto [math]B(t)[/math], donde [math]R[/math] es el radio de curvatura, que se puede calcular como: [math] R = \frac{1}{|B''(t)|}[/math].
4.4.2 Posición del centro
El centro de la circunferencia está desplazado desde el punto [math]B(t)[/math] a lo largo del vector normal [math]N(t)[/math] a una distancia [math]R[/math]. Entonces, la posición del centro de la circunferencia osculatriz es: [math]C(t) = B(t) + R·N(t)[/math]
4.4.3 Ecuación de la circunferencia:
La ecuación de la circunferencia en el plano es: [math]||r(t) − C(t)|| = R[/math] dónde [math]r(t)[/math] es cualquier punto sobre la circunferencia.
4.5 Código y animación
% Puntos de control coplanares
P0 = [0, 0,0];
P1 = [4, 2,0];
P2 = [0, 2,0];
P3 = [4, 4,0];
% Parámetro t (de 0 a 1)
t = linspace(0, 1, 100);
% Polinomios de Bernstein
B0 = (1 - t).^3;
B1 = 3 * t .* (1 - t).^2;
B2 = 3 * t.^2 .* (1 - t);
B3 = t.^3;
% Coordenadas de la curva de Bézier
x = B0 * P0(1) + B1 * P1(1) + B2 * P2(1) + B3 * P3(1);
y = B0 * P0(2) + B1 * P1(2) + B2 * P2(2) + B3 * P3(2);
% Derivadas de la curva de Bézier
dx = gradient(x, t);
dy = gradient(y, t);
% Vectores tangentes normalizados
T = [dx; dy] ./ sqrt(dx.^2 + dy.^2);
% Vectores normales (perpendiculares al tangente)
N = [-T(2, :); T(1, :)];
% Segunda derivada de la curva
d2x = gradient(dx, t);
d2y = gradient(dy, t);
% Curvatura
curvatura = abs(dx .* d2y - dy .* d2x) ./ (dx.^2 + dy.^2).^(3/2);
% Radio de curvatura
R = 1 ./ curvatura;
% Animación
figure;
for i = 1:length(t)
clf;
plot(x, y, 'b-', 'LineWidth', 2); hold on;
quiver(x(i), y(i), T(1, i), T(2, i), 0.5, 'r', 'LineWidth', 1.5); % Tangente
quiver(x(i), y(i), N(1, i), N(2, i), 0.5, 'g', 'LineWidth', 1.5); % Normal
% Circunferencia osculatriz
center = [x(i), y(i)] + R(i) * N(:, i)';
theta = linspace(0, 2*pi, 100);
circle_x = center(1) + R(i) * cos(theta);
circle_y = center(2) + R(i) * sin(theta);
plot(circle_x, circle_y, 'm--');
title('Animación: Vectores y Circunferencia Osculatriz');
xlabel('x'); ylabel('y');
axis equal; grid on;
pause(0.1);
end
5 Representación de la curva de Bézier tridimensional, junto con la curva poligonal que conecta los cuatro puntos que están en el espacio tridimensional y no pertenecen al mismo plano.
Para calcular y representar la curva de Bézier tridimensional que conecta los puntos {[math]P_0[/math], [math]P_1[/math], [math]P_2[/math], [math]P_3[/math]} siendo entre ellos no coplanarios, hemos utilizado la curva de Bézier cúbica; extendiéndola al espacio 3D. La diferencia principal es que los puntos de control están en [math]ℝ^{3}[/math], por lo que las coordenadas [math]x[/math], [math]y[/math], [math]z[/math] de cada punto de la curva serán calculadas en función de esas dimensiones.
Para el cálculo de la curva poligonal simplemente es una serie de líneas rectas que conectan los puntos de control {[math]P_0[/math], [math]P_1[/math], [math]P_2[/math], [math]P_3[/math]} y la hemos representado como un conjunto de segmentos de línea entre estos puntos.
Los puntos que hemos elegido para este apartado son:
[math] \;\left\{\begin{matrix}P_0=(0,0,0) \\ P_1=(2,3,1) \\ P_2=(4,1,3) \\ P_3=(6,4,0) \end{matrix}\right.[/math]
5.1 Código y representación
% Definimos los puntos de control (no coplanarios)
P0 = [0, 0, 0];
P1 = [2, 3, 1];
P2 = [4, 1, 3];
P3 = [6, 4, 0];
% Matriz de puntos de control
matrizPuntos = [P0; P1; P2; P3];
% Generar los puntos de la curva
t = linspace(0, 1, 100);
puntosCurva = zeros(100, 3);
for i = 1:100
puntosCurva(i, :) = puntosBezier(matrizPuntos, t(i));
end
% Configuración de la visualización
figure;
hold on;
grid on;
axis equal;
% Graficar la curva de Bézier
plot3(puntosCurva(:,1), puntosCurva(:,2), puntosCurva(:,3), 'b-', 'LineWidth', 2);
% Graficar la curva poligonal (polígono de control)
plot3(matrizPuntos(:,1), matrizPuntos(:,2), matrizPuntos(:,3), 'ro-', 'LineWidth', 1.5);
% Decorar los puntos de control
scatter3(matrizPuntos(:,1), matrizPuntos(:,2), matrizPuntos(:,3), 100, 'r', 'filled');
% Etiquetar los puntos de control
labels = {'P0', 'P1', 'P2', 'P3'};
for i = 1:length(labels)
text(matrizPuntos(i,1), matrizPuntos(i,2), matrizPuntos(i,3), ...
labels{i}, 'FontSize', 10, 'FontWeight', 'bold');
end
% Configuraciones finales de la figura
title('Curva de Bézier Cúbica en 3D');
xlabel('Eje X');
ylabel('Eje Y');
zlabel('Eje Z');
view(45, 30); % Ángulo de vista para mejor perspectiva 3D
legend('Curva de Bézier', 'Polígono de Control');
hold off;
% Función para calcular un punto en la curva de Bézier
function P = puntosBezier(matrizPuntos, t)
n = size(matrizPuntos, 1) - 1; % Orden de la curva (número de puntos - 1)
P = zeros(1, 3); % Inicializar el punto resultante en 3D
for i = 0:n
b = nchoosek(n, i) * (t^i) * ((1-t)^(n-i)); % Coeficiente de Bernstein
P = P + b * matrizPuntos(i+1, :); % Suma ponderada de los puntos de control
end
end
6 Representación de los gráficos de la curvatura y de la torsión como funciones del parámetro [math]t[/math].
Una vez la curva de Bézier tridimensional junto a su curva poligonal han sido representadas, se continuará con la representación de la curvatura y la torsión como funciones del parámetro [math]t[/math].
6.1 Curvatura:
Empezando por la curvatura ([math]\kappa(t)[/math]), que marca cuanto se desvía la recta tangente a lo largo de la curva, que en otros palabras sería cuánto cambia la curvatura en el plano, y se calcula en función de la siguiente expresión:
Siendo [math] \mathbf{B}'(t) [/math] la primera derivada de la curva en función de [math]t[/math], y [math] \mathbf{B}''(t) [/math] la segunda derivada en funcón de [math] t [/math].
Por tanto , [math] \|\mathbf{B}'(t) \times \mathbf{B}''(t)\| [/math] equivale a la norma del producto mixto de la primera y la segunda derivada de la curva [math] \mathbf{B}(t) [/math].
6.2 Torsión:
Por otro lado, encontramos la torsión([math] \tau(t)[/math]) que mide cuánto cambia la orientación del plano tangente a lo largo de la curva, y sigue la siguiente expresión:
Dónde [math] \mathbf{B}'(t) [/math] vuelve a ser la primera derivada de la curva en función de [math]t[/math], y [math] \mathbf{B}''(t) [/math] la segunda derivada de la curva en funcón de [math] t [/math], además, aparec también [math] \mathbf{B}'''(t) [/math] que sería la tercera derivada de la curva.
También como se puede observar en la expresión, hay un producto vectorial por un producto escalar, eso se convierte en un producto mixto y se resuelve como el determinante de las tres derivadas de la curva en este caso como se ve en el desarrollo de la expresión.
6.3 Código y representación de la curva de Bézier, su curvatura y torsión en función de [math] t [/math]:
% Visualización de la curva de Bézier 3D
% Puntos de control en el espacio tridimensional (no coplanarios)
P = [0 0 0; 2 3 1; 4 1 3; 6 4 0];
% Número de puntos para la curva
n = 100;
t = linspace(0, 1, n);
% Función para trabajar con el polinomio de Bernstein
function b = bernstein(i, n, t)
b = nchoosek(n, i) * (t.^i) .* ((1-t).^(n-i));
end
% Inicializamos la curva de Bézier
curve = zeros(n, 3);
% Calculamos los puntos de la curva de Bézier
for i = 1:size(P, 1)
curve = curve + bernstein(i-1, size(P, 1)-1, t)' .* P(i, :);
end
% Primera derivada
d1 = zeros(n, 3);
for i = 1:size(P, 1)-1
d1 = d1 + (size(P, 1)-1) * bernstein(i-1, size(P, 1)-2, t)' .* (P(i+1, :) - P(i, :));
end
% Segunda derivada
d2 = zeros(n, 3);
for i = 1:size(P, 1)-2
d2 = d2 + (size(P, 1)-1)*(size(P, 1)-2) * bernstein(i-1, size(P, 1)-3, t)' .* ...
(P(i+2, :) - 2*P(i+1, :) + P(i, :));
end
% Tercera derivada (para calcular la torsión)
d3 = zeros(n, 3);
for i = 1:size(P, 1)-3
d3 = d3 + (size(P, 1)-1)*(size(P, 1)-2)*(size(P, 1)-3) * bernstein(i-1, size(P, 1)-4, t)' .* ...
(P(i+3, :) - 3*P(i+2, :) + 3*P(i+1, :) - P(i, :));
end
% Calculamos la curvatura
tangent = d1 ./ vecnorm(d1, 2, 2);
curvature = vecnorm(cross(d1, d2), 2, 2) ./ (vecnorm(d1, 2, 2).^3);
% Calculamos la torsión
torsion = zeros(n, 1);
for i = 1:n
torsion(i) = dot(cross(d1(i,:), d2(i,:)), d3(i,:)) / norm(cross(d1(i,:), d2(i,:)))^2;
end
% Trazamos la gráfica
figure('Position', [100, 100, 1200, 800]);
% Curva 3D con polígono de control
subplot(2, 2, [1 3]);
% Curva de Bézier
plot3(curve(:,1), curve(:,2), curve(:,3), 'b-', 'LineWidth', 2);
hold on;
% Polígono de control
plot3(P(:,1), P(:,2), P(:,3), 'ro-', 'MarkerFaceColor', 'r');
title('Curva de Bézier');
xlabel('X'); ylabel('Y'); zlabel('Z');
grid on;
view(45, 30);
% Gráfico de curvatura
subplot(2, 2, 2);
plot(t, curvature, 'b-', 'LineWidth', 2);
title('Curvatura');
xlabel('t'); ylabel('Curvatura');
grid on;
% Gráfico de torsión
subplot(2, 2, 4);
plot(t, torsion, 'r-', 'LineWidth', 2);
title('Torsión');
xlabel('t'); ylabel('Torsión');
grid on;
sgtitle('Curvatura y torsión en función de t');
7 Animación que representa el triedro de Frenet que se mueve a lo largo de la curva.
Tras haber representado la curva, pasamos al triedro de Frenet que es un conjunto de tres vectores que se utilizan para describir el comportamiento geométrico de una curva en el espacio tridimensional. Estos vectores son:
el vector [math] \overrightarrow{T} [/math] que hace referencia al vector tangente a lo largo de la curva [math] \mathbf{B}(t) [/math]
el vector [math] \overrightarrow{n} [/math] que es el vector normal que esta orientado a la dirección en la que está curvando cada punto de la curva [math] \mathbf{B}(t) [/math]
y por último, el vector [math] \overrightarrow{BN} [/math] que es es vector binormal y es perpendicular a [math] \overrightarrow{T} [/math] y [math] \overrightarrow{N} [/math], y se calcula tal que : [math] \overrightarrow{BN} = {\overrightarrow{T} \times \overrightarrow{N}} [/math]
Una vez definido lo que es y los vectores que lo componen, se representa, gracias al programa MATLAB, una animación del Triedro de Frenet a lo largo de la curva, dónde se utilizó el siguiente código para su realización:
7.1 Código y animación
% Frenet Trihedral Animation for 3D Bézier Curve
% Control points in 3D space (non-coplanar)
P = [0 0 0; 1 2 1; 3 1 2; 4 3 3];
% Number of points for smooth curve
n = 100;
t = linspace(0, 1, n);
% Function to compute binomial coefficient
function b = binomial_coef(n, k)
b = factorial(n) / (factorial(k) * factorial(n-k));
end
% Function to compute Bernstein polynomial
function b = bernstein(i, n, t)
b = binomial_coef(n, i) * (t.^i) .* ((1-t).^(n-i));
end
% Compute Bézier curve points
curve = zeros(n, 3);
for i = 1:size(P, 1)
curve = curve + bernstein(i-1, size(P, 1)-1, t)' .* P(i, :);
end
% First derivative
d1 = zeros(n, 3);
for i = 1:size(P, 1)-1
d1 = d1 + (size(P, 1)-1) * bernstein(i-1, size(P, 1)-2, t)' .* (P(i+1, :) - P(i, :));
end
% Second derivative
d2 = zeros(n, 3);
for i = 1:size(P, 1)-2
d2 = d2 + (size(P, 1)-1)*(size(P, 1)-2) * bernstein(i-1, size(P, 1)-3, t)' .* ...
(P(i+2, :) - 2*P(i+1, :) + P(i, :));
end
% Compute Frenet frame
tangent = d1 ./ vecnorm(d1, 2, 2);
normal = cross(d2, d1) ./ (vecnorm(d1, 2, 2).^2);
binormal = cross(tangent, normal);
% Normalize vectors
normal = normal ./ vecnorm(normal, 2, 2);
binormal = binormal ./ vecnorm(binormal, 2, 2);
% Prepare animation
figure('Position', [100, 100, 1000, 800]);
axis equal;
hold on;
grid on;
% Plot Bézier curve
plot3(curve(:,1), curve(:,2), curve(:,3), 'b-', 'LineWidth', 2);
plot3(P(:,1), P(:,2), P(:,3), 'ro-', 'MarkerFaceColor', 'r');
% Animation of Frenet trihedral
title('Animación Triedro de Frenet');
xlabel('X'); ylabel('Y'); zlabel('Z');
% Vector length for visualization
vector_length = 0.3;
% Create lines for vectors
tangent_line = line([0 0], [0 0], [0 0], 'Color', 'r', 'LineWidth', 2);
normal_line = line([0 0], [0 0], [0 0], 'Color', 'g', 'LineWidth', 2);
binormal_line = line([0 0], [0 0], [0 0], 'Color', 'm', 'LineWidth', 2);
% Animation
view(80, 60);
for i = 1:n
% Update vector lines
set(tangent_line, 'XData', [curve(i,1), curve(i,1) + vector_length*tangent(i,1)], ...
'YData', [curve(i,2), curve(i,2) + vector_length*tangent(i,2)], ...
'ZData', [curve(i,3), curve(i,3) + vector_length*tangent(i,3)]);
set(normal_line, 'XData', [curve(i,1), curve(i,1) + vector_length*normal(i,1)], ...
'YData', [curve(i,2), curve(i,2) + vector_length*normal(i,2)], ...
'ZData', [curve(i,3), curve(i,3) + vector_length*normal(i,3)]);
set(binormal_line, 'XData', [curve(i,1), curve(i,1) + vector_length*binormal(i,1)], ...
'YData', [curve(i,2), curve(i,2) + vector_length*binormal(i,2)], ...
'ZData', [curve(i,3), curve(i,3) + vector_length*binormal(i,3)]);
drawnow;
pause(0.05);
end
8 Aplicación de una curva de Bézier al tramo de un circuito de [math]F_1[/math].
8.1 Condiciones
La velocidad escalar constante [math]ν_0[/math] que debe mantener un Ferrari F2004 para no salirse de la pista en ningún punto de un circuito con el trazado de una curva de Bézier, debe ser tal que la fuerza centrípeta [math]F_c=mκν^2[/math] no exceda la fuerza máxima de fricción [math]F_{\text{fricción}}=μmg[/math].
Siendo [math]m[/math] la masa del Ferrari, [math]κ[/math] la curvatura de la pista, [math]g[/math] la aceleración de la gravedad y [math]μ[/math] el coeficiente de fricción entre los neumáticos y la pista (se asume igual a 1.5).
8.2 Cálculo analítico de la velocidad escalar constante [math]ν_0[/math]
Esto implica que [math]F_c≤F_{\text{fricción}}→κν^2≤μg[/math]
Para que la velocidad sea constante y segura se tomará el valor máximo de [math]κ(t)[/math] a lo largo del intervalo [math]t∈[0,1][/math]. Así pues: [math]ν_0≤\sqrt{\frac{μg}{κ_{\text{máx}}}}[/math]
Como ya se ha mencionado en apartados anteriores, para calcular la curvatura [math]κ(t)[/math] se necesitan la primera y la segunda derivada de [math]B[/math]: [math] \kappa(t) = \frac{\|\mathbf{B}'(t) \times \mathbf{B}''(t)\|}{\|\mathbf{B}'(t)\|^3} [/math]
Siendo B para [math]n=3[/math] (por la fórmula general de las curvas de Bézier): [math]B=(1-t)^3P_0+3t(1-t)^2P_1+3t^2(1-t)P_2+t^3P_3[/math]
Además se tendrán en cuenta los siguientes puntos de control: [math]P_0 =[0,0,0], P_1 = [30,50,5], P_2 = [60,−30,−10], P_3 = [100,0,0][/math].
Analizando el problema con la animación 3D de la curva que se muestra más abajo, el programa nos devuelve el valor máximo de velocidad escalar constante posible para que el Ferrari no se salga de la pista: [math]24,1569[/math] [math]m/s[/math]
8.3 Aceleración centrípeta y su vector director
Por otro lado, la aceleración centrípeta es: [math]a_c=\frac{ν_0^2}{r}[/math]. Sabiendo que: [math]r=\frac{1}{κ(t)}[/math]. Entonces: [math]a_c=ν_0^2·κ(t)[/math]
Si esta se multiplica por el vector normal unitario a la curva de Bézier, se obtiene el vector aceleración centrípeta en la animación (radial, siempre apuntando al centro de la curvatura y perpendicular a la velocidad, que es tangencial)
8.4 Código y animación
% Puntos de control
P0 = [0, 0, 0];
P1 = [30, 50, 5];
P2 = [60, -30, -10];
P3 = [100, 0, 0];
% Constantes
mu = 1.5; % Coeficiente de fricción
g = 9.81; % Aceleración gravitatoria (m/s^2)
% Funciones de la curva de Bézier y derivadas
function B = bezier(t, P0, P1, P2, P3)
B = (1 - t)^3 * P0 + 3 * t * (1 - t)^2 * P1 + 3 * t^2 * (1 - t) * P2 + t^3 * P3;
end
function Bp = bezier_prime(t, P0, P1, P2, P3)
Bp = -3 * (1 - t)^2 * P0 + (3 * (1 - t)^2 - 6 * t * (1 - t)) * P1 ...
+ (6 * t * (1 - t) - 3 * t^2) * P2 + 3 * t^2 * P3;
end
function Bpp = bezier_double_prime(t, P0, P1, P2, P3)
Bpp = 6 * (1 - t) * P0 + (6 - 12 * t) * P1 + (6 * t - 12 * t + 6) * P2 - 6 * t * P3;
end
function k = curvature(t, P0, P1, P2, P3)
Bp = bezier_prime(t, P0, P1, P2, P3);
Bpp = bezier_double_prime(t, P0, P1, P2, P3);
cross_prod = norm(cross(Bp, Bpp));
norm_Bp = norm(Bp);
if norm_Bp == 0
k = 0;
else
k = cross_prod / (norm_Bp^3);
end
end
% Discretización de la curva
t_values = linspace(0, 1, 500);
curve = arrayfun(@(t) bezier(t, P0, P1, P2, P3), t_values, 'UniformOutput', false);
curve = cell2mat(curve')';
% Cálculo de la curvatura
curvatures = arrayfun(@(t) curvature(t, P0, P1, P2, P3), t_values);
% Velocidad máxima segura
kappa_max = max(curvatures);
v0 = sqrt(mu * g / kappa_max);
% Mostrar resultado
disp(['Velocidad máxima segura (v0): ', num2str(v0), ' m/s']);
% Crear figura
figure;
hold on;
grid on;
plot3(curve(1, :), curve(2, :), curve(3, :), 'b-', 'LineWidth', 2);
title('Curva de Bézier y animación del coche');
xlabel('X (m)');
ylabel('Y (m)');
zlabel('Z (m)');
view(3); % Vista 3D
% Congelar los límites de los ejes
axis([min(curve(1, :)) max(curve(1, :)) ...
min(curve(2, :)) max(curve(2, :)) ...
min(curve(3, :)) max(curve(3, :))]);
% Crear los vectores para animación
h_vel = quiver3(0, 0, 0, 0, 0, 0, 'r', 'LineWidth', 2); % Vector velocidad
h_ac = quiver3(0, 0, 0, 0, 0, 0, 'g', 'LineWidth', 2); % Vector aceleración centrípeta
% Animar la curva
for i = 1:10:length(t_values) % Aumentar el paso para controlar la velocidad de animación
t = t_values(i);
% Posición, velocidad y aceleración centrípeta
pos = bezier(t, P0, P1, P2, P3);
Bp = bezier_prime(t, P0, P1, P2, P3);
Bpp = bezier_double_prime(t, P0, P1, P2, P3);
% Dirección del vector normal (centrípeta)
normal_vec = cross(Bp, Bpp);
normal_vec = normal_vec / norm(normal_vec); % Normalizar
ac = curvature(t, P0, P1, P2, P3) * v0^2 * normal_vec;
% Actualizar la posición de los vectores
set(h_vel, 'XData', pos(1), 'YData', pos(2), 'ZData', pos(3), ...
'UData', Bp(1), 'VData', Bp(2), 'WData', Bp(3));
set(h_ac, 'XData', pos(1), 'YData', pos(2), 'ZData', pos(3), ...
'UData', ac(1), 'VData', ac(2), 'WData', ac(3));
% Pausa para crear la animación
pause(0.05);
end
legend('Curva Bézier', 'Velocidad', 'Aceleración centrípeta');
hold off;
9 Aplicaciones de las curvas de Bézier en la ingeniería.
Las curvas de Bézier son herramientas matemáticas que se utilizan en diversas áreas de la ingeniería por su capacidad para representar trayectorias, modelar superficies complejas y generar movimientos precisos. En la ingeniería podemos ver diferentes aplicaciones:
9.1 Modelización de trayectorias
Se utilizan para diseñar trayectorias óptimas en diversos sistemas automatizados como la robótica o los vehículos autónomos:
9.1.1 Robótica
En robótica, las curvas de Bézier se utilizan para planificar trayectorias de movimientos de brazos robóticos. Por ejemplo, un brazo robótico que ensambla las partes de un producto utiliza estas curvas para una trayectoria óptima en la que no haya colisiones o movimientos bruscos.
9.1.2 Vehículos autónomos
Las curvas de Bézier permiten calcular las rutas más seguras entre obstáculos en tiempo real. Por ejemplo, los vehículos tesla tienen una conducción autónoma donde utilizan estas curvas para planificar la trayectoria, optimizar el consumo energético y evitar colisiones.
9.2 Fabricación automatizada
En procesos como la impresión 3D y el corte por láser, las curvas de Bézier se utilizan para definir los patrones del movimiento que las herramientas deben seguir.
9.2.1 Impresión 3D
En la impresión 3D, las superficies y trayectorias generadas por las curvas de Bézier son necesarias para lograr precisión y minimizar las discontinuidades entre capas. Por ejemplo, si se desea imprimir una prótesis, las curvas de Bézier ayudan a modelar de forma precisa la forma necesaria para que pueda ajustarse a la persona que lo necesita.
9.2.2 Corte por láser
En el corte de piezas metálicas o textiles, las curvas de Bézier permiten definir las trayectorias que las herramientas deben seguir para cortar con precisión. Por ejemplo, una máquina que fabrica piezas de aeronaves puede emplear estas curvas para cortar bordes suaves y redondeados en chapas de aluminio.
9.3 Análisis de Superficies Complejas
Las curvas de Bézier son empleadas para la creación de modelos tridimensionales. Podemos diferenciar dos tipos de modelos: los de estructuras y los de transportes.
9.3.1 Construcción de estructuras
En arquitectura, las curvas de Bézier ayudan a diseñar cubiertas de estadios o fachadas. Un ejemplo es el nuevo Santiago Bernabéu, cuya estructura curva ha sido diseñada mediante las curvas de Bézier.
Mediante programas "CAD" se emplean curvas y superficies de Bézier para diseñar formas aerodinámicas. Por ejemplo, al modelar un ala de avión, estas curvas garantizan una distribución suave de las fuerzas aerodinámicas.
