INTEGRATION: CWS canvas02 (1.9.22); FILE MERGED
2005/10/08 13:13:44 thb 1.9.22.2: RESYNC: (1.9-1.10); FILE MERGED 2005/07/28 10:10:17 thb 1.9.22.1: Join from cws_src680_aw024: #i48939# and new rendering subsystem need AW's clipper changes
This commit is contained in:
parent
b68c2177db
commit
507a25b214
1 changed files with 159 additions and 16 deletions
|
@ -4,9 +4,9 @@
|
|||
*
|
||||
* $RCSfile: b2dcubicbezier.cxx,v $
|
||||
*
|
||||
* $Revision: 1.10 $
|
||||
* $Revision: 1.11 $
|
||||
*
|
||||
* last change: $Author: rt $ $Date: 2005-09-07 20:40:27 $
|
||||
* last change: $Author: kz $ $Date: 2005-11-02 13:56:14 $
|
||||
*
|
||||
* The Contents of this file are made available subject to
|
||||
* the terms of GNU Lesser General Public License Version 2.1.
|
||||
|
@ -314,8 +314,7 @@ namespace basegfx
|
|||
{
|
||||
}
|
||||
|
||||
B2DCubicBezier::B2DCubicBezier(const B2DPoint& rStart, const B2DPoint& rControlPointA,
|
||||
const B2DPoint& rControlPointB, const B2DPoint& rEnd)
|
||||
B2DCubicBezier::B2DCubicBezier(const B2DPoint& rStart, const B2DPoint& rControlPointA, const B2DPoint& rControlPointB, const B2DPoint& rEnd)
|
||||
: maStartPoint(rStart),
|
||||
maEndPoint(rEnd),
|
||||
maControlPointA(rControlPointA),
|
||||
|
@ -323,6 +322,14 @@ namespace basegfx
|
|||
{
|
||||
}
|
||||
|
||||
B2DCubicBezier::B2DCubicBezier(const B2DPoint& rStart, const B2DVector& rControlVectorA, const B2DVector& rControlVectorB, const B2DPoint& rEnd)
|
||||
: maStartPoint(rStart),
|
||||
maEndPoint(rEnd),
|
||||
maControlPointA(rStart + rControlVectorA),
|
||||
maControlPointB(rStart + rControlVectorB)
|
||||
{
|
||||
}
|
||||
|
||||
B2DCubicBezier::~B2DCubicBezier()
|
||||
{
|
||||
}
|
||||
|
@ -402,19 +409,10 @@ namespace basegfx
|
|||
{
|
||||
rTarget.append(maStartPoint);
|
||||
|
||||
if(nCount)
|
||||
for(sal_uInt32 a(0L); a < nCount; a++)
|
||||
{
|
||||
for(sal_uInt32 a(0L); a < nCount; a++)
|
||||
{
|
||||
const double fPos(double(a + 1L) / double(nCount + 1L));
|
||||
const B2DPoint aS1L(interpolate(maStartPoint, maControlPointA, fPos));
|
||||
const B2DPoint aS1C(interpolate(maControlPointA, maControlPointB, fPos));
|
||||
const B2DPoint aS1R(interpolate(maControlPointB, maEndPoint, fPos));
|
||||
const B2DPoint aS2L(interpolate(aS1L, aS1C, fPos));
|
||||
const B2DPoint aS2R(interpolate(aS1C, aS1R, fPos));
|
||||
const B2DPoint aS3C(interpolate(aS2L, aS2R, fPos));
|
||||
rTarget.append(aS3C);
|
||||
}
|
||||
const double fPos(double(a + 1L) / double(nCount + 1L));
|
||||
rTarget.append(interpolatePoint(fPos));
|
||||
}
|
||||
|
||||
if(bAddLastPoint)
|
||||
|
@ -422,6 +420,151 @@ namespace basegfx
|
|||
rTarget.append(maEndPoint);
|
||||
}
|
||||
}
|
||||
|
||||
B2DPoint B2DCubicBezier::interpolatePoint(double t) const
|
||||
{
|
||||
OSL_ENSURE(t >= 0.0 && t <= 1.0, "B2DCubicBezier::interpolatePoint: Access out of range (!)");
|
||||
const B2DPoint aS1L(interpolate(maStartPoint, maControlPointA, t));
|
||||
const B2DPoint aS1C(interpolate(maControlPointA, maControlPointB, t));
|
||||
const B2DPoint aS1R(interpolate(maControlPointB, maEndPoint, t));
|
||||
const B2DPoint aS2L(interpolate(aS1L, aS1C, t));
|
||||
const B2DPoint aS2R(interpolate(aS1C, aS1R, t));
|
||||
return interpolate(aS2L, aS2R, t);
|
||||
}
|
||||
|
||||
double B2DCubicBezier::getSmallestDistancePointToBezierSegment(const B2DPoint& rTestPoint, double& rCut) const
|
||||
{
|
||||
const sal_uInt32 nInitialDivisions(3L);
|
||||
B2DPolygon aInitialPolygon;
|
||||
|
||||
// as start make a fix division, creates nInitialDivisions + 2L points
|
||||
adaptiveSubdivideByCount(aInitialPolygon, nInitialDivisions, true);
|
||||
|
||||
// now look for the closest point
|
||||
const sal_uInt32 nPointCount(aInitialPolygon.count());
|
||||
B2DVector aVector(rTestPoint - aInitialPolygon.getB2DPoint(0L));
|
||||
double fQuadDist(aVector.getX() * aVector.getX() + aVector.getY() * aVector.getY());
|
||||
double fNewQuadDist;
|
||||
sal_uInt32 nSmallestIndex(0L);
|
||||
|
||||
for(sal_uInt32 a(1L); a < nPointCount; a++)
|
||||
{
|
||||
aVector = B2DVector(rTestPoint - aInitialPolygon.getB2DPoint(a));
|
||||
fNewQuadDist = aVector.getX() * aVector.getX() + aVector.getY() * aVector.getY();
|
||||
|
||||
if(fNewQuadDist < fQuadDist)
|
||||
{
|
||||
fQuadDist = fNewQuadDist;
|
||||
nSmallestIndex = a;
|
||||
}
|
||||
}
|
||||
|
||||
// look right and left for even smaller distances
|
||||
double fStepValue(1.0 / (double)((nPointCount - 1L) * 2L)); // half the edge step width
|
||||
double fPosition((double)nSmallestIndex / (double)(nPointCount - 1L));
|
||||
bool bDone(false);
|
||||
|
||||
while(!bDone)
|
||||
{
|
||||
if(!bDone)
|
||||
{
|
||||
// test left
|
||||
double fPosLeft(fPosition - fStepValue);
|
||||
|
||||
if(fPosLeft < 0.0)
|
||||
{
|
||||
fPosLeft = 0.0;
|
||||
aVector = B2DVector(rTestPoint - maStartPoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
aVector = B2DVector(rTestPoint - interpolatePoint(fPosLeft));
|
||||
}
|
||||
|
||||
fNewQuadDist = aVector.getX() * aVector.getX() + aVector.getY() * aVector.getY();
|
||||
|
||||
if(fTools::less(fNewQuadDist, fQuadDist))
|
||||
{
|
||||
fQuadDist = fNewQuadDist;
|
||||
fPosition = fPosLeft;
|
||||
}
|
||||
else
|
||||
{
|
||||
// test right
|
||||
double fPosRight(fPosition + fStepValue);
|
||||
|
||||
if(fPosRight > 1.0)
|
||||
{
|
||||
fPosRight = 1.0;
|
||||
aVector = B2DVector(rTestPoint - maEndPoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
aVector = B2DVector(rTestPoint - interpolatePoint(fPosRight));
|
||||
}
|
||||
|
||||
fNewQuadDist = aVector.getX() * aVector.getX() + aVector.getY() * aVector.getY();
|
||||
|
||||
if(fTools::less(fNewQuadDist, fQuadDist))
|
||||
{
|
||||
fQuadDist = fNewQuadDist;
|
||||
fPosition = fPosRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
// not less left or right, done
|
||||
bDone = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(0.0 == fPosition || 1.0 == fPosition)
|
||||
{
|
||||
// if we are completely left or right, we are done
|
||||
bDone = true;
|
||||
}
|
||||
|
||||
if(!bDone)
|
||||
{
|
||||
// prepare next step value
|
||||
fStepValue /= 2.0;
|
||||
}
|
||||
}
|
||||
|
||||
rCut = fPosition;
|
||||
return sqrt(fQuadDist);
|
||||
}
|
||||
|
||||
void B2DCubicBezier::split(double t, B2DCubicBezier& rBezierA, B2DCubicBezier& rBezierB) const
|
||||
{
|
||||
OSL_ENSURE(t >= 0.0 && t <= 1.0, "B2DCubicBezier::split: Access out of range (!)");
|
||||
const B2DPoint aS1L(interpolate(maStartPoint, maControlPointA, t));
|
||||
const B2DPoint aS1C(interpolate(maControlPointA, maControlPointB, t));
|
||||
const B2DPoint aS1R(interpolate(maControlPointB, maEndPoint, t));
|
||||
const B2DPoint aS2L(interpolate(aS1L, aS1C, t));
|
||||
const B2DPoint aS2R(interpolate(aS1C, aS1R, t));
|
||||
const B2DPoint aS3C(interpolate(aS2L, aS2R, t));
|
||||
|
||||
rBezierA.setStartPoint(maStartPoint);
|
||||
rBezierA.setEndPoint(aS3C);
|
||||
rBezierA.setControlPointA(aS1L);
|
||||
rBezierA.setControlPointB(aS2L);
|
||||
|
||||
rBezierB.setStartPoint(aS3C);
|
||||
rBezierB.setEndPoint(maEndPoint);
|
||||
rBezierB.setControlPointA(aS2R);
|
||||
rBezierB.setControlPointB(aS1R);
|
||||
}
|
||||
|
||||
B2DRange B2DCubicBezier::getRange() const
|
||||
{
|
||||
B2DRange aRetval(maStartPoint, maEndPoint);
|
||||
|
||||
aRetval.expand(maControlPointA);
|
||||
aRetval.expand(maControlPointB);
|
||||
|
||||
return aRetval;
|
||||
}
|
||||
} // end of namespace basegfx
|
||||
|
||||
// eof
|
||||
|
|
Loading…
Reference in a new issue