agg_trans_bilinear.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. // Bilinear 2D transformations
  17. //
  18. //----------------------------------------------------------------------------
  19. #ifndef AGG_TRANS_BILINEAR_INCLUDED
  20. #define AGG_TRANS_BILINEAR_INCLUDED
  21. #include "agg_basics.h"
  22. #include "agg_simul_eq.h"
  23. namespace agg
  24. {
  25. //==========================================================trans_bilinear
  26. class trans_bilinear
  27. {
  28. public:
  29. //--------------------------------------------------------------------
  30. trans_bilinear() : m_valid(false) {}
  31. //--------------------------------------------------------------------
  32. // Arbitrary quadrangle transformations
  33. trans_bilinear(const double* src, const double* dst)
  34. {
  35. quad_to_quad(src, dst);
  36. }
  37. //--------------------------------------------------------------------
  38. // Direct transformations
  39. trans_bilinear(double x1, double y1, double x2, double y2,
  40. const double* quad)
  41. {
  42. rect_to_quad(x1, y1, x2, y2, quad);
  43. }
  44. //--------------------------------------------------------------------
  45. // Reverse transformations
  46. trans_bilinear(const double* quad,
  47. double x1, double y1, double x2, double y2)
  48. {
  49. quad_to_rect(quad, x1, y1, x2, y2);
  50. }
  51. //--------------------------------------------------------------------
  52. // Set the transformations using two arbitrary quadrangles.
  53. void quad_to_quad(const double* src, const double* dst)
  54. {
  55. double left[4][4];
  56. double right[4][2];
  57. unsigned i;
  58. for(i = 0; i < 4; i++)
  59. {
  60. unsigned ix = i * 2;
  61. unsigned iy = ix + 1;
  62. left[i][0] = 1.0;
  63. left[i][1] = src[ix] * src[iy];
  64. left[i][2] = src[ix];
  65. left[i][3] = src[iy];
  66. right[i][0] = dst[ix];
  67. right[i][1] = dst[iy];
  68. }
  69. m_valid = simul_eq<4, 2>::solve(left, right, m_mtx);
  70. }
  71. //--------------------------------------------------------------------
  72. // Set the direct transformations, i.e., rectangle -> quadrangle
  73. void rect_to_quad(double x1, double y1, double x2, double y2,
  74. const double* quad)
  75. {
  76. double src[8];
  77. src[0] = src[6] = x1;
  78. src[2] = src[4] = x2;
  79. src[1] = src[3] = y1;
  80. src[5] = src[7] = y2;
  81. quad_to_quad(src, quad);
  82. }
  83. //--------------------------------------------------------------------
  84. // Set the reverse transformations, i.e., quadrangle -> rectangle
  85. void quad_to_rect(const double* quad,
  86. double x1, double y1, double x2, double y2)
  87. {
  88. double dst[8];
  89. dst[0] = dst[6] = x1;
  90. dst[2] = dst[4] = x2;
  91. dst[1] = dst[3] = y1;
  92. dst[5] = dst[7] = y2;
  93. quad_to_quad(quad, dst);
  94. }
  95. //--------------------------------------------------------------------
  96. // Check if the equations were solved successfully
  97. bool is_valid() const { return m_valid; }
  98. //--------------------------------------------------------------------
  99. // Transform a point (x, y)
  100. void transform(double* x, double* y) const
  101. {
  102. double tx = *x;
  103. double ty = *y;
  104. double xy = tx * ty;
  105. *x = m_mtx[0][0] + m_mtx[1][0] * xy + m_mtx[2][0] * tx + m_mtx[3][0] * ty;
  106. *y = m_mtx[0][1] + m_mtx[1][1] * xy + m_mtx[2][1] * tx + m_mtx[3][1] * ty;
  107. }
  108. //--------------------------------------------------------------------
  109. class iterator_x
  110. {
  111. double inc_x;
  112. double inc_y;
  113. public:
  114. double x;
  115. double y;
  116. iterator_x() {}
  117. iterator_x(double tx, double ty, double step, const double m[4][2]) :
  118. inc_x(m[1][0] * step * ty + m[2][0] * step),
  119. inc_y(m[1][1] * step * ty + m[2][1] * step),
  120. x(m[0][0] + m[1][0] * tx * ty + m[2][0] * tx + m[3][0] * ty),
  121. y(m[0][1] + m[1][1] * tx * ty + m[2][1] * tx + m[3][1] * ty)
  122. {
  123. }
  124. void operator ++ ()
  125. {
  126. x += inc_x;
  127. y += inc_y;
  128. }
  129. };
  130. iterator_x begin(double x, double y, double step) const
  131. {
  132. return iterator_x(x, y, step, m_mtx);
  133. }
  134. private:
  135. double m_mtx[4][2];
  136. bool m_valid;
  137. };
  138. }
  139. #endif