2#include <cgv/math/mat.h>
3#include <cgv/math/vec.h>
4#include <cgv/math/lin_solve.h>
18 mat<T> affine_transformation;
23 assert(p.
size() == 2);
25 r(0) = affine_transformation(0,0)
26 +affine_transformation(1,0)*p(0)
27 +affine_transformation(2,0)*p(1);
28 r(1) = affine_transformation(0,1)
29 +affine_transformation(1,1)*p(0)
30 +affine_transformation(2,1)*p(1);
31 for(
unsigned i = 0;i < weights.
nrows();i++)
33 T u_sqr_dist=
U(sqr_length(p-controlpoints.
col(i)));
34 r(0)+=weights(i,0)*u_sqr_dist;
35 r(1)+=weights(i,1)*u_sqr_dist;
43 assert(p.
size() == 2);
47 temp(0) = (affine_transformation(1,0) + affine_transformation(2,1))/2;
48 temp(1) = (affine_transformation(2,0) - affine_transformation(1,1))/2;
52 r(0) = affine_transformation(0,0)
55 r(1) = affine_transformation(0,1)
66 assert(points.
nrows() == 2);
69 for(
unsigned i = 0; i < points.
ncols(); i++)
76 static T
U(
const T& sqr_dist)
78 static const T factor = (T)(1.0/(2.0*log((
double)10)));
81 return sqr_dist*log(sqr_dist)*factor;
94void find_nonrigid_transformation(
const mat<T>& points1,
95 const mat<T>& points2,
96 thin_plate_spline<T>& spline)
98 assert(points1.nrows() == 2 && points2.nrows() == 2);
99 assert(points1.ncols() == points2.ncols());
100 assert(points1.ncols() > 2);
102 int n = points1.ncols();
107 for(
int i = 0; i < n;i++)
108 for(
int j = 0; j < n;j++)
110 T sqr_dist = sqr_length(points1.col(i)-points1.col(j));
114 for(
int i = 0; i < n; i++)
117 L(i,n+1) = points1.col(i)(0);
118 L(i,n+2) = points1.col(i)(1);
120 L(n+1,i) = points1.col(i)(0);
121 L(n+2,i) = points1.col(i)(1);
124 for(
int i = n; i < n+3;i++)
126 for(
int j = n; j < n+3;j++)
134 for(
int i =0;i < n; i++)
139 V(n,0)=V(n,1)=V(n+1,0)=V(n+1,1)=V(n+2,0)=V(n+2,1)=0;
144 spline.controlpoints=points1;
145 spline.weights=W.sub_mat(0,0,n,2);
147 spline.affine_transformation =W.sub_mat(n,0,3,2);
158 mat<T> affine_transformation;
164 assert(p.
size() == 3);
166 r(0) = affine_transformation(0,0)
167 +affine_transformation(1,0)*p(0)
168 +affine_transformation(2,0)*p(1)
169 +affine_transformation(3,0)*p(2);
171 r(1) = affine_transformation(0,1)
172 +affine_transformation(1,1)*p(0)
173 +affine_transformation(2,1)*p(1)
174 +affine_transformation(3,1)*p(2);
176 r(2) = affine_transformation(0,2)
177 +affine_transformation(1,2)*p(0)
178 +affine_transformation(2,2)*p(1)
179 +affine_transformation(3,2)*p(2);
181 for(
unsigned i = 0;i < weights.
nrows();i++)
183 T u=length(p-controlpoints.
col(i));
184 r(0)+=weights(i,0)*u;
185 r(1)+=weights(i,1)*u;
186 r(2)+=weights(i,2)*u;
196 assert(points.
nrows() == 3);
197 for(
unsigned i = 0; i < points.
ncols(); i++)
211void find_nonrigid_transformation(
const mat<T>& points1,
212 const mat<T>& points2,
213 thin_hyper_plate_spline<T>& spline)
215 assert(points1.nrows() == 3 && points2.nrows()==3);
216 assert(points1.ncols() == points2.ncols());
217 assert(points1.nrows()==4);
219 int n = points1.ncols();
224 for(
int i = 0; i < n;i++)
225 for(
int j = 0; j < n;j++)
227 L(i,j)=length(points1.col(i)-points1.col(j));
230 for(
int i = 0; i < n; i++)
233 L(i,n+1) = points1.col(i)(0);
234 L(i,n+2) = points1.col(i)(1);
235 L(i,n+3) = points1.col(i)(2);
237 L(n+1,i) = points1.col(i)(0);
238 L(n+2,i) = points1.col(i)(1);
239 L(n+3,i) = points1.col(i)(2);
243 for(
int i = n; i < n+4;i++)
245 for(
int j = n; j < n+4;j++)
253 for(
int i =0;i < n; i++)
259 V(n,0)=V(n,1)=V(n,2)=V(n+1,0)=V(n+1,1)=V(n+1,2)=V(n+2,0)=V(n+2,1)=V(n+2,2)
260 =V(n+3,0)=V(n+3,1)=V(n+3,2)=0;
265 spline.controlpoints=points1;
266 spline.weights=W.sub_mat(0,0,n,3);
267 spline.affine_transformation =W.sub_mat(n,0,4,3);
277void apply_nonrigid_transformation(
const thin_plate_spline<T>& s, mat<T>& points)
279 assert(points.nrows() == 2);
280 for(
unsigned i = 0; i < points.ncols(); i++)
282 points.set_col(i,s.map_position(points.col(i)));
289void apply_nonrigid_transformation(
const thin_hyper_plate_spline<T>& s, mat<T>& points)
291 assert(points.nrows() == 3);
292 for(
unsigned i = 0; i < points.ncols(); i++)
294 points.set_col(i,s.map_position(points.col(i)));
A matrix type (full column major storage) The matrix can be loaded directly into OpenGL without need ...
unsigned ncols() const
number of columns
void set_col(unsigned j, const vec< T > &v)
set column j of the matrix to vector v
const vec< T > col(unsigned j) const
extract a column of the matrix as a vector
unsigned nrows() const
number of rows
unsigned size() const
number of elements
A thin hyperplate spline which represents 3d deformations 3d extension of the thin plate spline.
mat< T > map_positions(const mat< T > &points)
deform 3d points stored as columns of the matrix points
vec< T > map_position(const vec< T > &p)
deform 2d point p
A thin plate spline which represents 2d deformations See Fred L.
vec< T > map_position(const vec< T > &p)
deform a 2d point
static T U(const T &sqr_dist)
basis function
mat< T > map_positions(const mat< T > &points)
deform 2d points stored as columns of the matrix points