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 : namespace basegfx
28 : {
29 : class B2DPolygon;
30 : }
31 :
32 : namespace basegfx
33 : {
34 : class BASEGFX_DLLPUBLIC B2DCubicBezier
35 : {
36 : B2DPoint maStartPoint;
37 : B2DPoint maEndPoint;
38 : B2DPoint maControlPointA;
39 : B2DPoint maControlPointB;
40 :
41 : public:
42 : B2DCubicBezier();
43 : B2DCubicBezier(const B2DCubicBezier& rBezier);
44 : B2DCubicBezier(const B2DPoint& rStart, const B2DPoint& rControlPointA, const B2DPoint& rControlPointB, const B2DPoint& rEnd);
45 : ~B2DCubicBezier();
46 :
47 : // assignment operator
48 : B2DCubicBezier& operator=(const B2DCubicBezier& rBezier);
49 :
50 : // compare operators
51 : bool operator==(const B2DCubicBezier& rBezier) const;
52 : bool operator!=(const B2DCubicBezier& rBezier) const;
53 : bool equal(const B2DCubicBezier& rBezier) const;
54 :
55 : // test if vectors are used
56 : bool isBezier() const;
57 :
58 : // test if contained bezier is trivial and reset vectors accordingly
59 : void testAndSolveTrivialBezier();
60 :
61 : /** get length of edge
62 :
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.
67 :
68 : For beziers, there is no direct way to get the length,
69 : thus this method may subdivide the bezier edge and may
70 : not be cheap.
71 :
72 : @param fDeviation
73 : The maximal allowed deviation between correct length
74 : and bezier edge length
75 :
76 : @return
77 : The length of the edge
78 : */
79 : double getLength(double fDeviation = 0.01) const;
80 :
81 : // get distance between start and end point
82 : double getEdgeLength() const;
83 :
84 : // get length of control polygon
85 : double getControlPolygonLength() const;
86 :
87 : // data interface
88 2052972 : B2DPoint getStartPoint() const { return maStartPoint; }
89 1442919 : void setStartPoint(const B2DPoint& rValue) { maStartPoint = rValue; }
90 :
91 2014475 : B2DPoint getEndPoint() const { return maEndPoint; }
92 1383846 : void setEndPoint(const B2DPoint& rValue) { maEndPoint = rValue; }
93 :
94 600494 : B2DPoint getControlPointA() const { return maControlPointA; }
95 1383846 : void setControlPointA(const B2DPoint& rValue) { maControlPointA = rValue; }
96 :
97 374430 : B2DPoint getControlPointB() const { return maControlPointB; }
98 1383846 : void setControlPointB(const B2DPoint& rValue) { maControlPointB = rValue; }
99 :
100 : /** get the tangent in point t
101 :
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
104 : point
105 :
106 : @param t
107 : The bezier index in the range [0.0 .. 1.0]. It will be truncated.
108 :
109 : @return
110 : The tangent vector in point t
111 : */
112 : B2DVector getTangent(double t) const;
113 :
114 : /** adaptive subdivide by angle criteria
115 : no start point is added, but all necessary created edges
116 : and the end point
117 : #i37443# allow the criteria to get unsharp in recursions
118 : */
119 : void adaptiveSubdivideByAngle(B2DPolygon& rTarget, double fAngleBound, bool bAllowUnsharpen) const;
120 :
121 : /** #i37443# adaptive subdivide by nCount subdivisions
122 : no start point is added, but all necessary created edges
123 : and the end point
124 : */
125 : void adaptiveSubdivideByCount(B2DPolygon& rTarget, sal_uInt32 nCount) const;
126 :
127 : /** Subdivide cubic bezier segment.
128 :
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
133 : value.
134 : No start point is added, but all necessary created edges
135 : and the end point
136 :
137 : @param rPoly
138 : Output polygon. The subdivided bezier segment is added to
139 : this polygon via B2DPolygon::append().
140 :
141 : @param rCurve
142 : The cubic bezier curve to subdivide
143 :
144 : @param fDistanceBound
145 : Bound on the maximal distance of the approximation to the
146 : true curve.
147 : */
148 : void adaptiveSubdivideByDistance(B2DPolygon& rTarget, double fDistanceBound) const;
149 :
150 : // get point at given relative position
151 : B2DPoint interpolatePoint(double t) const;
152 :
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;
156 :
157 : // do a split at position t and fill both resulting segments
158 : void split(double t, B2DCubicBezier* pBezierA, B2DCubicBezier* pBezierB) const;
159 :
160 : // extract snippet from fStart to fEnd from this bezier
161 : B2DCubicBezier snippet(double fStart, double fEnd) const;
162 :
163 : // get range including conrol points
164 : B2DRange getRange() const;
165 :
166 : /** Get the minimum extremum position t
167 :
168 : @param rfResult
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
171 :
172 : @return
173 : Returns true if there was at least one extremum found
174 : */
175 : bool getMinimumExtremumPosition(double& rfResult) const;
176 :
177 : /** Get all extremum pos of this segment
178 :
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[
181 :
182 : @param rResults
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.
188 : */
189 : void getAllExtremumPositions(::std::vector< double >& rResults) const;
190 : };
191 : } // end of namespace basegfx
192 :
193 : #endif // INCLUDED_BASEGFX_CURVE_B2DCUBICBEZIER_HXX
194 :
195 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|