11 # include <vcl_msvc_warnings.h> 15 static const char *vgl_conic_name[] =
24 "real intersecting lines",
25 "complex intersecting lines",
26 "real parallel lines",
27 "complex parallel lines",
41 for (
int i = (
int)no_type; i < num_conic_types; i++)
42 if (name == vgl_conic_name[i])
50 if (type <= 0 || type >= num_conic_types)
return vgl_conic_name[no_type];
51 return vgl_conic_name[type];
59 if ( type() != that.
type() )
return false;
60 return a()*that.
b() == b()*that.
a()
61 && a()*that.
c() == c()*that.
a()
62 && a()*that.
d() == d()*that.
a()
63 && a()*that.
e() == e()*that.
a()
64 && a()*that.
f() == f()*that.
a()
65 && b()*that.
c() == c()*that.
b()
66 && b()*that.
d() == d()*that.
b()
67 && b()*that.
e() == e()*that.
b()
68 && b()*that.
f() == f()*that.
b()
69 && c()*that.
d() == d()*that.
c()
70 && c()*that.
e() == e()*that.
c()
71 && c()*that.
f() == f()*that.
c()
72 && d()*that.
e() == e()*that.
d()
73 && d()*that.
f() == f()*that.
d()
74 && e()*that.
f() == f()*that.
e();
82 a_ = ta; b_ = tb; c_ = tc; d_ = td; e_ = te; f_ = tf;
83 set_type_from_equation();
90 : type_(no_type), a_(co[0]), b_(co[1]), c_(co[2]), d_(co[3]), e_(co[4]), f_(co[5])
99 : type_(no_type), a_(ta), b_(tb), c_(tc), d_(td), e_(te), f_(tf)
110 b_ = -2*co.
x()*co.
y();
114 theta /= std::sqrt(co.
x()*co.
x()+co.
y()*co.
y());
115 d_ = -2*a_*rx - b_*ry + 2*theta*co.
x();
116 e_ = -2*c_*ry - b_*rx + 2*theta*co.
y();
118 f_ = -a_*rx*rx-b_*rx*ry-c_*ry*ry-d_*rx-e_*ry;
121 rx = (rx < 0) ? (-rx*rx) : rx*rx;
122 ry = (ry < 0) ? (-ry*ry) : ry*ry;
124 double ct = std::cos(-theta);
125 double st = std::sin(-theta);
128 a_ = T(rx*st*st + ry*ct*ct);
129 b_ = T(2*(rx-ry)*ct*st);
130 c_ = T(rx*ct*ct + ry*st*st);
131 d_ = T(-2*(rx*st*st + ry*ct*ct)*u - 2*(rx-ry)*ct*st*
v);
132 e_ = T(-2*(rx-ry)*ct*st*u - 2*(rx*ct*ct + ry*st*st)*
v);
133 f_ = T((rx*st*st +ry*ct*ct)*u*u + 2*(rx-ry)*ct*st*u*
v + (rx*ct*ct + ry*st*st)*
v*
v - rx*ry);
135 set_type_from_equation();
146 T A = a_, B = b_/2, C = c_, D = d_/2, E = e_/2, F = f_;
149 T det = A*(C*F - E*E) - B*(B*F - D*E) + D*(B*E - C*D);
151 T K = (C*F - E*E) + (A*F - D*D);
157 if (A==C && B==0) type_ = real_circle;
158 else type_ = real_ellipse;
161 if (A==C && B==0) type_ = imaginary_circle;
162 else type_ = imaginary_ellipse;
165 else if (J < 0) type_ = hyperbola;
166 else type_ = parabola;
169 if (J < 0) type_ = real_intersecting_lines;
170 else if (J > 0) type_ = complex_intersecting_lines;
172 if ( A == 0 && B == 0 && C == 0 ) {
173 if ( D !=0 || E != 0 ) type_ = real_intersecting_lines;
174 else if (F != 0) type_ = coincident_lines;
175 else type_ = no_type;
177 else if (K < 0) type_ = real_parallel_lines;
178 else if (K > 0) type_ = complex_parallel_lines;
179 else type_ = coincident_lines;
187 return p.
x()*p.
x()*a_+p.
x()*p.
y()*b_+p.
y()*p.
y()*c_+p.
x()*p.
w()*d_+p.
y()*p.
w()*e_+p.
w()*p.
w()*f_ == 0;
193 T A = a_, B = b_/2, C = c_, D = d_/2, E = e_/2, F = f_;
194 T det = A*(C*F - E*E) - B*(B*F - D*E) + D*(B*E - C*D);
203 double& minor_axis_length,
double& angle_in_radians)
const 205 if (type_!=real_ellipse && type_ != real_circle)
209 double A = static_cast<double>(a_), B = static_cast<double>(b_)*0.5,
210 C = static_cast<double>(c_), D = static_cast<double>(d_)*0.5,
211 F = static_cast<double>(f_), E = static_cast<double>(e_)*0.5;
213 A=-A, B=-B, C=-C, D=-D, E=-E, F=-F;
215 double det = A*(C*F - E*E) - B*(B*F- D*E) + D*(B*E-C*D);
216 double D2 = A*C - B*B;
220 double trace = A + C;
221 double disc = std::sqrt(
trace*
trace - 4.0*D2);
222 double cmaj = (
trace+disc)*D2/(2*det);
if (cmaj < 0) cmaj = -cmaj;
223 double cmin = (
trace-disc)*D2/(2*det);
if (cmin < 0) cmin = -cmin;
224 minor_axis_length = 1.0/std::sqrt(cmaj>cmin?cmaj:cmin);
225 major_axis_length = 1.0/std::sqrt(cmaj>cmin?cmin:cmaj);
228 angle_in_radians = -0.5 * std::atan2(2*B, C-A);
240 if (!is_degenerate() ||
241 type() == complex_intersecting_lines ||
242 type() == complex_parallel_lines)
243 return std::list<vgl_homg_line_2d<T> >();
245 T A = a_, B = b_/2, C = c_, D = d_/2, E = e_/2, F = f_;
247 if (type() == coincident_lines) {
250 if (A!=0 || B!=0 || D!=0)
252 else if (C!=0 || E!=0)
256 return std::list<vgl_homg_line_2d<T> >(2,
l);
262 if (type() == real_parallel_lines)
269 std::list<vgl_homg_line_2d<T> >
v(1,l1);
v.push_back(l2);
275 std::list<vgl_homg_line_2d<T> >
v(1,l1);
v.push_back(l2);
281 if (A==0 && B==0 && C==0) {
291 std::list<vgl_homg_line_2d<T> >
v(1,l1);
v.push_back(l2);
297 std::list<vgl_homg_line_2d<T> >
v(1,l1);
v.push_back(l2);
308 return type_ == real_ellipse|| type_ == imaginary_ellipse|| type_ == hyperbola
309 || type_ == real_circle || type_ == imaginary_circle
310 || type_ == real_intersecting_lines|| type_ == complex_intersecting_lines;
318 f_ += c_ * y*y - a_ * x*x + d_ * x + e_ * y;
326 T A = a_, B = b_/2, C = c_, D = d_/2, E = e_/2, F = f_;
327 return vgl_conic<T>(E*E-C*F, 2*(B*F-D*E), D*D-A*F, 2*(C*D-B*E), 2*(A*E-B*D), B*B-A*C);
335 p.
x()*b_/2+p.
y()*c_ +p.
w()*e_/2,
336 p.
x()*d_/2+p.
y()*e_/2+p.
w()*f_ );
343 if (!is_degenerate()) {
346 l.a()*co.
b()/2+
l.b()*co.
c() +
l.c()*co.
e()/2,
347 l.a()*co.
d()/2+
l.b()*co.
e()/2+
l.c()*co.
f() );
350 if (a_==0 && b_==0 && d_==0)
352 else if (a_*c_*4==b_*b_ && a_*e_*2==b_*d_)
372 double f_x = 2*a_xx*x + a_xy*y + a_xw;
373 double f_y = 2*a_yy*y + a_xy*x + a_yw;
375 double f_xx = 2*a_xx;
376 double f_yy = 2*a_yy;
378 double f_x_2 = f_x*f_x;
379 double f_y_2 = f_y*f_y;
380 double denom = f_x_2 + f_y_2;
381 denom = std::sqrt(denom*denom*denom);
384 return (f_xx*f_y_2 - 2*f_x*f_y*f_xy + f_yy*f_x_2) / denom;
393 if (co.
a() == 1) s <<
"X^2";
394 else if (co.
a() == -1) s <<
"-X^2";
395 else if (co.
a() != 0) s << co.
a() <<
"X^2";
396 if (co.
b() > 0) s <<
'+';
397 if (co.
b() == 1) s <<
"XY";
398 else if (co.
b() == -1) s <<
"-XY";
399 else if (co.
b() != 0) s << co.
b() <<
"XY";
400 if (co.
c() > 0) s <<
'+';
401 if (co.
c() == 1) s <<
"Y^2";
402 else if (co.
c() == -1) s <<
"-Y^2";
403 else if (co.
c() != 0) s << co.
c() <<
"Y^2";
404 if (co.
d() > 0) s <<
'+';
405 if (co.
d() == 1) s <<
"XW";
406 else if (co.
d() == -1) s <<
"-XW";
407 else if (co.
d() != 0) s << co.
d() <<
"XW";
408 if (co.
e() > 0) s <<
'+';
409 if (co.
e() == 1) s <<
"YW";
410 else if (co.
e() == -1) s <<
"-YW";
411 else if (co.
e() != 0) s << co.
e() <<
"YW";
412 if (co.
f() > 0) s <<
'+';
413 if (co.
f() == 1) s <<
"W^2";
414 else if (co.
f() == -1) s <<
"-W^2";
415 else if (co.
f() != 0) s << co.
f() <<
"W^2";
416 return s <<
"=0 " << co.
real_type() <<
"> ";
423 T ta, tb, tc, td, te, tf; is >> ta >> tb >> tc >> td >> te >> tf;
424 co.
set(ta,tb,tc,td,te,tf);
return is;
427 #undef VGL_CONIC_INSTANTIATE 428 #define VGL_CONIC_INSTANTIATE(T) \ 429 template class vgl_conic<T >; \ 430 template std::ostream& operator<<(std::ostream&, const vgl_conic<T >&); \ 431 template std::istream& operator>>(std::istream&, vgl_conic<T >&) 433 #endif // vgl_conic_hxx_
vgl_conic_type type() const
vgl_homg_point_1d< T > centre(vgl_homg_point_1d< T > const &p1, vgl_homg_point_1d< T > const &p2)
Return the point at the centre of gravity of two given points.
Represents a homogeneous 2D line.
double curvature_at(vgl_point_2d< T > const &p) const
Returns the curvature of the conic at point p, assuming p is on the conic.
void translate_by(T x, T y)
Modify this conic by translating it over distance x in the X direction and distance y in the Y direct...
bool contains(vgl_homg_point_2d< T > const &pt) const
Returns true if the point pt belongs to the conic.
T f() const
Returns the coefficient of .
std::ostream & operator<<(std::ostream &s, vgl_orient_box_3d< Type > const &p)
Write box to stream.
void set_type_from_equation()
set conic type from polynomial coefficients and store in member type_.
T a() const
Returns the coefficient of .
T c() const
Returns the coefficient of .
static std::string type_by_number(vgl_conic_type type)
Converts the conic type from enum (internal representation) to string.
std::string real_type() const
Returns the type of the conic as a string.
bool is_central() const
Returns true if a central conic, i.e., an ellipse, circle, or hyperbola.
T e() const
Returns the coefficient of .
vgl_conic dual_conic() const
Returns the dual or tangential representation of this conic.
static vgl_conic_type type_by_name(std::string const &name)
Returns the internal enum value corresponding to the string argument.
T b() const
Returns the coefficient of .
bool ellipse_geometry(double &xc, double &yc, double &major_axis_length, double &minor_axis_length, double &angle_in_radians) const
Converts the coefficients to a geometric description of an ellipse.
vgl_homg_point_2d< T > polar_point(vgl_homg_line_2d< T > const &l) const
Returns the polar point of the given line, w.r.t. this conic.
std::istream & operator>>(std::istream &is, vgl_orient_box_3d< Type > &p)
Read box from stream.
T d() const
Returns the coefficient of .
vgl_homg_line_2d< T > polar_line(vgl_homg_point_2d< T > const &p) const
Returns the polar line of the given point, w.r.t. this conic.
void set(T a, T b, T c, T d, T e, T f)
set or reset the conic using polynomial coefficients.
std::list< vgl_homg_line_2d< T > > components() const
Returns the list of component lines, when degenerate and real components.
bool operator==(vgl_conic< T > const &c) const
comparison operator.
Represents a homogeneous 2D point.
bool is_degenerate() const
Returns true if this conic is degenerate, i.e., if it consists of 2 lines.