1 //////////////////////////////////////////////////////////////////////
2
3 struct Matrixf;
4
5 static const double TWOPI = 2 * M_PI;
6 static const double DEGRAD = M_PI / 180.0;
7
8 //////////////////////////////////////////////////////////////////////
9
10 //inline Pointf Pointf_0 () { return Pointf(0, 0); }
11 //inline Pointf Pointf_X () { return Pointf(1, 0); }
12 //inline Pointf Pointf_Y () { return Pointf(0, 1); }
13 //inline Pointf Pointf_RX () { return Pointf(-1, 1); }
14 //inline Pointf Pointf_RY () { return Pointf(1, -1); }
15
fpmin(Pointf p,Pointf q)16 inline Pointf fpmin (Pointf p, Pointf q) { return Pointf(min(p.x, q.x), min(p.y, q.y)); }
fpmax(Pointf p,Pointf q)17 inline Pointf fpmax (Pointf p, Pointf q) { return Pointf(max(p.x, q.x), max(p.y, q.y)); }
fpminmax(Pointf p,Pointf mn,Pointf mx)18 inline Pointf fpminmax (Pointf p, Pointf mn, Pointf mx) { return Pointf(minmax(p.x, mn.x, mx.x), minmax(p.y, mn.y, mx.y)); }
19
fpmin(Pointf p)20 inline double fpmin (Pointf p) { return min(p.x, p.y); }
fpmax(Pointf p)21 inline double fpmax (Pointf p) { return max(p.x, p.y); }
fpabsmin(Pointf p)22 inline double fpabsmin (Pointf p) { return min(fabs(p.x), fabs(p.y)); }
fpabsmax(Pointf p)23 inline double fpabsmax (Pointf p) { return max(fabs(p.x), fabs(p.y)); }
24
25 // temporary fix by Mirek Fidler:
26 //inline double ScalarProduct(Sizef a, Sizef b) { return a.cx * b.cx + a.cy * b.cy; }
27 //inline double VectorProduct(Sizef a, Sizef b) { return a.cx * b.cy - a.cy * b.cx; }
28 //inline double Squared(Sizef a) { return a.cx * a.cx + a.cy * a.cy; }
29 //inline double Length(Sizef a) { return hypot(a.cx, a.cy); }
30
31 //inline int ScalarProduct(Size a, Size b) { return a.cx * b.cx + a.cy * b.cy; }
32 //inline int VectorProduct(Size a, Size b) { return a.cx * b.cy - a.cy * b.cx; }
33 //inline int Squared(Size a) { return a.cx * a.cx + a.cy * a.cy; }
34 //inline double Length(Size a) { return hypot(a.cx, a.cy); }
35
36
Move(const Pointf & p,double dx,double dy)37 inline Pointf Move (const Pointf& p, double dx, double dy) { return Pointf(p.x + dx, p.y + dy); }
Mid(const Pointf & p,const Pointf & q,double wt)38 inline Pointf Mid (const Pointf& p, const Pointf& q, double wt) { return p + (q - p) * wt; }
Squared(const Pointf & p,const Pointf & q)39 inline double Squared (const Pointf& p, const Pointf& q) { return Squared(q - p); }
40 Pointf Length (const Pointf& p, double l);
UnitV(const Pointf & p)41 inline Pointf UnitV (const Pointf& p) { return Length(p, 1); }
Rotated(const Pointf & p,double a)42 inline Pointf Rotated (const Pointf& p, double a) { double s = sin(a), c = cos(a); return Pointf(p.x * c - p.y * s, p.x * s + p.y * c); }
Rotated(const Pointf & p,double angle,const Pointf & c)43 inline Pointf Rotated (const Pointf& p, double angle, const Pointf& c) { return c + Rotated(p - c, angle); }
44 Pointf Project (const Pointf& p, const Pointf& a, const Pointf& b);
45 Pointf Bezier2 (const Pointf& a, const Pointf& b, const Pointf& c, double t);
46 double Bezier2Length(const Pointf& a, const Pointf& b, const Pointf& c, double t);
47 Sizef Bezier2Tangent(const Pointf& a, const Pointf& b, const Pointf& c, double t);
48 Sizef Orthogonal (const Sizef& p, const Sizef& against);
49 Sizef Orthonormal (const Sizef& p, const Sizef& against);
50 Sizef FarthestAxis (const Sizef& p);
Reversed(const Pointf & p)51 inline Pointf Reversed (const Pointf& p) { return Pointf(-p.x, -p.y); }
ReversedX(const Pointf & p)52 inline Pointf ReversedX (const Pointf& p) { return Pointf(-p.x, p.y); }
ReversedY(const Pointf & p)53 inline Pointf ReversedY (const Pointf& p) { return Pointf(p.x, -p.y); }
54 //inline Pointf Abs (Pointf p) { return Pointf(fabs(p.x), fabs(p.y)); }
Left(const Pointf & p)55 inline Pointf Left (const Pointf& p) { return Pointf(-p.y, p.x); }
Right(const Pointf & p)56 inline Pointf Right (const Pointf& p) { return Pointf(p.y, -p.x); }
57
Bearing(const Pointf & p,const Pointf & c)58 inline double Bearing (const Pointf& p, const Pointf& c) { return Bearing(p - c); }
Select(const Pointf & p,const Pointf & A,const Pointf & B)59 inline bool Select (const Pointf& p, const Pointf& A, const Pointf& B) { return Squared(p - A) < Squared(p - B); }
60
61 inline double operator ^ (const Pointf& p, const Pointf& q) { return p.x * q.x + p.y * q.y; }
62 inline double operator % (const Pointf& p, const Pointf& q) { return p.x * q.y - p.y * q.x; }
63 inline double operator | (const Pointf& p, const Pointf& q) { return Distance(p, q); }
64
PolarPointf(double a)65 inline Pointf PolarPointf (double a) { return Pointf(cos(a), sin(a)); }
PolarPointf(double r,double a)66 inline Pointf PolarPointf (double r, double a) { return Pointf(r * cos(a), r * sin(a)); }
PolarPointf(const Pointf & c,double r,double a)67 inline Pointf PolarPointf (const Pointf& c, double r, double a) { return Pointf(c.x + r * cos(a), c.y + r * sin(a)); }
68
PointfToPoint(const Pointf & p)69 inline Point PointfToPoint(const Pointf& p) { return Point(fround(p.x), fround(p.y)); }
PointfToSize(const Pointf & p)70 inline Size PointfToSize (const Pointf& p) { return Size(fround(p.x), fround(p.y)); }
71
72 //////////////////////////////////////////////////////////////////////
73
74 //inline Sizef Sizef_0 () { return Sizef(0, 0); }
75 //inline Sizef Sizef_X () { return Sizef(1, 0); }
76 //inline Sizef Sizef_Y () { return Sizef(0, 1); }
77 //inline Sizef Sizef_RX () { return Sizef(-1, 1); }
78 //inline Sizef Sizef_RY () { return Sizef(1, -1); }
79
fpmin(const Sizef & p,const Sizef & q)80 inline Sizef fpmin (const Sizef& p, const Sizef& q) { return Sizef(min(p.cx, q.cx), min(p.cy, q.cy)); }
fpmax(const Sizef & p,const Sizef & q)81 inline Sizef fpmax (const Sizef& p, const Sizef& q) { return Sizef(max(p.cx, q.cx), max(p.cy, q.cy)); }
fpminmax(const Sizef & p,const Sizef & mn,const Sizef & mx)82 inline Sizef fpminmax (const Sizef& p, const Sizef& mn, const Sizef& mx) { return Sizef(minmax(p.cx, mn.cx, mx.cx), minmax(p.cy, mn.cy, mx.cy)); }
83
fpmin(const Sizef & p)84 inline double fpmin (const Sizef& p) { return min(p.cx, p.cy); }
fpmax(const Sizef & p)85 inline double fpmax (const Sizef& p) { return max(p.cx, p.cy); }
AbsMin(const Sizef & p)86 inline double AbsMin (const Sizef& p) { return min(fabs(p.cx), fabs(p.cy)); }
AbsMax(const Sizef & p)87 inline double AbsMax (const Sizef& p) { return max(fabs(p.cx), fabs(p.cy)); }
88
Mid(const Sizef & p,const Sizef & q)89 inline Sizef Mid (const Sizef& p, const Sizef& q) { return Sizef((p.cx + q.cx) / 2, (p.cy + q.cy) / 2); }
90 //inline double Squared (Sizef p) { return p.cx * p.cx + p.cy * p.cy; }
Squared(const Sizef & p,const Sizef & q)91 inline double Squared (const Sizef& p, const Sizef& q) { return Squared(q - p); }
92 //inline double Length (Sizef p) { return sqrt(Squared(p)); }
93 Sizef Length (const Sizef& p, double l);
UnitV(const Sizef & p)94 inline Sizef UnitV (const Sizef& p) { return Length(p, 1); }
Reversed(const Sizef & s)95 inline Sizef Reversed (const Sizef& s) { return Sizef(-s.cx, -s.cy); }
ReversedX(const Sizef & s)96 inline Sizef ReversedX (const Sizef& s) { return Sizef(-s.cx, s.cy); }
ReversedY(const Sizef & s)97 inline Sizef ReversedY (const Sizef& s) { return Sizef(s.cx, -s.cy); }
Abs(const Sizef & s)98 inline Sizef Abs (const Sizef& s) { return Sizef(fabs(s.cx), fabs(s.cy)); }
Left(const Sizef & s)99 inline Sizef Left (const Sizef& s) { return Sizef(-s.cy, s.cx); }
Right(const Sizef & s)100 inline Sizef Right (const Sizef& s) { return Sizef(s.cy, -s.cx); }
101
SizefToPoint(const Sizef & s)102 inline Point SizefToPoint (const Sizef& s) { return Point(fround(s.cx), fround(s.cy)); }
SizefToSize(const Sizef & s)103 inline Size SizefToSize (const Sizef& s) { return Size(fround(s.cx), fround(s.cy)); }
104
105 //////////////////////////////////////////////////////////////////////
106 // Rectf::
107
108 //inline Rectf Rectf_0() { return Rectf(0, 0, 0, 0); }
109 //inline Rectf Rectf_1() { return Rectf(0, 0, 1, 1); }
110
111 //////////////////////////////////////////////////////////////////////
112
113 inline Rectf operator * (const Rectf& r, double f) { return Rectf(r.left * f, r.top * f, r.right * f, r.bottom * f); }
114 inline Rectf operator * (const Rectf& r, const Sizef& s) { return Rectf(r.left * s.cx, r.top * s.cy, r.right * s.cx, r.bottom * s.cy); }
115 inline Rectf operator * (const Rectf& r, const Pointf& p) { return Rectf(r.left * p.x, r.top * p.y, r.right * p.x, r.bottom * p.y); }
116 inline Rectf operator * (const Rectf& r, const Rectf& s) { return Rectf(r.left * s.left, r.top * s.top, r.right * s.right, r.bottom * s.bottom); }
117
118 inline Rectf operator / (const Rectf& r, double f) { return Rectf(r.left / f, r.top / f, r.right / f, r.bottom / f); }
119 inline Rectf operator / (const Rectf& r, const Sizef& s) { return Rectf(r.left / s.cx, r.top / s.cy, r.right / s.cx, r.bottom / s.cy); }
120 inline Rectf operator / (const Rectf& r, const Pointf& p) { return Rectf(r.left / p.x, r.top / p.y, r.right / p.x, r.bottom / p.y); }
121 inline Rectf operator / (const Rectf& r, const Rectf& s) { return Rectf(r.left / s.left, r.top / s.top, r.right / s.right, r.bottom / s.bottom); }
122
123 extern Rectf& SetUnion (Rectf& rc, const Pointf& pt);
GetUnion(const Rectf & rc,const Pointf & p)124 inline Rectf GetUnion (const Rectf& rc, const Pointf& p) { Rectf tmp = rc; return SetUnion(tmp, p); }
125 extern Rectf GetUnion (const Array<Pointf>& pt);
126 extern Rectf& SetMinMaxMove(Rectf& rc, const Rectf& outer_rc);
GetMinMaxMove(const Rectf & rc,const Rectf & outer_rc)127 inline Rectf GetMinMaxMove(const Rectf& rc, const Rectf& outer_rc) { Rectf tmp = rc; return SetMinMaxMove(tmp, outer_rc); }
128 extern double Distance (const Rectf& rc, const Pointf& pt);
Diagonal(const Rectf & rc)129 inline double Diagonal (const Rectf& rc) { return Length(rc.Size()); }
Area(const Rectf & rc)130 inline double Area (const Rectf& rc) { return rc.Width() * rc.Height(); }
PointfRectf(const Pointf & pt)131 inline Rectf PointfRectf (const Pointf& pt) { return Rectf(pt.x, pt.y, pt.x, pt.y); }
SortRectf(const Pointf & p,const Pointf & q)132 inline Rectf SortRectf (const Pointf& p, const Pointf& q) { return Rectf(fpmin(p, q), fpmax(p, q)); }
RectfToRect(const Rectf & rc)133 inline Rect RectfToRect (const Rectf& rc) { return Rect(fround(rc.left), fround(rc.top), fround(rc.right), fround(rc.bottom)); }
134
fpminmax(const Pointf & p,const Rectf & rc)135 inline Pointf fpminmax (const Pointf& p, const Rectf& rc) { return Pointf(minmax(p.x, rc.left, rc.right), minmax(p.y, rc.top, rc.bottom)); }
136
137 //////////////////////////////////////////////////////////////////////
138 //////////////////////////////////////////////////////////////////////
139
140 const Matrixf& Matrixf_0();
141 const Matrixf& Matrixf_1();
142 const Matrixf& Matrixf_Null();
143 const Matrixf& Matrixf_MirrorX(); // mirror around X axis
144 const Matrixf& Matrixf_MirrorY(); // mirror around Y axis
145
146 //////////////////////////////////////////////////////////////////////
147
148 struct Matrixf : Moveable<Matrixf>
149 {
150 Pointf x, y, a;
151
MatrixfMatrixf152 Matrixf() { *this = Matrixf_1(); }
MatrixfMatrixf153 Matrixf(const Nuller&) : a(Null) {}
xMatrixf154 Matrixf(Pointf x, Pointf y, Pointf a = Pointf(0, 0)) : x(x), y(y), a(a) {}
MatrixfMatrixf155 Matrixf(const Matrixf& (*fn)()) { *this = fn(); }
MatrixfMatrixf156 Matrixf(double xx, double xy, double yx, double yy, double ax, double ay)
157 : x(xx, xy), y(yx, yy), a(ax, ay) {}
158
IsIdentityMatrixf159 bool IsIdentity() const { return x.x == 1 && x.y == 0 && y.x == 0 && y.y == 1 && a.x == 0 && a.y == 0; }
IsZeroMatrixf160 bool IsZero() const { return x.x == 0 && x.y == 0 && y.x == 0 && y.y == 0 && a.x == 0 && a.y == 0; }
161
FixMatrixf162 void Fix(Pointf vector) { a = vector - vector.x * x - vector.y * y; }
163 Matrixf& operator *= (const Matrixf& another);
164
165 String ToString() const;
166 };
167
168 //template DumpType<Matrixf>;
169
170 extern Matrixf MatrixfMove (Pointf vector);
171 extern Matrixf MatrixfRotate (double angle, Pointf fix = Pointf(0, 0));
172 extern Matrixf MatrixfScale (double scale, Pointf fix = Pointf(0, 0));
173 extern Matrixf MatrixfScale (Pointf scale, Pointf fix = Pointf(0, 0));
174 extern Matrixf MatrixfScale (const Rectf& src, const Rectf& dest);
175 extern Matrixf MatrixfMirror (Pointf A, Pointf B);
176 extern Matrixf MatrixfAffine (Pointf src1, Pointf dest1, Pointf src2, Pointf dest2);
177 extern Matrixf MatrixfAffine (Pointf src1, Pointf dest1, Pointf src2, Pointf dest2, Pointf src3, Pointf dest3);
178
179 extern Matrixf MatrixfInverse(const Matrixf& mx);
Determinant(const Matrixf & mx)180 inline double Determinant (const Matrixf& mx) { return mx.x % mx.y; }
IsReversing(const Matrixf & mx)181 inline bool IsReversing (const Matrixf& mx) { return Determinant(mx) < 0; }
182 extern double MatrixfMeasure(const Matrixf& mx);
183
184 template<>
IsNull(const Matrixf & mx)185 inline bool IsNull (const Matrixf& mx) { return IsNull(mx.a); }
186 inline bool operator == (const Matrixf& m1, const Matrixf& m2) { return m1.x == m2.x && m1.y == m2.y && m1.a == m2.a; }
187 inline bool operator != (const Matrixf& m1, const Matrixf& m2) { return !(m1 == m2); }
188
189 inline Pointf operator % (Pointf vector, const Matrixf& matrix) { return vector.x * matrix.x + vector.y * matrix.y; }
190 extern Pointf operator * (Pointf point, const Matrixf& matrix);
191 extern Pointf operator / (Pointf point, const Matrixf& matrix);
192 extern Rectf operator * (const Rectf& rect, const Matrixf& matrix);
193 extern Rectf operator / (const Rectf& rect, const Matrixf& matrix);
194
195 inline Pointf& operator %= (Pointf& point, const Matrixf& matrix) { return point = point % matrix; }
196 inline Pointf& operator *= (Pointf& point, const Matrixf& matrix) { return point = point * matrix; }
197
198 inline Matrixf operator * (const Matrixf& m1, const Matrixf& m2) { return Matrixf(m1) *= m2; }
199 inline Matrixf operator / (const Matrixf& m1, const Matrixf& m2) { return m1 * MatrixfInverse(m2); }
200
201 //////////////////////////////////////////////////////////////////////
202 // set distance of point from an object
203
204 double Distance (Pointf X, Pointf A, Pointf B, double *arg = NULL);
205 double Distance (Pointf X, Pointf A, Pointf B, double bulge, double *arg = NULL);
206 double Distance (Pointf X, Pointf C, double radius, double *arg = NULL);
207
208 //////////////////////////////////////////////////////////////////////
209 // set intersection with rectangle
210
211 bool Crosses (const Rectf& R, Pointf A, Pointf B);
212 bool Crosses (const Rectf& R, Pointf A, Pointf B, double bulge);
213 bool Crosses (const Rectf& R, Pointf C, double radius);
214
215 //////////////////////////////////////////////////////////////////////
216 // set intersection with polygon
217
218 enum { CMP_OUT = -1, CMP_SECT = 0, CMP_IN = +1 };
219
220 int ContainsPoints(const Array<Pointf>& polygon, const Array<Pointf>& points);
221 int ContainsPoints(const Array<Pointf>& polygon, const Vector<int>& polyend, const Array<Pointf>& points);
222 int ContainsPoint (const Array<Pointf>& polygon, Pointf pt);
223 int ContainsPoint (const Array<Pointf>& polygon, const Vector<int>& polyend, Pointf pt);
224 int ContainsPoly (const Array<Pointf>& chkpoly, const Array<Pointf>& polygon, const Vector<int>& polyend, bool closed);
225 int ContainsPoly (const Array<Pointf>& chkpoly, const Array<Pointf>& polygon, bool closed);
226
227 //////////////////////////////////////////////////////////////////////
228
229 bool ClipLine (Pointf& A, Pointf& B, const Rectf& box);
230 bool ClipLine (Pointf& A, Pointf& B, const Rect& box);
231 bool ClipLine (Point& A, Point& B, const Rect& box);
232
233 //////////////////////////////////////////////////////////////////////
234
235 Vector<int> ConvexHullOrder(const Vector<Point>& pt);
236 Vector<int> ConvexHullOrder(const Array<Pointf>& pt);
237
238 //////////////////////////////////////////////////////////////////////
239
240 Rectf GetBoundingBox(const Array<Pointf>& vertices);
241 Rect GetBoundingBox(const Point *vertices, int vertex_count);
242 Rect GetBoundingBox(const Vector<Point>& vertices);
243
244 void SplitPolygon (const Point *vertices, int vertex_count, const int *counts, int count_count,
245 Vector<Point>& out_vertices, Vector<int>& out_counts, Rect clip = Null, int max_trace_points = 8000);
246 void SplitPolygon (const Vector<Point>& vertices, const Vector<int>& counts,
247 Vector<Point>& out_vertices, Vector<int>& out_counts, Rect clip = Null, int max_trace_points = 8000);
248 void SplitPolygon (Array<Pointf>::ConstIterator vertices, int vertex_count, const int *counts, int count_count,
249 Array<Pointf>& out_vertices, Vector<int>& out_counts, const Rectf& clip = Null, int max_trace_points = 8000);
250 void SplitPolygon (const Array<Pointf>& vertices, const Vector<int>& counts,
251 Array<Pointf>& out_vertices, Vector<int>& out_counts, const Rectf& clip = Null, int max_trace_points = 8000);
252
253 //////////////////////////////////////////////////////////////////////
254
255 extern double Vec_outer_tolerance; // maximum reasonable coordinate value
256 extern double Vec_tolerance; // linear tolerance
257 extern double Vec_ang_tolerance; // angular tolerance
258
259 extern bool VecTolEq (double x, double y);
260 extern bool VecTolEq (Pointf a, Pointf b);
261
262 //////////////////////////////////////////////////////////////////////
263
264 class VecLine
265 {
266 public:
267 VecLine();
VecLine(Pointf A,Pointf B)268 VecLine(Pointf A, Pointf B) : A(A), B(B) {}
VecLine(double x1,double y1,double x2,double y2)269 VecLine(double x1, double y1, double x2, double y2) : A(x1, y1), B(x2, y2) {}
270
271 String ToString() const;
272
273 VecLine& SetNull();
274
Length()275 double Length() const { return A | B; }
276 Pointf Mid() const;
277 Pointf Right() const;
278 Pointf Left() const;
279 Pointf Vector() const;
280
281 double GetArg(Pointf pt) const;
282 Pointf GetPointAt(double arg) const;
283
284 VecLine Reversed() const;
285 VecLine& SetReversed();
286
287 Pointf Intersect(VecLine another) const;
288 VecLine& SetClip(const Rectf& rect);
Clip(const Rectf & rect)289 VecLine Clip(const Rectf& rect) const { return VecLine(*this).SetClip(rect); }
290
291 double Distance(Pointf point, double *arg = NULL) const;
292
IsNullInstance()293 bool IsNullInstance() const { return IsNull(A); }
294
295 // algorithms
296 static Pointf GetPointAt(Pointf A, Pointf B, double arg);
297
298 public:
299 Pointf A, B;
300 };
301
302 //template BitWiseType<VecLine>;
303 //template DumpType<VecLine>;
304
305 inline Pointf operator & (VecLine l1, VecLine l2) { return l1.Intersect(l2); }
306 inline VecLine operator & (VecLine line, const Rectf& rect) { return line.Clip(rect); }
307 inline double operator | (VecLine ln, Pointf pt) { return ln.Distance(pt); }
308 inline double operator | (Pointf pt, VecLine ln) { return ln.Distance(pt); }
309
310 //////////////////////////////////////////////////////////////////////
311
312 class VecArc : public VecLine
313 {
314 public:
315 VecArc();
VecLine(line)316 VecArc(VecLine line, double bulge = 0) : VecLine(line), bulge(bulge) {}
VecLine(A,B)317 VecArc(Pointf A, Pointf B, double bulge = 0) : VecLine(A, B), bulge(bulge) {}
318 VecArc(double x1, double y1, double x2, double y2, double bulge = 0)
VecLine(x1,y1,x2,y2)319 : VecLine(x1, y1, x2, y2), bulge(bulge) {}
320
321 String ToString() const;
322
323 Pointf ArcMid() const;
324 double ArcLength() const;
325
326 VecArc Reversed() const;
327 VecArc& SetReversed();
328
329 Pointf GetPointAt(double t) const;
330 Rectf GetBoundingBox() const;
331
332 // arc algorithms
333 static Pointf ArcMid(Pointf P, Pointf Q, double l, double h);
334 static double ArcLength(Pointf P, Pointf Q, double l, double h);
335 static void Bisect(Pointf P, Pointf Q, double l, double h,
336 Pointf& centre, double& ll, double& hh);
337 static Pointf GetPointAt(Pointf P, Pointf Q, double l, double h, double t);
338
339 public:
340 double bulge;
341 };
342
343 //template BitWiseType<VecArc>;
344 //template DumpType<VecArc>;
345
346 //////////////////////////////////////////////////////////////////////
347
348 /*
349 struct VecVertex : public Pointf
350 {
351 VecVertex();
352 VecVertex(Pointf point, double bulge = 0) : Pointf(point), bulge(bulge) {}
353 VecVertex(double x, double y, double bulge = 0) : Pointf(x, y), bulge(bulge) {}
354
355 String Dump() const;
356
357 double bulge; // bulge of segment __ENDING AT THIS VERTEX__
358 };
359
360 template BitWiseType<VecVertex>;
361 template DumpType<VecVertex>;
362 */
363
364 //////////////////////////////////////////////////////////////////////
365
366 /*
367 class VecCurve : public Vector<VecVertex>
368 {
369 public:
370 typedef Vector<VecVertex> Base;
371
372 VecCurve();
373 VecCurve(const VecCurve& another, int);
374
375 void Add(const VecVertex& vertex);
376 void Add(Pointf point); // can be used as lineto callback for Arc::Iterator
377 void Add(Pointf point, double bulge);
378 void Add(double x, double y, double bulge = 0);
379
380 VecArc Segment(int i) const;
381
382 Vector<Pointf> Check() const; // find self-intersections; empty return value = OK
383
384 String Dump() const;
385 };
386
387 template class DeepCopyOption<VecCurve>;
388 template DumpType<VecCurve>;
389 */
390
391 //////////////////////////////////////////////////////////////////////
392
393 #ifdef p
394 #undef p
395 #endif
396
397 class VecArcInfo : public VecArc
398 {
399 public:
400 VecArcInfo();
VecArcInfo(Pointf p,Pointf q)401 VecArcInfo(Pointf p, Pointf q) { Set(p, q); }
VecArcInfo(Pointf p,Pointf q,Pointf x)402 VecArcInfo(Pointf p, Pointf q, Pointf x) { Set(p, q, x); }
VecArcInfo(Pointf p,Pointf q,double bulge)403 VecArcInfo(Pointf p, Pointf q, double bulge) { Set(p, q, bulge); }
VecArcInfo(Pointf c,double r,double a,double b)404 VecArcInfo(Pointf c, double r, double a, double b) { Set(c, r, a, b); }
VecArcInfo(Pointf c,double r)405 VecArcInfo(Pointf c, double r) { Set(c, r); }
VecArcInfo(Pointf c,Pointf a,Pointf b,bool anticlockwise)406 VecArcInfo(Pointf c, Pointf a, Pointf b, bool anticlockwise) { Set(c, a, b, anticlockwise); }
VecArcInfo(const VecArc & arc)407 VecArcInfo(const VecArc& arc) { Set(arc); }
VecArcInfo(const VecArcInfo & arc)408 VecArcInfo(const VecArcInfo& arc) { *this = arc; }
409
410 String ToString() const;
411
412 void Set(Pointf P, Pointf Q);
413 void Set(Pointf P, Pointf Q, Pointf X);
414 void Set(Pointf P, Pointf Q, double bulge);
415 void Set(Pointf C, double r, double a, double b);
416 void Set(Pointf C, double r);
417 void Set(Pointf C, Pointf A, Pointf B, bool anticlockwise);
418
Set(const VecArc & arc)419 void Set(const VecArc& arc) { Set(arc.A, arc.B, arc.bulge); }
420
421 void Move(Pointf offset);
422
IsCircle()423 bool IsCircle() const { return circle; }
IsCurved()424 bool IsCurved() const { return curved; }
IsReversed()425 bool IsReversed() const { return reversed; }
426
427 double Length() const;
428 Pointf CentreOfMass() const;
429
430 bool ContainsBearing(double bearing) const;
431 double Distance(Pointf point, double *arg = NULL) const;
432 bool Crosses(const Rectf& rect) const;
433 Pointf GetPointAt(double t) const;
434 double GetMaxDistance(Pointf point, Pointf *farthest = NULL) const;
435
436 double GetArg(double bearing) const;
437 double GetArg(Pointf point) const;
438 VecArcInfo Subset(double start, double end) const;
439
440 Rectf GetBoundingBox() const;
441
442 double GetAngle() const; // oriented included angle
443 double GetStartTangent() const;
444 double GetEndTangent() const;
445 Pointf GetStartDir() const;
446 Pointf GetEndDir() const;
447
448 VecArcInfo Offset(double dist) const;
449
Reversed()450 VecArcInfo Reversed() const { return VecArcInfo(*this).SetReversed(); }
451 VecArcInfo& SetReversed();
452
453 Pointf C; // centre of circle (Null when not bulged)
454 double bow; // bow length
455 double alpha; // start angle (rad); most clockwise point on arc
456 double beta; // end angle (rad); most anticlockwise point on arc
457 double radius; // circle radius (Null when not bulged)
458 bool curved; // true = it's an arc, false = it's a circle
459 bool reversed; // true = arc has been entered as clockwise
460 bool circle; // true = it's a full circle
461 };
462
463 //////////////////////////////////////////////////////////////////////
464
465 class VecIntersection
466 {
467 public:
VecIntersection()468 VecIntersection() { count = 0; }
469
470 void Mirror();
Nothing()471 bool Nothing() { count = 0; return false; }
472 void Remove(int index);
473
474 bool LL(const Pointf& P1, const Pointf& Q1, const Pointf& P2, const Pointf& Q2);
475 bool LC(const Pointf& P1, const Pointf& Q1, const Pointf& C2, double r2);
476 bool LA(const Pointf& P1, const Pointf& Q1, const VecArcInfo& a2);
477 bool CC(const Pointf& C1, double r1, const Pointf& C2, double r2);
478 bool CA(const Pointf& C1, double r1, const VecArcInfo& a2);
479 bool AA(const VecArcInfo& a1, const VecArcInfo& a2);
480
IsEmpty()481 bool IsEmpty() const { return count == 0; }
GetCount()482 int GetCount() const { return count; }
483
484 public:
485 int count; // number of intersections
486 double t[2], u[2];
487
488 protected:
489 void CheckBearing(double *hints, const VecArcInfo& a);
490 };
491
492 //////////////////////////////////////////////////////////////////////
493
494 class VecArcIterator
495 {
496 public:
497 typedef Callback1<Pointf> DrawProc;
498 typedef Gate<Pointf, double> ArcProc;
499
500 VecArcIterator(const VecArc& arc, DrawProc _lineto);
501 VecArcIterator(Pointf start, Pointf end, double bulge, DrawProc _lineto);
502
Level(int _level)503 VecArcIterator& Level(int _level) { level = _level; return *this; }
Precision(double prec)504 VecArcIterator& Precision(double prec ) { precision = prec; return *this; }
Clip(const Rectf & rect,DrawProc _mv)505 VecArcIterator& Clip(const Rectf& rect, DrawProc _mv) { clip = rect; moveto = _mv; return *this; }
ArcTo(ArcProc _arc)506 VecArcIterator& ArcTo(ArcProc _arc) { arcto = _arc; return *this; }
507
508 void Go(); // recurse the arc
509
510 public:
511 double arclen; // degenerate to simple arc under such length
512 int level; // maximum # segments = 2 ^ level
513 double precision; // degenerate to line whenever |bulge| <= precision
514 VecArc arc; // arc to interpolate
515 Rectf clip; // clipping rectangle
516 DrawProc moveto; // moveto callback (needed only when clipping is on)
517 DrawProc lineto; // lineto callback
518 ArcProc arcto; // simple arcto callback
519
520 protected:
521 enum
522 {
523 CF_XL = 001,
524 CF_XG = 002,
525 CF_YL = 010,
526 CF_YG = 020,
527
528 DEFAULT_LEVEL = 10,
529 };
530
531 Pointf last; // last iteration point
532 int last_clip; // clipping status of last vertex
533
534 int GetClip(Pointf point) const;
535 void Recurse(Pointf to, double l, double h, int depth, int next_flclip);
536 };
537
538 //////////////////////////////////////////////////////////////////////
539