summaryrefslogtreecommitdiff
path: root/basegfx/source
diff options
context:
space:
mode:
authorOliver Bolte <obo@openoffice.org>2008-10-17 08:40:10 +0000
committerOliver Bolte <obo@openoffice.org>2008-10-17 08:40:10 +0000
commit98c9f4f4f2506db7385cc3f0fa7bb1b14930a417 (patch)
treee6881eda00d35e22f6ac51732df02db300814385 /basegfx/source
parent52a7bbb9c5d88ee817b4e484696846adbc7b305e (diff)
CWS-TOOLING: integrate CWS aw057
Diffstat (limited to 'basegfx/source')
-rw-r--r--basegfx/source/polygon/b2dpolygontools.cxx24
-rw-r--r--basegfx/source/polygon/b2dpolypolygon.cxx4
-rw-r--r--basegfx/source/polygon/b2dpolypolygontools.cxx4
-rw-r--r--basegfx/source/polygon/b3dpolygontools.cxx322
-rw-r--r--basegfx/source/polygon/b3dpolypolygontools.cxx29
-rw-r--r--basegfx/source/vector/b3dvector.cxx15
6 files changed, 376 insertions, 22 deletions
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 <basegfx/numeric/ftools.hxx>
#include <basegfx/range/b3drange.hxx>
#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/matrix/b3dhommatrix.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
#include <numeric>
//////////////////////////////////////////////////////////////////////////////
@@ -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
//////////////////////////////////////////////////////////////////////////////