proj home

Files   Classes   Functions   Hierarchy  

arc Class Reference

Convex arc of a circle through the points p0 and p1 in 2D. More...

#include <arc.h>

Collaboration diagram for arc:

List of all members.

Public Member Functions

 arc ()
 Construct an arc in an undefined state.
 arc (doublec radius_, pt2c &p0_, pt2c &p1_)
 Construct an arc.
void constructRadiusTwoPoints (doublec radius_, pt2c &p0_, pt2c &p1_)
 Construct the arc from two points and the signed radius.
void constructPhi0TwoPoints (doublec phi0_, pt2c &p0_, pt2c &p1_)
 Construct the arc from two points and an initial angle(in radians).
boolc isAntiClockwise () const
 Does the arc have an anticlockwise winding?
boolc isStraightLine () const
 Is the arc a straight line?
boolc valid () const
 Is the arc valid.
 operator string () const
 Output the arc uniquely as p0 p1 radius.
void print () const
 Print info on this class to the console (for debugging).
doublec length () const
 Find the length of the arc segment.
void distance (double &val, pt2c &p) const
 Find the distance from the point to the arc.
void distanceSquared (double &val, pt2c &p) const
 Find distance squared from the point to the arc.

Static Public Member Functions

static void arcreader (vector< arc > &v, string const &filename)
 Read in a file or vector arcs.

Public Attributes

pt2 p0
 The starting point of the arc.
pt2 p1
 The end point of the arc.
double radius
 The sign of the radius describes which side of line p01 the arc lies on.
double phi0
 Angle from center to p0 in radians.
double phi1
 Angle from center to p1 in radians.
pt2 center
 The center of the arc.

Static Public Attributes

static double zero = 1e-12
 Used to detect the straight line case.


Detailed Description

Convex arc of a circle through the points p0 and p1 in 2D.

For a positive radius the arc is on the rhs of line p01. For a negative radius the arc is on the lhs of line p01.

<TODO> clarify For a radius less that distance(p0,p1)/2 a straight line is assumed. For r==0.0 the arc is a straight line (infinite radius).

Definition at line 24 of file arc.h.


Constructor & Destructor Documentation

arc::arc (  ) 

Construct an arc in an undefined state.

Definition at line 10 of file arc.cpp.

00011   : radius(0.0), phi0(0.0), phi1(0.0)
00012 {
00013 }

arc::arc ( doublec  radius_,
pt2c p0_,
pt2c p1_ 
)

Construct an arc.

Definition at line 228 of file arc.cpp.

00233 {
00234   constructRadiusTwoPoints(radius_,p0_,p1_);
00235 }


Member Function Documentation

void arc::arcreader ( vector< arc > &  v,
string const &  filename 
) [static]

Read in a file or vector arcs.

The format is as follows. Number of points, points,
number of arcs, arcs. The arc is defined by indexing the two points into the points array and then the signed radius.
Example
7
0.0 0.0
1.0 1.1
1.5 2.8
2.8 4.2
4.8 4.0
6.8 4.2
8.1 5.5
6
0 1 -2.5
1 2 -2.5 
2 3 -2.5
3 4 0.0
4 5 2.5
5 6 3.0

Definition at line 256 of file arc.cpp.

References pts.

Referenced by test03(), and writearcgeometry().

00260 {
00261   v.clear();
00262 
00263   ifstream targ(filename.c_str());
00264 
00265   assert(targ.good()==true);
00266   if (targ.good()==false)
00267     return;
00268   
00269   vector< pt2 > pts;
00270 
00271   pt2 p;
00272   uint k;
00273   targ >> k;
00274   for ( uint i=0; i<k; ++i)
00275   {
00276     targ >> p;
00277     pts.push_back(p);
00278   }
00279 
00280   uint a;
00281   uint b;
00282   double radius;
00283 
00284   targ >> k;
00285 
00286   for ( uint i=0; i<k; ++i)
00287   {
00288     targ >> a;
00289     targ >> b;
00290     targ >> radius;
00291 
00292     assert(a<pts.size());
00293     assert(b<pts.size());
00294 
00295     v.push_back( arc(radius,pts[a],pts[b]) );
00296   }
00297 }

void arc::constructPhi0TwoPoints ( doublec  phi0_,
pt2c p0_,
pt2c p1_ 
)

Construct the arc from two points and an initial angle(in radians).

Definition at line 128 of file arc.cpp.

References point2< T >::dot(), point2< T >::x, and point2< T >::y.

Referenced by arcsconnected::constructPhi0(), test04(), and test08().

00133 {
00134   p0 = p0_;
00135   p1 = p1_;
00136   phi0 = phi0_;
00137 /*
00138 cout << endl << endl;
00139 
00140 cout << SHOW(phi0*180.0/PI) << endl; 
00141 cout << SHOW(p0) << endl;
00142 cout << SHOW(p1) << endl;
00143 */
00144 
00145   pt2c f(cos(phi0),sin(phi0));
00146   pt2c dp(p0-p1);
00147 
00148   doublec fdotdp(f.dot(dp));
00149   if ( abs(fdotdp)<zero)
00150   {
00151     radius=0.0;
00152     return;
00153   }
00154   
00155 
00156 if ( fdotdp< 0.0 )
00157 {
00158 #ifndef NDEBUG
00159 cout << "error:  wrong initial angle" << endl;
00160 #endif
00161   constructPhi0TwoPoints(phi0+PI,p0,p1);
00162   return;
00163 }
00164 
00165   radius = dp.dot() / fdotdp * 0.5;
00166 //cout << SHOW(radius) << endl;
00167 
00168 #ifndef NDEBUG
00169 if (radius<0.0)
00170   cout << "error: the radius should be positive." << endl;
00171 #endif
00172   //center = p0 - f * abs(radius);
00173   center = p0 - f * radius;
00174 
00175 
00176 
00177 
00178 
00179 /*
00180   pt2 c0 = p0 - f * radius;
00181   center = c0;
00182 
00183 
00184 cout << SHOW(c0) << endl;
00185 cout << SHOW(c0 + f * radius) << endl;
00186 cout << SHOW(c0 - f * radius) << endl;
00187 cout << SHOW( (p0-c0).distance() ) << endl;
00188 cout << SHOW( (p1-c0).distance() ) << endl;
00189 */
00190 
00191 
00192   pt2 p4(p1-center);
00193   p4 *= 1.0 / radius;
00194   phi1 = atan2(p4.y,p4.x);
00195 
00196   if (isAntiClockwise2()==false)
00197   {
00198 
00199     if (radius<0)
00200     {
00201 #ifndef NDEBUG
00202 cout << "error:  radius already -ve, this message should not appear" << endl;
00203 #endif
00204     }
00205     else
00206       radius *= -1;
00207   }
00208 
00209 /*
00210 
00211 cout << "Verify by finding p2 from phi1." << endl;
00212   pt2 p5(cos(phi1),sin(phi1));
00213   p5 *= radius;
00214   p5 += center;
00215 
00216 
00217 cout << SHOW(p4) << endl;
00218 cout << SHOW(p4.dot()) << endl;
00219 cout << SHOW(phi1*180.0/PI) << endl;
00220 cout << SHOW(p5) << endl;
00221 */
00222 
00223 
00224 }

void arc::constructRadiusTwoPoints ( doublec  radius_,
pt2c p0_,
pt2c p1_ 
)

Construct the arc from two points and the signed radius.

Definition at line 95 of file arc.cpp.

References point2< T >::x, and point2< T >::y.

00100 {
00101   radius = radius_;
00102   p0 = p0_;
00103   p1 = p1_;
00104 
00105   if (isStraightLine()==true)
00106     return;
00107 
00108   calculateCenter();
00109 
00110   pt2 g0(p0-center);
00111   //g0.normalize();
00112   phi0 = atan2(g0.y,g0.x);
00113   angleAdjusted(phi0);
00114   pt2 g1(p1-center);
00115   //g1.normalize();
00116   phi1 = atan2(g1.y,g1.x);
00117   angleAdjusted(phi1);
00118 
00119 /*
00120 cout << SHOW(g0) << " " << SHOW(phi0*180./PI) << endl;
00121 cout << SHOW(g1) << " " << SHOW(phi1*180./PI) << endl;
00122 cout << SHOW(phi1-phi0) << " " << SHOW(length()) << endl;
00123 */
00124   
00125 }

void arc::distance ( double &  val,
pt2c p 
) const

Find the distance from the point to the arc.

Definition at line 323 of file arc.cpp.

References center, point2< T >::distance(), point2< T >::dot(), isAntiClockwise(), p0, p1, radius, and point2< T >::rotate90().

Referenced by test06().

00324 {
00325   pt2 p3(p-center);
00326 
00327   if (isAntiClockwise())
00328   {
00329     {
00330       pt2 z(center-p0);
00331       z.rotate90();
00332       if (z.dot(p3)>0.0)
00333       {
00334 //cout << "greater than p0 arm." << endl;
00335         // Take the distance from the endpoint.
00336         val = (p-p0).distance();
00337         return;
00338       }
00339     }
00340     {
00341       pt2 z(p1-center);
00342       z.rotate90();
00343       if (z.dot(p3)>0.0)
00344       {
00345 //cout << "greater than p1 arm." << endl;
00346         // Take the distance from the endpoint.
00347         val = (p-p1).distance();
00348         return;
00349       }
00350     }
00351   }
00352   else
00353   {
00354     {
00355       pt2 z(center-p1);
00356       z.rotate90();
00357       if (z.dot(p3)>0.0)
00358       {
00359         val = (p-p1).distance();
00360         return;
00361       }
00362     }
00363     {
00364       pt2 z(p0-center);
00365       z.rotate90();
00366       if (z.dot(p3)>0.0)
00367       {
00368         val = (p-p0).distance();
00369         return;
00370       }
00371     }
00372   }
00373 
00374   val = abs(p3.distance() - radius);
00375   return;
00376   
00377 } 

void arc::distanceSquared ( double &  val,
pt2c p 
) const

Find distance squared from the point to the arc.

Definition at line 379 of file arc.cpp.

References center, point2< T >::dot(), isAntiClockwise(), p0, p1, radius, and point2< T >::rotate90().

Referenced by arcsconnected::sumdisttoarc().

00380 {
00381   pt2 p3(p-center);
00382 
00383   if (isAntiClockwise())
00384   {
00385     {
00386       pt2 z(center-p0);
00387       z.rotate90();
00388       if (z.dot(p3)>0.0)
00389       {
00390         //val = (p-p0).distanceSquared();
00391         val = (p-p0).dot();
00392         return;
00393       }
00394     }
00395     {
00396       pt2 z(p1-center);
00397       z.rotate90();
00398       if (z.dot(p3)>0.0)
00399       {
00400         //val = (p-p1).distanceSquared();
00401         val = (p-p1).dot();
00402         return;
00403       }
00404     }
00405   }
00406   else
00407   {
00408     {
00409       pt2 z(center-p1);
00410       z.rotate90();
00411       if (z.dot(p3)>0.0)
00412       {
00413         //val = (p-p1).distanceSquared();
00414         val = (p-p1).dot();
00415         return;
00416       }
00417     }
00418     {
00419       pt2 z(p0-center);
00420       z.rotate90();
00421       if (z.dot(p3)>0.0)
00422       {
00423         //val = (p-p0).distanceSquared();
00424         val = (p-p0).dot();
00425         return;
00426       }
00427     }
00428   }
00429 
00430   //val = abs(p3.distanceSquared() - radius*radius);
00431   val = abs(p3.dot() - radius*radius);
00432 } 

boolc arc::isAntiClockwise (  )  const [inline]

Does the arc have an anticlockwise winding?

Definition at line 79 of file arc.h.

References radius.

Referenced by distance(), distanceSquared(), print(), and arcdraw::update().

00080     { return radius > 0.0; }

boolc arc::isStraightLine (  )  const [inline]

Is the arc a straight line?

Definition at line 83 of file arc.h.

References radius.

Referenced by length(), arcdraw::update(), and valid().

00084     { return radius == 0.0; }

doublec arc::length (  )  const

Find the length of the arc segment.

Definition at line 237 of file arc.cpp.

References isStraightLine(), p0, p1, phi1, radius, and valid().

00238 {
00239   assert(valid()==true);
00240 
00241   if (isStraightLine())
00242     return (p1-p0).distance();
00243 
00244 
00245   // Interpret the arc as convex between points p0 and p1.
00246   //  Find the acute angle between the points p0 and p1.
00247   double dphi = abs(phi1-phi0);
00248   if (dphi>PI)
00249     dphi = 2.0*PI - dphi;
00250 
00251   return abs(dphi*radius);
00252 }

arc::operator string (  )  const

Output the arc uniquely as p0 p1 radius.

Definition at line 86 of file arc.cpp.

References p0, p1, and radius.

00087 {
00088   stringstream ss;
00089   ss << p0 << " " << p1 << " " << radius; 
00090   return ss.str();
00091 }

void arc::print (  )  const

Print info on this class to the console (for debugging).

Definition at line 300 of file arc.cpp.

References center, isAntiClockwise(), p0, p1, phi1, radius, and SHOW.

Referenced by test04(), test06(), and test08().

00301 {
00302   cout << SHOW(radius) << endl;
00303   cout << SHOW(p0) << endl;
00304   cout << SHOW(p1) << endl;
00305   
00306   cout << SHOW(center) << endl;
00307   cout << SHOW(phi0*180.0/PI) << endl;
00308   cout << SHOW(phi1*180.0/PI) << endl;
00309   cout << SHOW(isAntiClockwise()) << endl;
00310   cout << SHOW(isAntiClockwise2()) << endl;
00311   cout << SHOW(center+pt2(cos(phi0),sin(phi0))*abs(radius) ) << endl;
00312   cout << SHOW(center+pt2(cos(phi1),sin(phi1))*abs(radius) ) << endl;
00313   cout << endl;
00314 }

boolc arc::valid (  )  const

Is the arc valid.

For example if the radius is less than the distance between the arc end points then there can be no arc connecting the two points.

Definition at line 15 of file arc.cpp.

References isStraightLine(), p0, and p1.

Referenced by length().

00016 {
00017   
00018   if ((p0==p1)==true)
00019   {
00020     cout << "error:  " << *this << " has p0 and p1 equal.";
00021     cout << endl;
00022     return false;
00023   }
00024 
00025   if (isStraightLine())
00026     return true;
00027 
00028 /*
00029   if ( ((p0-p1).dot() <= radius*radius*4.0) == false )
00030   {
00031     cout << *this << " failed radius condition." << endl;
00032     assert(false);
00033     return false;
00034   }
00035 */
00036   
00037   return true;
00038 }


Member Data Documentation

The center of the arc.

Definition at line 50 of file arc.h.

Referenced by distance(), distanceSquared(), print(), test02(), and arcdraw::update().

The starting point of the arc.

Definition at line 34 of file arc.h.

Referenced by distance(), distanceSquared(), length(), operator string(), print(), arcdraw::update(), and valid().

The end point of the arc.

Definition at line 36 of file arc.h.

Referenced by distance(), distanceSquared(), length(), operator string(), print(), arcdraw::update(), and valid().

double arc::phi0

Angle from center to p0 in radians.

Definition at line 46 of file arc.h.

Referenced by arcdraw::update().

double arc::phi1

Angle from center to p1 in radians.

Definition at line 48 of file arc.h.

Referenced by length(), print(), test04(), and arcdraw::update().

double arc::radius

The sign of the radius describes which side of line p01 the arc lies on.

Definition at line 40 of file arc.h.

Referenced by arcsconnected::constructPhi0(), distance(), distanceSquared(), isAntiClockwise(), isStraightLine(), length(), operator string(), print(), and arcdraw::update().

double arc::zero = 1e-12 [static]

Used to detect the straight line case.

Definition at line 141 of file arc.h.


The documentation for this class was generated from the following files:

Generated on Fri Mar 4 00:49:50 2011 for Chelton Evans Source by  doxygen 1.5.8