From d2e3aaa262de3815c4ba165590ee5e98e5db2ac5 Mon Sep 17 00:00:00 2001 From: Armin Weiss Date: Tue, 11 Nov 2003 08:48:14 +0000 Subject: Added functionality at the Poly and PolyPolygon tools for subdivides, corrected polygon clipper further --- basegfx/source/polygon/b2dpolygontools.cxx | 86 +++++++++++++++++++++++++- basegfx/source/polygon/b2dpolypolygontools.cxx | 28 ++++++++- 2 files changed, 110 insertions(+), 4 deletions(-) (limited to 'basegfx/source') diff --git a/basegfx/source/polygon/b2dpolygontools.cxx b/basegfx/source/polygon/b2dpolygontools.cxx index 5061acfbfae4..bef74f8389ef 100644 --- a/basegfx/source/polygon/b2dpolygontools.cxx +++ b/basegfx/source/polygon/b2dpolygontools.cxx @@ -2,9 +2,9 @@ * * $RCSfile: b2dpolygontools.cxx,v $ * - * $Revision: 1.5 $ + * $Revision: 1.6 $ * - * last change: $Author: aw $ $Date: 2003-11-10 11:45:50 $ + * last change: $Author: aw $ $Date: 2003-11-11 09:48:13 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -75,6 +75,14 @@ #include #endif +#ifndef _BGFX_CURVE_B2DCUBICBEZIER_HXX +#include +#endif + +#ifndef _BGFX_CURVE_B2DBEZIERTOOLS_HXX +#include +#endif + ////////////////////////////////////////////////////////////////////////////// namespace basegfx @@ -230,6 +238,80 @@ namespace basegfx return eRetval; } + ::basegfx::polygon::B2DPolygon adaptiveSubdivide(const ::basegfx::polygon::B2DPolygon& rCandidate, double fDistanceBound) + { + ::basegfx::polygon::B2DPolygon aRetval(rCandidate); + + if(aRetval.areControlPointsUsed()) + { + const sal_uInt32 nPointCount(rCandidate.isClosed() ? rCandidate.count() : rCandidate.count() - 1L); + aRetval.clear(); + + for(sal_uInt32 a(0L); a < nPointCount; a++) + { + const ::basegfx::vector::B2DVector aVectorA(rCandidate.getControlVectorA(a)); + const ::basegfx::vector::B2DVector aVectorB(rCandidate.getControlVectorB(a)); + + if(!aVectorA.equalZero() || !aVectorB.equalZero()) + { + // vectors are used, get points + const sal_uInt32 nNext(getIndexOfSuccessor(a, rCandidate)); + ::basegfx::point::B2DPoint aPointA(rCandidate.getB2DPoint(a)); + ::basegfx::point::B2DPoint aPointB(rCandidate.getB2DPoint(nNext)); + + // build CubicBezier segment + ::basegfx::curve::B2DCubicBezier aBezier( + aPointA, aPointA + aVectorA, aPointB + aVectorB, aPointB); + + // generate DistanceBound + double fBound; + + if(0.0 == fDistanceBound) + { + // If not set, calculate rough length of bezier segment by taking + // half of the sum of the edge and the control polygon + ::basegfx::vector::B2DVector aSimpleDistance(aPointB - aPointA); + ::basegfx::vector::B2DVector aTripleDistanceTop((aPointB + aVectorB) - (aPointA + aVectorA)); + const double fRoughLength( + (aSimpleDistance.getLength() + + (aVectorA.getLength() + aVectorB.getLength() + aTripleDistanceTop.getLength())) / 2.0); + + // take 1/100th of the rouch curve length + fBound = fRoughLength * 0.01; + } + else + { + // use given bound value + fBound = fDistanceBound; + } + + // make sure bound value is not too small. The base units are 1/100th mm, thus + // just make sure it's not smaller then 1/100th of that + if(fBound < 0.01) + { + fBound = 0.01; + } + + // call adaptive subdivide + ::basegfx::curve::adaptiveSubdivide(aRetval, aBezier, fBound); + } + else + { + // no vectors used, add point + aRetval.append(rCandidate.getB2DPoint(a)); + } + } + + // check closed flag, aRetval was cleared and thus it may be invalid. + if(aRetval.isClosed() != rCandidate.isClosed()) + { + aRetval.setClosed(rCandidate.isClosed()); + } + } + + return aRetval; + } + sal_Bool isInside(const ::basegfx::polygon::B2DPolygon& rCandidate, const ::basegfx::point::B2DPoint& rPoint, sal_Bool bWithBorder) { sal_Bool bRetval(sal_False); diff --git a/basegfx/source/polygon/b2dpolypolygontools.cxx b/basegfx/source/polygon/b2dpolypolygontools.cxx index 07ada131585d..bd5b03a3549b 100644 --- a/basegfx/source/polygon/b2dpolypolygontools.cxx +++ b/basegfx/source/polygon/b2dpolypolygontools.cxx @@ -2,9 +2,9 @@ * * $RCSfile: b2dpolypolygontools.cxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: aw $ $Date: 2003-11-06 16:30:29 $ + * last change: $Author: aw $ $Date: 2003-11-11 09:48:14 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -172,6 +172,30 @@ namespace basegfx rCandidate.clear(); aCutter.getPolyPolygon(rCandidate); } + + ::basegfx::polygon::B2DPolyPolygon adaptiveSubdivide(const ::basegfx::polygon::B2DPolyPolygon& rCandidate, double fDistanceBound) + { + ::basegfx::polygon::B2DPolyPolygon aRetval(rCandidate); + + if(aRetval.areControlPointsUsed()) + { + const sal_uInt32 nPolygonCount(aRetval.count()); + + for(sal_uInt32 a(0L); aRetval.areControlPointsUsed() && a < nPolygonCount; a++) + { + ::basegfx::polygon::B2DPolygon aCandidate = aRetval.getPolygon(a); + + if(aCandidate.areControlPointsUsed()) + { + aCandidate = ::basegfx::polygon::tools::adaptiveSubdivide(aCandidate, fDistanceBound); + aRetval.setPolygon(a, aCandidate); + } + } + } + + return aRetval; + } + } // end of namespace tools } // end of namespace polygon } // end of namespace basegfx -- cgit v1.2.3