rebox.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include "rebox.h"
  2. #include <stdlib.h>
  3. #include "flags.h"
  4. /** Makes a new bounds box struct. */
  5. Rebox rebox_make(int x, int y, int w, int h) {
  6. Point p = bevec(x, y);
  7. Point s = bevec(w, h);
  8. Rebox result = { p, s };
  9. return result;
  10. }
  11. /** Initializes a bounds pointer by copying data from a bounds struct. */
  12. Rebox * rebox_initbounds(Rebox * self, Rebox bounds) {
  13. if(!self) return NULL;
  14. (*self) = bounds;
  15. return self;
  16. }
  17. /** Initializes a bounds pointer from it's coordinates. */
  18. Rebox * rebox_init(Rebox * self, int x, int y, int w, int h) {
  19. return rebox_initbounds(self, rebox_make(x, y, w, h));
  20. }
  21. /** Returns a newly initialised rectangular box. */
  22. Rebox rebox_new(float x, float y, float w, float h) {
  23. Rebox result;
  24. /** Avoid negative widths and heights by adjusting x and y accordingly */
  25. if (w < 0) { x = x - w ; w = -w ; }
  26. if (h < 0) { y = y - h ; w = -h ; }
  27. result.at = bevec(x, y);
  28. result.size = bevec(w, h);
  29. return result;
  30. }
  31. /** Return position of Rebox top left corner. */
  32. Point rebox_at(Rebox * self) {
  33. return self->at;
  34. }
  35. /** Return position of Rebox bottom right corner. */
  36. Point rebox_br(Rebox * self) {
  37. return bevec_add(self->at, self-> size);
  38. }
  39. /** Sets position by individual components. */
  40. Point rebox_x_(Rebox * self, float x) {
  41. self->at.x = x;
  42. return self->at;
  43. }
  44. /** Sets position by individual components. */
  45. Point rebox_y_(Rebox * self, float y) {
  46. self->at.y = y;
  47. return self->at;
  48. }
  49. /** Sets position by individual components. */
  50. Point rebox_xy_(Rebox * self, float x, float y) {
  51. self->at.x = x;
  52. self->at.y = y;
  53. return self->at;
  54. }
  55. /** Sets position. */
  56. Point rebox_at_(Rebox * self, Point at) {
  57. self->at = at;
  58. return self->at;
  59. }
  60. /** Return x position of Rebox top left corner. */
  61. float rebox_x(Rebox * self) {
  62. return self->at.x;
  63. }
  64. /** Return y position of Rebox top left corner. */
  65. float rebox_y(Rebox * self) {
  66. return self->at.y;
  67. }
  68. /** Return width of Rebox view. */
  69. float rebox_w(Rebox * self) {
  70. return self->size.x;
  71. }
  72. /** Return height of Rebox view. */
  73. float rebox_h(Rebox * self) {
  74. return self->size.y;
  75. }
  76. /** Return x position of Rebox bottom right corner. */
  77. float rebox_br_x(Rebox * self) {
  78. return self->at.x + self->size.x;
  79. }
  80. /** Return y position of Rebox bottom right corner. */
  81. float rebox_br_y(Rebox * self) {
  82. return self->at.y + self->size.y;
  83. }
  84. /** Return x position of Rebox view center. */
  85. float rebox_center_x(Rebox * self) {
  86. return self->at.x + (self->size.x / 2);
  87. }
  88. /** Return y position of Rebox bottom center */
  89. float rebox_center_y(Rebox * self) {
  90. return self->at.y + (self->size.y / 2);;
  91. }
  92. /** Return position of Rebox view center. */
  93. Point rebox_center(Rebox * self) {
  94. return bevec(rebox_center_x(self), rebox_center_y(self));
  95. }
  96. /** Sets position of center of Rebox to center. */
  97. Point rebox_center_(Rebox * self, Point center) {
  98. Point at;
  99. at.x = center.x - (rebox_w(self) / 2);
  100. at.y = center.y - (rebox_h(self) / 2);
  101. return rebox_at_(self, at);
  102. }
  103. /* Returns TRUE if the coordinates x and y are inside self, FALSE if not. */
  104. int rebox_coordinates_inside_p(Rebox * self, double x, double y) {
  105. if (x < self->at.x) return FALSE;
  106. if (y < self->at.y) return FALSE;
  107. if (x > rebox_br_x(self)) return FALSE;
  108. if (y > rebox_br_y(self)) return FALSE;
  109. return TRUE;
  110. }
  111. /* Returns TRUE if the point is inside self, FALSE if not. */
  112. int rebox_point_inside_p(Rebox * self, Point * point) {
  113. return rebox_coordinates_inside_p(self, point->x, point->y);
  114. }
  115. /* Returns TRUE if box 2 if other is wholly inside self, FALSE if not. */
  116. int rebox_inside_p(Rebox * self, Rebox * other) {
  117. if (other->at.x < self->at.x) return FALSE;
  118. if (other->at.y < self->at.y) return FALSE;
  119. if (rebox_br_x(other) > rebox_br_x(self)) return FALSE;
  120. if (rebox_br_y(other) > rebox_br_y(self)) return FALSE;
  121. return TRUE;
  122. }
  123. /* Returns 0 if Rebox other if other is wholly inside the Rebox self,
  124. otherwise the distance the box other has to move
  125. in the x direction to make it so.
  126. Only works if other is smaller than self. */
  127. double rebox_delta_x(Rebox * self, Rebox * other) {
  128. double dx = self->at.x - other->at.x;
  129. if (dx > 0) return dx;
  130. dx = rebox_br_x(other) - rebox_br_x(self);
  131. if (dx > 0) return -dx;
  132. return 0.0;
  133. }
  134. /* Returns 0 if box 2 if other is wholly inside self,
  135. otherwise the distance the box other has to move
  136. in the y direction to make it so.
  137. Only works if other is smaller than self. */
  138. double rebox_delta_y(Rebox * self, Rebox * other) {
  139. double dy = self->at.y - other->at.y;
  140. if (dy > 0) return dy;
  141. dy = rebox_br_y(other) - rebox_br_y(self);
  142. if (dy > 0) return -dy;
  143. return 0.0;
  144. }