Advertisement
Geklmin

stolen GJK code for hugh

Jan 22nd, 2018
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.77 KB | None | 0 0
  1. function flag = GJK(shape1,shape2,iterations)
  2. % GJK Gilbert-Johnson-Keerthi Collision detection implementation.
  3. % Returns whether two convex shapes are are penetrating or not
  4. % (true/false). Only works for CONVEX shapes.
  5. %
  6. % Inputs:
  7. % shape1:
  8. % must have fields for XData,YData,ZData, which are the x,y,z
  9. % coordinates of the vertices. Can be the same as what comes out of a
  10. % PATCH object. It isn't required that the points form faces like patch
  11. % data. This algorithm will assume the convex hull of the x,y,z points
  12. % given.
  13. %
  14. % shape2:
  15. % Other shape to test collision against. Same info as shape1.
  16. %
  17. % iterations:
  18. % The algorithm tries to construct a tetrahedron encompassing
  19. % the origin. This proves the objects have collided. If we fail within a
  20. % certain number of iterations, we give up and say the objects are not
  21. % penetrating. Low iterations means a higher chance of false-NEGATIVES
  22. % but faster computation. As the objects penetrate more, it takes fewer
  23. % iterations anyway, so low iterations is not a huge disadvantage.
  24. %
  25. % Outputs:
  26. % flag:
  27. % true - objects collided
  28. % false - objects not collided
  29. %
  30. %
  31. % This video helped me a lot when making this: https://mollyrocket.com/849
  32. % Not my video, but very useful.
  33. %
  34. % Matthew Sheen, 2016
  35. % Thanks, Matthew! - David M Webster
  36.  
  37. %Point 1 and 2 selection (line segment)
  38. v = [0.8 0.5 1];
  39. [a,b] = pickLine(v,shape2,shape1);
  40.  
  41. %Point 3 selection (triangle)
  42. [a,b,c,flag] = pickTriangle(a,b,shape2,shape1,iterations);
  43.  
  44. %Point 4 selection (tetrahedron)
  45. if flag == 1 %Only bother if we could find a viable triangle.
  46. [a,b,c,d,flag] = pickTetrahedron(a,b,c,shape2,shape1,iterations);
  47. end
  48.  
  49. end
  50. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  51. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  52. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  53. %/** End of the GJK function **/
  54. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  55. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  56. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  57.  
  58.  
  59.  
  60.  
  61. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  62. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  63. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  64. %/** Get a Line Step **/
  65. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  66. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  67. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  68. function [a,b] = pickLine(v,shape1,shape2)
  69. %Construct the first line of the simplex
  70. b = support(shape2,shape1,v);
  71. a = support(shape2,shape1,-v);
  72. end
  73. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  74. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  75. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  76. %/** Get a Triangle Step **/
  77. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  78. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  79. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  80. function [a,b,c,flag] = pickTriangle(a,b,shape1,shape2,IterationAllowed)
  81. flag = 0; %So far, we don't have a successful triangle.
  82.  
  83. %First try:
  84. ab = b-a;
  85. ao = -a;
  86. v = cross(cross(ab,ao),ab); % v is perpendicular to ab pointing in the general direction of the origin.
  87.  
  88. c = b;
  89. b = a;
  90. a = support(shape2,shape1,v);
  91.  
  92. for i = 1:IterationAllowed %iterations to see if we can draw a good triangle.
  93. %Time to check if we got it:
  94. ab = b-a;
  95. ao = -a;
  96. ac = c-a;
  97.  
  98. %Normal to face of triangle
  99. abc = cross(ab,ac);
  100.  
  101. %Perpendicular to AB going away from triangle
  102. abp = cross(ab,abc);
  103. %Perpendicular to AC going away from triangle
  104. acp = cross(abc,ac);
  105.  
  106. %First, make sure our triangle "contains" the origin in a 2d projection
  107. %sense.
  108. %Is origin above (outside) AB?
  109. if dot(abp,ao) > 0
  110. c = b; %Throw away the furthest point and grab a new one in the right direction
  111. b = a;
  112. v = abp; %cross(cross(ab,ao),ab);
  113.  
  114. %Is origin above (outside) AC?
  115. elseif dot(acp, ao) > 0
  116. b = a;
  117. v = acp; %cross(cross(ac,ao),ac);
  118.  
  119. else
  120. flag = 1;
  121. break; %We got a good one.
  122. end
  123. a = support(shape2,shape1,v);
  124. end
  125. end
  126.  
  127.  
  128. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  129. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  130. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  131. %/** Tetrahedron Step **/
  132. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  133. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  134. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  135. function [a,b,c,d,flag] = pickTetrahedron(a,b,c,shape1,shape2,IterationAllowed)
  136. %Now, if we're here, we have a successful 2D simplex, and we need to check
  137. %if the origin is inside a successful 3D simplex.
  138. %So, is the origin above or below the triangle?
  139. flag = 0;
  140.  
  141. ab = b-a;
  142. ac = c-a;
  143.  
  144. %Normal to face of triangle
  145. abc = cross(ab,ac);
  146. ao = -a;
  147.  
  148. if dot(abc, ao) > 0 %Above
  149. d = c;
  150. c = b;
  151. b = a;
  152.  
  153. v = abc;
  154. a = support(shape2,shape1,v); %Tetrahedron new point
  155.  
  156. else %below
  157. d = b;
  158. b = a;
  159. v = -abc;
  160. a = support(shape2,shape1,v); %Tetrahedron new point
  161. end
  162.  
  163. for i = 1:IterationAllowed %Allowing 10 tries to make a good tetrahedron.
  164. %Check the tetrahedron:
  165. ab = b-a;
  166. ao = -a;
  167. ac = c-a;
  168. ad = d-a;
  169.  
  170. %We KNOW that the origin is not under the base of the tetrahedron based on
  171. %the way we picked a. So we need to check faces ABC, ABD, and ACD.
  172.  
  173. %Normal to face of triangle
  174. abc = cross(ab,ac);
  175.  
  176. if dot(abc, ao) > 0 %Above triangle ABC
  177. %No need to change anything, we'll just iterate again with this face as
  178. %default.
  179. else
  180. acd = cross(ac,ad);%Normal to face of triangle
  181.  
  182. if dot(acd, ao) > 0 %Above triangle ACD
  183. %Make this the new base triangle.
  184. b = c;
  185. c = d;
  186. ab = ac;
  187. ac = ad;
  188. abc = acd;
  189. else
  190. adb = cross(ad,ab);%Normal to face of triangle
  191.  
  192. if dot(adb, ao) > 0 %Above triangle ADB
  193. %Make this the new base triangle.
  194. c = b;
  195. b = d;
  196. ac = ab;
  197. ab = ad;
  198. abc = adb;
  199. else
  200. flag = 1;
  201. break; %It's inside the tetrahedron.
  202. end
  203. end
  204. end
  205.  
  206. %try again:
  207. if dot(abc, ao) > 0 %Above
  208. d = c;
  209. c = b;
  210. b = a;
  211. v = abc;
  212. a = support(shape2,shape1,v); %Tetrahedron new point
  213. else %below
  214. d = b;
  215. b = a;
  216. v = -abc;
  217. a = support(shape2,shape1,v); %Tetrahedron new point
  218. end
  219. end
  220.  
  221. end
  222.  
  223. function point = getFarthestInDir(shape, v)
  224. %Find the furthest point in a given direction for a shape
  225. XData = get(shape,'XData'); % Making it more compatible with previous MATLAB releases.
  226. YData = get(shape,'YData');
  227. ZData = get(shape,'ZData');
  228. dotted = XData*v(1) + YData*v(2) + ZData*v(3);
  229. [maxInCol,rowIdxSet] = max(dotted);
  230. [maxInRow,colIdx] = max(maxInCol);
  231. rowIdx = rowIdxSet(colIdx);
  232. point = [XData(rowIdx,colIdx), YData(rowIdx,colIdx), ZData(rowIdx,colIdx)];
  233. end
  234.  
  235. function point = support(shape1,shape2,v)
  236. %Support function to get the Minkowski difference.
  237. point1 = getFarthestInDir(shape1, v);
  238. point2 = getFarthestInDir(shape2, -v);
  239. point = point1 - point2;
  240. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement