CollisionLine.java 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. package me.hammerle.supersnuvi.util;
  2. public class CollisionLine extends CollisionObject
  3. {
  4. private float x1;
  5. private float y1;
  6. private float x2;
  7. private float y2;
  8. private float cx1;
  9. private float cy1;
  10. private float cx2;
  11. private float cy2;
  12. public CollisionLine(float x1, float y1, float x2, float y2)
  13. {
  14. this.x1 = x1;
  15. this.y1 = y1;
  16. this.x2 = x2;
  17. this.y2 = y2;
  18. this.cx1 = x1;
  19. this.cy1 = y1;
  20. this.cx2 = x2;
  21. this.cy2 = y2;
  22. }
  23. @Override
  24. public Type getType()
  25. {
  26. return Type.LINE;
  27. }
  28. @Override
  29. public CollisionObject copy()
  30. {
  31. return new CollisionLine(cx1, cy1, cx2, cy2);
  32. }
  33. @Override
  34. public void save()
  35. {
  36. x1 = cx1;
  37. y1 = cy1;
  38. x2 = cx2;
  39. y2 = cy2;
  40. }
  41. @Override
  42. public CollisionObject reset()
  43. {
  44. cx1 = x1;
  45. cy1 = y1;
  46. cx2 = x2;
  47. cy2 = y2;
  48. return this;
  49. }
  50. @Override
  51. public float getWidth()
  52. {
  53. return Math.abs(x1 - x2);
  54. }
  55. @Override
  56. public float getHeight()
  57. {
  58. return Math.abs(y1 - y2);
  59. }
  60. @Override
  61. public float getMinX()
  62. {
  63. return cx1;
  64. }
  65. @Override
  66. public float getMaxX()
  67. {
  68. return cx2;
  69. }
  70. @Override
  71. public float getMinY()
  72. {
  73. return cy1;
  74. }
  75. @Override
  76. public float getMaxY()
  77. {
  78. return cy2;
  79. }
  80. @Override
  81. public CollisionObject expand(float x, float y)
  82. {
  83. return this;
  84. }
  85. @Override
  86. public CollisionObject offsetX(float x)
  87. {
  88. cx1 += x;
  89. cx2 += x;
  90. return this;
  91. }
  92. @Override
  93. public CollisionObject offsetY(float y)
  94. {
  95. cy1 += y;
  96. cy2 += y;
  97. return this;
  98. }
  99. @Override
  100. public boolean isColliding(CollisionObject cb)
  101. {
  102. switch(cb.getType())
  103. {
  104. case BOX:
  105. return cb.isColliding(this);
  106. case LINE:
  107. return CollisionLine.intersect(x1, y1, x2, y2, cb.getMinX(), cb.getMinY(), cb.getMaxX(), cb.getMaxY());
  108. }
  109. return false;
  110. }
  111. @Override
  112. public String toString()
  113. {
  114. StringBuilder sb = new StringBuilder("line[x1 = ");
  115. sb.append(cx1);
  116. sb.append(", y1 = ");
  117. sb.append(cy1);
  118. sb.append(", x2 = ");
  119. sb.append(cx2);
  120. sb.append(", y2 = ");
  121. sb.append(cy2);
  122. sb.append(']');
  123. return sb.toString();
  124. }
  125. public static boolean intersect(float x11, float y11, float x12, float y12, float x21, float y21, float x22, float y22)
  126. {
  127. if(compareFloats(x11, x12))
  128. {
  129. if(compareFloats(x21, x22))
  130. {
  131. return false;
  132. }
  133. else
  134. {
  135. if(!isBetween(x11, x21, x22))
  136. {
  137. return false;
  138. }
  139. float k = (y21 - y22) / (x21 - x22);
  140. float d = y22 - k * x22;
  141. float y = d + x11 * k;
  142. return isBetween(y, y11, y12) && isBetween(y, y21, y22);
  143. }
  144. }
  145. else
  146. {
  147. if(compareFloats(x21, x22))
  148. {
  149. if(!isBetween(x21, x11, x12))
  150. {
  151. return false;
  152. }
  153. float k = (y11 - y12) / (x11 - x12);
  154. float d = y12 - k * x12;
  155. float y = d + x21 * k;
  156. return isBetween(y, y11, y12) && isBetween(y, y21, y22);
  157. }
  158. else
  159. {
  160. float k1 = (y11 - y12) / (x11 - x12);
  161. float k2 = (y21 - y22) / (x21 - x22);
  162. if(compareFloats(k1, k2))
  163. {
  164. return false;
  165. }
  166. float d1 = y12 - k1 * x12;
  167. float d2 = y22 - k2 * x22;
  168. float x = (d1 - d2) / (k2 - k1);
  169. if(!isBetween(x, x11, x12) || !isBetween(x, x21, x22))
  170. {
  171. return false;
  172. }
  173. float y = k1 * x + d1;
  174. return isBetween(y, y11, y12) && isBetween(y, y21, y22);
  175. }
  176. }
  177. }
  178. private static final float ERROR = 1.0f / 512.0f;
  179. private static boolean isBetween(float y, float y1, float y2)
  180. {
  181. float min = Math.min(y1, y2) - ERROR;
  182. float max = Math.max(y1, y2) + ERROR;
  183. return y >= min && y <= max;
  184. }
  185. private static boolean compareFloats(float a, float b)
  186. {
  187. return Math.abs(a - b) < ERROR;
  188. }
  189. }