matrix.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #ifndef __MATRIX_H__
  2. #define __MATRIX_H__
  3. /* Port from ejoy2d: https://github.com/cloudwu/ejoy2d/blob/master/LICENSE
  4. * Original License:
  5. *
  6. * The MIT License (MIT)
  7. *
  8. * Copyright (c) 2013 Ejoy.com Inc.
  9. *
  10. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  11. * this software and associated documentation files (the "Software"), to deal in
  12. * the Software without restriction, including without limitation the rights to
  13. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  14. * the Software, and to permit persons to whom the Software is furnished to do so,
  15. * subject to the following conditions:
  16. *
  17. * The above copyright notice and this permission notice shall be included in all
  18. * copies or substantial portions of the Software.
  19. *
  20. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  22. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  23. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  24. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  25. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  26. */
  27. /* Port to RTGUI and modified by Grissiom */
  28. #ifdef _MSC_VER
  29. typedef __int32 int32_t;
  30. typedef unsigned __int32 uint32_t;
  31. typedef __int64 int64_t;
  32. typedef unsigned __int64 uint64_t;
  33. #else
  34. #include <stdint.h>
  35. #endif
  36. #define RTGUI_MATRIX_FRAC_BITS 11
  37. #define RTGUI_MATRIX_FRAC (1 << RTGUI_MATRIX_FRAC_BITS)
  38. struct rtgui_matrix
  39. {
  40. /* The matrix format is :
  41. *
  42. * | m[0] m[1] 0 |
  43. * | m[2] m[3] 0 |
  44. * | m[4] m[5] 1 |
  45. *
  46. * The format of the coordinate of a point is:
  47. *
  48. * | x y 1 |
  49. *
  50. * So, if you want to transform a point p with a matrix m, do:
  51. *
  52. * p * m
  53. *
  54. * Note: m[0-3] is in fix presentation that has 10 bits decimal
  55. * fraction(m/RTGUI_MATRIX_FRAC). While the unit of m[4-5] is pixel.
  56. *
  57. */
  58. int m[6];
  59. };
  60. rt_inline int32_t _rtgui_matrix_round_div32(int32_t n, int32_t d)
  61. {
  62. if (n == 0)
  63. return 0;
  64. if (d < 0)
  65. {
  66. d = -d;
  67. n = -n;
  68. }
  69. if (n > 0)
  70. return (n + d / 2) / d;
  71. else
  72. return (n - d / 2) / d;
  73. }
  74. rt_inline int32_t _rtgui_matrix_round_div6432(int64_t n, int32_t d)
  75. {
  76. if (n == 0)
  77. return 0;
  78. if (d < 0)
  79. {
  80. d = -d;
  81. n = -n;
  82. }
  83. if (n > 0)
  84. return (n + d / 2) / d;
  85. else
  86. return (n - d / 2) / d;
  87. }
  88. /* mm = mm1 * mm2 */
  89. rt_inline void rtgui_matrix_mul(struct rtgui_matrix *mm,
  90. const struct rtgui_matrix *mm1,
  91. const struct rtgui_matrix *mm2)
  92. {
  93. int *m = mm->m;
  94. const int *m1 = mm1->m;
  95. const int *m2 = mm2->m;
  96. m[0] = _rtgui_matrix_round_div32(m1[0] * m2[0] + m1[1] * m2[2], RTGUI_MATRIX_FRAC);
  97. m[1] = _rtgui_matrix_round_div32(m1[0] * m2[1] + m1[1] * m2[3], RTGUI_MATRIX_FRAC);
  98. m[2] = _rtgui_matrix_round_div32(m1[2] * m2[0] + m1[3] * m2[2], RTGUI_MATRIX_FRAC);
  99. m[3] = _rtgui_matrix_round_div32(m1[2] * m2[1] + m1[3] * m2[3], RTGUI_MATRIX_FRAC);
  100. m[4] = _rtgui_matrix_round_div32(m1[4] * m2[0] + m1[5] * m2[2], RTGUI_MATRIX_FRAC) + m2[4];
  101. m[5] = _rtgui_matrix_round_div32(m1[4] * m2[1] + m1[5] * m2[3], RTGUI_MATRIX_FRAC) + m2[5];
  102. }
  103. /* Matrix multiply point[(p) = (x, y) * m], ignore the movement components. */
  104. rt_inline void rtgui_matrix_mul_point_nomove(struct rtgui_point *p,
  105. int x, int y,
  106. struct rtgui_matrix *m)
  107. {
  108. int *mm = m->m;
  109. p->x = _rtgui_matrix_round_div32(x * mm[0] + y * mm[2], RTGUI_MATRIX_FRAC);
  110. p->y = _rtgui_matrix_round_div32(x * mm[1] + y * mm[3], RTGUI_MATRIX_FRAC);
  111. }
  112. /* Matrix multiply point[(p) = (x, y) * m]. */
  113. rt_inline void rtgui_matrix_mul_point(struct rtgui_point *p,
  114. int x, int y,
  115. struct rtgui_matrix *m)
  116. {
  117. int *mm = m->m;
  118. p->x = _rtgui_matrix_round_div32(x * mm[0] + y * mm[2], RTGUI_MATRIX_FRAC) + mm[4];
  119. p->y = _rtgui_matrix_round_div32(x * mm[1] + y * mm[3], RTGUI_MATRIX_FRAC) + mm[5];
  120. }
  121. /** Set @mm to an identity matrix. */
  122. rt_inline void rtgu_matrix_identity(struct rtgui_matrix *mm)
  123. {
  124. int *mat = mm->m;
  125. mat[0] = RTGUI_MATRIX_FRAC;
  126. mat[1] = 0;
  127. mat[2] = 0;
  128. mat[3] = RTGUI_MATRIX_FRAC;
  129. mat[4] = 0;
  130. mat[5] = 0;
  131. }
  132. /** Save the inversed matrix of @mm to @mo.
  133. *
  134. * @return If the matrix is not inversale, return 1. Otherwise, return 0. */
  135. int rtgui_matrix_inverse(const struct rtgui_matrix *mm, struct rtgui_matrix *mo);
  136. /** @degree range from 0 ~ 512. */
  137. void rtgui_matrix_rotate(struct rtgui_matrix *m, int degree);
  138. /** The unit is fixed point number. RTGUI_MATRIX_FRAC means 1.0. */
  139. void rtgui_matrix_scale(struct rtgui_matrix *m, int sx, int sy);
  140. /** The unit is pixel. Not the fixed point number. */
  141. void rtgui_matrix_move(struct rtgui_matrix *m, int dx, int dy);
  142. #endif /* end of include guard: __MATRIX_H__ */