Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #ifndef INCLUDED_BASEGFX_CURVE_B2DCUBICBEZIER_HXX
21 : #define INCLUDED_BASEGFX_CURVE_B2DCUBICBEZIER_HXX
22 :
23 : #include <basegfx/point/b2dpoint.hxx>
24 : #include <basegfx/range/b2drange.hxx>
25 : #include <basegfx/basegfxdllapi.h>
26 :
27 :
28 : // predeclarations
29 :
30 : namespace basegfx
31 : {
32 : class B2DPolygon;
33 : } // end of namespace basegfx
34 :
35 :
36 :
37 : namespace basegfx
38 : {
39 : class BASEGFX_DLLPUBLIC B2DCubicBezier
40 : {
41 : B2DPoint maStartPoint;
42 : B2DPoint maEndPoint;
43 : B2DPoint maControlPointA;
44 : B2DPoint maControlPointB;
45 :
46 : public:
47 : B2DCubicBezier();
48 : B2DCubicBezier(const B2DCubicBezier& rBezier);
49 : B2DCubicBezier(const B2DPoint& rStart, const B2DPoint& rControlPointA, const B2DPoint& rControlPointB, const B2DPoint& rEnd);
50 : ~B2DCubicBezier();
51 :
52 : // assignment operator
53 : B2DCubicBezier& operator=(const B2DCubicBezier& rBezier);
54 :
55 : // compare operators
56 : bool operator==(const B2DCubicBezier& rBezier) const;
57 : bool operator!=(const B2DCubicBezier& rBezier) const;
58 : bool equal(const B2DCubicBezier& rBezier) const;
59 :
60 : // test if vectors are used
61 : bool isBezier() const;
62 :
63 : // test if contained bezier is trivial and reset vectors accordingly
64 : void testAndSolveTrivialBezier();
65 :
66 : /** get length of edge
67 :
68 : This method handles beziers and simple edges. For
69 : beziers, the deviation describes the maximum allowed
70 : deviation from the real edge length. The default
71 : allows a deviation of 1% from the correct length.
72 :
73 : For beziers, there is no direct way to get the length,
74 : thus this method may subdivide the bezier edge and may
75 : not be cheap.
76 :
77 : @param fDeviation
78 : The maximal allowed deviation between correct length
79 : and bezier edge length
80 :
81 : @return
82 : The length of the edge
83 : */
84 : double getLength(double fDeviation = 0.01) const;
85 :
86 : // get distance between start and end point
87 : double getEdgeLength() const;
88 :
89 : // get length of control polygon
90 : double getControlPolygonLength() const;
91 :
92 : // data interface
93 0 : B2DPoint getStartPoint() const { return maStartPoint; }
94 0 : void setStartPoint(const B2DPoint& rValue) { maStartPoint = rValue; }
95 :
96 0 : B2DPoint getEndPoint() const { return maEndPoint; }
97 0 : void setEndPoint(const B2DPoint& rValue) { maEndPoint = rValue; }
98 :
99 0 : B2DPoint getControlPointA() const { return maControlPointA; }
100 0 : void setControlPointA(const B2DPoint& rValue) { maControlPointA = rValue; }
101 :
102 0 : B2DPoint getControlPointB() const { return maControlPointB; }
103 0 : void setControlPointB(const B2DPoint& rValue) { maControlPointB = rValue; }
104 :
105 : /** get the tangent in point t
106 :
107 : This method handles all the exceptions, e.g. when control point
108 : A is equal to start point and/or control point B is equal to end
109 : point
110 :
111 : @param t
112 : The bezier index in the range [0.0 .. 1.0]. It will be truncated.
113 :
114 : @return
115 : The tangent vector in point t
116 : */
117 : B2DVector getTangent(double t) const;
118 :
119 : /** adaptive subdivide by angle criteria
120 : no start point is added, but all necessary created edges
121 : and the end point
122 : #i37443# allow the criteria to get unsharp in recursions
123 : */
124 : void adaptiveSubdivideByAngle(B2DPolygon& rTarget, double fAngleBound, bool bAllowUnsharpen) const;
125 :
126 : /** #i37443# adaptive subdivide by nCount subdivisions
127 : no start point is added, but all necessary created edges
128 : and the end point
129 : */
130 : void adaptiveSubdivideByCount(B2DPolygon& rTarget, sal_uInt32 nCount) const;
131 :
132 : /** Subdivide cubic bezier segment.
133 :
134 : This function adaptively subdivides the bezier
135 : segment into as much straight line segments as necessary,
136 : such that the maximal orthogonal distance from any of the
137 : segments to the true curve is less than the given error
138 : value.
139 : No start point is added, but all necessary created edges
140 : and the end point
141 :
142 : @param rPoly
143 : Output polygon. The subdivided bezier segment is added to
144 : this polygon via B2DPolygon::append().
145 :
146 : @param rCurve
147 : The cubic bezier curve to subdivide
148 :
149 : @param fDistanceBound
150 : Bound on the maximal distance of the approximation to the
151 : true curve.
152 : */
153 : void adaptiveSubdivideByDistance(B2DPolygon& rTarget, double fDistanceBound) const;
154 :
155 : // get point at given relative position
156 : B2DPoint interpolatePoint(double t) const;
157 :
158 : // calculate the smallest distance from given point to this cubic bezier segment
159 : // and return the value. The relative position on the segment is returned in rCut.
160 : double getSmallestDistancePointToBezierSegment(const B2DPoint& rTestPoint, double& rCut) const;
161 :
162 : // do a split at position t and fill both resulting segments
163 : void split(double t, B2DCubicBezier* pBezierA, B2DCubicBezier* pBezierB) const;
164 :
165 : // extract snippet from fStart to fEnd from this bezier
166 : B2DCubicBezier snippet(double fStart, double fEnd) const;
167 :
168 : // get range including conrol points
169 : B2DRange getRange() const;
170 :
171 : /** Get the minimum extremum position t
172 :
173 : @param rfResult
174 : Will be changed and set to a eventually found split value which should be in the
175 : range [0.0 .. 1.0]. It will be the smallest current extremum; there may be more
176 :
177 : @return
178 : Returns true if there was at least one extremum found
179 : */
180 : bool getMinimumExtremumPosition(double& rfResult) const;
181 :
182 : /** Get all extremum pos of this segment
183 :
184 : This method will calculate all extremum positions of the segment
185 : and add them to rResults if they are in the range ]0.0 .. 1.0[
186 :
187 : @param rResults
188 : The vector of doubles where the results will be added. Evtl.
189 : existing contents will be removed since an empty vector is a
190 : necessary result to express that there are no extreme positions
191 : anymore. Since there is an upper maximum of 4 values, it makes
192 : sense to use reserve(4) at the vector as preparation.
193 : */
194 : void getAllExtremumPositions(::std::vector< double >& rResults) const;
195 : };
196 : } // end of namespace basegfx
197 :
198 : #endif // INCLUDED_BASEGFX_CURVE_B2DCUBICBEZIER_HXX
199 :
200 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|