summaryrefslogtreecommitdiff
path: root/basegfx/inc/basegfx/curve/b2dcubicbezier.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'basegfx/inc/basegfx/curve/b2dcubicbezier.hxx')
-rw-r--r--basegfx/inc/basegfx/curve/b2dcubicbezier.hxx222
1 files changed, 222 insertions, 0 deletions
diff --git a/basegfx/inc/basegfx/curve/b2dcubicbezier.hxx b/basegfx/inc/basegfx/curve/b2dcubicbezier.hxx
new file mode 100644
index 000000000000..ea58a0a50b80
--- /dev/null
+++ b/basegfx/inc/basegfx/curve/b2dcubicbezier.hxx
@@ -0,0 +1,222 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _BGFX_CURVE_B2DCUBICBEZIER_HXX
+#define _BGFX_CURVE_B2DCUBICBEZIER_HXX
+
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/range/b2drange.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+// predeclarations
+
+namespace basegfx
+{
+ class B2DPolygon;
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ class B2DCubicBezier
+ {
+ B2DPoint maStartPoint;
+ B2DPoint maEndPoint;
+ B2DPoint maControlPointA;
+ B2DPoint maControlPointB;
+
+ public:
+ B2DCubicBezier();
+ B2DCubicBezier(const B2DCubicBezier& rBezier);
+ B2DCubicBezier(const B2DPoint& rStart, const B2DPoint& rEnd);
+ B2DCubicBezier(const B2DPoint& rStart, const B2DPoint& rControlPointA, const B2DPoint& rControlPointB, const B2DPoint& rEnd);
+ ~B2DCubicBezier();
+
+ // assignment operator
+ B2DCubicBezier& operator=(const B2DCubicBezier& rBezier);
+
+ // compare operators
+ bool operator==(const B2DCubicBezier& rBezier) const;
+ bool operator!=(const B2DCubicBezier& rBezier) const;
+ bool equal(const B2DCubicBezier& rBezier) const;
+
+ // test if vectors are used
+ bool isBezier() const;
+
+ // test if contained bezier is trivial and reset vectors accordingly
+ void testAndSolveTrivialBezier();
+
+ /** get length of edge
+
+ This method handles beziers and simple edges. For
+ beziers, the deviation describes the maximum allowed
+ deviation from the real edge length. The default
+ allows a deviation of 1% from the correct length.
+
+ For beziers, there is no direct way to get the length,
+ thus this method may subdivide the bezier edge and may
+ not be cheap.
+
+ @param fDeviation
+ The maximal allowed deviation between correct length
+ and bezier edge length
+
+ @return
+ The length of the edge
+ */
+ double getLength(double fDeviation = 0.01) const;
+
+ // get distance between start and end point
+ double getEdgeLength() const;
+
+ // get length of control polygon
+ double getControlPolygonLength() const;
+
+ // data interface
+ B2DPoint getStartPoint() const { return maStartPoint; }
+ void setStartPoint(const B2DPoint& rValue) { maStartPoint = rValue; }
+
+ B2DPoint getEndPoint() const { return maEndPoint; }
+ void setEndPoint(const B2DPoint& rValue) { maEndPoint = rValue; }
+
+ B2DPoint getControlPointA() const { return maControlPointA; }
+ void setControlPointA(const B2DPoint& rValue) { maControlPointA = rValue; }
+
+ B2DPoint getControlPointB() const { return maControlPointB; }
+ void setControlPointB(const B2DPoint& rValue) { maControlPointB = rValue; }
+
+ /** get the tangent in point t
+
+ This method handles all the exceptions, e.g. when control point
+ A is equal to start point and/or control point B is equal to end
+ point
+
+ @param t
+ The bezier index in the range [0.0 .. 1.0]. It will be truncated.
+
+ @return
+ The tangent vector in point t
+ */
+ B2DVector getTangent(double t) const;
+
+ /** adaptive subdivide by angle criteria
+ no start point is added, but all necessary created edges
+ and the end point
+ #i37443# allow the criteria to get unsharp in recursions
+ */
+ void adaptiveSubdivideByAngle(B2DPolygon& rTarget, double fAngleBound, bool bAllowUnsharpen) const;
+
+ /** #i37443# adaptive subdivide by nCount subdivisions
+ no start point is added, but all necessary created edges
+ and the end point
+ */
+ void adaptiveSubdivideByCount(B2DPolygon& rTarget, sal_uInt32 nCount) const;
+
+ /** Subdivide cubic bezier segment.
+
+ This function adaptively subdivides the bezier
+ segment into as much straight line segments as necessary,
+ such that the maximal orthogonal distance from any of the
+ segments to the true curve is less than the given error
+ value.
+ No start point is added, but all necessary created edges
+ and the end point
+
+ @param rPoly
+ Output polygon. The subdivided bezier segment is added to
+ this polygon via B2DPolygon::append().
+
+ @param rCurve
+ The cubic bezier curve to subdivide
+
+ @param fDistanceBound
+ Bound on the maximal distance of the approximation to the
+ true curve.
+ */
+ void adaptiveSubdivideByDistance(B2DPolygon& rTarget, double fDistanceBound) const;
+
+ // get point at given relative position
+ B2DPoint interpolatePoint(double t) const;
+
+ // calculate the smallest distance from given point to this cubic bezier segment
+ // and return the value. The relative position on the segment is returned in rCut.
+ double getSmallestDistancePointToBezierSegment(const B2DPoint& rTestPoint, double& rCut) const;
+
+ // do a split at position t and fill both resulting segments
+ void split(double t, B2DCubicBezier* pBezierA, B2DCubicBezier* pBezierB) const;
+
+ // extract snippet from fStart to fEnd from this bezier
+ B2DCubicBezier snippet(double fStart, double fEnd) const;
+
+ // get range including conrol points
+ B2DRange getRange() const;
+
+ /** Get the minimum extremum position t
+
+ @param rfResult
+ Will be changed and set to a eventually found split value which should be in the
+ range [0.0 .. 1.0]. It will be the smallest current extremum; there may be more
+
+ @return
+ Returns true if there was at least one extremum found
+ */
+ bool getMinimumExtremumPosition(double& rfResult) const;
+
+ /** Get all extremum pos of this segment
+
+ This method will calculate all extremum positions of the segment
+ and add them to rResults if they are in the range ]0.0 .. 1.0[
+
+ @param rResults
+ The vector of doubles where the results will be added. Evtl.
+ existing contents will be removed since an empty vector is a
+ necessary result to express that there are no extreme positions
+ anymore. Since there is an upper maximum of 4 values, it makes
+ sense to use reserve(4) at the vector as preparation.
+ */
+ void getAllExtremumPositions(::std::vector< double >& rResults) const;
+
+ /** Get optimum-split position on this segment
+
+ This method calculates the positions of all points of the segment
+ that have the maximimum distance to the corresponding line from
+ startpoint-endpoint. This helps to approximate the bezier curve
+ with a minimum number of line segments
+
+ @param fResults
+ Result positions are in the range ]0.0 .. 1.0[
+ Cubic beziers have at most two of these positions
+
+ @return
+ Returns the number of split positions found
+ */
+ int getMaxDistancePositions( double fResults[2]) const;
+ };
+} // end of namespace basegfx
+
+#endif /* _BGFX_CURVE_B2DCUBICBEZIER_HXX */