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