Shape.cpp File Reference

Go to the source code of this file.

Functions

bool directedEulerian (Shape const *s)
 A directed graph is Eulerian iff every vertex has equal indegree and outdegree.
double distance (Shape const *s, Geom::Point const &p)
bool distanceLessThanOrEqual (Shape const *s, Geom::Point const &p, double const max_l2)
 Returns true iff the L2 distance from thePt to this shape is <= max_l2.

Function Documentation

bool directedEulerian ( Shape const *  s  ) 

A directed graph is Eulerian iff every vertex has equal indegree and outdegree.

http://mathworld.wolfram.com/EulerianGraph.html

Parameters:
s Directed shape.
Returns:
true if s is Eulerian.

Definition at line 2174 of file Shape.cpp.

References Shape::getPoint(), Barcode::Code39Ext::i, and Shape::numberOfPoints().

Referenced by Shape::Booleen(), Shape::ConvertToShape(), and Shape::Reoriente().

02175 {
02176     for (int i = 0; i < s->numberOfPoints(); i++) {
02177         if (s->getPoint(i).dI != s->getPoint(i).dO) {
02178             return false;
02179         }
02180     }
02181 
02182     return true;
02183 }

double distance ( Shape const *  s,
Geom::Point const &  p 
)
Parameters:
s Shape.
p Point.
Returns:
Minimum distance from p to any of the points or edges of s.

Definition at line 2193 of file Shape.cpp.

References NR::cross(), NR::d, Geom::dot(), addnodes::e, Shape::getEdge(), Shape::getPoint(), Shape::hasPoints(), Barcode::Code39Ext::i, Shape::numberOfEdges(), Shape::numberOfPoints(), pathalongpath::offset(), Geom::sqrt(), and voronoi::x.

02194 {
02195     if ( s->hasPoints() == false) {
02196         return 0.0;
02197     }
02198 
02199     /* Find the minimum distance from p to one of the points on s.
02200     ** Computing the dot product of the difference vector gives
02201     ** us the distance squared; we can leave the square root
02202     ** until the end.
02203     */
02204     double bdot = Geom::dot(p - s->getPoint(0).x, p - s->getPoint(0).x);
02205 
02206     for (int i = 0; i < s->numberOfPoints(); i++) {
02207         Geom::Point const offset( p - s->getPoint(i).x );
02208         double ndot = Geom::dot(offset, offset);
02209         if ( ndot < bdot ) {
02210             bdot = ndot;
02211         }
02212     }
02213 
02214     for (int i = 0; i < s->numberOfEdges(); i++) {
02215         if ( s->getEdge(i).st >= 0 && s->getEdge(i).en >= 0 ) {
02216             /* The edge has start and end points */
02217             Geom::Point const st(s->getPoint(s->getEdge(i).st).x); // edge start
02218             Geom::Point const en(s->getPoint(s->getEdge(i).en).x); // edge end
02219 
02220             Geom::Point const d(p - st);       // vector between p and edge start
02221             Geom::Point const e(en - st);      // vector of the edge
02222             double const el = Geom::dot(e, e); // edge length
02223 
02224             /* Update bdot if appropriate */
02225             if ( el > 0.001 ) {
02226                 double const npr = Geom::dot(d, e);
02227                 if ( npr > 0 && npr < el ) {
02228                     double const nl = fabs( NR::cross(d, e) );
02229                     double ndot = nl * nl / el;
02230                     if ( ndot < bdot ) {
02231                         bdot = ndot;
02232                     }
02233                 }
02234             }
02235         }
02236     }
02237     
02238     return sqrt(bdot);
02239 }

bool distanceLessThanOrEqual ( Shape const *  s,
Geom::Point const &  p,
double const   max_l2 
)

Returns true iff the L2 distance from thePt to this shape is <= max_l2.

Distance = the min of distance to its points and distance to its edges. Points without edges are considered, which is maybe unwanted...

This is largely similar to distance().

Parameters:
s Shape.
p Point.
max_l2 L2 distance.

Definition at line 2255 of file Shape.cpp.

References NR::cross(), NR::d, Geom::dot(), addnodes::e, Shape::getEdge(), Shape::getPoint(), Shape::hasPoints(), Barcode::Code39Ext::i, NR::L1(), Geom::L2(), Shape::numberOfEdges(), Shape::numberOfPoints(), pathalongpath::offset(), and voronoi::x.

02256 {
02257     if ( s->hasPoints() == false ) {
02258         return false;
02259     }
02260     
02261     /* TODO: Consider using bbox to return early, perhaps conditional on nbPt or nbAr. */
02262     
02263     /* TODO: Efficiency: In one test case (scribbling with the freehand tool to create a small number of long
02264     ** path elements), changing from a Distance method to a DistanceLE method reduced this
02265     ** function's CPU time from about 21% of total inkscape CPU time to 14-15% of total inkscape
02266     ** CPU time, due to allowing early termination.  I don't know how much the L1 test helps, it
02267     ** may well be a case of premature optimization.  Consider testing dot(offset, offset)
02268     ** instead.
02269     */
02270   
02271     double const max_l1 = max_l2 * M_SQRT2;
02272     for (int i = 0; i < s->numberOfPoints(); i++) {
02273         Geom::Point const offset( p - s->getPoint(i).x );
02274         double const l1 = NR::L1(offset);
02275         if ( (l1 <= max_l2) || ((l1 <= max_l1) && (Geom::L2(offset) <= max_l2)) ) {
02276             return true;
02277         }
02278     }
02279     
02280     for (int i = 0; i < s->numberOfEdges(); i++) {
02281         if ( s->getEdge(i).st >= 0 && s->getEdge(i).en >= 0 ) {
02282             Geom::Point const st(s->getPoint(s->getEdge(i).st).x);
02283             Geom::Point const en(s->getPoint(s->getEdge(i).en).x);
02284             Geom::Point const d(p - st);
02285             Geom::Point const e(en - st);
02286             double const el = Geom::L2(e);
02287             if ( el > 0.001 ) {
02288                 Geom::Point const e_unit(e / el);
02289                 double const npr = Geom::dot(d, e_unit);
02290                 if ( npr > 0 && npr < el ) {
02291                     double const nl = fabs(NR::cross(d, e_unit));
02292                     if ( nl <= max_l2 ) {
02293                         return true;
02294                     }
02295                 }
02296             }
02297         }
02298     }
02299     
02300     return false;
02301 }