2 #ifndef vgl_quadric_3d_hxx_ 3 #define vgl_quadric_3d_hxx_ 9 #define RANK_FACTOR 100000 10 #define DET_FACTOR 100 11 static const char* quadric_class_name[] =
15 "imaginary_ellipsoid",
16 "hyperboloid_of_one_sheet",
17 "hyperboloid_of_two_sheets",
19 "imaginary_elliptic_cone",
20 "elliptic_paraboloid",
21 "hyperbolic_paraboloid",
22 "real_elliptic_cylinder",
23 "imaginary_elliptic_cylinder",
24 "hyperbolic_cylinder",
25 "real_intersecting_planes",
26 "imaginary_intersecting_planes",
28 "real_parallel_planes",
29 "imaginary_parallel_planes",
37 for(
size_t i = 1; i<num_quadric_types; i++){
38 if(quadric_class_name[i]==name)
39 return static_cast<vgl_quadric_type>(i);
50 this->
set(coeff[0],coeff[1],coeff[2],coeff[3],coeff[4],coeff[5],coeff[6],coeff[7],coeff[8],coeff[9]);
61 this->
set(Q[0][0], Q[1][1], Q[2][2], T(2)*Q[0][1], T(2)*Q[0][2],
62 T(2)*Q[1][2], T(2)*Q[0][3], T(2)*Q[1][3], T(2)*Q[2][3], Q[3][3]);
66 std::vector<std::vector<T> >
const& H){
70 std::vector<std::vector<T> > R(3,std::vector<T>(3, T(0)));
71 std::vector<std::vector<T> > Qg(4, std::vector<T>(4, T(0)));
72 std::vector<std::vector<T> > qr(3,std::vector<T>(3, T(0)));
73 std::vector<T> qu(3,T(0)), t(3, T(0)), c(3,T(0)), Rc(3,T(0)),
74 RqRt(3, T(0)), Rtrt(3,T(0));
75 for(
size_t r = 0; r<3; ++r){
77 qu[r] = canonical_quadric[r][r];
78 c[r]=canonical_quadric[r][3];
79 for(
size_t c = 0; c<3; ++c)
82 qr[0][0]=R[0][0]*qu[0]*R[0][0] +R[0][1]*qu[1]*R[0][1] +R[0][2]*qu[2]*R[0][2];
83 qr[1][0]=R[1][0]*qu[0]*R[0][0] +R[1][1]*qu[1]*R[0][1] +R[1][2]*qu[2]*R[0][2];
84 qr[2][0]=R[2][0]*qu[0]*R[0][0] +R[2][1]*qu[1]*R[0][1] +R[2][2]*qu[2]*R[0][2];
85 qr[1][1]=R[1][0]*qu[0]*R[1][0] +R[1][1]*qu[1]*R[1][1] +R[1][2]*qu[2]*R[1][2];
86 qr[2][1]=R[2][0]*qu[0]*R[1][0] +R[2][1]*qu[1]*R[1][1] +R[2][2]*qu[2]*R[1][2];
87 qr[2][2]=R[2][0]*qu[0]*R[2][0] +R[2][1]*qu[1]*R[2][1] +R[2][2]*qu[2]*R[2][2];
88 qr[0][1]=qr[1][0]; qr[0][2]=qr[2][0]; qr[2][1]=qr[1][2];
90 Rc[0] = R[0][0]*c[0] + R[0][1]*c[1] + R[0][2]*c[2];
91 Rc[1] = R[1][0]*c[0] + R[1][1]*c[1] + R[1][2]*c[2];
92 Rc[2] = R[2][0]*c[0] + R[2][1]*c[1] + R[2][2]*c[2];
94 Rtrt[0]=R[0][0]*t[0] + R[1][0]*t[1] + R[2][0]*t[2];
95 Rtrt[1]=R[0][1]*t[0] + R[1][1]*t[1] + R[2][1]*t[2];
96 Rtrt[2]=R[0][2]*t[0] + R[1][2]*t[1] + R[2][2]*t[2];
98 RqRt[0] = (qr[0][0]*t[0] + qr[0][1]*t[1] + qr[0][2]*t[2]);
99 RqRt[1] = (qr[1][0]*t[0] + qr[1][1]*t[1] + qr[1][2]*t[2]);
100 RqRt[2] = (qr[2][0]*t[0] + qr[2][1]*t[1] + qr[2][2]*t[2]);
102 T tRqRt = t[0]*RqRt[0] + t[1]*RqRt[1] + t[2]*RqRt[2];
103 T tRc = t[0]*Rc[0] + t[1]*Rc[1] + t[2]*Rc[2];
104 T ctrRtrt = c[0]*Rtrt[0] + c[1]*Rtrt[1] + c[2]*Rtrt[2];
106 Qg[0][3] = Rc[0]-RqRt[0];
107 Qg[1][3] = Rc[1]-RqRt[1];
108 Qg[2][3] = Rc[2]-RqRt[2];
109 Qg[3][0] = Qg[0][3]; Qg[3][1] = Qg[1][3]; Qg[3][2] = Qg[2][3];
111 for(
size_t r = 0; r<3; ++r)
114 Qg[1][0] = qr[1][0]; Qg[2][0] = qr[2][0]; Qg[2][1] = qr[2][1];
115 Qg[0][1] = Qg[1][0]; Qg[0][2] = Qg[2][0]; Qg[1][2] = Qg[2][1];
116 Qg[3][3] = canonical_quadric[3][3]- ctrRtrt + tRqRt - tRc;
121 std::vector<std::vector<T> >
const& H){
122 std::vector<std::vector<T> > Qg(4, std::vector<T>(4, T(0)));
123 Qg[0][0] = diag[0];Qg[1][1] = diag[1];Qg[2][2] = diag[2];Qg[3][3] = diag[3];
128 a_ = a; b_ = b; c_ = c; d_ = d; e_ = e; f_ = f;
129 g_ = g; h_ = h; i_ = i; j_ = j;
130 this->compute_type();
134 this->set(Q[0][0], Q[1][1], Q[2][2], T(2)*Q[0][1],
135 T(2)*Q[0][2], T(2)*Q[1][2], T(2)*Q[0][3],
136 T(2)*Q[1][3], T(2)*Q[2][3], Q[3][3]);
140 std::vector<std::vector<T> > Q(4,std::vector<T>(4,T(0)));
141 Q[0][0]=a_;Q[1][1]=b_; Q[2][2]=c_; Q[3][3]=j_;
142 Q[0][1]= Q[1][0]=d_/T(2); Q[0][2]= Q[2][0]=e_/T(2);
143 Q[0][3]= Q[3][0]=g_/T(2); Q[1][2]= Q[2][1]=f_/T(2);
144 Q[1][3]= Q[3][1]=h_/T(2); Q[3][2]=Q[2][3] =i_/T(2);
149 T x = pt.
x(), y = pt.
y(), z = pt.
z(), w = pt.
w();
150 T algebraic_dist = a_*x*x + b_*y*y + c_*z*z + d_*x*y + e_*x*z + f_*y*z + g_*x*w + h_*y*w + i_*z*w +j_*w*w;
151 T grad_x = (T(2)*a_*x + d_*y * e_*z + g_*w);
152 T grad_y = (T(2)*b_*y + d_*x * f_*z + h_*w);
153 T grad_z = (T(2)*c_*z + e_*x * f_*y + i_*w );
154 T grad_mag_sqrd = grad_x*grad_x + grad_y*grad_y + grad_z*grad_z;
155 T sampson_dist_sqrd = (algebraic_dist*algebraic_dist)/grad_mag_sqrd;
156 return sqrt(sampson_dist_sqrd);
160 T d = this->sampson_dist(pt);
167 if(!(type_ == real_ellipsoid || type_==real_elliptic_cone ||
168 type_ == hyperboloid_of_one_sheet || type_ == hyperboloid_of_two_sheets)
177 T upper_det = a_*b_*c_ - a_*h*f_*h*f_ - h*d_*h*d_*c_ + d_*h*f_*h*e_*h + e_*h*d_*h*f_*h - e_*h*b_*e_*h;
181 T det_inv = T(1)/upper_det;
184 d[0] = (b_*c_ -f_*f_*h*h)*det_inv;
185 d[1] = (f_*h*e_*h -c_*d_*h)*det_inv;
186 d[2] = (d_*h*f_*h -e_*h*b_)*det_inv;
187 d[3] = (f_*h*e_*h -d_*h*c_)*det_inv;
188 d[4] = (a_*c_ -e_*h*e_*h)*det_inv;
189 d[5] = (d_*h*e_*h -f_*h*a_)*det_inv;
190 d[6] = (d_*h*f_*h -b_*e_*h)*det_inv;
191 d[7] = (d_*h*e_*h -a_*f_*h)*det_inv;
192 d[8] = (a_*b_ -d_*h*d_*h)*det_inv;
198 T tx = h*(d[0]*g_ + d[1]*h_ + d[2]*i_);
199 T ty = h*(d[3]*g_ + d[4]*h_ + d[5]*i_);
200 T tz = h*(d[6]*g_ + d[7]*h_ + d[8]*i_);
201 center.
set(-tx, -ty, -tz);
208 std::vector<std::vector<T> > Q = this->coef_matrix();
209 T m[4][4]; T
l[4]; T vc[4][4];
210 for(
size_t r = 0; r<4; ++r)
211 for(
size_t c = 0; c<4; ++c)
214 T mu[3][3]; T lu[3]; T vcu[3][3];
215 for(
size_t r = 0; r<3; ++r)
216 for(
size_t c = 0; c<3; ++c)
220 eigen<T, 4>( m,
l, vc);
224 std::vector<T> eig_vals;
226 eig_vals.push_back(fabs(i));
230 std::sort(eig_vals.begin(), eig_vals.end(), std::greater<T>());
231 T largest_eig_val = eig_vals[0];
233 for (
size_t i = 0; i < 4; ++i) {
234 eig_vals[i] /= largest_eig_val;
235 if (eig_vals[i] > rank_tol)
238 std::vector<T> non_zero_vals;
239 for(
size_t i = 0 ; i<4; ++i){
240 if(fabs(lv[i])/largest_eig_val <= rank_tol)
242 non_zero_vals.push_back(lv[i]);
245 size_t nz = non_zero_vals.size();
250 sign =(non_zero_vals[0]>z && non_zero_vals[1]>z)||
251 (non_zero_vals[0]<z && non_zero_vals[1]<z);
253 sign = (non_zero_vals[0]>z && non_zero_vals[1]>z && non_zero_vals[2]>z) ||
254 (non_zero_vals[0]<z&& non_zero_vals[1]< z&& non_zero_vals[2]< z);
256 sign=(non_zero_vals[0]>z&&non_zero_vals[1]>z&&non_zero_vals[2]>z&&non_zero_vals[3]>z)||
257 (non_zero_vals[0]<z&& non_zero_vals[1]< z&& non_zero_vals[2]< z&& non_zero_vals[3]< z);
262 eigen<T, 3>( mu, lu, vcu);
263 std::vector<T> upper_eig_vals;
265 upper_eig_vals.push_back(fabs(i));
268 std::sort(upper_eig_vals.begin(), upper_eig_vals.end(), std::greater<T>());
269 largest_eig_val = upper_eig_vals[0];
271 for (
size_t i = 0; i < 3; ++i) {
272 upper_eig_vals[i] /= largest_eig_val;
273 if (upper_eig_vals[i] > rank_tol){
277 std::vector<T> non_zero_uvals;
278 for(
size_t i = 0 ; i<3; ++i){
279 if(fabs(lvu[i])/largest_eig_val <= rank_tol)
281 non_zero_uvals.push_back(lvu[i]);
283 nz = non_zero_uvals.size();
288 signu =(non_zero_uvals[0]>z && non_zero_uvals[1]>z)||
289 (non_zero_uvals[0]<z && non_zero_uvals[1]<z);
291 signu = (non_zero_uvals[0]>z && non_zero_uvals[1]>z && non_zero_uvals[2]>z) ||
292 (non_zero_uvals[0]<z&& non_zero_uvals[1]< z&& non_zero_uvals[2]< z);
295 T det = Q[0][0]*Q[1][1]*Q[2][2]*Q[3][3]
296 - Q[0][0]*Q[1][1]*Q[3][2]*Q[2][3]
297 - Q[0][0]*Q[2][1]*Q[1][2]*Q[3][3]
298 + Q[0][0]*Q[2][1]*Q[3][2]*Q[1][3]
299 + Q[0][0]*Q[3][1]*Q[1][2]*Q[2][3]
300 - Q[0][0]*Q[3][1]*Q[2][2]*Q[1][3]
301 - Q[1][0]*Q[0][1]*Q[2][2]*Q[3][3]
302 + Q[1][0]*Q[0][1]*Q[3][2]*Q[2][3]
303 + Q[1][0]*Q[2][1]*Q[0][2]*Q[3][3]
304 - Q[1][0]*Q[2][1]*Q[3][2]*Q[0][3]
305 - Q[1][0]*Q[3][1]*Q[0][2]*Q[2][3]
306 + Q[1][0]*Q[3][1]*Q[2][2]*Q[0][3]
307 + Q[2][0]*Q[0][1]*Q[1][2]*Q[3][3]
308 - Q[2][0]*Q[0][1]*Q[3][2]*Q[1][3]
309 - Q[2][0]*Q[1][1]*Q[0][2]*Q[3][3]
310 + Q[2][0]*Q[1][1]*Q[3][2]*Q[0][3]
311 + Q[2][0]*Q[3][1]*Q[0][2]*Q[1][3]
312 - Q[2][0]*Q[3][1]*Q[1][2]*Q[0][3]
313 - Q[3][0]*Q[0][1]*Q[1][2]*Q[2][3]
314 + Q[3][0]*Q[0][1]*Q[2][2]*Q[1][3]
315 + Q[3][0]*Q[1][1]*Q[0][2]*Q[2][3]
316 - Q[3][0]*Q[1][1]*Q[2][2]*Q[0][3]
317 - Q[3][0]*Q[2][1]*Q[0][2]*Q[1][3]
318 + Q[3][0]*Q[2][1]*Q[1][2]*Q[0][3];
344 if(r3==1&&r4==1) type_ = coincident_planes;
345 else if(r3== 3 &&r4== 4 &>_0&&signu) type_ = imaginary_ellipsoid;
346 else if(r3== 3 &&r4== 4 &&!gt_0&&signu) type_ = real_ellipsoid;
347 else if(r3== 3 &&r4== 3 &&signu) type_ = imaginary_elliptic_cone;
348 else if(r3== 3 &&r4== 3 &&!signu) type_ = real_elliptic_cone;
349 else if(r3== 2 &&r4== 3 &&signu&&sign) type_ = imaginary_elliptic_cylinder;
350 else if(r3== 2 &&r4== 3 &&signu&&!sign) type_ = real_elliptic_cylinder;
351 else if(r3== 2 &&r4== 4 &&!gt_0&&signu) type_ = elliptic_paraboloid;
352 else if(r3== 2 &&r4== 3 &&!signu) type_ = hyperbolic_cylinder;
353 else if(r3== 2 &&r4== 4 &>_0&&!signu) type_ = hyperbolic_paraboloid;
354 else if(r3== 3 &&r4== 4 &>_0&&!signu) type_ = hyperboloid_of_one_sheet;
355 else if(r3== 3 &&r4== 4 &&!gt_0&&!signu) type_ = hyperboloid_of_two_sheets;
356 else if(r3== 2 &&r4== 2 &&signu) type_ = imaginary_intersecting_planes;
357 else if(r3== 2 &&r4== 2 &&!signu) type_ = real_intersecting_planes;
358 else if(r3== 1 &&r4== 3 ) type_ = parabolic_cylinder;
359 else if(r3== 1 &&r4== 2 &&sign) type_ = imaginary_parallel_planes;
360 else if(r3== 1 &&r4== 2 &&!sign) type_ = real_parallel_planes;
365 if ( type() != that.
type() )
return false;
366 T mag_coefs = (fabs(a_)+fabs(b_)+fabs(c_)+fabs(d_)+fabs(e_)+fabs(f_)+fabs(g_)+fabs(h_)+fabs(i_)+fabs(j_))/T(10);
367 T mag_coefs_that = (fabs(that.
a())+fabs(that.
b())+fabs(that.
c())+fabs(that.
d())+fabs(that.
e())+fabs(that.
f())+fabs(that.
g())+fabs(that.
h())+fabs(that.
i())+fabs(that.
j()))/T(10);
369 return fabs(a_*mag_coefs_that - that.
a()*mag_coefs)<tol &&
370 fabs(b_*mag_coefs_that - that.
b()*mag_coefs)<tol &&
371 fabs(c_*mag_coefs_that - that.
c()*mag_coefs)<tol &&
372 fabs(d_*mag_coefs_that - that.
d()*mag_coefs)<tol &&
373 fabs(e_*mag_coefs_that - that.
e()*mag_coefs)<tol &&
374 fabs(f_*mag_coefs_that - that.
f()*mag_coefs)<tol &&
375 fabs(g_*mag_coefs_that - that.
g()*mag_coefs)<tol &&
376 fabs(h_*mag_coefs_that - that.
h()*mag_coefs)<tol &&
377 fabs(i_*mag_coefs_that - that.
i()*mag_coefs)<tol &&
378 fabs(j_*mag_coefs_that - that.
j()*mag_coefs)<tol;
382 std::vector<std::vector<T> > Q = this->coef_matrix();
383 T mu[3][3]; T lu[3]; T vcu[3][3];
384 for(
size_t r = 0; r<3; ++r)
385 for(
size_t c = 0; c<3; ++c)
388 eigen<T, 3>( mu, lu, vcu);
390 eigenvalues.push_back(i);
392 eigenvectors.resize(3, std::vector<T>(3, T(0)));
393 for(
size_t r = 0; r<3; ++r)
394 for(
size_t c = 0; c<3; ++c)
395 eigenvectors[r][c]=vcu[r][c];
399 diag.resize(4, T(0));
400 H.resize(4, std::vector<T>(4, T(0)));
402 bool good = this->center(cent);
405 H[0][3] = cent.
x(); H[1][3] = cent.
y(); H[2][3] = cent.
z();
408 T centered_j = j_ + (cent.
x()*g_ + cent.
y()*h_ + cent.
z()*i_)/T(2);
410 std::vector<T> eigenvalues;
411 std::vector<std::vector<T> > eigenvectors;
412 this->upper_3x3_eigensystem(eigenvalues, eigenvectors);
414 for(
size_t r = 0; r<3; ++r)
415 for(
size_t c = 0; c<3; ++c)
416 H[r][c]=eigenvectors[c][r];
418 for(
size_t i = 0; i<3; ++i)
419 diag[i]=eigenvalues[i];
420 diag[3] = centered_j;
425 std::vector<std::vector<T> > ret(4, std::vector<T>(4, T(0)));
426 std::vector<T> tr(3, T(0));
427 if(type_ == no_type){
428 std::cout <<
"Invalid quadric" << std::endl;
432 if(type_ == real_ellipsoid || type_==real_elliptic_cone ||
433 type_ == hyperboloid_of_one_sheet || type_ == hyperboloid_of_two_sheets){
435 if(canonical_central_quadric(diag, H)){
436 for(
size_t i = 0; i<4; ++i)
440 std::cout <<
"Shouldn't happen! Inconsistent quadric type assignment " << type_by_number(type_) << std::endl;
445 H.resize(4, std::vector<T>(4, T(0)));
448 std::vector<T> lambda, sorted_eigenvalues(3,T(0));
449 std::vector<std::vector<T> > E;
450 this->upper_3x3_eigensystem(lambda, E);
453 for(
size_t r = 0; r<3; ++r)
454 for(
size_t c = 0; c<3; ++c)
458 for(
size_t i = 0; i<3; ++i)
459 sorted_eigenvalues[i]=fabs(lambda[i]);
460 std::sort(sorted_eigenvalues.begin(), sorted_eigenvalues.end(), std::greater<T>());
461 T largest_eigenval = sorted_eigenvalues[0];
464 for(
size_t i = 0; i<3; ++i)
465 if(fabs(lambda[i]/largest_eigenval) < rtol){
469 if(rank == 3 || rank == 0){
470 std::cout <<
"Shouldn't happen! rank == 3 or rank ==0 " << type_by_number(type_) << std::endl;
474 for(
size_t i = 0; i<3; ++i)
475 ret[i][i] = lambda[i];
482 T gp = (E[0][0]*g_ + E[0][1]*h_ + E[0][2]*i_)/T(2);
483 T hp = (E[1][0]*g_ + E[1][1]*h_ + E[1][2]*i_)/T(2);
484 T ip = (E[2][0]*g_ + E[2][1]*h_ + E[2][2]*i_)/T(2);
486 std::vector<bool> t_known(3,
false);
488 if(lambda[0] != T(0)){
489 tr[0] = gp/lambda[0];
496 if(lambda[1] != T(0)){
497 tr[1] = hp/lambda[1];
504 if(lambda[2] != T(0)){
505 tr[2] = ip/lambda[2];
523 tr[0] = (j_ - sum)/(T(2)*gp);
525 }
else if(!t_known[1]){
531 tr[1] = (j_ - sum)/(T(2)*hp);
533 }
else if(!t_known[2]){
539 tr[2] = (j_ - sum)/(T(2)*ip);
549 if(!t_known[0]&&!t_known[1]){
550 if((fabs(gp) < rtol)&& (fabs(hp) < rtol)){
552 }
else if((fabs(gp) >= rtol) && (fabs(hp) >= rtol)){
553 T temp = (j_ - sum)/(T(2)*(gp+hp));
554 tr[0] = temp; tr[1] = temp;
555 }
else if((fabs(gp) >= rtol)&&(fabs(hp) < rtol)){
556 tr[0] = (j_ - sum)/(T(2)*gp);
559 }
else if((fabs(gp) < rtol)&&(fabs(hp) >= rtol)){
560 tr[1] = (j_ - sum)/(T(2)*hp);
564 }
else if(!t_known[0]&&!t_known[2]){
565 if((fabs(gp) < rtol)&& (fabs(ip) < rtol)){
567 }
else if((fabs(gp) >= rtol) && (fabs(ip) >= rtol)){
568 T temp = (j_ - sum)/(T(2)*(gp+ip));
569 tr[0] = temp; tr[2] = temp;
570 }
else if((fabs(gp) >= rtol)&&(fabs(ip) < rtol)){
571 tr[0] = (j_ - sum)/(T(2)*gp);
574 }
else if((fabs(gp) < rtol)&&(fabs(ip) >= rtol)){
575 tr[2] = (j_ - sum)/(T(2)*ip);
579 }
else if(!t_known[1]&&!t_known[2]){
580 if((fabs(hp) < rtol) && (fabs(ip) < rtol)){
582 }
else if((fabs(hp) >= rtol) && (fabs(ip) >= rtol)){
583 T temp = (j_ - sum)/(T(2)*(hp+ip));
584 tr[1] = temp; tr[2] = temp;
585 }
else if((fabs(hp) >= rtol) && (fabs(ip) < rtol)){
586 tr[1] = (j_ - sum)/(T(2)*hp);
589 }
else if((fabs(hp) < rtol) && (fabs(ip) >= rtol)){
590 tr[2] = (j_ - sum)/(T(2)*ip);
596 H[0][3] = -(E[0][0]*tr[0] + E[1][0]*tr[1] + E[2][0]*tr[2]);
597 H[1][3] = -(E[0][1]*tr[0] + E[1][1]*tr[1] + E[2][1]*tr[2]);
598 H[2][3] = -(E[0][2]*tr[0] + E[1][2]*tr[1] + E[2][2]*tr[2]);
603 template <
class R,
size_t n>
604 void twst(R m[n][n], R c, R s,
int i,
int j){
607 R t = m[i][k]*c+ m[j][k]*s;
608 m[j][k] = -s*(m[i][k])+c*(m[j][k]); m[i][k] = t;
612 template <
class R,
size_t n>
613 void eigen(R m[n][n], R
l[n], R vc[n][n]){
626 R mod = 0;
int i=0, j=0;
627 {
int k=n;
while(k--){
630 R q = fabs(m2[k][m]);
631 if(q > mod) {mod=q; i=k; j=m;
636 if(mod < 0.00000000001)
break;
638 if(
db) std::cout <<
"mii=" << m2[i][i] <<
"mjj=" << m2[j][j] << std::endl;
639 R th = 0.5*atan(2*m2[i][j]/(m2[i][i] - m2[j][j]));
641 if(
db) std::cout <<
"th=" << th <<
"i" << i <<
"j=" << j << std::endl;
643 R c = cos(th), s = sin(th);
644 {
int k=n;
while(k--){
645 R t = c*m2[k][i] + s*m2[k][j];
646 m2[k][j] = -s*m2[k][i] + c*m2[k][j]; m2[k][i]=t;
649 twst<R,n>( m2, c, s, i, j);
650 twst<R,n>( vc, c, s, i, j);
655 while(j--)
l[j] = m2[j][j];
661 os <<
"vgl_quadric_3d: a=" << q.
a() <<
" b=" << q.
b() <<
" c=" << q.
c() <<
" d=" 662 << q.
d() <<
" e=" << q.
e()<<
" f=" << q.
f() <<
" g=" << q.
g()
663 <<
" h=" << q.
h() <<
" i=" << q.
i() <<
" j=" << q.
j() << std::endl;
669 T a,b,c,d,e,f,g,h,i,j;
670 ist >> a >> b >> c >> d >> e >> f >> g >> h >> i >> j;
671 q.
set(a, b, c, d, e, f, g, h , i, j);
674 #undef VGL_QUADRIC_3D_INSTANTIATE 675 #define VGL_QUADRIC_3D_INSTANTIATE(T) \ 676 template class vgl_quadric_3d<T>; \ 677 template std::ostream& operator<<(std::ostream&, const vgl_quadric_3d<T>&); \ 678 template std::istream& operator>>(std::istream&, vgl_quadric_3d<T>&) void twst(R m[n][n], R c, R s, int i, int j)
T h() const
Returns the coefficient of .
bool operator==(vgl_quadric_3d< T > const &c) const
comparison operator.
T b() const
Returns the coefficient of .
bool center(vgl_point_3d< T > ¢er) const
if the upper 3x3 submatrix of Q is full rank then the center of the quadric can be defined.
vgl_quadric_type type() const
bool on(vgl_homg_point_3d< T > const &pt, T tol=T(0)) const
Returns true if the point pt belongs to the quadric surface.
T c() const
Returns the coefficient of .
T j() const
Returns the coefficient of .
std::vector< std::vector< T > > coef_matrix() const
return a matrix of quadric coefficients of the form:.
void upper_3x3_eigensystem(std::vector< T > &eigenvalues, std::vector< std::vector< T > > &eigenvectors) const
: eigenvalues and eigenvectors of the upper 3x3 quadric matrix.
std::vector< std::vector< T > > canonical_quadric(std::vector< std::vector< T > > &H) const
The quadric coefficient matrix in the canonical frame, whether or not the quadric is central.
std::ostream & operator<<(std::ostream &s, vgl_orient_box_3d< Type > const &p)
Write box to stream.
Represents a homogeneous 3D point.
A 2nd order algebraic surface in 3-d.
static vgl_quadric_type type_by_name(std::string const &name)
Returns the internal enum value corresponding to the string argument.
T e() const
Returns the coefficient of .
void eigen(R m[n][n], R l[n], R vc[n][n])
void set(T a, T b, T c, T d, T e, T f, T g, T h, T i, T j)
set or reset the quadric using polynomial coefficients.
T sampson_dist(vgl_homg_point_3d< T > const &pt) const
Sampson distance d_sampson(p) = ||p^t Q p||^2/||grad(p*t Q p)||^2.
T f() const
Returns the coefficient of .
T d() const
Returns the coefficient of .
std::istream & operator>>(std::istream &is, vgl_orient_box_3d< Type > &p)
Read box from stream.
void compute_type()
set quadric type from polynomial coefficients and store in member type_.
void set(Type px, Type py, Type pz)
Set x, y and z.
T a() const
Returns the coefficient of .
T g() const
Returns the coefficient of .
T i() const
Returns the coefficient of .
bool canonical_central_quadric(std::vector< T > &diag, std::vector< std::vector< T > > &H) const
: The quadric in its canonical frame if the center is defined, i.e. the upper 3x3 quadric matrix is f...
static std::string type_by_number(vgl_quadric_type const &type)
Converts the quadric type from enum (internal representation) to string.