| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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 */ |