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().
| 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 }
