function Q = evaltps(shape, params, S)

% evaltps(shape, params, S)
%
% Aplica um par de thin-plate splines determinado pelos parâmetros
% dados por params e pelos marcos contidos em S a uma forma
% representada pelos marcos presentes em shape, e devolve a forma
% transformada em Q.
%
% Argumentos:
%
%         |sh1_x sh1_y|
% shape = |sh2_x sh2_y|
%         | ...   ... |
%         |shm_x shm_y|
%
% (conjunto de marcos que representam a forma sobre a qual
% queremos aplicar o par de thin-plate splines)
%
% params = |wx_1 wx_2 ... wx_n a_x b_xx b_xy|'
%          |wy_1 wy_2 ... wy_n a_y b_yx b_yy|
%
% (parâmetros para as thin-plate splines, podem ser gerados pela
% função thinplate(S, Q))
%
%     |s1_x s1_y|
% S = |s2_x s2_y|
%     |...  ... |
%     |sn_x sn_y|
%
% (marcos utilizados no cálculo da transformação, são os marcos da
% forma utilizada como entrada na determinação das thin-plate splines)
% 
% Devolve uma matriz
% 
%     |q1_x q1_y|
% Q = |q2_x q2_y|
%     |...  ... |
%     |qm_x qm_y|
%
% que são os pontos resultantes da aplicação das thin-plate
% splines.
%
% Referência:
%
% R. M. Cesar Jr. e L. F. Costa. "Shape Analysis and
% Classification". CRC Press, 2001, seção 4.9.6.

% Parâmetros das thin-plate splines
n = size(params, 1) - 3;

ax = params(n + 1, 1);
bxx = params(n + 2, 1);
bxy = params(n + 3, 1);

ay = params(n + 1, 2);
byx = params(n + 2, 2);
byy = params(n + 3, 2);

for j=1:n
  Wx(j, 1) = params(j, 1);
  Wy(j, 1) = params(j, 2);
end

% Para cada ponto da forma de entrada, calculamos sua transformação
% usando as equações 4.22 e 4.23 (pág. 325) do livro
for i=1:size(shape, 1)
  
  x = shape(i, 1);
  y = shape(i, 2);

  for j=1:size(S, 1)
    g(j, 1) = base(dist([x, y], [S(j, 1), S(j, 2)]));
  end
  
  Q(i, 1) = ax + bxx * x + bxy * y + Wx' * g;
  Q(i, 2) = ay + byx * x + byy * y + Wy' * g;

end
