00001
00002
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031
00032 #ifndef RCSC_GEOM_LINE2D_H
00033 #define RCSC_GEOM_LINE2D_H
00034
00035 #include <rcsc/geom/vector_2d.h>
00036
00037 #include <cmath>
00038
00039 namespace rcsc {
00040
00047 class Line2D {
00048 public:
00049
00050 static const double EPSILON;
00051 static const double ERROR_VALUE;
00052
00053 private:
00054
00055 double M_a;
00056 double M_b;
00057 double M_c;
00058
00059
00060 Line2D();
00061
00062 public:
00069 Line2D( const double & a,
00070 const double & b,
00071 const double & c )
00072 : M_a( a )
00073 , M_b( b )
00074 , M_c( c )
00075 { }
00076
00082 Line2D( const Vector2D & p1,
00083 const Vector2D & p2 )
00084 {
00085 assign( p1, p2 );
00086 }
00087
00093 Line2D( const Vector2D & origin,
00094 const AngleDeg & linedir )
00095 {
00096 assign( origin, linedir );
00097 }
00098
00105 const
00106 Line2D & assign( const Vector2D & p1,
00107 const Vector2D & p2 )
00108 {
00109 M_a = -( p2.y - p1.y );
00110 M_b = p2.x - p1.x;
00111 M_c = -M_a * p1.x - M_b * p1.y;
00112 return *this;
00113 }
00114
00121 const
00122 Line2D & assign( const Vector2D & origin,
00123 const AngleDeg & linedir )
00124 {
00125 M_a = - linedir.sin();
00126 M_b = linedir.cos();
00127 M_c = -M_a * origin.x - M_b * origin.y;
00128 return *this;
00129 }
00130
00135 const
00136 double & a() const
00137 {
00138 return M_a;
00139 }
00140
00145 const
00146 double & getA() const
00147 {
00148 return M_a;
00149 }
00150
00155 const
00156 double & b() const
00157 {
00158 return M_b;
00159 }
00160
00169 const
00170 double & getB() const
00171 {
00172 return M_b;
00173 }
00174
00179 const
00180 double & c() const
00181 {
00182 return M_c;
00183 }
00184
00189 const
00190 double & getC() const
00191 {
00192 return M_c;
00193 }
00194
00200 double getX( const double & y ) const
00201 {
00202 if ( std::fabs( M_a ) < EPSILON )
00203 {
00204 return ERROR_VALUE;
00205 }
00206 return -( M_b * y + M_c ) / M_a;
00207 }
00208
00214 double getY( const double & x ) const
00215 {
00216 if ( std::fabs( M_b ) < EPSILON )
00217 {
00218 return ERROR_VALUE;
00219 }
00220
00221 return -( M_a * x + M_c ) / M_b;
00222 }
00223
00229 double dist( const Vector2D & p ) const
00230 {
00231 return std::fabs( ( M_a * p.x + M_b * p.y + M_c )
00232 / std::sqrt( M_a * M_a + M_b * M_b ) );
00233 }
00239 double dist2( const Vector2D & p ) const
00240 {
00241 double d = M_a * p.x + M_b * p.y + M_c;
00242 return (d * d) / (M_a * M_a + M_b * M_b);
00243 }
00244
00251 bool isParallel( const Line2D & line ) const
00252 {
00253 return std::fabs( a() * line.b() - line.a() * b() ) < EPSILON;
00254 }
00255
00262 Vector2D intersection( const Line2D & line ) const
00263 {
00264 return intersection( *this, line );
00265 }
00266
00272 Line2D perpendicular( const Vector2D & p ) const
00273 {
00274 return Line2D( b(), -a(), a() * p.y - b() * p.x );
00275 }
00276
00282 Vector2D projection( const Vector2D & p ) const
00283 {
00284 return intersection( perpendicular( p ) );
00285 }
00286
00287
00288
00296 static
00297 Vector2D intersection( const Line2D & line1,
00298 const Line2D & line2 );
00299
00307 static
00308 Line2D angle_bisector( const Vector2D & origin,
00309 const AngleDeg & left,
00310 const AngleDeg & right )
00311 {
00312 return Line2D( origin, AngleDeg::bisect( left, right ) );
00313 }
00314
00321 static
00322 Line2D perpendicular_bisector( const Vector2D & p1,
00323 const Vector2D & p2 );
00324
00325 };
00326
00327 }
00328
00329 #endif