From 98c9f4f4f2506db7385cc3f0fa7bb1b14930a417 Mon Sep 17 00:00:00 2001 From: Oliver Bolte Date: Fri, 17 Oct 2008 08:40:10 +0000 Subject: CWS-TOOLING: integrate CWS aw057 --- basegfx/inc/basegfx/polygon/b2dpolygontools.hxx | 9 +- basegfx/inc/basegfx/polygon/b3dpolygontools.hxx | 36 ++- .../inc/basegfx/polygon/b3dpolypolygontools.hxx | 6 +- basegfx/inc/basegfx/vector/b3dvector.hxx | 16 +- basegfx/source/polygon/b2dpolygontools.cxx | 24 +- basegfx/source/polygon/b2dpolypolygon.cxx | 4 +- basegfx/source/polygon/b2dpolypolygontools.cxx | 4 +- basegfx/source/polygon/b3dpolygontools.cxx | 322 ++++++++++++++++++++- basegfx/source/polygon/b3dpolypolygontools.cxx | 29 +- basegfx/source/vector/b3dvector.cxx | 15 +- 10 files changed, 433 insertions(+), 32 deletions(-) (limited to 'basegfx') diff --git a/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx b/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx index 20845c8c7cbe..45423ace62c6 100644 --- a/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx +++ b/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: b2dpolygontools.hxx,v $ - * $Revision: 1.24 $ + * $Revision: 1.24.4.1 $ * * This file is part of OpenOffice.org. * @@ -242,8 +242,9 @@ namespace basegfx bool isInEpsilonRange(const B2DPoint& rEdgeStart, const B2DPoint& rEdgeEnd, const B2DPoint& rTestPosition, double fDistance); // test if point is inside epsilon-range around the given Polygon. Can be used - // for HitTesting. The epsilon-range is defined to be the tube around the polygon - // with distance fDistance and rounded edges (start and end point). + // for HitTesting. The epsilon-range is defined to be the rectangle centered + // to the given edge, using height 2 x fDistance, and the circle around both points + // with radius fDistance. bool isInEpsilonRange(const B2DPolygon& rCandidate, const B2DPoint& rTestPosition, double fDistance); /** Create a polygon from a rectangle. @@ -379,7 +380,7 @@ namespace basegfx /** Create an unit ellipse polygon with the given angles, from start to end */ - B2DPolygon createPolygonFromEllipseSegment( const B2DPoint& rCenter, double fRadiusX, double fRadiusY, double fStart, double fEnd ); + B2DPolygon createPolygonFromEllipseSegment( const B2DPoint& rCenter, double fRadiusX, double fRadiusY, double fStart, double fEnd ); B2DPolygon createPolygonFromUnitEllipseSegment( double fStart, double fEnd ); diff --git a/basegfx/inc/basegfx/polygon/b3dpolygontools.hxx b/basegfx/inc/basegfx/polygon/b3dpolygontools.hxx index d3dbb333a896..7b451970c565 100644 --- a/basegfx/inc/basegfx/polygon/b3dpolygontools.hxx +++ b/basegfx/inc/basegfx/polygon/b3dpolygontools.hxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: b3dpolygontools.hxx,v $ - * $Revision: 1.10 $ + * $Revision: 1.10.4.1 $ * * This file is part of OpenOffice.org. * @@ -81,9 +81,6 @@ namespace basegfx // get area of polygon double getArea(const B3DPolygon& rCandidate); - // get normal vector of polygon - ::basegfx::B3DVector getNormal(const ::basegfx::B3DPolygon& rCandidate); - // get signed area of polygon double getSignedArea(const B3DPolygon& rCandidate); @@ -141,6 +138,37 @@ namespace basegfx */ B3DPolygon applyDefaultTextureCoordinatesSphere( const B3DPolygon& rCandidate, const B3DPoint& rCenter, bool bChangeX = true, bool bChangeY = true); + // test if point is inside epsilon-range around an edge defined + // by the two given points. Can be used for HitTesting. The epsilon-range + // is defined to be the cylinder centered to the given edge, using radius + // fDistance, and the sphere around both points with radius fDistance. + bool isInEpsilonRange(const B3DPoint& rEdgeStart, const B3DPoint& rEdgeEnd, const B3DPoint& rTestPosition, double fDistance); + + // test if point is inside epsilon-range around the given Polygon. Can be used + // for HitTesting. The epsilon-range is defined to be the cylinder centered to + // the given edge, using radius fDistance, and the sphere around both points with radius fDistance. + bool isInEpsilonRange(const B3DPolygon& rCandidate, const B3DPoint& rTestPosition, double fDistance); + + // isInside tests for B3DPoint and other B3DPolygon. On border is not inside as long as + // not true is given in bWithBorder flag. + bool isInside(const B3DPolygon& rCandidate, const B3DPoint& rPoint, bool bWithBorder = false); + bool isInside(const B3DPolygon& rCandidate, const B3DPolygon& rPolygon, bool bWithBorder = false); + + // calculates if given point is on given line, taking care of the numerical epsilon + bool isPointOnLine(const B3DPoint& rStart, const B3DPoint& rEnd, const B3DPoint& rCandidate, bool bWithPoints = false); + + // calculates if given point is on given polygon, taking care of the numerical epsilon. Uses + // isPointOnLine internally + bool isPointOnPolygon(const B3DPolygon& rCandidate, const B3DPoint& rPoint, bool bWithPoints = true); + + // helper to get a fCut position between a plane (given with normal and a point) + // and a line given by start and end point + bool getCutBetweenLineAndPlane(const B3DVector& rPlaneNormal, const B3DPoint& rPlanePoint, const B3DPoint& rEdgeStart, const B3DPoint& rEdgeEnd, double& fCut); + + // helper to get a fCut position between a 3d Polygon + // and a line given by start and end point + bool getCutBetweenLineAndPolygon(const B3DPolygon& rCandidate, const B3DPoint& rEdgeStart, const B3DPoint& rEdgeEnd, double& fCut); + ////////////////////////////////////////////////////////////////////// // comparators with tolerance for 3D Polygons bool equal(const B3DPolygon& rCandidateA, const B3DPolygon& rCandidateB, const double& rfSmallValue); diff --git a/basegfx/inc/basegfx/polygon/b3dpolypolygontools.hxx b/basegfx/inc/basegfx/polygon/b3dpolypolygontools.hxx index fcb78f484a1b..466aa25edd96 100644 --- a/basegfx/inc/basegfx/polygon/b3dpolypolygontools.hxx +++ b/basegfx/inc/basegfx/polygon/b3dpolypolygontools.hxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: b3dpolypolygontools.hxx,v $ - * $Revision: 1.8 $ + * $Revision: 1.8.4.1 $ * * This file is part of OpenOffice.org. * @@ -142,6 +142,10 @@ namespace basegfx */ B3DPolyPolygon applyDefaultTextureCoordinatesSphere( const B3DPolyPolygon& rCandidate, const B3DPoint& rCenter, bool bChangeX = true, bool bChangeY = true); + // isInside test for B3DPoint. On border is not inside as long as not true is given + // in bWithBorder flag. It is assumed that the orientations of the given polygon are correct. + bool isInside(const B3DPolyPolygon& rCandidate, const B3DPoint& rPoint, bool bWithBorder = false); + ////////////////////////////////////////////////////////////////////// // comparators with tolerance for 3D PolyPolygons bool equal(const B3DPolyPolygon& rCandidateA, const B3DPolyPolygon& rCandidateB, const double& rfSmallValue); diff --git a/basegfx/inc/basegfx/vector/b3dvector.hxx b/basegfx/inc/basegfx/vector/b3dvector.hxx index f5e2c68b98a7..e39500a15cd7 100644 --- a/basegfx/inc/basegfx/vector/b3dvector.hxx +++ b/basegfx/inc/basegfx/vector/b3dvector.hxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: b3dvector.hxx,v $ - * $Revision: 1.12 $ + * $Revision: 1.12.4.1 $ * * This file is part of OpenOffice.org. * @@ -296,6 +296,20 @@ namespace basegfx return aPerpendicular; } + /** Test two vectors which need not to be normalized for parallelism + + @param rVecA + The first 3D Vector + + @param rVecB + The second 3D Vector + + @return + bool if the two values are parallel. Also true if + one of the vectors is empty. + */ + bool areParallel( const B3DVector& rVecA, const B3DVector& rVecB ); + /** Transform vector by given transformation matrix. Since this is a vector, translational components of the diff --git a/basegfx/source/polygon/b2dpolygontools.cxx b/basegfx/source/polygon/b2dpolygontools.cxx index d001bfb5a4cb..7a7a60ae37b5 100644 --- a/basegfx/source/polygon/b2dpolygontools.cxx +++ b/basegfx/source/polygon/b2dpolygontools.cxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: b2dpolygontools.cxx,v $ - * $Revision: 1.29 $ + * $Revision: 1.29.4.1 $ * * This file is part of OpenOffice.org. * @@ -1552,12 +1552,10 @@ namespace basegfx { // build edge vector const B2DVector aEdge(rEdgeEnd - rEdgeStart); - bool bDeltaXIsZero(fTools::equalZero(aEdge.getX())); - bool bDeltaYIsZero(fTools::equalZero(aEdge.getY())); bool bDoDistanceTestStart(false); bool bDoDistanceTestEnd(false); - if(bDeltaXIsZero && bDeltaYIsZero) + if(aEdge.equalZero()) { // no edge, just a point. Do one of the distance tests. bDoDistanceTestStart = true; @@ -1570,7 +1568,6 @@ namespace basegfx (aPerpend.getY() * (rTestPosition.getX() - rEdgeStart.getX()) + aPerpend.getX() * (rEdgeStart.getY() - rTestPosition.getY())) / (aEdge.getX() * aEdge.getX() + aEdge.getY() * aEdge.getY())); - const double fZero(0.0); const double fOne(1.0); @@ -1588,9 +1585,8 @@ namespace basegfx { // inside line [0.0 .. 1.0] const B2DPoint aCutPoint(interpolate(rEdgeStart, rEdgeEnd, fCut)); - const double fDeltaX(rTestPosition.getX() - aCutPoint.getX()); - const double fDeltaY(rTestPosition.getY() - aCutPoint.getY()); - const double fDistanceSquare(fDeltaX * fDeltaX + fDeltaY * fDeltaY); + const B2DVector aDelta(rTestPosition - aCutPoint); + const double fDistanceSquare(aDelta.scalar(aDelta)); if(fDistanceSquare <= fDistance * fDistance) { @@ -1598,16 +1594,15 @@ namespace basegfx } else { - return sal_False; + return false; } } } if(bDoDistanceTestStart) { - const double fDeltaX(rTestPosition.getX() - rEdgeStart.getX()); - const double fDeltaY(rTestPosition.getY() - rEdgeStart.getY()); - const double fDistanceSquare(fDeltaX * fDeltaX + fDeltaY * fDeltaY); + const B2DVector aDelta(rTestPosition - rEdgeStart); + const double fDistanceSquare(aDelta.scalar(aDelta)); if(fDistanceSquare <= fDistance * fDistance) { @@ -1616,9 +1611,8 @@ namespace basegfx } else if(bDoDistanceTestEnd) { - const double fDeltaX(rTestPosition.getX() - rEdgeEnd.getX()); - const double fDeltaY(rTestPosition.getY() - rEdgeEnd.getY()); - const double fDistanceSquare(fDeltaX * fDeltaX + fDeltaY * fDeltaY); + const B2DVector aDelta(rTestPosition - rEdgeEnd); + const double fDistanceSquare(aDelta.scalar(aDelta)); if(fDistanceSquare <= fDistance * fDistance) { diff --git a/basegfx/source/polygon/b2dpolypolygon.cxx b/basegfx/source/polygon/b2dpolypolygon.cxx index 853e822537e5..6467e7120c03 100644 --- a/basegfx/source/polygon/b2dpolypolygon.cxx +++ b/basegfx/source/polygon/b2dpolypolygon.cxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: b2dpolypolygon.cxx,v $ - * $Revision: 1.21 $ + * $Revision: 1.21.4.1 $ * * This file is part of OpenOffice.org. * @@ -106,7 +106,7 @@ public: for(sal_uInt32 a(0L); a < nCount; a++) { - maPolygons.insert(aIndex, rPolyPolygon.getB2DPolygon(a)); + aIndex = maPolygons.insert(aIndex, rPolyPolygon.getB2DPolygon(a)); aIndex++; } } diff --git a/basegfx/source/polygon/b2dpolypolygontools.cxx b/basegfx/source/polygon/b2dpolypolygontools.cxx index 7d2f6dcc8f01..c92f2f29147b 100644 --- a/basegfx/source/polygon/b2dpolypolygontools.cxx +++ b/basegfx/source/polygon/b2dpolypolygontools.cxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: b2dpolypolygontools.cxx,v $ - * $Revision: 1.19 $ + * $Revision: 1.19.4.1 $ * * This file is part of OpenOffice.org. * @@ -230,7 +230,7 @@ namespace basegfx for(sal_uInt32 a(0L); a < nPolygonCount; a++) { const B2DPolygon aPolygon(rCandidate.getB2DPolygon(a)); - const sal_Bool bInside(isInside(aPolygon, rPoint, bWithBorder)); + const bool bInside(isInside(aPolygon, rPoint, bWithBorder)); if(bInside) { diff --git a/basegfx/source/polygon/b3dpolygontools.cxx b/basegfx/source/polygon/b3dpolygontools.cxx index eaaf08f5b739..3ea163a85e89 100644 --- a/basegfx/source/polygon/b3dpolygontools.cxx +++ b/basegfx/source/polygon/b3dpolygontools.cxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: b3dpolygontools.cxx,v $ - * $Revision: 1.11 $ + * $Revision: 1.11.4.1 $ * * This file is part of OpenOffice.org. * @@ -36,6 +36,9 @@ #include #include #include +#include +#include +#include #include ////////////////////////////////////////////////////////////////////////////// @@ -748,6 +751,323 @@ namespace basegfx return aRetval; } + bool isInEpsilonRange(const B3DPoint& rEdgeStart, const B3DPoint& rEdgeEnd, const B3DPoint& rTestPosition, double fDistance) + { + // build edge vector + const B3DVector aEdge(rEdgeEnd - rEdgeStart); + bool bDoDistanceTestStart(false); + bool bDoDistanceTestEnd(false); + + if(aEdge.equalZero()) + { + // no edge, just a point. Do one of the distance tests. + bDoDistanceTestStart = true; + } + else + { + // calculate fCut in aEdge + const B3DVector aTestEdge(rTestPosition - rEdgeStart); + const double fScalarTestEdge(aEdge.scalar(aTestEdge)); + const double fScalarStartEdge(aEdge.scalar(rEdgeStart)); + const double fScalarEdge(aEdge.scalar(aEdge)); + const double fCut((fScalarTestEdge - fScalarStartEdge) / fScalarEdge); + const double fZero(0.0); + const double fOne(1.0); + + if(fTools::less(fCut, fZero)) + { + // left of rEdgeStart + bDoDistanceTestStart = true; + } + else if(fTools::more(fCut, fOne)) + { + // right of rEdgeEnd + bDoDistanceTestEnd = true; + } + else + { + // inside line [0.0 .. 1.0] + const B3DPoint aCutPoint(interpolate(rEdgeStart, rEdgeEnd, fCut)); + const B3DVector aDelta(rTestPosition - aCutPoint); + const double fDistanceSquare(aDelta.scalar(aDelta)); + + if(fDistanceSquare <= fDistance * fDistance * fDistance) + { + return true; + } + else + { + return false; + } + } + } + + if(bDoDistanceTestStart) + { + const B3DVector aDelta(rTestPosition - rEdgeStart); + const double fDistanceSquare(aDelta.scalar(aDelta)); + + if(fDistanceSquare <= fDistance * fDistance * fDistance) + { + return true; + } + } + else if(bDoDistanceTestEnd) + { + const B3DVector aDelta(rTestPosition - rEdgeEnd); + const double fDistanceSquare(aDelta.scalar(aDelta)); + + if(fDistanceSquare <= fDistance * fDistance * fDistance) + { + return true; + } + } + + return false; + } + + bool isInEpsilonRange(const B3DPolygon& rCandidate, const B3DPoint& rTestPosition, double fDistance) + { + const sal_uInt32 nPointCount(rCandidate.count()); + + if(nPointCount) + { + const sal_uInt32 nEdgeCount(rCandidate.isClosed() ? nPointCount : nPointCount - 1L); + B3DPoint aCurrent(rCandidate.getB3DPoint(0)); + + if(nEdgeCount) + { + // edges + for(sal_uInt32 a(0); a < nEdgeCount; a++) + { + const sal_uInt32 nNextIndex((a + 1) % nPointCount); + const B3DPoint aNext(rCandidate.getB3DPoint(nNextIndex)); + + if(isInEpsilonRange(aCurrent, aNext, rTestPosition, fDistance)) + { + return true; + } + + // prepare next step + aCurrent = aNext; + } + } + else + { + // no edges, but points -> not closed. Check single point. Just + // use isInEpsilonRange with twice the same point, it handles those well + if(isInEpsilonRange(aCurrent, aCurrent, rTestPosition, fDistance)) + { + return true; + } + } + } + + return false; + } + + bool isInside(const B3DPolygon& rCandidate, const B3DPoint& rPoint, bool bWithBorder) + { + if(bWithBorder && isPointOnPolygon(rCandidate, rPoint, true)) + { + return true; + } + else + { + const B3DVector aPlaneNormal(rCandidate.getNormal()); + + if(!aPlaneNormal.equalZero()) + { + const double fAbsX(fabs(aPlaneNormal.getX())); + const double fAbsY(fabs(aPlaneNormal.getY())); + const double fAbsZ(fabs(aPlaneNormal.getZ())); + + if(fAbsX > fAbsY && fAbsX > fAbsZ) + { + // normal points mostly in X-Direction, use YZ-Polygon projection for check + B3DHomMatrix aTrans; + + aTrans.set(0, 0, 0.0); + aTrans.set(0, 1, 1.0); + aTrans.set(1, 1, 0.0); + aTrans.set(1, 2, 1.0); + + const B2DPolygon aYZ(createB2DPolygonFromB3DPolygon(rCandidate, aTrans)); + + return isInside(aYZ, B2DPoint(rPoint.getY(), rPoint.getZ()), bWithBorder); + } + else if(fAbsY > fAbsX && fAbsY > fAbsZ) + { + // normal points mostly in Y-Direction, use XZ-Polygon projection for check + B3DHomMatrix aTrans; + + aTrans.set(1, 1, 0.0); + aTrans.set(1, 2, 1.0); + + const B2DPolygon aXZ(createB2DPolygonFromB3DPolygon(rCandidate, aTrans)); + + return isInside(aXZ, B2DPoint(rPoint.getX(), rPoint.getZ()), bWithBorder); + } + else + { + // normal points mostly in Z-Direction, use XY-Polygon projection for check + B3DHomMatrix aTrans; + + const B2DPolygon aXY(createB2DPolygonFromB3DPolygon(rCandidate, aTrans)); + + return isInside(aXY, B2DPoint(rPoint.getX(), rPoint.getY()), bWithBorder); + } + } + + return false; + } + } + + bool isInside(const B3DPolygon& rCandidate, const B3DPolygon& rPolygon, bool bWithBorder) + { + const sal_uInt32 nPointCount(rPolygon.count()); + + for(sal_uInt32 a(0L); a < nPointCount; a++) + { + const B3DPoint aTestPoint(rPolygon.getB3DPoint(a)); + + if(!isInside(rCandidate, aTestPoint, bWithBorder)) + { + return false; + } + } + + return true; + } + + bool isPointOnLine(const B3DPoint& rStart, const B3DPoint& rEnd, const B3DPoint& rCandidate, bool bWithPoints) + { + if(rCandidate.equal(rStart) || rCandidate.equal(rEnd)) + { + // candidate is in epsilon around start or end -> inside + return bWithPoints; + } + else if(rStart.equal(rEnd)) + { + // start and end are equal, but candidate is outside their epsilon -> outside + return false; + } + else + { + const B3DVector aEdgeVector(rEnd - rStart); + const B3DVector aTestVector(rCandidate - rStart); + + if(areParallel(aEdgeVector, aTestVector)) + { + const double fZero(0.0); + const double fOne(1.0); + double fParamTestOnCurr(0.0); + + if(aEdgeVector.getX() > aEdgeVector.getY()) + { + if(aEdgeVector.getX() > aEdgeVector.getZ()) + { + // X is biggest + fParamTestOnCurr = aTestVector.getX() / aEdgeVector.getX(); + } + else + { + // Z is biggest + fParamTestOnCurr = aTestVector.getZ() / aEdgeVector.getZ(); + } + } + else + { + if(aEdgeVector.getY() > aEdgeVector.getZ()) + { + // Y is biggest + fParamTestOnCurr = aTestVector.getY() / aEdgeVector.getY(); + } + else + { + // Z is biggest + fParamTestOnCurr = aTestVector.getZ() / aEdgeVector.getZ(); + } + } + + if(fTools::more(fParamTestOnCurr, fZero) && fTools::less(fParamTestOnCurr, fOne)) + { + return true; + } + } + + return false; + } + } + + bool isPointOnPolygon(const B3DPolygon& rCandidate, const B3DPoint& rPoint, bool bWithPoints) + { + const sal_uInt32 nPointCount(rCandidate.count()); + + if(nPointCount > 1L) + { + const sal_uInt32 nLoopCount(rCandidate.isClosed() ? nPointCount : nPointCount - 1L); + B3DPoint aCurrentPoint(rCandidate.getB3DPoint(0)); + + for(sal_uInt32 a(0); a < nLoopCount; a++) + { + const B3DPoint aNextPoint(rCandidate.getB3DPoint((a + 1) % nPointCount)); + + if(isPointOnLine(aCurrentPoint, aNextPoint, rPoint, bWithPoints)) + { + return true; + } + + aCurrentPoint = aNextPoint; + } + } + else if(nPointCount && bWithPoints) + { + return rPoint.equal(rCandidate.getB3DPoint(0)); + } + + return false; + } + + bool getCutBetweenLineAndPlane(const B3DVector& rPlaneNormal, const B3DPoint& rPlanePoint, const B3DPoint& rEdgeStart, const B3DPoint& rEdgeEnd, double& fCut) + { + if(!rPlaneNormal.equalZero() && !rEdgeStart.equal(rEdgeEnd)) + { + const B3DVector aTestEdge(rEdgeEnd - rEdgeStart); + const double fScalarEdge(rPlaneNormal.scalar(aTestEdge)); + + if(!fTools::equalZero(fScalarEdge)) + { + const B3DVector aCompareEdge(rPlanePoint - rEdgeStart); + const double fScalarCompare(rPlaneNormal.scalar(aCompareEdge)); + + fCut = fScalarCompare / fScalarEdge; + return true; + } + } + + return false; + } + + bool getCutBetweenLineAndPolygon(const B3DPolygon& rCandidate, const B3DPoint& rEdgeStart, const B3DPoint& rEdgeEnd, double& fCut) + { + const sal_uInt32 nPointCount(rCandidate.count()); + + if(nPointCount > 2 && !rEdgeStart.equal(rEdgeEnd)) + { + const B3DVector aPlaneNormal(rCandidate.getNormal()); + + if(!aPlaneNormal.equalZero()) + { + const B3DPoint aPointOnPlane(rCandidate.getB3DPoint(0)); + + return getCutBetweenLineAndPlane(aPlaneNormal, aPointOnPlane, rEdgeStart, rEdgeEnd, fCut); + } + } + + return false; + } + ////////////////////////////////////////////////////////////////////// // comparators with tolerance for 3D Polygons diff --git a/basegfx/source/polygon/b3dpolypolygontools.cxx b/basegfx/source/polygon/b3dpolypolygontools.cxx index 2f73d9688b15..fe75e3919d21 100644 --- a/basegfx/source/polygon/b3dpolypolygontools.cxx +++ b/basegfx/source/polygon/b3dpolypolygontools.cxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: b3dpolypolygontools.cxx,v $ - * $Revision: 1.8 $ + * $Revision: 1.8.4.1 $ * * This file is part of OpenOffice.org. * @@ -496,6 +496,33 @@ namespace basegfx return aRetval; } + bool isInside(const B3DPolyPolygon& rCandidate, const B3DPoint& rPoint, bool bWithBorder) + { + const sal_uInt32 nPolygonCount(rCandidate.count()); + + if(1L == nPolygonCount) + { + return isInside(rCandidate.getB3DPolygon(0), rPoint, bWithBorder); + } + else + { + sal_Int32 nInsideCount(0); + + for(sal_uInt32 a(0); a < nPolygonCount; a++) + { + const B3DPolygon aPolygon(rCandidate.getB3DPolygon(a)); + const bool bInside(isInside(aPolygon, rPoint, bWithBorder)); + + if(bInside) + { + nInsideCount++; + } + } + + return (nInsideCount % 2L); + } + } + ////////////////////////////////////////////////////////////////////// // comparators with tolerance for 3D PolyPolygons diff --git a/basegfx/source/vector/b3dvector.cxx b/basegfx/source/vector/b3dvector.cxx index 0bba99dbee1b..3a7e04f4eea1 100644 --- a/basegfx/source/vector/b3dvector.cxx +++ b/basegfx/source/vector/b3dvector.cxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: b3dvector.cxx,v $ - * $Revision: 1.9 $ + * $Revision: 1.9.4.1 $ * * This file is part of OpenOffice.org. * @@ -99,6 +99,19 @@ namespace basegfx B3DVector aRes( rVec ); return aRes*=rMat; } + + bool areParallel( const B3DVector& rVecA, const B3DVector& rVecB ) + { + // i think fastest is to compare relations, need no square or division + if(!fTools::equal(rVecA.getX() * rVecB.getY(), rVecA.getY() * rVecB.getX())) + return false; + + if(!fTools::equal(rVecA.getX() * rVecB.getZ(), rVecA.getZ() * rVecB.getX())) + return false; + + return (fTools::equal(rVecA.getY() * rVecB.getZ(), rVecA.getZ() * rVecB.getY())); + } + } // end of namespace basegfx ////////////////////////////////////////////////////////////////////////////// -- cgit