summaryrefslogtreecommitdiff
path: root/basegfx/source/polygon/b2dpolypolygoncutter.cxx
diff options
context:
space:
mode:
authorArmin Weiss <aw@openoffice.org>2003-11-28 10:18:16 +0000
committerArmin Weiss <aw@openoffice.org>2003-11-28 10:18:16 +0000
commitd539c95155ccc7030411f7494704894a3ac610a8 (patch)
treedc3dbd283a5f501f6e48dd585d80bb158db920e3 /basegfx/source/polygon/b2dpolypolygoncutter.cxx
parentce0ce72d1fd37f7b8e7cb4ebc372d8cd6b4ab9c0 (diff)
Removed in-between namespaces (curve, matrix, numeric, point, polygon, range, tuple, vector). Names were too common and e.g. vector leaded to problems with some defines. This is now avoided. Also some bug fixes, addition of 3d polygon tooling etc.
Diffstat (limited to 'basegfx/source/polygon/b2dpolypolygoncutter.cxx')
-rw-r--r--basegfx/source/polygon/b2dpolypolygoncutter.cxx1542
1 files changed, 765 insertions, 777 deletions
diff --git a/basegfx/source/polygon/b2dpolypolygoncutter.cxx b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
index a86bfce3d937..17d1c476acbf 100644
--- a/basegfx/source/polygon/b2dpolypolygoncutter.cxx
+++ b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: b2dpolypolygoncutter.cxx,v $
*
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
*
- * last change: $Author: aw $ $Date: 2003-11-26 14:40:12 $
+ * last change: $Author: aw $ $Date: 2003-11-28 11:18:06 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -88,231 +88,228 @@
namespace basegfx
{
- namespace polygon
+ B2DPolygonNode::B2DPolygonNode(const ::basegfx::B2DPoint& rPosition, B2DPolygonNode* pPrevious)
+ : maPosition(rPosition)
{
- B2DPolygonNode::B2DPolygonNode(const ::basegfx::point::B2DPoint& rPosition, B2DPolygonNode* pPrevious)
- : maPosition(rPosition)
- {
- mpListPrevious = this;
- mpListNext = this;
+ mpListPrevious = this;
+ mpListNext = this;
- if(pPrevious)
- {
- mpNext = pPrevious->getNext();
- mpPrevious = pPrevious;
- mpNext->mpPrevious = this;
- mpPrevious->mpNext = this;
- }
- else
- {
- mpPrevious = mpNext = this;
- }
+ if(pPrevious)
+ {
+ mpNext = pPrevious->getNext();
+ mpPrevious = pPrevious;
+ mpNext->mpPrevious = this;
+ mpPrevious->mpNext = this;
}
-
- B2DPolygonNode::~B2DPolygonNode()
+ else
{
- if(mpNext != this)
- {
- mpPrevious->mpNext = mpNext;
- mpNext->mpPrevious = mpPrevious;
- }
+ mpPrevious = mpNext = this;
}
+ }
- void B2DPolygonNode::calcMinMaxX(double& fMaxAX, double& fMinAX) const
+ B2DPolygonNode::~B2DPolygonNode()
+ {
+ if(mpNext != this)
{
- if(maPosition.getX() > mpNext->maPosition.getX())
- {
- fMaxAX = maPosition.getX();
- fMinAX = mpNext->maPosition.getX();
- }
- else
- {
- fMaxAX = mpNext->maPosition.getX();
- fMinAX = maPosition.getX();
- }
+ mpPrevious->mpNext = mpNext;
+ mpNext->mpPrevious = mpPrevious;
}
+ }
- void B2DPolygonNode::calcMinMaxY(double& fMaxAY, double& fMinAY) const
+ void B2DPolygonNode::calcMinMaxX(double& fMaxAX, double& fMinAX) const
+ {
+ if(maPosition.getX() > mpNext->maPosition.getX())
{
- if(maPosition.getY() > mpNext->maPosition.getY())
- {
- fMaxAY = maPosition.getY();
- fMinAY = mpNext->maPosition.getY();
- }
- else
- {
- fMaxAY = mpNext->maPosition.getY();
- fMinAY = maPosition.getY();
- }
+ fMaxAX = maPosition.getX();
+ fMinAX = mpNext->maPosition.getX();
+ }
+ else
+ {
+ fMaxAX = mpNext->maPosition.getX();
+ fMinAX = maPosition.getX();
}
+ }
- void B2DPolygonNode::swapNextPointers(B2DPolygonNode* pCand)
+ void B2DPolygonNode::calcMinMaxY(double& fMaxAY, double& fMinAY) const
+ {
+ if(maPosition.getY() > mpNext->maPosition.getY())
{
- B2DPolygonNode* pTemporary = mpNext;
- mpNext = pCand->mpNext;
- pCand->mpNext = pTemporary;
- mpNext->mpPrevious = this;
- pCand->mpNext->mpPrevious = pCand;
+ fMaxAY = maPosition.getY();
+ fMinAY = mpNext->maPosition.getY();
+ }
+ else
+ {
+ fMaxAY = mpNext->maPosition.getY();
+ fMinAY = maPosition.getY();
}
+ }
- void B2DPolygonNode::addToList(B2DPolygonNode*& rpList)
+ void B2DPolygonNode::swapNextPointers(B2DPolygonNode* pCand)
+ {
+ B2DPolygonNode* pTemporary = mpNext;
+ mpNext = pCand->mpNext;
+ pCand->mpNext = pTemporary;
+ mpNext->mpPrevious = this;
+ pCand->mpNext->mpPrevious = pCand;
+ }
+
+ void B2DPolygonNode::addToList(B2DPolygonNode*& rpList)
+ {
+ if(rpList)
{
- if(rpList)
- {
- mpListNext = rpList->mpListNext;
- rpList->mpListNext = this;
- mpListPrevious = rpList;
- mpListNext->mpListPrevious = this;
- }
- else
- {
- rpList = this;
- }
+ mpListNext = rpList->mpListNext;
+ rpList->mpListNext = this;
+ mpListPrevious = rpList;
+ mpListNext->mpListPrevious = this;
+ }
+ else
+ {
+ rpList = this;
}
+ }
- void B2DPolygonNode::remFromList(B2DPolygonNode*& rpList)
+ void B2DPolygonNode::remFromList(B2DPolygonNode*& rpList)
+ {
+ if(mpListNext != this)
{
- if(mpListNext != this)
+ if(rpList == this)
{
- if(rpList == this)
- {
- rpList = mpListPrevious;
- }
-
- mpListPrevious->mpListNext = mpListNext;
- mpListNext->mpListPrevious = mpListPrevious;
- mpListNext = mpListPrevious = this;
+ rpList = mpListPrevious;
}
- else
+
+ mpListPrevious->mpListNext = mpListNext;
+ mpListNext->mpListPrevious = mpListPrevious;
+ mpListNext = mpListPrevious = this;
+ }
+ else
+ {
+ if(rpList == this)
{
- if(rpList == this)
- {
- rpList = 0L;
- }
+ rpList = 0L;
}
}
+ }
- sal_Bool B2DPolygonNode::getOrientation() const
- {
- const B2DPolygonNode* pOutmost = this;
- const B2DPolygonNode* pCurrent = this->getNext();
+ sal_Bool B2DPolygonNode::getOrientation() const
+ {
+ const B2DPolygonNode* pOutmost = this;
+ const B2DPolygonNode* pCurrent = this->getNext();
- while(pCurrent != this)
+ while(pCurrent != this)
+ {
+ if(::basegfx::fTools::more(pOutmost->getPosition().getX(), pCurrent->getPosition().getX()))
{
- if(::basegfx::numeric::fTools::more(pOutmost->getPosition().getX(), pCurrent->getPosition().getX()))
+ if(pCurrent->getPosition().getX() < pOutmost->getPosition().getX())
+ {
+ pOutmost = pCurrent;
+ }
+ else
{
- if(pCurrent->getPosition().getX() < pOutmost->getPosition().getX())
+ if(pCurrent->getPosition().getY() < pOutmost->getPosition().getY())
{
pOutmost = pCurrent;
}
- else
- {
- if(pCurrent->getPosition().getY() < pOutmost->getPosition().getY())
- {
- pOutmost = pCurrent;
- }
- }
}
-
- // next node
- pCurrent = pCurrent->getNext();
}
- ::basegfx::vector::B2DVector aVec1(pOutmost->getPrevious()->getPosition() - pOutmost->getPosition());
- ::basegfx::vector::B2DVector aVec2(pOutmost->getNext()->getPosition() - pOutmost->getPosition());
- return sal_Bool(::basegfx::numeric::fTools::more(aVec1.getX() * aVec2.getY(), aVec1.getY() * aVec2.getX()));
+ // next node
+ pCurrent = pCurrent->getNext();
}
- void B2DPolygonNode::swapOrientation()
- {
- B2DPolygonNode* pCurrent = this;
+ ::basegfx::B2DVector aVec1(pOutmost->getPrevious()->getPosition() - pOutmost->getPosition());
+ ::basegfx::B2DVector aVec2(pOutmost->getNext()->getPosition() - pOutmost->getPosition());
+ return sal_Bool(::basegfx::fTools::more(aVec1.getX() * aVec2.getY(), aVec1.getY() * aVec2.getX()));
+ }
- do {
- pCurrent->swapPreviousNext();
- pCurrent = pCurrent->getPrevious();
- } while(pCurrent != this);
- }
+ void B2DPolygonNode::swapOrientation()
+ {
+ B2DPolygonNode* pCurrent = this;
- ::basegfx::range::B2DRange B2DPolygonNode::getRange() const
- {
- ::basegfx::range::B2DRange aRetval;
- const B2DPolygonNode* pCurrent = this;
+ do {
+ pCurrent->swapPreviousNext();
+ pCurrent = pCurrent->getPrevious();
+ } while(pCurrent != this);
+ }
- do {
- aRetval.expand(pCurrent->getPosition());
- pCurrent = pCurrent->getPrevious();
- } while(pCurrent != this);
+ ::basegfx::B2DRange B2DPolygonNode::getRange() const
+ {
+ ::basegfx::B2DRange aRetval;
+ const B2DPolygonNode* pCurrent = this;
- return aRetval;
- }
+ do {
+ aRetval.expand(pCurrent->getPosition());
+ pCurrent = pCurrent->getPrevious();
+ } while(pCurrent != this);
- sal_Bool B2DPolygonNode::isInside(const ::basegfx::point::B2DPoint& rPoint, sal_Bool bWithBorder) const
+ return aRetval;
+ }
+
+ sal_Bool B2DPolygonNode::isInside(const ::basegfx::B2DPoint& rPoint, sal_Bool bWithBorder) const
+ {
+ sal_Bool bInside(sal_False);
+ const B2DPolygonNode* pCurrent = this;
+
+ do
{
- sal_Bool bInside(sal_False);
- const B2DPolygonNode* pCurrent = this;
+ if(bWithBorder && pCurrent->getPosition().equal(rPoint))
+ {
+ return sal_True;
+ }
+
+ B2DPolygonNode* pNext = pCurrent->getNext();
+ const sal_Bool bCompYA(::basegfx::fTools::more(pCurrent->getPosition().getY(), rPoint.getY()));
+ const sal_Bool bCompYB(::basegfx::fTools::more(pNext->getPosition().getY(), rPoint.getY()));
- do
+ if(bCompYA != bCompYB)
{
- if(bWithBorder && pCurrent->getPosition().equal(rPoint))
+ const sal_Bool bCompXA(::basegfx::fTools::more(pCurrent->getPosition().getX(), rPoint.getX()));
+ const sal_Bool bCompXB(::basegfx::fTools::more(pNext->getPosition().getX(), rPoint.getX()));
+
+ if(bCompXA == bCompXB)
{
- return sal_True;
+ if(bCompXA)
+ {
+ bInside = !bInside;
+ }
}
-
- B2DPolygonNode* pNext = pCurrent->getNext();
- const sal_Bool bCompYA(::basegfx::numeric::fTools::more(pCurrent->getPosition().getY(), rPoint.getY()));
- const sal_Bool bCompYB(::basegfx::numeric::fTools::more(pNext->getPosition().getY(), rPoint.getY()));
-
- if(bCompYA != bCompYB)
+ else
{
- const sal_Bool bCompXA(::basegfx::numeric::fTools::more(pCurrent->getPosition().getX(), rPoint.getX()));
- const sal_Bool bCompXB(::basegfx::numeric::fTools::more(pNext->getPosition().getX(), rPoint.getX()));
+ double fCmp =
+ pNext->getPosition().getX() - (pNext->getPosition().getY() - rPoint.getY()) *
+ (pCurrent->getPosition().getX() - pNext->getPosition().getX()) /
+ (pCurrent->getPosition().getY() - pNext->getPosition().getY());
- if(bCompXA == bCompXB)
+ if(bWithBorder && ::basegfx::fTools::more(fCmp, rPoint.getX()))
{
- if(bCompXA)
- {
- bInside = !bInside;
- }
+ bInside = !bInside;
}
- else
+ else if(::basegfx::fTools::moreOrEqual(fCmp, rPoint.getX()))
{
- double fCmp =
- pNext->getPosition().getX() - (pNext->getPosition().getY() - rPoint.getY()) *
- (pCurrent->getPosition().getX() - pNext->getPosition().getX()) /
- (pCurrent->getPosition().getY() - pNext->getPosition().getY());
-
- if(bWithBorder && ::basegfx::numeric::fTools::more(fCmp, rPoint.getX()))
- {
- bInside = !bInside;
- }
- else if(::basegfx::numeric::fTools::moreOrEqual(fCmp, rPoint.getX()))
- {
- bInside = !bInside;
- }
+ bInside = !bInside;
}
}
+ }
- // next edge
- pCurrent = pNext;
+ // next edge
+ pCurrent = pNext;
- } while(pCurrent != this);
+ } while(pCurrent != this);
- return bInside;
- }
+ return bInside;
+ }
- sal_Bool B2DPolygonNode::isPolygonInside(B2DPolygonNode* pPoly, sal_Bool bWithBorder) const
- {
- B2DPolygonNode* pTest = pPoly;
- sal_Bool bAllAInside(sal_True);
+ sal_Bool B2DPolygonNode::isPolygonInside(B2DPolygonNode* pPoly, sal_Bool bWithBorder) const
+ {
+ B2DPolygonNode* pTest = pPoly;
+ sal_Bool bAllAInside(sal_True);
- do {
- bAllAInside = isInside(pTest->getPosition(), bWithBorder);
- pTest = pTest->getNext();
- } while(bAllAInside && pTest != pPoly);
+ do {
+ bAllAInside = isInside(pTest->getPosition(), bWithBorder);
+ pTest = pTest->getNext();
+ } while(bAllAInside && pTest != pPoly);
- return bAllAInside;
- }
- } // end of namespace polygon
+ return bAllAInside;
+ }
} // end of namespace basegfx
//////////////////////////////////////////////////////////////////////////////
@@ -320,26 +317,23 @@ namespace basegfx
namespace basegfx
{
- namespace polygon
+ void B2DSimpleCut::solve()
{
- void B2DSimpleCut::solve()
- {
- mpLeft->swapNextPointers(mpRight);
+ mpLeft->swapNextPointers(mpRight);
- if(mbCorrectOrientation)
+ if(mbCorrectOrientation)
+ {
+ if(mpLeft->getOrientation() != mbOrientation)
{
- if(mpLeft->getOrientation() != mbOrientation)
- {
- mpLeft->swapOrientation();
- }
+ mpLeft->swapOrientation();
+ }
- if(mpRight->getOrientation() != mbOrientation)
- {
- mpRight->swapOrientation();
- }
+ if(mpRight->getOrientation() != mbOrientation)
+ {
+ mpRight->swapOrientation();
}
}
- } // end of namespace polygon
+ }
} // end of namespace basegfx
//////////////////////////////////////////////////////////////////////////////
@@ -347,27 +341,24 @@ namespace basegfx
namespace basegfx
{
- namespace polygon
+ void B2DClipExtraPolygonInfo::init(B2DPolygonNode* pNew)
{
- void B2DClipExtraPolygonInfo::init(B2DPolygonNode* pNew)
+ maRange = pNew->getRange();
+ mbOrientation = pNew->getOrientation();
+ mnDepth = (mbOrientation) ? 0L : -1L;
+ }
+
+ void B2DClipExtraPolygonInfo::changeDepth(sal_Bool bOrientation)
+ {
+ if(bOrientation)
{
- maRange = pNew->getRange();
- mbOrientation = pNew->getOrientation();
- mnDepth = (mbOrientation) ? 0L : -1L;
+ mnDepth++;
}
-
- void B2DClipExtraPolygonInfo::changeDepth(sal_Bool bOrientation)
+ else
{
- if(bOrientation)
- {
- mnDepth++;
- }
- else
- {
- mnDepth--;
- }
+ mnDepth--;
}
- } // end of namespace polygon
+ }
} // end of namespace basegfx
//////////////////////////////////////////////////////////////////////////////
@@ -375,772 +366,769 @@ namespace basegfx
namespace basegfx
{
- namespace polygon
+ B2DPolyPolygonCutter::~B2DPolyPolygonCutter()
{
- B2DPolyPolygonCutter::~B2DPolyPolygonCutter()
+ for(sal_uInt32 a(0L); a < maPolygonList.size(); a++)
{
- for(sal_uInt32 a(0L); a < maPolygonList.size(); a++)
- {
- delete maPolygonList[a];
- }
-
- maPolygonList.clear();
+ delete maPolygonList[a];
}
- void B2DPolyPolygonCutter::removeIncludedPolygons(sal_Bool bUseOr)
+ maPolygonList.clear();
+ }
+
+ void B2DPolyPolygonCutter::removeIncludedPolygons(sal_Bool bUseOr)
+ {
+ const sal_uInt32 aCount(maPolygonList.size());
+ B2DClipExtraPolygonInfo* pInfos = new B2DClipExtraPolygonInfo[aCount];
+ sal_uInt32 a, b;
+
+ // fill infos
+ for(a = 0L; a < aCount; a++)
{
- const sal_uInt32 aCount(maPolygonList.size());
- B2DClipExtraPolygonInfo* pInfos = new B2DClipExtraPolygonInfo[aCount];
- sal_uInt32 a, b;
+ pInfos[a].init(maPolygonList[a]);
+ }
- // fill infos
- for(a = 0L; a < aCount; a++)
- {
- pInfos[a].init(maPolygonList[a]);
- }
+ // get all includes
+ for(a = 0L; a < aCount; a++)
+ {
+ B2DClipExtraPolygonInfo& rInfoA = pInfos[a];
- // get all includes
- for(a = 0L; a < aCount; a++)
+ for(b = 0L; b < aCount; b++)
{
- B2DClipExtraPolygonInfo& rInfoA = pInfos[a];
+ B2DClipExtraPolygonInfo& rInfoB = pInfos[b];
- for(b = 0L; b < aCount; b++)
+ if(a != b && doRangesInclude(rInfoA.getRange(), rInfoB.getRange()))
{
- B2DClipExtraPolygonInfo& rInfoB = pInfos[b];
-
- if(a != b && doRangesInclude(rInfoA.getRange(), rInfoB.getRange()))
+ // volume B in A, test pA, pB for inclusion, with border
+ if(maPolygonList[a]->isPolygonInside(maPolygonList[b], sal_True))
{
- // volume B in A, test pA, pB for inclusion, with border
- if(maPolygonList[a]->isPolygonInside(maPolygonList[b], sal_True))
- {
- // pB is inside pA
- rInfoB.changeDepth(rInfoA.getOrientation());
- }
+ // pB is inside pA
+ rInfoB.changeDepth(rInfoA.getOrientation());
}
}
}
+ }
- // delete removable
- for(a = 0L, b = 0L; a < aCount; a++)
- {
- B2DClipExtraPolygonInfo& rInfo = pInfos[a];
+ // delete removable
+ for(a = 0L, b = 0L; a < aCount; a++)
+ {
+ B2DClipExtraPolygonInfo& rInfo = pInfos[a];
- if((bUseOr && rInfo.getDepth() != 0L) || (!bUseOr && rInfo.getDepth() < 1L))
- {
- B2DPolygonNodeVector::iterator aPosition(maPolygonList.begin() + b);
- B2DPolygonNode* pCandidate = *aPosition;
- maPolygonList.erase(aPosition);
- deletePolygon(pCandidate);
- }
- else
- {
- b++;
- }
+ if((bUseOr && rInfo.getDepth() != 0L) || (!bUseOr && rInfo.getDepth() < 1L))
+ {
+ B2DPolygonNodeVector::iterator aPosition(maPolygonList.begin() + b);
+ B2DPolygonNode* pCandidate = *aPosition;
+ maPolygonList.erase(aPosition);
+ deletePolygon(pCandidate);
+ }
+ else
+ {
+ b++;
}
-
- // delete infos
- delete[] pInfos;
}
- void B2DPolyPolygonCutter::solveAllCuts(B2DSimpleCutVector& rCuts)
- {
- B2DPolygonNode* pNewList = 0L;
-
- // add all nodes of polys to list
- polysToList(pNewList);
+ // delete infos
+ delete[] pInfos;
+ }
- // solve cuts
- B2DSimpleCutVector::iterator aCandidate(rCuts.begin());
+ void B2DPolyPolygonCutter::solveAllCuts(B2DSimpleCutVector& rCuts)
+ {
+ B2DPolygonNode* pNewList = 0L;
- for(; aCandidate < rCuts.end(); aCandidate++)
- {
- B2DSimpleCut* pCut = *aCandidate;
- pCut->solve();
- delete pCut;
- }
+ // add all nodes of polys to list
+ polysToList(pNewList);
- rCuts.clear();
+ // solve cuts
+ B2DSimpleCutVector::iterator aCandidate(rCuts.begin());
- // extract polys
- listToPolys(pNewList);
+ for(; aCandidate < rCuts.end(); aCandidate++)
+ {
+ B2DSimpleCut* pCut = *aCandidate;
+ pCut->solve();
+ delete pCut;
}
- void B2DPolyPolygonCutter::polysToList(B2DPolygonNode*& rpList)
- {
- B2DPolygonNodeVector::iterator aCandidate(maPolygonList.begin());
+ rCuts.clear();
- for(; aCandidate != maPolygonList.end(); aCandidate++)
- {
- addAllNodes(*aCandidate, rpList);
- }
+ // extract polys
+ listToPolys(pNewList);
+ }
- maPolygonList.clear();
- }
+ void B2DPolyPolygonCutter::polysToList(B2DPolygonNode*& rpList)
+ {
+ B2DPolygonNodeVector::iterator aCandidate(maPolygonList.begin());
- void B2DPolyPolygonCutter::listToPolys(B2DPolygonNode*& rpList)
+ for(; aCandidate != maPolygonList.end(); aCandidate++)
{
- while(rpList)
- {
- // get one
- B2DPolygonNode* pNew = extractNextPolygon(rpList);
-
- if(pNew)
- {
- maPolygonList.push_back(pNew);
- }
- }
+ addAllNodes(*aCandidate, rpList);
}
- B2DPolygonNode* B2DPolyPolygonCutter::createNewPolygon(const B2DPolygon& rPolygon)
+ maPolygonList.clear();
+ }
+
+ void B2DPolyPolygonCutter::listToPolys(B2DPolygonNode*& rpList)
+ {
+ while(rpList)
{
- B2DPolygonNode* pRetval = NULL;
+ // get one
+ B2DPolygonNode* pNew = extractNextPolygon(rpList);
- for(sal_uInt32 a(0L); a < rPolygon.count(); a++)
+ if(pNew)
{
- ::basegfx::point::B2DPoint aPoint(rPolygon.getB2DPoint(a));
- pRetval = new B2DPolygonNode(aPoint, pRetval);
+ maPolygonList.push_back(pNew);
}
-
- return pRetval;
}
+ }
+
+ B2DPolygonNode* B2DPolyPolygonCutter::createNewPolygon(const B2DPolygon& rPolygon)
+ {
+ B2DPolygonNode* pRetval = NULL;
- void B2DPolyPolygonCutter::deletePolygon(B2DPolygonNode* pCand)
+ for(sal_uInt32 a(0L); a < rPolygon.count(); a++)
{
- B2DPolygonNode* pPoly = pCand;
+ ::basegfx::B2DPoint aPoint(rPolygon.getB2DPoint(a));
+ pRetval = new B2DPolygonNode(aPoint, pRetval);
+ }
- while(pPoly)
- {
- B2DPolygonNode* pNext = pPoly->getNext();
+ return pRetval;
+ }
- if(pNext == pPoly)
- {
- pNext = 0L;
- }
+ void B2DPolyPolygonCutter::deletePolygon(B2DPolygonNode* pCand)
+ {
+ B2DPolygonNode* pPoly = pCand;
+
+ while(pPoly)
+ {
+ B2DPolygonNode* pNext = pPoly->getNext();
- delete pPoly;
- pPoly = pNext;
+ if(pNext == pPoly)
+ {
+ pNext = 0L;
}
+
+ delete pPoly;
+ pPoly = pNext;
}
+ }
- void B2DPolyPolygonCutter::addAllNodes(B2DPolygonNode* pPolygon, B2DPolygonNode*& rpList)
- {
- B2DPolygonNode* pAct = pPolygon;
+ void B2DPolyPolygonCutter::addAllNodes(B2DPolygonNode* pPolygon, B2DPolygonNode*& rpList)
+ {
+ B2DPolygonNode* pAct = pPolygon;
- do {
- pAct->addToList(rpList);
- pAct = pAct->getNext();
- } while(pAct != pPolygon);
- }
+ do {
+ pAct->addToList(rpList);
+ pAct = pAct->getNext();
+ } while(pAct != pPolygon);
+ }
- void B2DPolyPolygonCutter::addPolyPolygon(const B2DPolyPolygon& rPolyPolygon, sal_Bool bForceOrientation)
+ void B2DPolyPolygonCutter::addPolyPolygon(const B2DPolyPolygon& rPolyPolygon, sal_Bool bForceOrientation)
+ {
+ for(sal_uInt32 a(0L); a < rPolyPolygon.count(); a++)
{
- for(sal_uInt32 a(0L); a < rPolyPolygon.count(); a++)
- {
- B2DPolygon aCandidate = rPolyPolygon.getB2DPolygon(a);
- aCandidate.removeDoublePoints();
+ B2DPolygon aCandidate = rPolyPolygon.getB2DPolygon(a);
+ aCandidate.removeDoublePoints();
- if(!aCandidate.isClosed() || aCandidate.count() < 3)
- {
- maNotClosedPolygons.append(aCandidate);
- }
- else
+ if(!aCandidate.isClosed() || aCandidate.count() < 3)
+ {
+ maNotClosedPolygons.append(aCandidate);
+ }
+ else
+ {
+ if(bForceOrientation)
{
- if(bForceOrientation)
- {
- ::basegfx::vector::B2DVectorOrientation aOrientation =
- ::basegfx::polygon::tools::getOrientation(aCandidate);
+ ::basegfx::B2DVectorOrientation aOrientation =
+ ::basegfx::tools::getOrientation(aCandidate);
- if(::basegfx::vector::ORIENTATION_POSITIVE != aOrientation)
- {
- aCandidate.flip();
- }
+ if(::basegfx::ORIENTATION_POSITIVE != aOrientation)
+ {
+ aCandidate.flip();
}
-
- B2DPolygonNode* pNew = createNewPolygon(aCandidate);
- maPolygonList.push_back(pNew);
}
+
+ B2DPolygonNode* pNew = createNewPolygon(aCandidate);
+ maPolygonList.push_back(pNew);
}
}
+ }
+
+ void B2DPolyPolygonCutter::getPolyPolygon(B2DPolyPolygon& rPolyPolygon)
+ {
+ B2DPolygonNodeVector::iterator aCandidate(maPolygonList.begin());
- void B2DPolyPolygonCutter::getPolyPolygon(B2DPolyPolygon& rPolyPolygon)
+ for(; aCandidate < maPolygonList.end(); aCandidate++)
{
- B2DPolygonNodeVector::iterator aCandidate(maPolygonList.begin());
+ B2DPolygonNode* pCand = *aCandidate;
+ B2DPolygonNode* pAct = pCand;
+ sal_uInt32 nCount(0L);
+
+ do {
+ nCount++;
+ pAct = pAct->getNext();
+ } while(pAct != pCand);
- for(; aCandidate < maPolygonList.end(); aCandidate++)
+ if(nCount > 2L)
{
- B2DPolygonNode* pCand = *aCandidate;
- B2DPolygonNode* pAct = pCand;
- sal_uInt32 nCount(0L);
+ B2DPolygon aNewPolygon;
do {
- nCount++;
+ aNewPolygon.append(pAct->getPosition());
pAct = pAct->getNext();
} while(pAct != pCand);
- if(nCount > 2L)
- {
- B2DPolygon aNewPolygon;
+ aNewPolygon.setClosed(sal_True);
+ rPolyPolygon.append(aNewPolygon);
+ }
- do {
- aNewPolygon.append(pAct->getPosition());
- pAct = pAct->getNext();
- } while(pAct != pCand);
+ deletePolygon(pCand);
+ }
- aNewPolygon.setClosed(sal_True);
- rPolyPolygon.append(aNewPolygon);
- }
+ maPolygonList.clear();
- deletePolygon(pCand);
- }
+ while(maNotClosedPolygons.count())
+ {
+ rPolyPolygon.append(maNotClosedPolygons.getB2DPolygon(0L));
+ maNotClosedPolygons.remove(0L);
+ }
+ }
- maPolygonList.clear();
+ B2DSimpleCut* B2DPolyPolygonCutter::getExistingCut(B2DSimpleCutVector& rTmpCuts, B2DPolygonNode* pA, B2DPolygonNode* pB)
+ {
+ for(sal_uInt32 a(0L); a < rTmpCuts.size(); a++)
+ {
+ B2DSimpleCut* pCand = rTmpCuts[a];
- while(maNotClosedPolygons.count())
+ if(pCand->isSameCut(pA, pB))
{
- rPolyPolygon.append(maNotClosedPolygons.getB2DPolygon(0L));
- maNotClosedPolygons.remove(0L);
+ return pCand;
}
}
- B2DSimpleCut* B2DPolyPolygonCutter::getExistingCut(B2DSimpleCutVector& rTmpCuts, B2DPolygonNode* pA, B2DPolygonNode* pB)
- {
- for(sal_uInt32 a(0L); a < rTmpCuts.size(); a++)
- {
- B2DSimpleCut* pCand = rTmpCuts[a];
+ return 0L;
+ }
- if(pCand->isSameCut(pA, pB))
- {
- return pCand;
- }
- }
+ B2DPolygonNode* B2DPolyPolygonCutter::extractNextPolygon(B2DPolygonNode*& rpList)
+ {
+ B2DPolygonNode* pStart = rpList;
+
+ // remove all nodes of this poly from list
+ B2DPolygonNode* pAct = pStart;
+ sal_uInt32 nNumNodes(0L);
+
+ do {
+ pAct->remFromList(rpList);
+ pAct = pAct->getNext();
+ nNumNodes++;
+ } while(pAct != pStart);
+ if(nNumNodes < 3L)
+ {
+ deletePolygon(pStart);
return 0L;
}
-
- B2DPolygonNode* B2DPolyPolygonCutter::extractNextPolygon(B2DPolygonNode*& rpList)
+ else
{
- B2DPolygonNode* pStart = rpList;
-
- // remove all nodes of this poly from list
- B2DPolygonNode* pAct = pStart;
- sal_uInt32 nNumNodes(0L);
-
- do {
- pAct->remFromList(rpList);
- pAct = pAct->getNext();
- nNumNodes++;
- } while(pAct != pStart);
-
- if(nNumNodes < 3L)
- {
- deletePolygon(pStart);
- return 0L;
- }
- else
- {
- return pStart;
- }
+ return pStart;
}
+ }
- void B2DPolyPolygonCutter::removeSelfIntersections()
+ void B2DPolyPolygonCutter::removeSelfIntersections()
+ {
+ B2DSimpleCutVector aCuts;
+ B2DSimpleCutVector aNewCuts;
+ B2DPolygonNode* pCand;
+ B2DPolygonNode* pA;
+ B2DPolygonNode* pB;
+ double fMaxAX, fMinAX, fMaxAY, fMinAY;
+ double fMaxBX, fMinBX, fMaxBY, fMinBY;
+ double fCut;
+
+ // first job: Find all cuts and add points there
+ for(sal_uInt32 a(0L); a < maPolygonList.size(); a++)
{
- B2DSimpleCutVector aCuts;
- B2DSimpleCutVector aNewCuts;
- B2DPolygonNode* pCand;
- B2DPolygonNode* pA;
- B2DPolygonNode* pB;
- double fMaxAX, fMinAX, fMaxAY, fMinAY;
- double fMaxBX, fMinBX, fMaxBY, fMinBY;
- double fCut;
-
- // first job: Find all cuts and add points there
- for(sal_uInt32 a(0L); a < maPolygonList.size(); a++)
- {
- pCand = maPolygonList[a];
- pA = pCand;
+ pCand = maPolygonList[a];
+ pA = pCand;
+
+ // one run to find same start positions (so there is no need to
+ // search for existing cuts in main loop)
+ do {
+ pB = pA->getNext();
- // one run to find same start positions (so there is no need to
- // search for existing cuts in main loop)
do {
- pB = pA->getNext();
+ if(isSamePos(pA->getPosition(), pB->getPosition()))
+ {
+ aNewCuts.push_back(new B2DSimpleCut(pA, pB, sal_True, pCand->getOrientation()));
+ }
- do {
- if(isSamePos(pA->getPosition(), pB->getPosition()))
- {
- aNewCuts.push_back(new B2DSimpleCut(pA, pB, sal_True, pCand->getOrientation()));
- }
+ // next B
+ pB = pB->getNext();
+ } while(pB != pCand);
- // next B
- pB = pB->getNext();
- } while(pB != pCand);
+ // next A
+ pA = pA->getNext();
+ } while(pA->getNext() != pCand);
- // next A
- pA = pA->getNext();
- } while(pA->getNext() != pCand);
+ // second run to find real cuts
+ pA = pCand;
- // second run to find real cuts
- pA = pCand;
+ do {
+ // get bounds for this edge in poly
+ pA->calcMinMaxX(fMaxAX, fMinAX);
+ pA->calcMinMaxY(fMaxAY, fMinAY);
+ pB = pA->getNext();
do {
- // get bounds for this edge in poly
- pA->calcMinMaxX(fMaxAX, fMinAX);
- pA->calcMinMaxY(fMaxAY, fMinAY);
- pB = pA->getNext();
+ pB->calcMinMaxX(fMaxBX, fMinBX);
- do {
- pB->calcMinMaxX(fMaxBX, fMinBX);
+ if(::basegfx::fTools::more(fMaxBX, fMinAX)
+ && ::basegfx::fTools::more(fMaxAX, fMinBX))
+ {
+ pB->calcMinMaxY(fMaxBY, fMinBY);
- if(::basegfx::numeric::fTools::more(fMaxBX, fMinAX)
- && ::basegfx::numeric::fTools::more(fMaxAX, fMinBX))
+ if(::basegfx::fTools::more(fMaxBY, fMinAY)
+ && ::basegfx::fTools::more(fMaxAY, fMinBY))
{
- pB->calcMinMaxY(fMaxBY, fMinBY);
-
- if(::basegfx::numeric::fTools::more(fMaxBY, fMinAY)
- && ::basegfx::numeric::fTools::more(fMaxAY, fMinBY))
+ if(!isSamePos(pA->getPosition(), pB->getPosition()))
{
- if(!isSamePos(pA->getPosition(), pB->getPosition()))
- {
- const ::basegfx::vector::B2DVector aVectorA(pA->getNext()->getPosition() - pA->getPosition());
- const ::basegfx::vector::B2DVector aVectorB(pB->getNext()->getPosition() - pB->getPosition());
+ const ::basegfx::B2DVector aVectorA(pA->getNext()->getPosition() - pA->getPosition());
+ const ::basegfx::B2DVector aVectorB(pB->getNext()->getPosition() - pB->getPosition());
- if(::basegfx::polygon::tools::findCut(pA->getPosition(), aVectorA, pB->getPosition(), aVectorB, CUTFLAG_LINE, &fCut))
+ if(::basegfx::tools::findCut(pA->getPosition(), aVectorA, pB->getPosition(), aVectorB, CUTFLAG_LINE, &fCut))
+ {
+ // crossover, two new points
+ ::basegfx::B2DPoint aNewPos(::basegfx::interpolate(pA->getPosition(), pA->getNext()->getPosition(), fCut));
+ B2DPolygonNode* pCutLo = new B2DPolygonNode(aNewPos, pA);
+ B2DPolygonNode* pCutHi = new B2DPolygonNode(aNewPos, pB);
+ aNewCuts.push_back(new B2DSimpleCut(pCutLo, pCutHi, sal_True, pCand->getOrientation()));
+ pA->calcMinMaxX(fMaxAX, fMinAX);
+ pA->calcMinMaxY(fMaxAY, fMinAY);
+ }
+ else
+ {
+ if(::basegfx::tools::isPointOnEdge(pA->getPosition(), pB->getPosition(), aVectorB, &fCut))
{
- // crossover, two new points
- ::basegfx::point::B2DPoint aNewPos(::basegfx::tuple::interpolate(pA->getPosition(), pA->getNext()->getPosition(), fCut));
- B2DPolygonNode* pCutLo = new B2DPolygonNode(aNewPos, pA);
- B2DPolygonNode* pCutHi = new B2DPolygonNode(aNewPos, pB);
- aNewCuts.push_back(new B2DSimpleCut(pCutLo, pCutHi, sal_True, pCand->getOrientation()));
- pA->calcMinMaxX(fMaxAX, fMinAX);
- pA->calcMinMaxY(fMaxAY, fMinAY);
+ // startpoint A at edge B, one new point
+ B2DPolygonNode* pCutHi = new B2DPolygonNode(pA->getPosition(), pB);
+ aNewCuts.push_back(new B2DSimpleCut(pA, pCutHi, sal_True, pCand->getOrientation()));
}
- else
+ else if(::basegfx::tools::isPointOnEdge(pB->getPosition(), pA->getPosition(), aVectorA, &fCut))
{
- if(::basegfx::polygon::tools::isPointOnEdge(pA->getPosition(), pB->getPosition(), aVectorB, &fCut))
- {
- // startpoint A at edge B, one new point
- B2DPolygonNode* pCutHi = new B2DPolygonNode(pA->getPosition(), pB);
- aNewCuts.push_back(new B2DSimpleCut(pA, pCutHi, sal_True, pCand->getOrientation()));
- }
- else if(::basegfx::polygon::tools::isPointOnEdge(pB->getPosition(), pA->getPosition(), aVectorA, &fCut))
- {
- // startpoint B at edge A, one new point
- B2DPolygonNode* pCutLo = new B2DPolygonNode(pB->getPosition(), pA);
- aNewCuts.push_back(new B2DSimpleCut(pCutLo, pB, sal_True, pCand->getOrientation()));
- pA->calcMinMaxX(fMaxAX, fMinAX);
- pA->calcMinMaxY(fMaxAY, fMinAY);
- }
+ // startpoint B at edge A, one new point
+ B2DPolygonNode* pCutLo = new B2DPolygonNode(pB->getPosition(), pA);
+ aNewCuts.push_back(new B2DSimpleCut(pCutLo, pB, sal_True, pCand->getOrientation()));
+ pA->calcMinMaxX(fMaxAX, fMinAX);
+ pA->calcMinMaxY(fMaxAY, fMinAY);
}
}
}
}
+ }
- // next B
- pB = pB->getNext();
- } while(pB != pCand);
+ // next B
+ pB = pB->getNext();
+ } while(pB != pCand);
- // next A
- pA = pA->getNext();
- } while(pA->getNext() != pCand);
+ // next A
+ pA = pA->getNext();
+ } while(pA->getNext() != pCand);
- // copy new cuts to cuts
- aCuts.insert(aCuts.begin(), aNewCuts.begin(), aNewCuts.end());
- aNewCuts.clear();
- }
+ // copy new cuts to cuts
+ aCuts.insert(aCuts.begin(), aNewCuts.begin(), aNewCuts.end());
+ aNewCuts.clear();
+ }
- // second job: if there were cuts, split polys
- if(aCuts.size())
- {
- solveAllCuts(aCuts);
- }
+ // second job: if there were cuts, split polys
+ if(aCuts.size())
+ {
+ solveAllCuts(aCuts);
}
+ }
- sal_Bool B2DPolyPolygonCutter::isCrossover(B2DPolygonNode* pA, B2DPolygonNode* pB)
+ sal_Bool B2DPolyPolygonCutter::isCrossover(B2DPolygonNode* pA, B2DPolygonNode* pB)
+ {
+ // build entering vectors
+ ::basegfx::B2DVector aVecA(pA->getPrevious()->getPosition() - pA->getPosition());
+ ::basegfx::B2DVector aVecB(pB->getPrevious()->getPosition() - pA->getPosition());
+ aVecA.normalize();
+ aVecB.normalize();
+ double fDegreeA2 = atan2(aVecA.getY(), aVecA.getX());
+ double fDegreeB2 = atan2(aVecB.getY(), aVecB.getX());
+
+ // build leaving vectors
+ aVecA = pA->getNext()->getPosition() - pA->getPosition();
+ aVecB = pB->getNext()->getPosition() - pA->getPosition();
+ aVecA.normalize();
+ aVecB.normalize();
+ double fDegreeA1 = atan2(aVecA.getY(), aVecA.getX());
+ double fDegreeB1 = atan2(aVecB.getY(), aVecB.getX());
+
+ // compare
+ if(fDegreeA1 > fDegreeA2)
{
- // build entering vectors
- ::basegfx::vector::B2DVector aVecA(pA->getPrevious()->getPosition() - pA->getPosition());
- ::basegfx::vector::B2DVector aVecB(pB->getPrevious()->getPosition() - pA->getPosition());
- aVecA.normalize();
- aVecB.normalize();
- double fDegreeA2 = atan2(aVecA.getY(), aVecA.getX());
- double fDegreeB2 = atan2(aVecB.getY(), aVecB.getX());
-
- // build leaving vectors
- aVecA = pA->getNext()->getPosition() - pA->getPosition();
- aVecB = pB->getNext()->getPosition() - pA->getPosition();
- aVecA.normalize();
- aVecB.normalize();
- double fDegreeA1 = atan2(aVecA.getY(), aVecA.getX());
- double fDegreeB1 = atan2(aVecB.getY(), aVecB.getX());
-
- // compare
- if(fDegreeA1 > fDegreeA2)
- {
- double fTemp = fDegreeA2;
- fDegreeA2 = fDegreeA1;
- fDegreeA1 = fTemp;
- }
+ double fTemp = fDegreeA2;
+ fDegreeA2 = fDegreeA1;
+ fDegreeA1 = fTemp;
+ }
- sal_Bool bB1Inside(::basegfx::numeric::fTools::more(fDegreeB1, fDegreeA1)
- && ::basegfx::numeric::fTools::more(fDegreeA2, fDegreeB1));
- sal_Bool bB2Inside(::basegfx::numeric::fTools::more(fDegreeB2, fDegreeA1)
- && ::basegfx::numeric::fTools::more(fDegreeA2, fDegreeB2));
+ sal_Bool bB1Inside(::basegfx::fTools::more(fDegreeB1, fDegreeA1)
+ && ::basegfx::fTools::more(fDegreeA2, fDegreeB1));
+ sal_Bool bB2Inside(::basegfx::fTools::more(fDegreeB2, fDegreeA1)
+ && ::basegfx::fTools::more(fDegreeA2, fDegreeB2));
- if(bB1Inside && bB2Inside)
- {
- return sal_False;
- }
+ if(bB1Inside && bB2Inside)
+ {
+ return sal_False;
+ }
+
+ sal_Bool bB1Outside(::basegfx::fTools::more(fDegreeA1, fDegreeB1)
+ || ::basegfx::fTools::more(fDegreeB1, fDegreeA2));
+ sal_Bool bB2Outside(::basegfx::fTools::more(fDegreeA1, fDegreeB2)
+ || ::basegfx::fTools::more(fDegreeB2, fDegreeA2));
- sal_Bool bB1Outside(::basegfx::numeric::fTools::more(fDegreeA1, fDegreeB1)
- || ::basegfx::numeric::fTools::more(fDegreeB1, fDegreeA2));
- sal_Bool bB2Outside(::basegfx::numeric::fTools::more(fDegreeA1, fDegreeB2)
- || ::basegfx::numeric::fTools::more(fDegreeB2, fDegreeA2));
+ return !(bB1Outside && bB2Outside);
+ }
- return !(bB1Outside && bB2Outside);
+ sal_Bool B2DPolyPolygonCutter::isCrossover(B2DSimpleCut* pEnter, B2DSimpleCut* pLeave)
+ {
+ // build entering vectors
+ ::basegfx::B2DVector aVecJ(pEnter->getLeft()->getNext()->getPosition() - pEnter->getLeft()->getPosition());
+ ::basegfx::B2DVector aVecA(pEnter->getLeft()->getPrevious()->getPosition() - pEnter->getLeft()->getPosition());
+ ::basegfx::B2DVector aVecB(pEnter->getRight()->getPrevious()->getPosition() - pEnter->getLeft()->getPosition());
+ aVecJ.normalize();
+ aVecA.normalize();
+ aVecB.normalize();
+ double fDegreeJo = atan2(aVecJ.getY(), aVecJ.getX());
+ double fDegreeA2 = atan2(aVecA.getY(), aVecA.getX()) - fDegreeJo;
+ double fDegreeB2 = atan2(aVecB.getY(), aVecB.getX()) - fDegreeJo;
+
+ // move to range [0..2PI[
+ while(fDegreeA2 < 0.0)
+ {
+ fDegreeA2 += (2.0 * F_PI);
}
- sal_Bool B2DPolyPolygonCutter::isCrossover(B2DSimpleCut* pEnter, B2DSimpleCut* pLeave)
+ while(fDegreeA2 >= (2.0 * F_PI))
{
- // build entering vectors
- ::basegfx::vector::B2DVector aVecJ(pEnter->getLeft()->getNext()->getPosition() - pEnter->getLeft()->getPosition());
- ::basegfx::vector::B2DVector aVecA(pEnter->getLeft()->getPrevious()->getPosition() - pEnter->getLeft()->getPosition());
- ::basegfx::vector::B2DVector aVecB(pEnter->getRight()->getPrevious()->getPosition() - pEnter->getLeft()->getPosition());
- aVecJ.normalize();
- aVecA.normalize();
- aVecB.normalize();
- double fDegreeJo = atan2(aVecJ.getY(), aVecJ.getX());
- double fDegreeA2 = atan2(aVecA.getY(), aVecA.getX()) - fDegreeJo;
- double fDegreeB2 = atan2(aVecB.getY(), aVecB.getX()) - fDegreeJo;
-
- // move to range [0..2PI[
- while(fDegreeA2 < 0.0)
- {
- fDegreeA2 += (2.0 * F_PI);
- }
+ fDegreeA2 -= (2.0 * F_PI);
+ }
- while(fDegreeA2 >= (2.0 * F_PI))
- {
- fDegreeA2 -= (2.0 * F_PI);
- }
+ // move to range [0..2PI[
+ while(fDegreeB2 < 0.0)
+ {
+ fDegreeB2 += (2.0 * F_PI);
+ }
- // move to range [0..2PI[
- while(fDegreeB2 < 0.0)
- {
- fDegreeB2 += (2.0 * F_PI);
- }
+ while(fDegreeB2 >= (2.0 * F_PI))
+ {
+ fDegreeB2 -= (2.0 * F_PI);
+ }
- while(fDegreeB2 >= (2.0 * F_PI))
- {
- fDegreeB2 -= (2.0 * F_PI);
- }
+ sal_Bool bA2BiggerB2(::basegfx::fTools::more(fDegreeA2, fDegreeB2));
+
+ // build leaving vectors
+ aVecJ = pLeave->getLeft()->getPrevious()->getPosition() - pLeave->getLeft()->getPosition();
+ aVecA = pLeave->getLeft()->getNext()->getPosition() - pLeave->getLeft()->getPosition();
+ aVecB = pLeave->getRight()->getNext()->getPosition() - pLeave->getLeft()->getPosition();
+ aVecJ.normalize();
+ aVecA.normalize();
+ aVecB.normalize();
+ fDegreeJo = atan2(aVecJ.getY(), aVecJ.getX());
+ double fDegreeA1 = atan2(aVecA.getY(), aVecA.getX()) - fDegreeJo;
+ double fDegreeB1 = atan2(aVecB.getY(), aVecB.getX()) - fDegreeJo;
+
+ // move to range [0..2PI[
+ while(fDegreeA1 < 0.0)
+ {
+ fDegreeA1 += (2.0 * F_PI);
+ }
- sal_Bool bA2BiggerB2(::basegfx::numeric::fTools::more(fDegreeA2, fDegreeB2));
-
- // build leaving vectors
- aVecJ = pLeave->getLeft()->getPrevious()->getPosition() - pLeave->getLeft()->getPosition();
- aVecA = pLeave->getLeft()->getNext()->getPosition() - pLeave->getLeft()->getPosition();
- aVecB = pLeave->getRight()->getNext()->getPosition() - pLeave->getLeft()->getPosition();
- aVecJ.normalize();
- aVecA.normalize();
- aVecB.normalize();
- fDegreeJo = atan2(aVecJ.getY(), aVecJ.getX());
- double fDegreeA1 = atan2(aVecA.getY(), aVecA.getX()) - fDegreeJo;
- double fDegreeB1 = atan2(aVecB.getY(), aVecB.getX()) - fDegreeJo;
-
- // move to range [0..2PI[
- while(fDegreeA1 < 0.0)
- {
- fDegreeA1 += (2.0 * F_PI);
- }
+ while(fDegreeA1 >= (2.0 * F_PI))
+ {
+ fDegreeA1 -= (2.0 * F_PI);
+ }
- while(fDegreeA1 >= (2.0 * F_PI))
- {
- fDegreeA1 -= (2.0 * F_PI);
- }
+ // move to range [0..2PI[
+ while(fDegreeB1 < 0)
+ {
+ fDegreeB1 += (2.0 * F_PI);
+ }
- // move to range [0..2PI[
- while(fDegreeB1 < 0)
- {
- fDegreeB1 += (2.0 * F_PI);
- }
+ while(fDegreeB1 >= (2.0 * F_PI))
+ {
+ fDegreeB1 -= (2.0 * F_PI);
+ }
- while(fDegreeB1 >= (2.0 * F_PI))
- {
- fDegreeB1 -= (2.0 * F_PI);
- }
+ sal_Bool bA1BiggerB1(::basegfx::fTools::more(fDegreeA1, fDegreeB1));
- sal_Bool bA1BiggerB1(::basegfx::numeric::fTools::more(fDegreeA1, fDegreeB1));
+ // compare
+ return (bA1BiggerB1 == bA2BiggerB2);
+ }
- // compare
- return (bA1BiggerB1 == bA2BiggerB2);
+ void B2DPolyPolygonCutter::removeDoubleIntersections()
+ {
+ double fMaxAX, fMinAX, fMaxAY, fMinAY;
+ double fMaxBX, fMinBX, fMaxBY, fMinBY;
+ double fCut;
+ B2DSimpleCutVector aCuts;
+ B2DSimpleCutVector aTmpCuts;
+ B2DSimpleCutVector aNewCuts;
+ B2DPolygonNode* pCandA;
+ B2DPolygonNode* pCandB;
+ B2DPolygonNode* pA;
+ B2DPolygonNode* pB;
+ sal_uInt32 a;
+
+ // create volume list for all polys for faster compares
+ ::basegfx::B2DRange* pVolumes = new ::basegfx::B2DRange[maPolygonList.size()];
+
+ for(a = 0L; a < maPolygonList.size(); a++)
+ {
+ pVolumes[a] = maPolygonList[a]->getRange();
}
- void B2DPolyPolygonCutter::removeDoubleIntersections()
+ // register cuts (and add points for them) between pCandA and pCandB
+ for(a = 0L; a + 1L < maPolygonList.size(); a++)
{
- double fMaxAX, fMinAX, fMaxAY, fMinAY;
- double fMaxBX, fMinBX, fMaxBY, fMinBY;
- double fCut;
- B2DSimpleCutVector aCuts;
- B2DSimpleCutVector aTmpCuts;
- B2DSimpleCutVector aNewCuts;
- B2DPolygonNode* pCandA;
- B2DPolygonNode* pCandB;
- B2DPolygonNode* pA;
- B2DPolygonNode* pB;
- sal_uInt32 a;
-
- // create volume list for all polys for faster compares
- ::basegfx::range::B2DRange* pVolumes = new ::basegfx::range::B2DRange[maPolygonList.size()];
-
- for(a = 0L; a < maPolygonList.size(); a++)
- {
- pVolumes[a] = maPolygonList[a]->getRange();
- }
+ pCandA = maPolygonList[a];
- // register cuts (and add points for them) between pCandA and pCandB
- for(a = 0L; a + 1L < maPolygonList.size(); a++)
+ for(sal_uInt32 b = a + 1L; b < maPolygonList.size(); b++)
{
- pCandA = maPolygonList[a];
-
- for(sal_uInt32 b = a + 1L; b < maPolygonList.size(); b++)
+ if(doRangesIntersect(pVolumes[a], pVolumes[b]))
{
- if(doRangesIntersect(pVolumes[a], pVolumes[b]))
- {
- pCandB = maPolygonList[b];
- pA = pCandA;
+ pCandB = maPolygonList[b];
+ pA = pCandA;
+
+ // one run to find same start positions (so there is no need to
+ // search for existing cuts in main loop)
+ do {
+ pB = pCandB;
- // one run to find same start positions (so there is no need to
- // search for existing cuts in main loop)
do {
- pB = pCandB;
+ if(isSamePos(pA->getPosition(), pB->getPosition()))
+ {
+ aTmpCuts.push_back(new B2DSimpleCut(pA, pB));
+ }
- do {
- if(isSamePos(pA->getPosition(), pB->getPosition()))
- {
- aTmpCuts.push_back(new B2DSimpleCut(pA, pB));
- }
+ // next B
+ pB = pB->getNext();
+ } while(pB != pCandB);
- // next B
- pB = pB->getNext();
- } while(pB != pCandB);
+ // next A
+ pA = pA->getNext();
+ } while(pA != pCandA);
- // next A
- pA = pA->getNext();
- } while(pA != pCandA);
+ // second run to find real cuts
+ pA = pCandA;
- // second run to find real cuts
- pA = pCandA;
+ do {
+ // get bounds for this edge in poly
+ pA->calcMinMaxX(fMaxAX, fMinAX);
+ pA->calcMinMaxY(fMaxAY, fMinAY);
+ pB = pCandB;
do {
- // get bounds for this edge in poly
- pA->calcMinMaxX(fMaxAX, fMinAX);
- pA->calcMinMaxY(fMaxAY, fMinAY);
- pB = pCandB;
+ pB->calcMinMaxX(fMaxBX, fMinBX);
- do {
- pB->calcMinMaxX(fMaxBX, fMinBX);
+ if(::basegfx::fTools::more(fMaxBX, fMinAX)
+ && ::basegfx::fTools::more(fMaxAX, fMinBX))
+ {
+ pB->calcMinMaxY(fMaxBY, fMinBY);
- if(::basegfx::numeric::fTools::more(fMaxBX, fMinAX)
- && ::basegfx::numeric::fTools::more(fMaxAX, fMinBX))
+ if(::basegfx::fTools::more(fMaxBY, fMinAY)
+ && ::basegfx::fTools::more(fMaxAY, fMinBY))
{
- pB->calcMinMaxY(fMaxBY, fMinBY);
-
- if(::basegfx::numeric::fTools::more(fMaxBY, fMinAY)
- && ::basegfx::numeric::fTools::more(fMaxAY, fMinBY))
+ if(!isSamePos(pA->getPosition(), pB->getPosition()))
{
- if(!isSamePos(pA->getPosition(), pB->getPosition()))
- {
- const ::basegfx::vector::B2DVector aVectorA(pA->getNext()->getPosition() - pA->getPosition());
- const ::basegfx::vector::B2DVector aVectorB(pB->getNext()->getPosition() - pB->getPosition());
+ const ::basegfx::B2DVector aVectorA(pA->getNext()->getPosition() - pA->getPosition());
+ const ::basegfx::B2DVector aVectorB(pB->getNext()->getPosition() - pB->getPosition());
- if(::basegfx::polygon::tools::findCut(pA->getPosition(), aVectorA, pB->getPosition(), aVectorB, CUTFLAG_LINE, &fCut))
+ if(::basegfx::tools::findCut(pA->getPosition(), aVectorA, pB->getPosition(), aVectorB, CUTFLAG_LINE, &fCut))
+ {
+ // crossover, two new points, use as cutpoint
+ ::basegfx::B2DPoint aNewPos(::basegfx::interpolate(pA->getPosition(), pA->getNext()->getPosition(), fCut));
+ B2DPolygonNode* pCutLo = new B2DPolygonNode(aNewPos, pA);
+ B2DPolygonNode* pCutHi = new B2DPolygonNode(aNewPos, pB);
+ aNewCuts.push_back(new B2DSimpleCut(pCutLo, pCutHi));
+ pA->calcMinMaxX(fMaxAX, fMinAX);
+ pA->calcMinMaxY(fMaxAY, fMinAY);
+ }
+ else
+ {
+ if(::basegfx::tools::isPointOnEdge(pA->getPosition(), pB->getPosition(), aVectorB, &fCut))
{
- // crossover, two new points, use as cutpoint
- ::basegfx::point::B2DPoint aNewPos(::basegfx::tuple::interpolate(pA->getPosition(), pA->getNext()->getPosition(), fCut));
- B2DPolygonNode* pCutLo = new B2DPolygonNode(aNewPos, pA);
- B2DPolygonNode* pCutHi = new B2DPolygonNode(aNewPos, pB);
- aNewCuts.push_back(new B2DSimpleCut(pCutLo, pCutHi));
- pA->calcMinMaxX(fMaxAX, fMinAX);
- pA->calcMinMaxY(fMaxAY, fMinAY);
+ // startpoint A at edge B, one new point
+ // leaves or enters common section
+ B2DPolygonNode* pCutHi = new B2DPolygonNode(pA->getPosition(), pB);
+ aTmpCuts.push_back(new B2DSimpleCut(pA, pCutHi));
}
- else
+ else if(::basegfx::tools::isPointOnEdge(pB->getPosition(), pA->getPosition(), aVectorA, &fCut))
{
- if(::basegfx::polygon::tools::isPointOnEdge(pA->getPosition(), pB->getPosition(), aVectorB, &fCut))
- {
- // startpoint A at edge B, one new point
- // leaves or enters common section
- B2DPolygonNode* pCutHi = new B2DPolygonNode(pA->getPosition(), pB);
- aTmpCuts.push_back(new B2DSimpleCut(pA, pCutHi));
- }
- else if(::basegfx::polygon::tools::isPointOnEdge(pB->getPosition(), pA->getPosition(), aVectorA, &fCut))
- {
- // startpoint B at edge A, one new point
- // leaves or enters common section
- B2DPolygonNode* pCutLo = new B2DPolygonNode(pB->getPosition(), pA);
- aTmpCuts.push_back(new B2DSimpleCut(pCutLo, pB));
- pA->calcMinMaxX(fMaxAX, fMinAX);
- pA->calcMinMaxY(fMaxAY, fMinAY);
- }
+ // startpoint B at edge A, one new point
+ // leaves or enters common section
+ B2DPolygonNode* pCutLo = new B2DPolygonNode(pB->getPosition(), pA);
+ aTmpCuts.push_back(new B2DSimpleCut(pCutLo, pB));
+ pA->calcMinMaxX(fMaxAX, fMinAX);
+ pA->calcMinMaxY(fMaxAY, fMinAY);
}
}
}
}
+ }
- // next B
- pB = pB->getNext();
- } while(pB != pCandB);
-
- // next A
- pA = pA->getNext();
- } while(pA != pCandA);
+ // next B
+ pB = pB->getNext();
+ } while(pB != pCandB);
- // test all temporary cuts for simple criteria
- for(sal_uInt32 c(0L); c < aTmpCuts.size();)
- {
- B2DSimpleCut* pCand = aTmpCuts[c];
- sal_Bool bPrevSamePos(isPrevSamePos(pCand->getLeft(), pCand->getRight()));
- sal_Bool bNextSamePos(isNextSamePos(pCand->getLeft(), pCand->getRight()));
- sal_Bool bDelete(sal_False);
- sal_Bool bIncC(sal_True);
+ // next A
+ pA = pA->getNext();
+ } while(pA != pCandA);
- if(bPrevSamePos && bNextSamePos)
- {
- // single point inside continued same direction section
- bDelete = sal_True;
- }
- else if(!bPrevSamePos && !bNextSamePos)
- {
- // this is no same direction section, test for real cut
- if(isCrossover(pCand->getLeft(), pCand->getRight()))
- {
- // real cut, move to real cutlist
- aNewCuts.push_back(pCand);
- aTmpCuts.erase(aTmpCuts.begin() + c);
- bIncC = sal_False;
- }
- else
- {
- // no cut, just a touch in one point
- bDelete = sal_True;
- }
- }
+ // test all temporary cuts for simple criteria
+ for(sal_uInt32 c(0L); c < aTmpCuts.size();)
+ {
+ B2DSimpleCut* pCand = aTmpCuts[c];
+ sal_Bool bPrevSamePos(isPrevSamePos(pCand->getLeft(), pCand->getRight()));
+ sal_Bool bNextSamePos(isNextSamePos(pCand->getLeft(), pCand->getRight()));
+ sal_Bool bDelete(sal_False);
+ sal_Bool bIncC(sal_True);
- // delete if wanted
- if(bDelete)
+ if(bPrevSamePos && bNextSamePos)
+ {
+ // single point inside continued same direction section
+ bDelete = sal_True;
+ }
+ else if(!bPrevSamePos && !bNextSamePos)
+ {
+ // this is no same direction section, test for real cut
+ if(isCrossover(pCand->getLeft(), pCand->getRight()))
{
- delete pCand;
+ // real cut, move to real cutlist
+ aNewCuts.push_back(pCand);
aTmpCuts.erase(aTmpCuts.begin() + c);
bIncC = sal_False;
}
+ else
+ {
+ // no cut, just a touch in one point
+ bDelete = sal_True;
+ }
+ }
- // next candidate
- if(bIncC)
- c++;
+ // delete if wanted
+ if(bDelete)
+ {
+ delete pCand;
+ aTmpCuts.erase(aTmpCuts.begin() + c);
+ bIncC = sal_False;
}
- // are there entering/leaving same direction sections?
- while(aTmpCuts.size())
+ // next candidate
+ if(bIncC)
+ c++;
+ }
+
+ // are there entering/leaving same direction sections?
+ while(aTmpCuts.size())
+ {
+ // this cuts enter/leave a common same-direction section between
+ // polygons pCandA, pCandB. If it is a real crossover, a cutpoint
+ // for it is needed, else it can be ignored.
+ B2DSimpleCut* pCutA = aTmpCuts[0L];
+ aTmpCuts.erase(aTmpCuts.begin());
+ B2DPolygonNode* pActA = pCutA->getLeft();
+ B2DPolygonNode* pActB = pCutA->getRight();
+ sal_Bool bPrevSamePos(isPrevSamePos(pActA, pActB));
+ sal_Bool bNextSamePos(isNextSamePos(pActA, pActB));
+
+ if(aTmpCuts.size())
{
- // this cuts enter/leave a common same-direction section between
- // polygons pCandA, pCandB. If it is a real crossover, a cutpoint
- // for it is needed, else it can be ignored.
- B2DSimpleCut* pCutA = aTmpCuts[0L];
- aTmpCuts.erase(aTmpCuts.begin());
- B2DPolygonNode* pActA = pCutA->getLeft();
- B2DPolygonNode* pActB = pCutA->getRight();
- sal_Bool bPrevSamePos(isPrevSamePos(pActA, pActB));
- sal_Bool bNextSamePos(isNextSamePos(pActA, pActB));
-
- if(aTmpCuts.size())
+ B2DSimpleCut* pCutB = 0L;
+
+ if(isNextSamePos(pCutA->getLeft(), pCutA->getRight()))
{
- B2DSimpleCut* pCutB = 0L;
+ // this is a start node
+ B2DPolygonNode* pActA = pCutA->getLeft()->getNext();
+ B2DPolygonNode* pActB = pCutA->getRight()->getNext();
- if(isNextSamePos(pCutA->getLeft(), pCutA->getRight()))
+ while(!pCutB && pActA != pCutA->getLeft())
{
- // this is a start node
- B2DPolygonNode* pActA = pCutA->getLeft()->getNext();
- B2DPolygonNode* pActB = pCutA->getRight()->getNext();
-
- while(!pCutB && pActA != pCutA->getLeft())
+ if(!isNextSamePos(pActA, pActB))
{
- if(!isNextSamePos(pActA, pActB))
- {
- pCutB = getExistingCut(aTmpCuts, pActA, pActB);
- }
-
- pActA = pActA->getNext();
- pActB = pActB->getNext();
+ pCutB = getExistingCut(aTmpCuts, pActA, pActB);
}
- if(pCutB)
+ pActA = pActA->getNext();
+ pActB = pActB->getNext();
+ }
+
+ if(pCutB)
+ {
+ const B2DSimpleCutVector::iterator aFindResult = ::std::find(aTmpCuts.begin(), aTmpCuts.end(), pCutB);
+ aTmpCuts.erase(aFindResult);
+
+ if(isCrossover(pCutA, pCutB))
+ {
+ aNewCuts.push_back(pCutB);
+ }
+ else
{
- const B2DSimpleCutVector::iterator aFindResult = ::std::find(aTmpCuts.begin(), aTmpCuts.end(), pCutB);
- aTmpCuts.erase(aFindResult);
+ delete pCutB;
+ }
+ }
+ }
+ else
+ {
+ // this is a end node
+ B2DPolygonNode* pActA = pCutA->getLeft()->getPrevious();
+ B2DPolygonNode* pActB = pCutA->getRight()->getPrevious();
- if(isCrossover(pCutA, pCutB))
- {
- aNewCuts.push_back(pCutB);
- }
- else
- {
- delete pCutB;
- }
+ while(!pCutB && pActA != pCutA->getLeft())
+ {
+ if(!isPrevSamePos(pActA, pActB))
+ {
+ pCutB = getExistingCut(aTmpCuts, pActA, pActB);
}
+
+ pActA = pActA->getPrevious();
+ pActB = pActB->getPrevious();
}
- else
+
+ if(pCutB)
{
- // this is a end node
- B2DPolygonNode* pActA = pCutA->getLeft()->getPrevious();
- B2DPolygonNode* pActB = pCutA->getRight()->getPrevious();
+ const B2DSimpleCutVector::iterator aFindResult = ::std::find(aTmpCuts.begin(), aTmpCuts.end(), pCutB);
+ aTmpCuts.erase(aFindResult);
- while(!pCutB && pActA != pCutA->getLeft())
+ if(isCrossover(pCutB, pCutA))
{
- if(!isPrevSamePos(pActA, pActB))
- {
- pCutB = getExistingCut(aTmpCuts, pActA, pActB);
- }
-
- pActA = pActA->getPrevious();
- pActB = pActB->getPrevious();
+ aNewCuts.push_back(pCutB);
}
-
- if(pCutB)
+ else
{
- const B2DSimpleCutVector::iterator aFindResult = ::std::find(aTmpCuts.begin(), aTmpCuts.end(), pCutB);
- aTmpCuts.erase(aFindResult);
-
- if(isCrossover(pCutB, pCutA))
- {
- aNewCuts.push_back(pCutB);
- }
- else
- {
- delete pCutB;
- }
+ delete pCutB;
}
}
}
-
- // delete cut in EVERY case
- delete pCutA;
}
- // copy new cuts to all cuts
- aCuts.insert(aCuts.begin(), aNewCuts.begin(), aNewCuts.end());
- aNewCuts.clear();
+ // delete cut in EVERY case
+ delete pCutA;
}
+
+ // copy new cuts to all cuts
+ aCuts.insert(aCuts.begin(), aNewCuts.begin(), aNewCuts.end());
+ aNewCuts.clear();
}
}
+ }
- // delete volume list again
- delete[] pVolumes;
+ // delete volume list again
+ delete[] pVolumes;
- // are there cuts to solve? Solve them all in one run
- if(aCuts.size())
- {
- solveAllCuts(aCuts);
- }
+ // are there cuts to solve? Solve them all in one run
+ if(aCuts.size())
+ {
+ solveAllCuts(aCuts);
}
- } // end of namespace polygon
+ }
} // end of namespace basegfx
//////////////////////////////////////////////////////////////////////////////