~ubuntu-branches/ubuntu/precise/ipe/precise

« back to all changes in this revision

Viewing changes to src/include/ipegeo.h

  • Committer: Bazaar Package Importer
  • Author(s): Steve M. Robbins
  • Date: 2004-06-08 00:44:02 UTC
  • Revision ID: james.westby@ubuntu.com-20040608004402-72yu51xlh7vt6p9m
Tags: upstream-6.0pre16
ImportĀ upstreamĀ versionĀ 6.0pre16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- C++ -*-
 
2
// --------------------------------------------------------------------
 
3
// Geometric primitives
 
4
// --------------------------------------------------------------------
 
5
/*
 
6
 
 
7
    This file is part of the extensible drawing editor Ipe.
 
8
    Copyright (C) 1993-2004  Otfried Cheong
 
9
 
 
10
    Ipe is free software; you can redistribute it and/or modify it
 
11
    under the terms of the GNU General Public License as published by
 
12
    the Free Software Foundation; either version 2 of the License, or
 
13
    (at your option) any later version.
 
14
 
 
15
    As a special exception, you have permission to link Ipe with the
 
16
    CGAL library and distribute executables, as long as you follow the
 
17
    requirements of the Gnu General Public License in regard to all of
 
18
    the software in the executable aside from CGAL.
 
19
 
 
20
    Ipe is distributed in the hope that it will be useful, but WITHOUT
 
21
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 
22
    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
 
23
    License for more details.
 
24
 
 
25
    You should have received a copy of the GNU General Public License
 
26
    along with Ipe; if not, you can find it at
 
27
    "http://www.gnu.org/copyleft/gpl.html", or write to the Free
 
28
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
29
 
 
30
*/
 
31
 
 
32
#ifndef IPEGEO_H
 
33
#define IPEGEO_H
 
34
 
 
35
#include "ipebase.h"
 
36
 
 
37
#include <cmath>
 
38
 
 
39
// --------------------------------------------------------------------
 
40
 
 
41
/*! \var typedef double IpeScalar
 
42
 * \ingroup geo
 
43
 * Type of coordinates in IpeVectors.
 
44
 */
 
45
typedef double IpeScalar;
 
46
 
 
47
/*! \ingroup geo
 
48
  Maximum of two values.
 
49
*/
 
50
template<class T>
 
51
inline T IpeMax(const T &lhs, const T &rhs)
 
52
{
 
53
  return (lhs > rhs) ? lhs : rhs;
 
54
}
 
55
 
 
56
/*! \ingroup geo
 
57
  Minimum of two values.
 
58
*/
 
59
template<class T>
 
60
inline T IpeMin(const T &lhs, const T &rhs)
 
61
{
 
62
  return (lhs < rhs) ? lhs : rhs;
 
63
}
 
64
 
 
65
/*! \ingroup geo
 
66
  Absolute value.
 
67
*/
 
68
inline double IpeAbs(double val)
 
69
{
 
70
  return (val > 0) ? val : -val;
 
71
}
 
72
 
 
73
 
 
74
/*! \var double IpePi
 
75
 * \ingroup geo
 
76
 * The constant pi.
 
77
 */
 
78
// const double IpePi = 3.1415926535897932385;
 
79
#define IpePi 3.1415926535897932385
 
80
/*! \var double IpeTwoPi
 
81
 * \ingroup geo
 
82
 * The constant 2 * pi.
 
83
 */
 
84
// const double IpeTwoPi = 6.2831853071795862;
 
85
#define IpeTwoPi 6.2831853071795862
 
86
/*! \var double IpeHalfPi
 
87
 * \ingroup geo
 
88
 * The constant pi / 2.
 
89
 */
 
90
// const double IpeHalfPi = 1.5707963267948966;
 
91
#define IpeHalfPi 1.5707963267948966
 
92
 
 
93
// --------------------------------------------------------------------
 
94
 
 
95
class IPE_EXPORT IpeAngle {
 
96
public:
 
97
  //! Construct uninitialized angle.
 
98
  inline explicit IpeAngle() { /* nothing */ }
 
99
  //! Construct an angle (in radians).
 
100
  inline IpeAngle(double alpha) : iAlpha(alpha) { }
 
101
  //! Construct an angle in degrees.
 
102
  inline static IpeAngle Degrees(double alpha) {
 
103
    return IpeAngle(alpha * IpePi / 180.0); }
 
104
  //! Return value (in radians).
 
105
  inline operator double() const { return iAlpha; }
 
106
  double Degrees() const;
 
107
  IpeAngle Normalize(double lowlimit);
 
108
  bool LiesBetween(IpeAngle small, IpeAngle large) const;
 
109
private:
 
110
  double iAlpha;
 
111
};
 
112
 
 
113
// --------------------------------------------------------------------
 
114
 
 
115
class IPE_EXPORT IpeVector {
 
116
public:
 
117
  //! Uninitialized vector.
 
118
  IpeVector() { /* no initialization */ }
 
119
  explicit IpeVector(IpeAngle alpha);
 
120
  //! Construct a vector.
 
121
  explicit IpeVector(IpeScalar x, IpeScalar y) : iX(x), iY(y) { }
 
122
  //! Return square of Euclidean length
 
123
  inline double SqLen() const;
 
124
  double Len() const;
 
125
  IpeAngle Angle() const;
 
126
  IpeVector Normalized() const;
 
127
  IpeVector Orthogonal() const;
 
128
  double Factorize(IpeVector &unit) const;
 
129
 
 
130
  inline bool operator==(const IpeVector &rhs) const;
 
131
  inline bool operator!=(const IpeVector &rhs) const;
 
132
  inline void operator+=(const IpeVector &rhs);
 
133
  inline void operator-=(const IpeVector &rhs);
 
134
  inline void operator*=(double rhs);
 
135
  inline IpeVector operator+(const IpeVector &rhs) const;
 
136
  inline IpeVector operator-(const IpeVector &rhs) const;
 
137
  inline IpeVector operator*(double rhs) const;
 
138
 
 
139
  static IpeVector Zero;
 
140
 
 
141
public:
 
142
  //!{
 
143
  //! Vector coordinates are public.
 
144
  IpeScalar iX;
 
145
  IpeScalar iY;
 
146
  //!}
 
147
};
 
148
 
 
149
IPE_EXPORT IpeStream &operator<<(IpeStream &stream, const IpeVector &rhs);
 
150
 
 
151
// --------------------------------------------------------------------
 
152
 
 
153
class IPE_EXPORT IpeRect {
 
154
public:
 
155
  //! Create empty rectangle.
 
156
  explicit IpeRect() : iMin(1,0), iMax(-1,0) { }
 
157
  //! Create rectangle containing just the point \a c.
 
158
  explicit IpeRect(const IpeVector &c) : iMin(c), iMax(c) { }
 
159
  explicit IpeRect(const IpeVector &c1, const IpeVector &c2);
 
160
 
 
161
  //! True if rectangle is empty.
 
162
  int IsEmpty() const { return iMin.iX > iMax.iX; }
 
163
  //! Return top right corner.
 
164
  inline IpeVector Max() const { return iMax; }
 
165
  //! Return bottom left corner.
 
166
  inline IpeVector Min() const { return iMin; }
 
167
  //! Return top left corner.
 
168
  inline IpeVector TopLeft() const { return IpeVector(iMin.iX, iMax.iY); }
 
169
  //! Return bottom right corner.
 
170
  inline IpeVector BottomRight() const { return IpeVector(iMax.iX, iMin.iY); }
 
171
  //! Return width.
 
172
  IpeScalar Width() const { return iMax.iX - iMin.iX; }
 
173
  //! Return height.
 
174
  IpeScalar Height() const { return iMax.iY - iMin.iY; }
 
175
  void AddPoint(const IpeVector &rhs);
 
176
  void AddRect(const IpeRect &rhs);
 
177
  bool Contains(const IpeVector &rhs) const;
 
178
  bool Contains(const IpeRect &rhs) const;
 
179
  bool CertainClearance(const IpeVector &v, double bound) const;
 
180
  bool Intersects(const IpeRect &rhs) const;
 
181
private:
 
182
  IpeVector iMin;   //!< Lower-left corner.
 
183
  IpeVector iMax;   //!< Top-right corner.
 
184
};
 
185
 
 
186
IPE_EXPORT IpeStream &operator<<(IpeStream &stream, const IpeRect &rhs);
 
187
 
 
188
// --------------------------------------------------------------------
 
189
 
 
190
class IPE_EXPORT IpeLine {
 
191
public:
 
192
  //! Create default line (x-axis).
 
193
  explicit IpeLine() : iP(0.0, 0.0), iDir(1.0, 0.0) { }
 
194
  explicit IpeLine(const IpeVector &p, const IpeVector &dir);
 
195
  static IpeLine Through(const IpeVector &p, const IpeVector &q);
 
196
  double Side(const IpeVector &p) const;
 
197
  inline IpeVector Normal() const;
 
198
  double Distance(const IpeVector &v) const;
 
199
  bool Intersects(const IpeLine &line, IpeVector &pt);
 
200
  IpeVector Project(const IpeVector &v) const;
 
201
  inline IpeVector Dir() const;
 
202
 
 
203
public:
 
204
  //! Point on the line.
 
205
  IpeVector iP;
 
206
private:
 
207
  IpeVector iDir; // unit vector
 
208
};
 
209
 
 
210
// --------------------------------------------------------------------
 
211
 
 
212
class IPE_EXPORT IpeSegment {
 
213
public:
 
214
  //! Create default segment
 
215
  IpeSegment() : iP(0.0, 0.0), iQ(1.0, 0.0) { }
 
216
  explicit IpeSegment(const IpeVector &p, const IpeVector &q)
 
217
    : iP(p), iQ(q) { }
 
218
  inline IpeLine Line() const;
 
219
  double Distance(const IpeVector &v, double bound) const;
 
220
  double Distance(const IpeVector &v) const;
 
221
  bool Project(const IpeVector &v, IpeVector &projection) const;
 
222
  bool Intersects(const IpeSegment &seg, IpeVector &pt) const;
 
223
  bool Intersects(const IpeLine &l, IpeVector &pt) const;
 
224
 
 
225
public:
 
226
  //! First endpoint.
 
227
  IpeVector iP;
 
228
  //! Second endpoint.
 
229
  IpeVector iQ;
 
230
};
 
231
 
 
232
// --------------------------------------------------------------------
 
233
 
 
234
class IPE_EXPORT IpeBezier {
 
235
public:
 
236
  //! Default constructor, uninitialized curve.
 
237
  inline IpeBezier() { /* nothing */ }
 
238
  inline IpeBezier(const IpeVector &p0, const IpeVector &p1,
 
239
                   const IpeVector &p2, const IpeVector &p3);
 
240
  IpeVector Point(double t) const;
 
241
  double Distance(const IpeVector &v, double bound);
 
242
  bool Straight(double precision) const;
 
243
  void Subdivide(IpeBezier &l, IpeBezier &r) const;
 
244
  void Approximate(double precision, std::vector<IpeVector> &result) const;
 
245
  IpeRect BBox() const;
 
246
  static IpeBezier QuadBezier(const IpeVector &p0, const IpeVector &p1,
 
247
                              const IpeVector &p2);
 
248
  static void Spline(int n,  const IpeVector *v,
 
249
                     std::vector<IpeBezier> &result);
 
250
  static void ClosedSpline(int n,  const IpeVector *v,
 
251
                           std::vector<IpeBezier> &result);
 
252
  bool Intersects(const IpeLine &l, IpeVector &pt) const;
 
253
  bool Intersects(const IpeSegment &l, IpeVector &pt) const;
 
254
public:
 
255
  IpeVector iV[4];
 
256
};
 
257
 
 
258
// --------------------------------------------------------------------
 
259
 
 
260
class IPE_EXPORT IpeLinear {
 
261
public:
 
262
  IpeLinear();
 
263
  explicit IpeLinear(IpeAngle angle);
 
264
  inline explicit IpeLinear(double m11, double m21, double m12, double m22);
 
265
  explicit IpeLinear(IpeString str);
 
266
  IpeLinear Inverse() const;
 
267
  inline bool IsIdentity() const;
 
268
  inline IpeVector operator*(const IpeVector &rhs) const;
 
269
  inline bool operator==(const IpeLinear &rhs) const;
 
270
public:
 
271
  double iA[4];
 
272
};
 
273
 
 
274
IPE_EXPORT IpeStream &operator<<(IpeStream &stream, const IpeLinear &rhs);
 
275
 
 
276
// --------------------------------------------------------------------
 
277
 
 
278
class IPE_EXPORT IpeMatrix {
 
279
public:
 
280
  IpeMatrix();
 
281
  inline IpeMatrix(const IpeLinear &linear);
 
282
  inline explicit IpeMatrix(const IpeLinear &linear, const IpeVector &t);
 
283
  inline explicit IpeMatrix(double m11, double m21, double m12, double m22,
 
284
                            double t1, double t2);
 
285
  inline explicit IpeMatrix(const IpeVector &v);
 
286
  explicit IpeMatrix(IpeString str);
 
287
  IpeMatrix Inverse() const;
 
288
  inline IpeVector operator*(const IpeVector &rhs) const;
 
289
  inline IpeBezier operator*(const IpeBezier &rhs) const;
 
290
  inline IpeVector Translation() const;
 
291
  inline IpeLinear Linear() const;
 
292
  inline bool IsIdentity() const;
 
293
  inline bool operator==(const IpeMatrix &rhs) const;
 
294
public:
 
295
  double iA[6];
 
296
};
 
297
 
 
298
IPE_EXPORT IpeStream &operator<<(IpeStream &stream, const IpeMatrix &rhs);
 
299
 
 
300
// --------------------------------------------------------------------
 
301
 
 
302
class IPE_EXPORT IpeArc {
 
303
public:
 
304
  //! Construct unit circle.
 
305
  inline IpeArc() : iAlpha(0.0), iBeta(0.0) { /* nothing */ }
 
306
  inline IpeArc(const IpeMatrix &m, IpeAngle alpha, IpeAngle beta);
 
307
  inline IpeArc(const IpeMatrix &m);
 
308
  IpeArc(const IpeMatrix &m0, const IpeVector &begp, const IpeVector &endp);
 
309
  double Distance(const IpeVector &v, double bound);
 
310
  double Distance(const IpeVector &v, double bound,
 
311
                  IpeVector &pos, IpeAngle &angle);
 
312
  IpeRect BBox() const;
 
313
  bool Intersects(const IpeLine &l, IpeVector &pt) const;
 
314
  bool Intersects(const IpeSegment &l, IpeVector &pt) const;
 
315
public:
 
316
  IpeMatrix iM;
 
317
  IpeAngle iAlpha;
 
318
  IpeAngle iBeta;
 
319
};
 
320
 
 
321
// --------------------------------------------------------------------
 
322
 
 
323
//! Return square of vector's length.
 
324
inline double IpeVector::SqLen() const
 
325
{
 
326
  return (iX * iX + iY * iY);
 
327
}
 
328
 
 
329
//! Equality.
 
330
inline bool IpeVector::operator==(const IpeVector &rhs) const
 
331
{
 
332
  return iX == rhs.iX && iY == rhs.iY;
 
333
}
 
334
 
 
335
//! Inequality.
 
336
inline bool IpeVector::operator!=(const IpeVector &rhs) const
 
337
{
 
338
  return iX != rhs.iX || iY != rhs.iY;
 
339
}
 
340
 
 
341
//! Vector-addition.
 
342
inline void IpeVector::operator+=(const IpeVector &rhs)
 
343
{
 
344
  iX += rhs.iX; iY += rhs.iY;
 
345
}
 
346
 
 
347
//! Vector-subtraction.
 
348
inline void IpeVector::operator-=(const IpeVector &rhs)
 
349
{
 
350
  iX -= rhs.iX; iY -= rhs.iY;
 
351
}
 
352
 
 
353
//! Multiply vector by scalar.
 
354
inline void IpeVector::operator*=(double rhs)
 
355
{
 
356
  iX *= rhs; iY *= rhs;
 
357
}
 
358
 
 
359
//! Vector-addition.
 
360
inline IpeVector IpeVector::operator+(const IpeVector &rhs) const
 
361
{
 
362
  IpeVector result = *this; result += rhs; return result;
 
363
}
 
364
 
 
365
//! Vector-subtraction.
 
366
inline IpeVector IpeVector::operator-(const IpeVector &rhs) const
 
367
{
 
368
  IpeVector result = *this; result -= rhs; return result;
 
369
}
 
370
 
 
371
//! Vector * scalar.
 
372
inline IpeVector IpeVector::operator*(double rhs) const
 
373
{
 
374
  IpeVector result = *this; result *= rhs; return result;
 
375
}
 
376
 
 
377
//! Scalar * vector. \relates IpeVector
 
378
inline IpeVector operator*(double lhs, const IpeVector &rhs)
 
379
{
 
380
  return IpeVector(lhs * rhs.iX, lhs * rhs.iY);
 
381
}
 
382
 
 
383
//! Dotproduct of two vectors. \relates IpeVector
 
384
inline double Dot(const IpeVector &lhs, const IpeVector &rhs)
 
385
{
 
386
  return lhs.iX * rhs.iX + lhs.iY * rhs.iY;
 
387
}
 
388
 
 
389
//! Return a normal vector pointing to the left of the directed line.
 
390
inline IpeVector IpeLine::Normal() const
 
391
{
 
392
  return IpeVector(-iDir.iY, iDir.iX);
 
393
}
 
394
 
 
395
//! Return direction of line.
 
396
inline IpeVector IpeLine::Dir() const
 
397
{
 
398
  return iDir;
 
399
}
 
400
 
 
401
//! Return directed line supporting the segment.
 
402
inline IpeLine IpeSegment::Line() const
 
403
{
 
404
  return IpeLine(iP, (iQ - iP).Normalized());
 
405
}
 
406
 
 
407
//! Unary minus for IpeVector.
 
408
inline IpeVector operator-(const IpeVector &rhs)
 
409
{
 
410
  return -1 * rhs;
 
411
}
 
412
 
 
413
//! Constructor with four control points.
 
414
inline IpeBezier::IpeBezier(const IpeVector &p0, const IpeVector &p1,
 
415
                            const IpeVector &p2, const IpeVector &p3)
 
416
{
 
417
  iV[0] = p0; iV[1] = p1; iV[2] = p2; iV[3] = p3;
 
418
}
 
419
 
 
420
//! Transform Bezier spline.
 
421
inline IpeBezier IpeMatrix::operator*(const IpeBezier &rhs) const
 
422
{
 
423
  return IpeBezier(*this * rhs.iV[0], *this * rhs.iV[1],
 
424
                   *this * rhs.iV[2], *this * rhs.iV[3]);
 
425
};
 
426
 
 
427
//! Construct with given parameters.
 
428
inline IpeArc::IpeArc(const IpeMatrix &m, IpeAngle alpha, IpeAngle beta)
 
429
  : iM(m), iAlpha(alpha), iBeta(beta)
 
430
{
 
431
  // nothing
 
432
}
 
433
 
 
434
//! Construct an ellipse
 
435
inline IpeArc::IpeArc(const IpeMatrix &m)
 
436
  : iM(m), iAlpha(0.0), iBeta(0.0)
 
437
{
 
438
  // nothing
 
439
}
 
440
 
 
441
// --------------------------------------------------------------------
 
442
 
 
443
//! Create identity matrix.
 
444
inline IpeLinear::IpeLinear()
 
445
{
 
446
  iA[0] = iA[3] = 1.0;
 
447
  iA[1] = iA[2] = 0.0;
 
448
}
 
449
 
 
450
//! Create linear matrix with given coefficients.
 
451
inline IpeLinear::IpeLinear(double m11, double m21, double m12, double m22)
 
452
{
 
453
  iA[0] = m11; iA[1] = m21; iA[2] = m12; iA[3] = m22;
 
454
}
 
455
 
 
456
//! Linear matrix times vector.
 
457
inline IpeVector IpeLinear::operator*(const IpeVector &rhs) const
 
458
{
 
459
  return IpeVector(iA[0] * rhs.iX + iA[2] * rhs.iY,
 
460
                   iA[1] * rhs.iX + iA[3] * rhs.iY);
 
461
};
 
462
 
 
463
//! Is this the identity matrix?
 
464
inline bool IpeLinear::IsIdentity() const
 
465
{
 
466
  return (iA[0] == 1.0 && iA[1] == 0.0 &&
 
467
          iA[2] == 0.0 && iA[3] == 1.0);
 
468
}
 
469
 
 
470
//! Linear matrix multiplication.
 
471
inline IpeLinear operator*(const IpeLinear &lhs, const IpeLinear &rhs)
 
472
{
 
473
  IpeLinear m;
 
474
  m.iA[0] = lhs.iA[0] * rhs.iA[0] + lhs.iA[2] * rhs.iA[1];
 
475
  m.iA[1] = lhs.iA[1] * rhs.iA[0] + lhs.iA[3] * rhs.iA[1];
 
476
  m.iA[2] = lhs.iA[0] * rhs.iA[2] + lhs.iA[2] * rhs.iA[3];
 
477
  m.iA[3] = lhs.iA[1] * rhs.iA[2] + lhs.iA[3] * rhs.iA[3];
 
478
  return m;
 
479
}
 
480
 
 
481
//! Check for equality of two linear matrices.
 
482
inline bool IpeLinear::operator==(const IpeLinear &rhs) const
 
483
{
 
484
  return (iA[0] == rhs.iA[0] && iA[1] == rhs.iA[1] &&
 
485
          iA[2] == rhs.iA[2] && iA[3] == rhs.iA[3]);
 
486
}
 
487
 
 
488
// --------------------------------------------------------------------
 
489
 
 
490
//! Create matrix with given coefficients.
 
491
inline IpeMatrix::IpeMatrix(double m11, double m21, double m12, double m22,
 
492
                            double t1, double t2)
 
493
{
 
494
  iA[0] = m11; iA[1] = m21; iA[2] = m12; iA[3] = m22;
 
495
  iA[4] = t1; iA[5] = t2;
 
496
}
 
497
 
 
498
//! Create linear matrix.
 
499
inline IpeMatrix::IpeMatrix(const IpeLinear &linear)
 
500
{
 
501
  iA[0] = linear.iA[0]; iA[1] = linear.iA[1];
 
502
  iA[2] = linear.iA[2]; iA[3] = linear.iA[3];
 
503
  iA[4] = iA[5] = 0.0;
 
504
}
 
505
 
 
506
inline IpeMatrix::IpeMatrix(const IpeLinear &linear, const IpeVector &t)
 
507
{
 
508
  iA[0] = linear.iA[0]; iA[1] = linear.iA[1];
 
509
  iA[2] = linear.iA[2]; iA[3] = linear.iA[3];
 
510
  iA[4] = t.iX; iA[5] = t.iY;
 
511
}
 
512
 
 
513
//! Matrix times vector.
 
514
inline IpeVector IpeMatrix::operator*(const IpeVector &rhs) const
 
515
{
 
516
  return IpeVector(iA[0] * rhs.iX + iA[2] * rhs.iY + iA[4],
 
517
                   iA[1] * rhs.iX + iA[3] * rhs.iY + iA[5]);
 
518
};
 
519
 
 
520
//! Is this the identity matrix?
 
521
inline bool IpeMatrix::IsIdentity() const
 
522
{
 
523
  return (iA[0] == 1.0 && iA[1] == 0.0 &&
 
524
          iA[2] == 0.0 && iA[3] == 1.0 &&
 
525
          iA[4] == 0.0 && iA[5] == 0.0);
 
526
}
 
527
 
 
528
//! Create identity matrix.
 
529
inline IpeMatrix::IpeMatrix()
 
530
{
 
531
  iA[0] = iA[3] = 1.0;
 
532
  iA[1] = iA[2] = iA[4] = iA[5] = 0.0;
 
533
}
 
534
 
 
535
//! Matrix multiplication.
 
536
inline IpeMatrix operator*(const IpeMatrix &lhs, const IpeMatrix &rhs)
 
537
{
 
538
  IpeMatrix m;
 
539
  m.iA[0] = lhs.iA[0] * rhs.iA[0] + lhs.iA[2] * rhs.iA[1];
 
540
  m.iA[1] = lhs.iA[1] * rhs.iA[0] + lhs.iA[3] * rhs.iA[1];
 
541
  m.iA[2] = lhs.iA[0] * rhs.iA[2] + lhs.iA[2] * rhs.iA[3];
 
542
  m.iA[3] = lhs.iA[1] * rhs.iA[2] + lhs.iA[3] * rhs.iA[3];
 
543
  m.iA[4] = lhs.iA[0] * rhs.iA[4] + lhs.iA[2] * rhs.iA[5] + lhs.iA[4];
 
544
  m.iA[5] = lhs.iA[1] * rhs.iA[4] + lhs.iA[3] * rhs.iA[5] + lhs.iA[5];
 
545
  return m;
 
546
}
 
547
 
 
548
//! Create translation matrix.
 
549
inline IpeMatrix::IpeMatrix(const IpeVector &v)
 
550
{
 
551
  iA[0] = iA[3] = 1.0;
 
552
  iA[1] = iA[2] = 0.0;
 
553
  iA[4] = v.iX;
 
554
  iA[5] = v.iY;
 
555
}
 
556
 
 
557
//! Return translation component.
 
558
inline IpeVector IpeMatrix::Translation() const
 
559
{
 
560
  return IpeVector(iA[4], iA[5]);
 
561
}
 
562
 
 
563
//! Check for equality of two matrices.
 
564
inline bool IpeMatrix::operator==(const IpeMatrix &rhs) const
 
565
{
 
566
  return (iA[0] == rhs.iA[0] && iA[1] == rhs.iA[1] && iA[2] == rhs.iA[2] &&
 
567
          iA[3] == rhs.iA[3] && iA[4] == rhs.iA[4] && iA[5] == rhs.iA[5]);
 
568
}
 
569
 
 
570
//! Return linear transformation component of this affine transformation.
 
571
inline IpeLinear IpeMatrix::Linear() const
 
572
{
 
573
  return IpeLinear(iA[0], iA[1], iA[2], iA[3]);
 
574
}
 
575
 
 
576
// --------------------------------------------------------------------
 
577
 
 
578
//! Transform arc.
 
579
inline IpeArc operator*(const IpeMatrix &lhs, const IpeArc &rhs)
 
580
{
 
581
  return IpeArc(lhs * rhs.iM, rhs.iAlpha, rhs.iBeta);
 
582
}
 
583
 
 
584
// --------------------------------------------------------------------
 
585
#endif