1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef _BGFX_CURVE_B2DCUBICBEZIER_HXX 25 #define _BGFX_CURVE_B2DCUBICBEZIER_HXX 26 27 #include <basegfx/point/b2dpoint.hxx> 28 #include <basegfx/range/b2drange.hxx> 29 #include <basegfx/basegfxdllapi.h> 30 31 ////////////////////////////////////////////////////////////////////////////// 32 // predeclarations 33 34 namespace basegfx 35 { 36 class B2DPolygon; 37 } // end of namespace basegfx 38 39 ////////////////////////////////////////////////////////////////////////////// 40 41 namespace basegfx 42 { 43 class BASEGFX_DLLPUBLIC B2DCubicBezier 44 { 45 B2DPoint maStartPoint; 46 B2DPoint maEndPoint; 47 B2DPoint maControlPointA; 48 B2DPoint maControlPointB; 49 50 public: 51 B2DCubicBezier(); 52 B2DCubicBezier(const B2DCubicBezier& rBezier); 53 B2DCubicBezier(const B2DPoint& rStart, const B2DPoint& rEnd); 54 B2DCubicBezier(const B2DPoint& rStart, const B2DPoint& rControlPointA, const B2DPoint& rControlPointB, const B2DPoint& rEnd); 55 ~B2DCubicBezier(); 56 57 // assignment operator 58 B2DCubicBezier& operator=(const B2DCubicBezier& rBezier); 59 60 // compare operators 61 bool operator==(const B2DCubicBezier& rBezier) const; 62 bool operator!=(const B2DCubicBezier& rBezier) const; 63 bool equal(const B2DCubicBezier& rBezier) const; 64 65 // test if vectors are used 66 bool isBezier() const; 67 68 // test if contained bezier is trivial and reset vectors accordingly 69 void testAndSolveTrivialBezier(); 70 71 /** get length of edge 72 73 This method handles beziers and simple edges. For 74 beziers, the deviation describes the maximum allowed 75 deviation from the real edge length. The default 76 allows a deviation of 1% from the correct length. 77 78 For beziers, there is no direct way to get the length, 79 thus this method may subdivide the bezier edge and may 80 not be cheap. 81 82 @param fDeviation 83 The maximal allowed deviation between correct length 84 and bezier edge length 85 86 @return 87 The length of the edge 88 */ 89 double getLength(double fDeviation = 0.01) const; 90 91 // get distance between start and end point 92 double getEdgeLength() const; 93 94 // get length of control polygon 95 double getControlPolygonLength() const; 96 97 // data interface getStartPoint() const98 B2DPoint getStartPoint() const { return maStartPoint; } setStartPoint(const B2DPoint & rValue)99 void setStartPoint(const B2DPoint& rValue) { maStartPoint = rValue; } 100 getEndPoint() const101 B2DPoint getEndPoint() const { return maEndPoint; } setEndPoint(const B2DPoint & rValue)102 void setEndPoint(const B2DPoint& rValue) { maEndPoint = rValue; } 103 getControlPointA() const104 B2DPoint getControlPointA() const { return maControlPointA; } setControlPointA(const B2DPoint & rValue)105 void setControlPointA(const B2DPoint& rValue) { maControlPointA = rValue; } 106 getControlPointB() const107 B2DPoint getControlPointB() const { return maControlPointB; } setControlPointB(const B2DPoint & rValue)108 void setControlPointB(const B2DPoint& rValue) { maControlPointB = rValue; } 109 110 /** get the tangent in point t 111 112 This method handles all the exceptions, e.g. when control point 113 A is equal to start point and/or control point B is equal to end 114 point 115 116 @param t 117 The bezier index in the range [0.0 .. 1.0]. It will be truncated. 118 119 @return 120 The tangent vector in point t 121 */ 122 B2DVector getTangent(double t) const; 123 124 /** adaptive subdivide by angle criteria 125 no start point is added, but all necessary created edges 126 and the end point 127 #i37443# allow the criteria to get unsharp in recursions 128 */ 129 void adaptiveSubdivideByAngle(B2DPolygon& rTarget, double fAngleBound, bool bAllowUnsharpen) const; 130 131 /** #i37443# adaptive subdivide by nCount subdivisions 132 no start point is added, but all necessary created edges 133 and the end point 134 */ 135 void adaptiveSubdivideByCount(B2DPolygon& rTarget, sal_uInt32 nCount) const; 136 137 /** Subdivide cubic bezier segment. 138 139 This function adaptively subdivides the bezier 140 segment into as much straight line segments as necessary, 141 such that the maximal orthogonal distance from any of the 142 segments to the true curve is less than the given error 143 value. 144 No start point is added, but all necessary created edges 145 and the end point 146 147 @param rPoly 148 Output polygon. The subdivided bezier segment is added to 149 this polygon via B2DPolygon::append(). 150 151 @param rCurve 152 The cubic bezier curve to subdivide 153 154 @param fDistanceBound 155 Bound on the maximal distance of the approximation to the 156 true curve. 157 */ 158 void adaptiveSubdivideByDistance(B2DPolygon& rTarget, double fDistanceBound) const; 159 160 // get point at given relative position 161 B2DPoint interpolatePoint(double t) const; 162 163 // calculate the smallest distance from given point to this cubic bezier segment 164 // and return the value. The relative position on the segment is returned in rCut. 165 double getSmallestDistancePointToBezierSegment(const B2DPoint& rTestPoint, double& rCut) const; 166 167 // do a split at position t and fill both resulting segments 168 void split(double t, B2DCubicBezier* pBezierA, B2DCubicBezier* pBezierB) const; 169 170 // extract snippet from fStart to fEnd from this bezier 171 B2DCubicBezier snippet(double fStart, double fEnd) const; 172 173 // get range including conrol points 174 B2DRange getRange() const; 175 176 /** Get the minimum extremum position t 177 178 @param rfResult 179 Will be changed and set to a eventually found split value which should be in the 180 range [0.0 .. 1.0]. It will be the smallest current extremum; there may be more 181 182 @return 183 Returns true if there was at least one extremum found 184 */ 185 bool getMinimumExtremumPosition(double& rfResult) const; 186 187 /** Get all extremum pos of this segment 188 189 This method will calculate all extremum positions of the segment 190 and add them to rResults if they are in the range ]0.0 .. 1.0[ 191 192 @param rResults 193 The vector of doubles where the results will be added. Evtl. 194 existing contents will be removed since an empty vector is a 195 necessary result to express that there are no extreme positions 196 anymore. Since there is an upper maximum of 4 values, it makes 197 sense to use reserve(4) at the vector as preparation. 198 */ 199 void getAllExtremumPositions(::std::vector< double >& rResults) const; 200 201 /** Get optimum-split position on this segment 202 203 This method calculates the positions of all points of the segment 204 that have the maximimum distance to the corresponding line from 205 startpoint-endpoint. This helps to approximate the bezier curve 206 with a minimum number of line segments 207 208 @param fResults 209 Result positions are in the range ]0.0 .. 1.0[ 210 Cubic beziers have at most two of these positions 211 212 @return 213 Returns the number of split positions found 214 */ 215 int getMaxDistancePositions( double fResults[2]) const; 216 }; 217 } // end of namespace basegfx 218 219 #endif /* _BGFX_CURVE_B2DCUBICBEZIER_HXX */ 220