Slides

Tema 1.1 — Interpolación

Ejercicios

Ejercicio 1.1.1

Escribe una función de MATLAB para visualizar los polinomios base de Hermite de grado 3.

function plot_hermite_basis()
    figure;
    hold on;
    grid on;
                
    % Rango
    x = 0:0.0001:1;
                
    H0 = 2*x.^3 - 3*x.^2 +1 ;
    plot(x,H0);

    % Completar...
    
    hold off;
end                    
Solución

Ejercicio 1.1.2

Calcula el polinomio de Hermite P(x) tal que P(0) = 1, P(1) = 1, P'(0) = 0, P'(1) = 1. Implementa una función en MATLAB para visualizar el resultado.

function hermite_interpolation_demo()
    figure;
    hold on;
    x = [0,1];
    y = [1,1];
                    
    % Completar
                    
    plot(x,y);
    hold off;
end
Solución

Ejercicio 1.1.3

Calcula el polinomio interpolador de Lagrange de la siguiente tabla. Escribe una función de MATLAB que dibuje cada uno de los polinomios interpoladores y el polinomio resultante.

x -9 -4 -1 7
y 5 2 -2 9

El resultado debe ser algo parecido a esto. ¿Cuál es el valor del primer polinomio interpolador en x=-4, x=-1 y x=7? ¿Cuál es el valor del segundo polinomio interpolador en x=-9, x=-1 y x=7? ¿Cuál es el valor del tercer polinomio interpolador en x=-9, x=-4 y x=7? ¿Cuál es el valor del cuarto polinomio interpolador en x=-9, x=-4 y x=-1?

Solución

Ejercicio 1.1.4

Interpolar y dibujar en MATLAB con splines lineales la función f(x) = 1 / x en los puntos en los que x vale 1, 2 y 4.

Solución

Ejercicio 1.1.5

Interpolar y dibujar en MATLAB con splines quadráticas (grado 2) la función f(x) que pasa por los puntos f(3) = 2.5; f(4.5) = 1; f(7) = 2.5; f(9)=0.5. Utiliza la función de MATLAB X = linsolve(A,b) para resolver el sistema de ecuaciones.

Se trata de un sistema indeterminado, con más incognitas que ecuaciones. ¿Qué se puede hacer en estos casos? Calcula por lo menos 2 posibles soluciones del sistema, y dibuja las splines resultantes en MATLAB.

Solución

Ejercicio 1.1.6

Utilizando como referencia la función bezier_linear() de más abajo que dibuja una de Bezier de con sólo dos puntos de control, escribe dos nuevas funciones bezier_quadratic() y bezier_cubic() que calculen y dibujen curvas cuadráticas y cúbicas.

Modifica el tercer parámetro de la función linspace y observa como cambian las curvas dibujadas. ¿Qué controla este parámetro?

function placelabel(pt,str)
    x = pt(1);
    y = pt(2);
    h = line(x,y);
    h.Marker = '*';
    h = text(x,y,str);

    h.HorizontalAlignment = 'center';
    h.VerticalAlignment = 'bottom';
end
                
function bezier_linear()
    figure;
    hold on
    pt1 = [ 5;-10];
    pt2 = [45; 15];

    placelabel(pt1,'  pt_1');
    placelabel(pt2,'  pt_2');
    xlim([0 50])
    axis equal

    % Crea un vector de 100 valores equidistantes entre 0 y 1
    t = linspace(0,1,100);
    % Evalua la funcion (1-t) * pt1 + t * pt2 en todos los puntos t
    pts = kron((1-t),pt1) + kron(t,pt2);
    %plot(pts(1,:),pts(2,:))

    % Metodo alternativo
    %pts = [];
    %for t=0:0.2:1
    %    pts = [pts ((1-t) * pt1 + t * pt2)];
    %end

    plot(pts(1,:), pts(2,:));

    hold off;
end

Tema 1.2 — Movimiento a través de una curva

Ejercicios

Ejercicio 1.2.1

Escribe una funcion en MATLAB llamada compute_arc_length_cubic_bezier(pt1, pt2, pt3, pt4, samples) que calcule mediante Forward Differencing la longitud del arco de una curva cúbica de Bezier. ¿Cómo cambia el resultado en función del parámetro samples?

Solución

Ejercicio 1.2.2

Escribe una función en MATLAB que dados 4 puntos de control, calcule su curva de Bezier y marque sobre ella: puntos equidistantes con respecto el parámetro t (tiempo) y con respecto el parámetro s (longitud del arco). El resultado final debería ser parecido a esto.

Solución

Ejercicio 1.2.3

¿Qué condiciones tienen que darse para que una curva formada por 2 curvas de Bezier tenga continuidad C0? ¿Y C1?

Dibuja en MATLAB un curva cerrada con continuidad C1 creada por 4 curvas cúbicas de Bezier. Utiliza transformaciones del tipo translación y escalado en los puntos de control para cambiar el tamaño la curva dibujada. Aquí tienes un ejemplo del tipo de resultado que puedes conseguir.

Solución

Tema 2.1 — Cinemática directa

Ejercicios

Ejercicio 2.1.1

Desarrolla la función plot_skeleton(skeleton, rots) en MATLAB que dibuje mediante la técnica de Cinemática Directa la estructura jerárquica inicializada a continuación.

function skeleton_demo()
    close all;

    trans0 = [0,0];
    trans1 = [-1,-1]; % Offset con respecto joint 0
    trans2 = [0,-1];  % Offset con respecto joint 1
    trans3 = [0,-1];  % Offset con respecto joint 2

    rot1 = 0;         % Rotacion local del joint 0
    rot2 = 0;         % Rotacion local del joint 0
    rot3 = 0;         % Rotacion local del joint 0

    skeleton = [trans0; trans1; trans2; trans3];
    rots = [rot1 rot2 rot3];

    figure;
    hold on;
    grid on;
    axis equal;
    xlim([-5 5]);
    ylim([-5 5]);

    plot_skeleton(skeleton, rots); % Acaba de desarrollar esta función

    hold off;
end

function plot_skeleton(skeleton, rots)
    rot1 = rots(1);
    rot2 = rots(2);
    rot3 = rots(3);
    % Aplicamos nodo 0

    rot0_matrix = [ 1 0 0;
    0 1 0;
    0 0 1];

    trans0_matrix = [1 0 skeleton(1,1);
    0 1 skeleton(1,2);
    0 0 1];

    pos             = rot0_matrix * trans0_matrix;
    scatter(pos(1,3), pos(2,3),300,'o','filled');

    % Aplicamos nodo 1
    rot1_matrix = [ +cosd(rot1) -sind(rot1) 0;
    +sind(rot1) +cosd(rot1) 0;
    0          0          1 ];

    trans1_matrix = [1 0 skeleton(2,1);
    0 1 skeleton(2,2);
    0 0 1];

    old_pos = pos;
    pos     =   rot0_matrix * trans0_matrix ...
    * rot1_matrix * trans1_matrix ;

    scatter(pos(1,3), pos(2,3),300,'o','filled');
    line([pos(1,3),old_pos(1,3)],[pos(2,3),old_pos(2,3)], 'LineWidth', 2);

    % Desarrolla el código para pintar el resto de la cadena

end

Ejercicio 2.1.2

Cambia los valores de los parámetros del vector rots y observa como cambia la posición de la cadena. Consigue articulaciones parecidas a estas: ejemplo1, ejemplo2, ejemplo3, ejemplo4. Asegúrate de entender cómo afectan los cambios de cada uno de los parámetros en el estado final de la cadena.

Ejercicio 2.1.3

Añade dos eslabones más en la estructura jeráquica del ejercicio anterior.

Tema 2.2 — Cinemática inversa

Ejercicios

Ejercicio 2.2.1 — Entrega el 4 de Diciembre 2016

Desarrolla una función de Cinemática Inversa run_IK() que, dado una cadena jerárquica en reposo (vector de desplazamientos en 2D) y un objetivo (una coordenada 2D), calcule el valor de cada uno de los ángulos del cadena de tal forma que el end effector (punta de la cadena) este lo más cerca posible al objetivo. Para ello, utiliza la técnica del Jacobiano explicada en clase, y visualiza en MATLAB cada una de las iteraciones.

Aquí tienes una animación de cómo debería ser el resultado

Recuerda que la parte principal de la función run_IK es un bucle de este estilo.

while(error(current_position, target) > 0.1)
    % Dibuja el estado actual
    plot_skeleton(skeleton, rots)
    drawnow;

    % Calcula Jacobiano del estado actual
    J = compute_jacobian(skeleton, rots);

    % Calcula posicion actual del end effector
    current_position = compute_position(skeleton, rots);

    % Calcula incrementos de las rotaciones
    update = ... ;

    % Actualiza rotaciones
    rots(1) = rots(1) + update(1);
    rots(2) = rots(2) + update(2);
    rots(3) = rots(3) + update(3);
end

Tema 3.1 — Caminar

Ejercicios

Ejercicio 3.1.1

Descárgate este archivo BVH que contiene el esqueleto báisco. Importalo a Blender. Edítalo con un editor de texto para crear alguna animación sencilla, por ejemplo:

  1. Añade un movimiento translacional al nodo root durante 10 frames.
  2. Añade un movimiento rotacional en alguno de sus articulaciones durante 10 frames.
  3. Añade un eslabón nuevo a su cuerpo en reposo, con 2 DOFs.

Aquí tienes una sencilla animación de lo que tienes que conseguir.

Ejercicio 3.1.2

Edita el archivo del ejercicio anterior, y cambia las línias del tipo CHANNELS 3 Xrotation Yrotation Zrotation por CHANNELS 3 Zrotation Xrotation Yrotation. ¿Puedes adivinar qué es lo que estás cambiando? ¿Qué consecuencuas tiene en la animación resultante?

Ejercicio 3.1.3

Descárgate esta escena de Blender y fíjate en las curvas de valores cómo la translación y la rotación de la pelvis (nodo root). Debería parecerse a esto, que coincide con los gráficos correspondientes a la acción de caminar como hemos visto en clase. Intenta modificar las curvas en el Editor de Curvas de Blender, y observa cómo cambia la animación.

Tema 3.2 — Animación Facial

Ejercicios

Ejercicio 3.2.1

Descárgate este zip que contiene un set de blendshapes, descomprimelo y guárdalas en un directorio. Descárgate también la función para dibujar mallas en format OBJ read_vertices_and_faces_from_obj_file.m.

Acaba de implementar la función compute_global_blendshapes(), para que interpole entre 2 mallas utilizado el método de blendshape global que hemos visto en clase.

%% Looping global blendshape from alpha 0 to 1 to 0
function compute_global_blendshapes()
    close all
    
    % Read OBJ files
    [V00,F] = read_vertices_and_faces_from_obj_file(PATH); %Substituir PATH por ruta al obj
    
    % ¡¡¡¡¡Leer más OBJ aquí!!!!
    
    figure;

    %  Creamos un vector t con parametros alpha que utilizaremos
    t=0:0.2:1;
    t = [t flip(t)];
    iterations = 0;
    
    % Loop infinito para ver los resultados
    while 1
       
       % Iteración actual. Utilizamos módulo para siempre tener un número
       % de iteración > tamaño del vector de alphas t.
       iterations = mod(iterations,size(t,2)) + 1;
       
       % Alpha correspondiente a la iteración actial
       alpha = t(iterations);
       
       % Stores current viewpoint
       [az, el] = view; 
       
       % ¡¡¡¡¡Calcular blendshape y guardar en los vectors X, Y y Z las coordenadas de la nueva malla!!!!
        X = ...
        Y = ...
        Z = ...
        
        % Draws mesh
        trisurf(F,X(:),Y(:),Z(:),'FaceColor',[0.26,0.63,1.0 ],'EdgeColor','none','LineStyle','none','SpecularStrength',0.4);
      
        % Sets current viewpoint
        view (az, el);
       
        % Set up lighing
        light('Position',[-1.0,-1.0,100.0],'Style','infinite');
        lighting phong;
        
        % Set up axis
        axis equal
        axis([-1.5 1.5 0 2 -1 1.5])
       
        drawnow;
    end
end

Ejercicio 3.2.2

¿Qué pasa cuándo asignamos una alpha mayor que 1, utilizando el método global de blendshapes?

Ejercicio 3.2.3

Usando como referencia la función desarrollada en el ejercicio 3.2.1, implementa la función compute_delta_blendshapes() utilizando el método delta blendshapes presentado en clase. Mezcla más de 2 mallas a la vez. Por ejemplo, consigue una animación donde el personaje abra la boca y cierre los dos ojos. Aquí tienes una animación de lo que tienes que conseguir.

Ejercicio 3.2.4

¿Qué pasa cuándo asignamos una alpha mayor que 1, utilizando el método delta de blendshapes?


Animación por Computador, 2016 — Dan Casas