GJK (Gilbert–johnson–keerthi) to determine if arbitrary convex graphs overlap

Source: Internet
Author: User
Tags dashed line

Reference: http://www.dyn4j.org/2010/04/gjk-gilbert-johnson-keerthi/

As with the SAT (split axis) method, the GJK can determine whether two convex shapes overlap. Compared to the SAT, GJK is able to handle all the graphics in the same way, while the SAT determines that two different shapes (polygon-polygon/polygon-circle/Circle-circle) are treated differently.

GJK principle: If the Minkowski of two convex graphs contains the origin, then these two graphs overlap. So the question turns into judging whether a Minkowski graph contains the origin.

Minkowski the points in the two graphs as vectors, adding the vector points of the two graphs together to get a new shape.

Minkowski the vector of one of the graphs is reversed, which is equivalent to the reversal of the origin, and then the two figure for Minkowski.

GJK does not directly ask for two graphs of the Minkowski, but through the following auxiliary function, enter a different search direction, return to Minkowski a point on the difference, iteratively using these points to form a sub-shape, to determine whether the child shape contains the origin point.

Proc Getsupportpoint (S1:sprite2d, S2:sprite2d, dir:vector2d): vector2d =    let        invM1 = S1.invmatrix        invM2 = s  2.invMatrix        v1 = S1.matrix * S1.graph.getFarthestPointInDirection (invM1 * dir-invm1 * VECTOR2D (x:0, y:0))        v2 = S2.matrix * S2.graph.getFarthestPointInDirection (INVM2 * dir.negate ()-invM2 * VECTOR2D (x:0, y:0))    return V1-v2

The above function returns the farthest point of the Minkowski graph in one direction. This first transforms the search direction into the object space, and the object finds itself at the farthest point in the search direction, then transforms it back into world space.

The function to find the farthest point of the polygon in the lookup direction is as follows. Distance is judged based on the size of the projection by projecting all vertices into the lookup direction.

Method getfarthestpointindirection* (Self:polygon, direction:vector2d): vector2d =    var        curr = self[0]        Bestprojection:float32 = Curr * Direction        projection:float32    result = Curr for        i in 1..self.len-1:        Curr = Self[i]        projection = Curr * Direction        if projection > bestprojection:            bestprojection = projection            result = Curr

Circular. Norm is the unit vector.

Method getfarthestpointindirection* (Self:circle, direction:vector2d): vector2d =    direction.norm () * Self.radius

GJK each generated sub-shape is a simplex (simplex). The simplex is a triangle at 2D and a tetrahedron under 3D.

The GJK pseudo-code given on the wiki is as follows:

   function gjk_intersection (shape p, shape Q, vector initial_axis):       vector  A = support (P, Initial_axis)-Support (q ,-initial_axis)       simplex s = {a}       vector  D =-a       loop:           a = Support (P, D)-Support (q,-D)           if Dot (A, D) < 0:              reject           s = s∪a           s, D, Contains_origin = Nearestsimplex (s)           if Contains_origin:              Accept

The specific implementation of the individual is as follows:

Suppose Minkowski's shape is elliptical.

The first point A on the simplex is found by using the Getsupportpoint function with an initial lookup direction. At this point, the vector OA is projected onto the find direction vector. If the projection is negative, then the Origin o must be outside the Minkowski (on the right side of the red dashed line that is over a), which determines that the two graphic does not overlap. Each time a single vertex is found, it is so judged.

Then, reverse the lookup direction (or use the AO direction) to find the second point B. Then judge that the origin is not on the left side of the dotted line B.

Connect A and B to find a vector perpendicular to AB in the direction of the AO as the search direction, and get the point C. Now, where the origin may be, there are three red dashed lines surrounded by a quad with AB.

The vector acperp perpendicular to the ab direction of the AC is obtained, and the vector bcperp that is perpendicular to the BC is directed toward the BA direction.

The AO is projected onto the acperp, and if the projection is negative, then the origin is not in the simplex. At this time discard the point at the farthest from the origin of B, with point A and point C as the new point a ' and point B ', repeat the above process.

The OB is projected onto the bcperp, as above to determine whether the origin is inside or outside the BC. If it is outside the BC, discard the one farthest from the origin, using B and C as the new points A and B, repeating the above process.

If the two projections are non-negative, then the origin is within the simplex ABC, and the two graphs are judged to overlap.

Proc isintersect* (S1, s2:sprite2d): bool = var dir = vector2d (x:1, y:0) Simplexa, Simplexb, Simplexc:    vector2d Simplexa = getsupportpoint (S1, S2, dir) if Simplexa * dir < 0:return false dir = Simplexa.negate ()        Simplexb = Getsupportpoint (S1, S2, dir) if Simplexb * Dir < 0:return false let AO = Simplexa.negate ()  AB = Simplexb-simplexa dir = tripleproduct (AB, AO, ab) while True:simplexc = Getsupportpoint (S1, S2,            DIR) If Simplexc * Dir < 0:return false let BA = Simplexa-simplexb  AC = simplexc-simplexa BC = Simplexc-simplexb acperp = Tripleproduct (AC, ba.negate (),            AC) bcperp = tripleproduct (BC, BA, BC) if ACPERP * simplexa > 0:SIMPLEXB = Simplexc dir = acperp.negate () elif bcperp * simplexb > 0:simplexa = simplexc dir = bcperp. Negate () Else:reTurn true 

The upper tripleproduct is a continuous two-pronged multiplication, and the axbxa will get a vector perpendicular to a in the direction of B.

Proc tripleproduct* (v1, v2, v3:vector2d): vector2d =    result.x =-(v1.x * V2.Y-V1.Y * v2.x) * v3.y    Result.y = (v 1.x * V2.Y-V1.Y * v2.x) * v3.x

GJK (Gilbert–johnson–keerthi) to determine if arbitrary convex graphs overlap

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.