vgl_affine_coordinates.hxx
Go to the documentation of this file.
1 // This is core/vgl/vgl_affine_coordinates.hxx
2 #ifndef vgl_affine_coordinates_hxx_
3 #define vgl_affine_coordinates_hxx_
4 #include <cassert>
5 #include <cmath>
7 #include <vgl/vgl_vector_2d.h>
8 #include <vgl/vgl_vector_3d.h>
9 #include <vgl/vgl_tolerance.h>
10 // Points are all coplanar. The first three points in pts are the basis, pts[0] is the origin
11 template <class T>
12 void vgl_affine_coordinates_2d(std::vector<vgl_point_2d<T> > const& pts, std::vector<vgl_point_2d<T> >& affine_pts)
13 {
14  assert(pts.size()>=3);
15  vgl_vector_2d<T> v0 = pts[1]-pts[0];
16  vgl_vector_2d<T> v1 = pts[2]-pts[0];
17  T dv0v0 = dot_product(v0,v0);
18  T dv0v1 = dot_product(v0,v1);
19  T dv1v1 = dot_product(v1,v1);
20  T det = dv0v0*dv1v1 - dv0v1*dv0v1;
22  assert(fabs(det)>tol);
23  for(unsigned i =0; i<pts.size(); ++i){
24  vgl_vector_2d<T> vp = pts[i]-pts[0];
25  T dvpv0 = dot_product(vp, v0);
26  T dvpv1 = dot_product(vp, v1);
27  T alpha = (dvpv0*dv1v1-dv0v1*dvpv1)/det;
28  T beta = (dv0v0*dvpv1-dvpv0*dv0v1)/det;
29  affine_pts.push_back(vgl_point_2d<T>(alpha, beta));
30  }
31 }
32 // The first four points in pts are the basis.
33 template <class T>
34 void vgl_affine_coordinates_3d(std::vector<vgl_point_3d<T> > const& pts, std::vector<vgl_point_3d<T> >& affine_pts)
35 {
36  assert(pts.size()>=4);
37  vgl_vector_3d<T> v0 = pts[1]-pts[0];
38  vgl_vector_3d<T> v1 = pts[2]-pts[0];
39  vgl_vector_3d<T> v2 = pts[3]-pts[0];
40  T dv0v0 = dot_product(v0,v0);
41  T dv0v1 = dot_product(v0,v1);
42  T dv0v2 = dot_product(v0,v2);
43  T dv1v1 = dot_product(v1,v1);
44  T dv1v2 = dot_product(v1,v2);
45  T dv2v2 = dot_product(v2,v2);
46  T det = -dv0v2*dv0v2*dv1v1 + 2*dv0v1*dv0v2*dv1v2 - dv0v0*dv1v2*dv1v2 - dv0v1*dv0v1*dv2v2 + dv0v0*dv1v1*dv2v2;
48  assert(fabs(det)>tol);
49  for(unsigned i =0; i<pts.size(); ++i){
50  vgl_vector_3d<T> vp = pts[i]-pts[0];
51  T dvpv0 = dot_product(vp, v0);
52  T dvpv1 = dot_product(vp, v1);
53  T dvpv2 = dot_product(vp, v2);
54  T alpha = (-dv1v2*dv1v2*dvpv0 + dv1v1*dv2v2*dvpv0 + dv0v2*dv1v2*dvpv1 -
55  dv0v1*dv2v2*dvpv1 - dv0v2*dv1v1*dvpv2 + dv0v1*dv1v2*dvpv2)/det;
56  T beta = (dv0v2*dv1v2*dvpv0 - dv0v1*dv2v2*dvpv0 - dv0v2*dv0v2*dvpv1 +
57  dv0v0*dv2v2*dvpv1 + dv0v1*dv0v2*dvpv2 - dv0v0*dv1v2*dvpv2)/det;
58  T gamma = (-dv0v2*dv1v1*dvpv0 + dv0v1*dv1v2*dvpv0 + dv0v1*dv0v2*dvpv1 -
59  dv0v0*dv1v2*dvpv1 - dv0v1*dv0v1*dvpv2 + dv0v0*dv1v1*dvpv2)/det;
60  affine_pts.push_back(vgl_point_3d<T>(alpha, beta, gamma));
61  }
62 }
63 
64 // Two 2-d pointsets define the 3-d basis. The first four points in pts1 and pts2 are the basis.
65 template <class T>
66 void vgl_affine_coordinates_3d(std::vector<vgl_point_2d<T> > const& pts1, std::vector<vgl_point_2d<T> > const& pts2,
67  std::vector<vgl_point_3d<T> >& affine_pts)
68 {
69  unsigned n1 = pts1.size(), n2 = pts2.size();
70  assert(n1>=4);
71  assert(n1==n2);
73  //normalize 2-d pointsets
74  T x1=T(0), x2=T(0), y1 = T(0), y2 = T(0);
75  T dist_1 = T(0), dist_2 = T(0);
76  for(unsigned i = 0; i<n1;++i){
77  x1+=pts1[i].x(); y1+=pts1[i].y();
78  x2+=pts2[i].x(); y2+=pts2[i].y();
79  }
80  vgl_point_2d<T> cent_1(x1/n1, y1/n1), cent_2(x2/n1, y2/n1);
81  for(unsigned i = 0; i<n1;++i){
82  dist_1+=(pts1[i]-cent_1).length();
83  dist_2+=(pts2[i]-cent_2).length();
84  }
85  dist_1/=n1; dist_2/=n2;
86  std::vector<vgl_point_2d<T> > norm_pts1, norm_pts2;
87  for(unsigned i = 0; i<n1;++i){
88  vgl_point_2d<T> np1(pts1[i].x()-cent_1.x(), pts1[i].y()-cent_1.y());
89  if(dist_1>tol)
90  np1.set(np1.x()/dist_1, np1.y()/dist_1);
91  vgl_point_2d<T> np2(pts2[i].x()-cent_2.x(), pts2[i].y()-cent_2.y());
92  if(dist_2>tol)
93  np2.set(np2.x()/dist_2, np2.y()/dist_2);
94  norm_pts1.push_back(np1);
95  norm_pts2.push_back(np2);
96  }
97  // 2-d basis for pts1
98  vgl_vector_2d<T> v01 = norm_pts1[1]-norm_pts1[0];
99  vgl_vector_2d<T> v11 = norm_pts1[2]-norm_pts1[0];
100  T dv01v01 = dot_product(v01,v01);
101  T dv01v11 = dot_product(v01,v11);
102  T dv11v11 = dot_product(v11,v11);
103  T det1 = dv01v01*dv11v11 - dv01v11*dv01v11;
104  assert(fabs(det1)>tol);
105  //affine coordinates for V2' (pts1)
106  vgl_vector_2d<T> v21 = norm_pts1[3]-norm_pts1[0];
107  T dv21v01 = dot_product(v01, v21);
108  T dv21v11 = dot_product(v11, v21);
109  T alpha_1 = (dv21v01*dv11v11-dv01v11*dv21v11)/det1;
110  T beta_1 = (dv01v01*dv21v11-dv21v01*dv01v11)/det1;
111  // 2-d basis for pts2
112  vgl_vector_2d<T> v02 = norm_pts2[1]-norm_pts2[0];
113  vgl_vector_2d<T> v12 = norm_pts2[2]-norm_pts2[0];
114  T dv02v02 = dot_product(v02,v02);
115  T dv02v12 = dot_product(v02,v12);
116  T dv12v12 = dot_product(v12,v12);
117  T det2 = dv02v02*dv12v12 - dv02v12*dv02v12;
118  assert(fabs(det2)>tol);
119  //affine coordinates for V2 (pts2)
120  vgl_vector_2d<T> v22 = norm_pts2[3]-norm_pts2[0];
121  T dv22v02 = dot_product(v02, v22);
122  T dv22v12 = dot_product(v12, v22);
123  T alpha_2 = (dv22v02*dv12v12-dv02v12*dv22v12)/det2;
124  T beta_2 = (dv02v02*dv22v12-dv22v02*dv02v12)/det2;
125  //length of V2'V2 in pts2
126  vgl_vector_2d<T> V2pV2 = (alpha_2-alpha_1)*v02 + (beta_2-beta_1)*v12;
127  T L2 = V2pV2.length();
128  assert(L2>tol);// otherwise the views are the same or the basis points are coplanar
129  //determine sign of L2
130  T s2 = (alpha_2-alpha_1), fs2 = fabs(s2);
131  if(fs2<tol){
132  s2 = (beta_2-beta_1);
133  fs2 = fabs(s2);
134  if(fs2<tol){
135  s2 = 1.0;
136  fs2 = 1.0;
137  }
138  }
139  L2 *= s2/fs2;
140  for(unsigned i = 0; i<n1; ++i){
141  //affine coordinates for p in pts1
142  vgl_vector_2d<T> vp1 = norm_pts1[i]-norm_pts1[0];
143  T dvp1v01 = dot_product(vp1, v01);
144  T dvp1v11 = dot_product(vp1, v11);
145  T alpha_p1 = (dvp1v01*dv11v11-dv01v11*dvp1v11)/det1;
146  T beta_p1 = (dv01v01*dvp1v11-dvp1v01*dv01v11)/det1;
147  //affine coordinates for p in pts2
148  vgl_vector_2d<T> vp2 = norm_pts2[i]-norm_pts2[0];
149  T dvp2v02 = dot_product(vp2, v02);
150  T dvp2v12 = dot_product(vp2, v12);
151  T alpha_p2 = (dvp2v02*dv12v12-dv02v12*dvp2v12)/det2;
152  T beta_p2 = (dv02v02*dvp2v12-dvp2v02*dv02v12)/det2;
153  // length of PP' in pts 2
154  vgl_vector_2d<T> PpP = (alpha_p2-alpha_p1)*v02 + (beta_p2-beta_p1)*v12;
155  T Lp = PpP.length();
156  //determine sign of PP'
157  T sp = (alpha_p2-alpha_p1), fsp = fabs(sp);
158  if(fsp<tol){
159  sp = (beta_p2-beta_p1);
160  fsp = fabs(sp);
161  if(fsp<tol){
162  sp = 1.0;
163  fsp= 1.0;
164  }
165  }
166  Lp *= sp/fsp;
167  T gamma_p = Lp/L2;
168  T alpha_p = (alpha_p1-gamma_p*alpha_1);
169  T beta_p = (beta_p1-gamma_p*beta_1);
170  affine_pts.push_back(vgl_point_3d<T>(alpha_p, beta_p, gamma_p));
171  }
172 }
173 #undef VGL_AFFINE_COORDINATES_INSTANTIATE
174 #define VGL_AFFINE_COORDINATES_INSTANTIATE(T) \
175  template void vgl_affine_coordinates_2d(std::vector<vgl_point_2d<T> > const& pts, std::vector<vgl_point_2d<T> >& affine_pts); \
176  template void vgl_affine_coordinates_3d(std::vector<vgl_point_3d<T> > const& pts, std::vector<vgl_point_3d<T> >& affine_pts); \
177  template void vgl_affine_coordinates_3d(std::vector<vgl_point_2d<T> > const& pts1, std::vector<vgl_point_2d<T> > const& pts2, \
178  std::vector<vgl_point_3d<T> >& affine_pts)
179 #endif // vgl_affine_coordinates_h_
T dot_product(v const &a, v const &b)
dot product or inner product of two vectors.
Direction vector in Euclidean 2D space, templated by type of element.
Definition: vgl_fwd.h:12
direction vector in Euclidean 3D space
double length() const
Return the length of this vector.
double length(v const &a)
Return the length of a vector.
Definition: vgl_vector_2d.h:94
void vgl_affine_coordinates_3d(std::vector< vgl_point_3d< T > > const &pts, std::vector< vgl_point_3d< T > > &affine_pts)
#define vp(os, v, s)
void set(Type px, Type py)
Set x and y.
Definition: vgl_point_2d.h:79
Type & y()
Definition: vgl_point_2d.h:72
direction vector in Euclidean 2D space
void vgl_affine_coordinates_2d(std::vector< vgl_point_2d< T > > const &pts, std::vector< vgl_point_2d< T > > &affine_pts)
Direction vector in Euclidean 3D space, templated by type of element.
Definition: vgl_fwd.h:13
Computes 2-d and 3-d affine coordinates of point sets.
Type & x()
Definition: vgl_point_2d.h:71