diff options
Diffstat (limited to 'basegfx/source/curve/b2dcubicbezier.cxx')
-rw-r--r-- | basegfx/source/curve/b2dcubicbezier.cxx | 174 |
1 files changed, 87 insertions, 87 deletions
diff --git a/basegfx/source/curve/b2dcubicbezier.cxx b/basegfx/source/curve/b2dcubicbezier.cxx index e1fad1e8a552..4fd2e33fe299 100644 --- a/basegfx/source/curve/b2dcubicbezier.cxx +++ b/basegfx/source/curve/b2dcubicbezier.cxx @@ -381,86 +381,86 @@ namespace basegfx void B2DCubicBezier::testAndSolveTrivialBezier() { - if(maControlPointA != maStartPoint || maControlPointB != maEndPoint) - { - const B2DVector aEdge(maEndPoint - maStartPoint); + if(maControlPointA == maStartPoint && maControlPointB == maEndPoint) + return; - // controls parallel to edge can be trivial. No edge -> not parallel -> control can - // still not be trivial (e.g. ballon loop) - if(!aEdge.equalZero()) - { - // get control vectors - const B2DVector aVecA(maControlPointA - maStartPoint); - const B2DVector aVecB(maControlPointB - maEndPoint); - - // check if trivial per se - bool bAIsTrivial(aVecA.equalZero()); - bool bBIsTrivial(aVecB.equalZero()); - - // #i102241# prepare inverse edge length to normalize cross values; - // else the small compare value used in fTools::equalZero - // will be length dependent and this detection will work as less - // precise as longer the edge is. In principle, the length of the control - // vector would need to be used too, but to be trivial it is assumed to - // be of roughly equal length to the edge, so edge length can be used - // for both. Only needed when one of both is not trivial per se. - const double fInverseEdgeLength(bAIsTrivial && bBIsTrivial - ? 1.0 - : 1.0 / aEdge.getLength()); - - // if A is not zero, check if it could be - if(!bAIsTrivial) - { - // #i102241# parallel to edge? Check aVecA, aEdge. Use cross() which does what - // we need here with the precision we need - const double fCross(aVecA.cross(aEdge) * fInverseEdgeLength); + const B2DVector aEdge(maEndPoint - maStartPoint); - if(fTools::equalZero(fCross)) - { - // get scale to edge. Use bigger distance for numeric quality - const double fScale(fabs(aEdge.getX()) > fabs(aEdge.getY()) - ? aVecA.getX() / aEdge.getX() - : aVecA.getY() / aEdge.getY()); + // controls parallel to edge can be trivial. No edge -> not parallel -> control can + // still not be trivial (e.g. ballon loop) + if(aEdge.equalZero()) + return; - // relative end point of vector in edge range? - if (fTools::betweenOrEqualEither(fScale, 0.0, 1.0)) - { - bAIsTrivial = true; - } - } - } + // get control vectors + const B2DVector aVecA(maControlPointA - maStartPoint); + const B2DVector aVecB(maControlPointB - maEndPoint); + + // check if trivial per se + bool bAIsTrivial(aVecA.equalZero()); + bool bBIsTrivial(aVecB.equalZero()); + + // #i102241# prepare inverse edge length to normalize cross values; + // else the small compare value used in fTools::equalZero + // will be length dependent and this detection will work as less + // precise as longer the edge is. In principle, the length of the control + // vector would need to be used too, but to be trivial it is assumed to + // be of roughly equal length to the edge, so edge length can be used + // for both. Only needed when one of both is not trivial per se. + const double fInverseEdgeLength(bAIsTrivial && bBIsTrivial + ? 1.0 + : 1.0 / aEdge.getLength()); + + // if A is not zero, check if it could be + if(!bAIsTrivial) + { + // #i102241# parallel to edge? Check aVecA, aEdge. Use cross() which does what + // we need here with the precision we need + const double fCross(aVecA.cross(aEdge) * fInverseEdgeLength); - // if B is not zero, check if it could be, but only if A is already trivial; - // else solve to trivial will not be possible for whole edge - if(bAIsTrivial && !bBIsTrivial) + if(fTools::equalZero(fCross)) + { + // get scale to edge. Use bigger distance for numeric quality + const double fScale(fabs(aEdge.getX()) > fabs(aEdge.getY()) + ? aVecA.getX() / aEdge.getX() + : aVecA.getY() / aEdge.getY()); + + // relative end point of vector in edge range? + if (fTools::betweenOrEqualEither(fScale, 0.0, 1.0)) { - // parallel to edge? Check aVecB, aEdge - const double fCross(aVecB.cross(aEdge) * fInverseEdgeLength); + bAIsTrivial = true; + } + } + } - if(fTools::equalZero(fCross)) - { - // get scale to edge. Use bigger distance for numeric quality - const double fScale(fabs(aEdge.getX()) > fabs(aEdge.getY()) - ? aVecB.getX() / aEdge.getX() - : aVecB.getY() / aEdge.getY()); + // if B is not zero, check if it could be, but only if A is already trivial; + // else solve to trivial will not be possible for whole edge + if(bAIsTrivial && !bBIsTrivial) + { + // parallel to edge? Check aVecB, aEdge + const double fCross(aVecB.cross(aEdge) * fInverseEdgeLength); - // end point of vector in edge range? Caution: controlB is directed AGAINST edge - if (fTools::betweenOrEqualEither(fScale, -1.0, 0.0)) - { - bBIsTrivial = true; - } - } - } + if(fTools::equalZero(fCross)) + { + // get scale to edge. Use bigger distance for numeric quality + const double fScale(fabs(aEdge.getX()) > fabs(aEdge.getY()) + ? aVecB.getX() / aEdge.getX() + : aVecB.getY() / aEdge.getY()); - // if both are/can be reduced, do it. - // Not possible if only one is/can be reduced (!) - if(bAIsTrivial && bBIsTrivial) + // end point of vector in edge range? Caution: controlB is directed AGAINST edge + if (fTools::betweenOrEqualEither(fScale, -1.0, 0.0)) { - maControlPointA = maStartPoint; - maControlPointB = maEndPoint; + bBIsTrivial = true; } } } + + // if both are/can be reduced, do it. + // Not possible if only one is/can be reduced (!) + if(bAIsTrivial && bBIsTrivial) + { + maControlPointA = maStartPoint; + maControlPointB = maEndPoint; + } } namespace { @@ -994,27 +994,27 @@ namespace basegfx void B2DCubicBezier::transform(const basegfx::B2DHomMatrix& rMatrix) { - if(!rMatrix.isIdentity()) + if(rMatrix.isIdentity()) + return; + + if(maControlPointA == maStartPoint) { - if(maControlPointA == maStartPoint) - { - maControlPointA = maStartPoint = rMatrix * maStartPoint; - } - else - { - maStartPoint *= rMatrix; - maControlPointA *= rMatrix; - } + maControlPointA = maStartPoint = rMatrix * maStartPoint; + } + else + { + maStartPoint *= rMatrix; + maControlPointA *= rMatrix; + } - if(maControlPointB == maEndPoint) - { - maControlPointB = maEndPoint = rMatrix * maEndPoint; - } - else - { - maEndPoint *= rMatrix; - maControlPointB *= rMatrix; - } + if(maControlPointB == maEndPoint) + { + maControlPointB = maEndPoint = rMatrix * maEndPoint; + } + else + { + maEndPoint *= rMatrix; + maControlPointB *= rMatrix; } } |