1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <basegfx/point/b2dpoint.hxx>
23 #include <basegfx/range/b2drange.hxx>
24 #include <basegfx/basegfxdllapi.h>
33 class BASEGFX_DLLPUBLIC B2DCubicBezier
36 B2DPoint maStartPoint
;
38 B2DPoint maControlPointA
;
39 B2DPoint maControlPointB
;
43 B2DCubicBezier(const B2DCubicBezier
& rBezier
);
44 B2DCubicBezier(const B2DPoint
& rStart
, const B2DPoint
& rControlPointA
, const B2DPoint
& rControlPointB
, const B2DPoint
& rEnd
);
47 // assignment operator
48 B2DCubicBezier
& operator=(const B2DCubicBezier
& rBezier
);
51 bool operator==(const B2DCubicBezier
& rBezier
) const;
52 bool operator!=(const B2DCubicBezier
& rBezier
) const;
53 bool equal(const B2DCubicBezier
& rBezier
) const;
55 // test if vectors are used
56 bool isBezier() const;
58 // test if contained bezier is trivial and reset vectors accordingly
59 void testAndSolveTrivialBezier();
61 /** get length of edge
63 This method handles beziers and simple edges. For
64 beziers, the deviation describes the maximum allowed
65 deviation from the real edge length. The default
66 allows a deviation of 1% from the correct length.
68 For beziers, there is no direct way to get the length,
69 thus this method may subdivide the bezier edge and may
73 The maximal allowed deviation between correct length
74 and bezier edge length
77 The length of the edge
79 double getLength(double fDeviation
= 0.01) const;
81 // get distance between start and end point
82 double getEdgeLength() const;
84 // get length of control polygon
85 double getControlPolygonLength() const;
88 const B2DPoint
& getStartPoint() const { return maStartPoint
; }
89 void setStartPoint(const B2DPoint
& rValue
) { maStartPoint
= rValue
; }
91 const B2DPoint
& getEndPoint() const { return maEndPoint
; }
92 void setEndPoint(const B2DPoint
& rValue
) { maEndPoint
= rValue
; }
94 const B2DPoint
& getControlPointA() const { return maControlPointA
; }
95 void setControlPointA(const B2DPoint
& rValue
) { maControlPointA
= rValue
; }
97 const B2DPoint
& getControlPointB() const { return maControlPointB
; }
98 void setControlPointB(const B2DPoint
& rValue
) { maControlPointB
= rValue
; }
100 /** get the tangent in point t
102 This method handles all the exceptions, e.g. when control point
103 A is equal to start point and/or control point B is equal to end
107 The bezier index in the range [0.0 .. 1.0]. It will be truncated.
110 The tangent vector in point t
112 B2DVector
getTangent(double t
) const;
114 /** adaptive subdivide by angle criteria
115 no start point is added, but all necessary created edges
117 #i37443# allow the criteria to get unsharp in recursions
119 void adaptiveSubdivideByAngle(B2DPolygon
& rTarget
, double fAngleBound
) const;
121 /** #i37443# adaptive subdivide by nCount subdivisions
122 no start point is added, but all necessary created edges
125 void adaptiveSubdivideByCount(B2DPolygon
& rTarget
, sal_uInt32 nCount
) const;
127 /** Subdivide cubic bezier segment.
129 This function adaptively subdivides the bezier
130 segment into as much straight line segments as necessary,
131 such that the maximal orthogonal distance from any of the
132 segments to the true curve is less than the given error
134 No start point is added, but all necessary created edges
138 Output polygon. The subdivided bezier segment is added to
139 this polygon via B2DPolygon::append().
142 The cubic bezier curve to subdivide
144 @param fDistanceBound
145 Bound on the maximal distance of the approximation to the
148 void adaptiveSubdivideByDistance(B2DPolygon
& rTarget
, double fDistanceBound
) const;
150 // get point at given relative position
151 B2DPoint
interpolatePoint(double t
) const;
153 // calculate the smallest distance from given point to this cubic bezier segment
154 // and return the value. The relative position on the segment is returned in rCut.
155 double getSmallestDistancePointToBezierSegment(const B2DPoint
& rTestPoint
, double& rCut
) const;
157 // do a split at position t and fill both resulting segments
158 void split(double t
, B2DCubicBezier
* pBezierA
, B2DCubicBezier
* pBezierB
) const;
160 // extract snippet from fStart to fEnd from this bezier
161 B2DCubicBezier
snippet(double fStart
, double fEnd
) const;
163 // get range including control points
164 B2DRange
getRange() const;
166 /** Get the minimum extremum position t
169 Will be changed and might possibly be set to a found split value, which should be in the
170 range [0.0 .. 1.0]. It will be the smallest current extremum; there may be more
173 Returns true if there was at least one extremum found
175 bool getMinimumExtremumPosition(double& rfResult
) const;
177 /** Get all extremum pos of this segment
179 This method will calculate all extremum positions of the segment
180 and add them to rResults if they are in the range ]0.0 .. 1.0[
183 The vector of doubles where the results will be added. Evtl.
184 existing contents will be removed since an empty vector is a
185 necessary result to express that there are no extreme positions
186 anymore. Since there is an upper maximum of 4 values, it makes
187 sense to use reserve(4) at the vector as preparation.
189 void getAllExtremumPositions(::std::vector
< double >& rResults
) const;
191 /// apply transformation given in matrix form
192 void transform(const basegfx::B2DHomMatrix
& rMatrix
);
197 } // end of namespace basegfx
199 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */