agg_trans_affine.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. //----------------------------------------------------------------------------
  2. // Anti-Grain Geometry - Version 2.4
  3. // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
  4. //
  5. // Permission to copy, use, modify, sell and distribute this software
  6. // is granted provided this copyright notice appears in all copies.
  7. // This software is provided "as is" without express or implied
  8. // warranty, and with no claim as to its suitability for any purpose.
  9. //
  10. //----------------------------------------------------------------------------
  11. // Contact: mcseem@antigrain.com
  12. // mcseemagg@yahoo.com
  13. // http://www.antigrain.com
  14. //----------------------------------------------------------------------------
  15. //
  16. // Affine transformation classes.
  17. //
  18. //----------------------------------------------------------------------------
  19. #ifndef AGG_TRANS_AFFINE_INCLUDED
  20. #define AGG_TRANS_AFFINE_INCLUDED
  21. #include <math.h>
  22. #include "agg_basics.h"
  23. namespace agg
  24. {
  25. const double affine_epsilon = 1e-14;
  26. //============================================================trans_affine
  27. //
  28. // See Implementation agg_trans_affine.cpp
  29. //
  30. // Affine transformation are linear transformations in Cartesian coordinates
  31. // (strictly speaking not only in Cartesian, but for the beginning we will
  32. // think so). They are rotation, scaling, translation and skewing.
  33. // After any affine transformation a line segment remains a line segment
  34. // and it will never become a curve.
  35. //
  36. // There will be no math about matrix calculations, since it has been
  37. // described many times. Ask yourself a very simple question:
  38. // "why do we need to understand and use some matrix stuff instead of just
  39. // rotating, scaling and so on". The answers are:
  40. //
  41. // 1. Any combination of transformations can be done by only 4 multiplications
  42. // and 4 additions in floating point.
  43. // 2. One matrix transformation is equivalent to the number of consecutive
  44. // discrete transformations, i.e. the matrix "accumulates" all transformations
  45. // in the order of their settings. Suppose we have 4 transformations:
  46. // * rotate by 30 degrees,
  47. // * scale X to 2.0,
  48. // * scale Y to 1.5,
  49. // * move to (100, 100).
  50. // The result will depend on the order of these transformations,
  51. // and the advantage of matrix is that the sequence of discret calls:
  52. // rotate(30), scaleX(2.0), scaleY(1.5), move(100,100)
  53. // will have exactly the same result as the following matrix transformations:
  54. //
  55. // affine_matrix m;
  56. // m *= rotate_matrix(30);
  57. // m *= scaleX_matrix(2.0);
  58. // m *= scaleY_matrix(1.5);
  59. // m *= move_matrix(100,100);
  60. //
  61. // m.transform_my_point_at_last(x, y);
  62. //
  63. // What is the good of it? In real life we will set-up the matrix only once
  64. // and then transform many points, let alone the convenience to set any
  65. // combination of transformations.
  66. //
  67. // So, how to use it? Very easy - literally as it's shown above. Not quite,
  68. // let us write a correct example:
  69. //
  70. // agg::trans_affine m;
  71. // m *= agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0);
  72. // m *= agg::trans_affine_scaling(2.0, 1.5);
  73. // m *= agg::trans_affine_translation(100.0, 100.0);
  74. // m.transform(&x, &y);
  75. //
  76. // The affine matrix is all you need to perform any linear transformation,
  77. // but all transformations have origin point (0,0). It means that we need to
  78. // use 2 translations if we want to rotate someting around (100,100):
  79. //
  80. // m *= agg::trans_affine_translation(-100.0, -100.0); // move to (0,0)
  81. // m *= agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0); // rotate
  82. // m *= agg::trans_affine_translation(100.0, 100.0); // move back to (100,100)
  83. //----------------------------------------------------------------------
  84. struct trans_affine
  85. {
  86. double sx, shy, shx, sy, tx, ty;
  87. //------------------------------------------ Construction
  88. // Identity matrix
  89. trans_affine() :
  90. sx(1.0), shy(0.0), shx(0.0), sy(1.0), tx(0.0), ty(0.0)
  91. {}
  92. // Custom matrix. Usually used in derived classes
  93. trans_affine(double v0, double v1, double v2,
  94. double v3, double v4, double v5) :
  95. sx(v0), shy(v1), shx(v2), sy(v3), tx(v4), ty(v5)
  96. {}
  97. // Custom matrix from m[6]
  98. explicit trans_affine(const double* m) :
  99. sx(m[0]), shy(m[1]), shx(m[2]), sy(m[3]), tx(m[4]), ty(m[5])
  100. {}
  101. // Rectangle to a parallelogram.
  102. trans_affine(double x1, double y1, double x2, double y2,
  103. const double* parl)
  104. {
  105. rect_to_parl(x1, y1, x2, y2, parl);
  106. }
  107. // Parallelogram to a rectangle.
  108. trans_affine(const double* parl,
  109. double x1, double y1, double x2, double y2)
  110. {
  111. parl_to_rect(parl, x1, y1, x2, y2);
  112. }
  113. // Arbitrary parallelogram transformation.
  114. trans_affine(const double* src, const double* dst)
  115. {
  116. parl_to_parl(src, dst);
  117. }
  118. //---------------------------------- Parellelogram transformations
  119. // transform a parallelogram to another one. Src and dst are
  120. // pointers to arrays of three points (double[6], x1,y1,...) that
  121. // identify three corners of the parallelograms assuming implicit
  122. // fourth point. The arguments are arrays of double[6] mapped
  123. // to x1,y1, x2,y2, x3,y3 where the coordinates are:
  124. // *-----------------*
  125. // / (x3,y3)/
  126. // / /
  127. // /(x1,y1) (x2,y2)/
  128. // *-----------------*
  129. const trans_affine& parl_to_parl(const double* src,
  130. const double* dst);
  131. const trans_affine& rect_to_parl(double x1, double y1,
  132. double x2, double y2,
  133. const double* parl);
  134. const trans_affine& parl_to_rect(const double* parl,
  135. double x1, double y1,
  136. double x2, double y2);
  137. //------------------------------------------ Operations
  138. // Reset - load an identity matrix
  139. const trans_affine& reset();
  140. // Direct transformations operations
  141. const trans_affine& translate(double x, double y);
  142. const trans_affine& rotate(double a);
  143. const trans_affine& scale(double s);
  144. const trans_affine& scale(double x, double y);
  145. // Multiply matrix to another one
  146. const trans_affine& multiply(const trans_affine& m);
  147. // Multiply "m" to "this" and assign the result to "this"
  148. const trans_affine& premultiply(const trans_affine& m);
  149. // Multiply matrix to inverse of another one
  150. const trans_affine& multiply_inv(const trans_affine& m);
  151. // Multiply inverse of "m" to "this" and assign the result to "this"
  152. const trans_affine& premultiply_inv(const trans_affine& m);
  153. // Invert matrix. Do not try to invert degenerate matrices,
  154. // there's no check for validity. If you set scale to 0 and
  155. // then try to invert matrix, expect unpredictable result.
  156. const trans_affine& invert();
  157. // Mirroring around X
  158. const trans_affine& flip_x();
  159. // Mirroring around Y
  160. const trans_affine& flip_y();
  161. //------------------------------------------- Load/Store
  162. // Store matrix to an array [6] of double
  163. void store_to(double* m) const
  164. {
  165. *m++ = sx; *m++ = shy; *m++ = shx; *m++ = sy; *m++ = tx; *m++ = ty;
  166. }
  167. // Load matrix from an array [6] of double
  168. const trans_affine& load_from(const double* m)
  169. {
  170. sx = *m++; shy = *m++; shx = *m++; sy = *m++; tx = *m++; ty = *m++;
  171. return *this;
  172. }
  173. //------------------------------------------- Operators
  174. // Multiply the matrix by another one
  175. const trans_affine& operator *= (const trans_affine& m)
  176. {
  177. return multiply(m);
  178. }
  179. // Multiply the matrix by inverse of another one
  180. const trans_affine& operator /= (const trans_affine& m)
  181. {
  182. return multiply_inv(m);
  183. }
  184. // Multiply the matrix by another one and return
  185. // the result in a separete matrix.
  186. trans_affine operator * (const trans_affine& m) const
  187. {
  188. return trans_affine(*this).multiply(m);
  189. }
  190. // Multiply the matrix by inverse of another one
  191. // and return the result in a separete matrix.
  192. trans_affine operator / (const trans_affine& m) const
  193. {
  194. return trans_affine(*this).multiply_inv(m);
  195. }
  196. // Calculate and return the inverse matrix
  197. trans_affine operator ~ () const
  198. {
  199. trans_affine ret = *this;
  200. return ret.invert();
  201. }
  202. // Equal operator with default epsilon
  203. bool operator == (const trans_affine& m) const
  204. {
  205. return is_equal(m, affine_epsilon);
  206. }
  207. // Not Equal operator with default epsilon
  208. bool operator != (const trans_affine& m) const
  209. {
  210. return !is_equal(m, affine_epsilon);
  211. }
  212. //-------------------------------------------- Transformations
  213. // Direct transformation of x and y
  214. void transform(double* x, double* y) const;
  215. // Direct transformation of x and y, 2x2 matrix only, no translation
  216. void transform_2x2(double* x, double* y) const;
  217. // Inverse transformation of x and y. It works slower than the
  218. // direct transformation. For massive operations it's better to
  219. // invert() the matrix and then use direct transformations.
  220. void inverse_transform(double* x, double* y) const;
  221. //-------------------------------------------- Auxiliary
  222. // Calculate the determinant of matrix
  223. double determinant() const
  224. {
  225. return sx * sy - shy * shx;
  226. }
  227. // Calculate the reciprocal of the determinant
  228. double determinant_reciprocal() const
  229. {
  230. return 1.0 / (sx * sy - shy * shx);
  231. }
  232. // Get the average scale (by X and Y).
  233. // Basically used to calculate the approximation_scale when
  234. // decomposinting curves into line segments.
  235. double scale() const;
  236. // Check to see if the matrix is not degenerate
  237. bool is_valid(double epsilon = affine_epsilon) const;
  238. // Check to see if it's an identity matrix
  239. bool is_identity(double epsilon = affine_epsilon) const;
  240. // Check to see if two matrices are equal
  241. bool is_equal(const trans_affine& m, double epsilon = affine_epsilon) const;
  242. // Determine the major parameters. Use with caution considering
  243. // possible degenerate cases.
  244. double rotation() const;
  245. void translation(double* dx, double* dy) const;
  246. void scaling(double* x, double* y) const;
  247. void scaling_abs(double* x, double* y) const;
  248. };
  249. //------------------------------------------------------------------------
  250. inline void trans_affine::transform(double* x, double* y) const
  251. {
  252. double tmp = *x;
  253. *x = tmp * sx + *y * shx + tx;
  254. *y = tmp * shy + *y * sy + ty;
  255. }
  256. //------------------------------------------------------------------------
  257. inline void trans_affine::transform_2x2(double* x, double* y) const
  258. {
  259. double tmp = *x;
  260. *x = tmp * sx + *y * shx;
  261. *y = tmp * shy + *y * sy;
  262. }
  263. //------------------------------------------------------------------------
  264. inline void trans_affine::inverse_transform(double* x, double* y) const
  265. {
  266. double d = determinant_reciprocal();
  267. double a = (*x - tx) * d;
  268. double b = (*y - ty) * d;
  269. *x = a * sy - b * shx;
  270. *y = b * sx - a * shy;
  271. }
  272. //------------------------------------------------------------------------
  273. inline double trans_affine::scale() const
  274. {
  275. double x = 0.707106781 * sx + 0.707106781 * shx;
  276. double y = 0.707106781 * shy + 0.707106781 * sy;
  277. return sqrt(x*x + y*y);
  278. }
  279. //------------------------------------------------------------------------
  280. inline const trans_affine& trans_affine::translate(double x, double y)
  281. {
  282. tx += x;
  283. ty += y;
  284. return *this;
  285. }
  286. //------------------------------------------------------------------------
  287. inline const trans_affine& trans_affine::rotate(double a)
  288. {
  289. double ca = cos(a);
  290. double sa = sin(a);
  291. double t0 = sx * ca - shy * sa;
  292. double t2 = shx * ca - sy * sa;
  293. double t4 = tx * ca - ty * sa;
  294. shy = sx * sa + shy * ca;
  295. sy = shx * sa + sy * ca;
  296. ty = tx * sa + ty * ca;
  297. sx = t0;
  298. shx = t2;
  299. tx = t4;
  300. return *this;
  301. }
  302. //------------------------------------------------------------------------
  303. inline const trans_affine& trans_affine::scale(double x, double y)
  304. {
  305. double mm0 = x; // Possible hint for the optimizer
  306. double mm3 = y;
  307. sx *= mm0;
  308. shx *= mm0;
  309. tx *= mm0;
  310. shy *= mm3;
  311. sy *= mm3;
  312. ty *= mm3;
  313. return *this;
  314. }
  315. //------------------------------------------------------------------------
  316. inline const trans_affine& trans_affine::scale(double s)
  317. {
  318. double m = s; // Possible hint for the optimizer
  319. sx *= m;
  320. shx *= m;
  321. tx *= m;
  322. shy *= m;
  323. sy *= m;
  324. ty *= m;
  325. return *this;
  326. }
  327. //------------------------------------------------------------------------
  328. inline const trans_affine& trans_affine::premultiply(const trans_affine& m)
  329. {
  330. trans_affine t = m;
  331. return *this = t.multiply(*this);
  332. }
  333. //------------------------------------------------------------------------
  334. inline const trans_affine& trans_affine::multiply_inv(const trans_affine& m)
  335. {
  336. trans_affine t = m;
  337. t.invert();
  338. return multiply(t);
  339. }
  340. //------------------------------------------------------------------------
  341. inline const trans_affine& trans_affine::premultiply_inv(const trans_affine& m)
  342. {
  343. trans_affine t = m;
  344. t.invert();
  345. return *this = t.multiply(*this);
  346. }
  347. //------------------------------------------------------------------------
  348. inline void trans_affine::scaling_abs(double* x, double* y) const
  349. {
  350. // Used to calculate scaling coefficients in image resampling.
  351. // When there is considerable shear this method gives us much
  352. // better estimation than just sx, sy.
  353. *x = sqrt(sx * sx + shx * shx);
  354. *y = sqrt(shy * shy + sy * sy);
  355. }
  356. //====================================================trans_affine_rotation
  357. // Rotation matrix. sin() and cos() are calculated twice for the same angle.
  358. // There's no harm because the performance of sin()/cos() is very good on all
  359. // modern processors. Besides, this operation is not going to be invoked too
  360. // often.
  361. class trans_affine_rotation : public trans_affine
  362. {
  363. public:
  364. trans_affine_rotation(double a) :
  365. trans_affine(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0)
  366. {}
  367. };
  368. //====================================================trans_affine_scaling
  369. // Scaling matrix. x, y - scale coefficients by X and Y respectively
  370. class trans_affine_scaling : public trans_affine
  371. {
  372. public:
  373. trans_affine_scaling(double x, double y) :
  374. trans_affine(x, 0.0, 0.0, y, 0.0, 0.0)
  375. {}
  376. trans_affine_scaling(double s) :
  377. trans_affine(s, 0.0, 0.0, s, 0.0, 0.0)
  378. {}
  379. };
  380. //================================================trans_affine_translation
  381. // Translation matrix
  382. class trans_affine_translation : public trans_affine
  383. {
  384. public:
  385. trans_affine_translation(double x, double y) :
  386. trans_affine(1.0, 0.0, 0.0, 1.0, x, y)
  387. {}
  388. };
  389. //====================================================trans_affine_skewing
  390. // Sckewing (shear) matrix
  391. class trans_affine_skewing : public trans_affine
  392. {
  393. public:
  394. trans_affine_skewing(double x, double y) :
  395. trans_affine(1.0, tan(y), tan(x), 1.0, 0.0, 0.0)
  396. {}
  397. };
  398. //===============================================trans_affine_line_segment
  399. // Rotate, Scale and Translate, associating 0...dist with line segment
  400. // x1,y1,x2,y2
  401. class trans_affine_line_segment : public trans_affine
  402. {
  403. public:
  404. trans_affine_line_segment(double x1, double y1, double x2, double y2,
  405. double dist)
  406. {
  407. double dx = x2 - x1;
  408. double dy = y2 - y1;
  409. if(dist > 0.0)
  410. {
  411. multiply(trans_affine_scaling(sqrt(dx * dx + dy * dy) / dist));
  412. }
  413. multiply(trans_affine_rotation(atan2(dy, dx)));
  414. multiply(trans_affine_translation(x1, y1));
  415. }
  416. };
  417. //============================================trans_affine_reflection_unit
  418. // Reflection matrix. Reflect coordinates across the line through
  419. // the origin containing the unit vector (ux, uy).
  420. // Contributed by John Horigan
  421. class trans_affine_reflection_unit : public trans_affine
  422. {
  423. public:
  424. trans_affine_reflection_unit(double ux, double uy) :
  425. trans_affine(2.0 * ux * ux - 1.0,
  426. 2.0 * ux * uy,
  427. 2.0 * ux * uy,
  428. 2.0 * uy * uy - 1.0,
  429. 0.0, 0.0)
  430. {}
  431. };
  432. //=================================================trans_affine_reflection
  433. // Reflection matrix. Reflect coordinates across the line through
  434. // the origin at the angle a or containing the non-unit vector (x, y).
  435. // Contributed by John Horigan
  436. class trans_affine_reflection : public trans_affine_reflection_unit
  437. {
  438. public:
  439. trans_affine_reflection(double a) :
  440. trans_affine_reflection_unit(cos(a), sin(a))
  441. {}
  442. trans_affine_reflection(double x, double y) :
  443. trans_affine_reflection_unit(x / sqrt(x * x + y * y), y / sqrt(x * x + y * y))
  444. {}
  445. };
  446. }
  447. #endif