Cut out the collision Point (manifold) (for GJK General change)

Source: Internet
Author: User

After using EPA to get the embedded direction of the graph, the collision point (edge) can be cut out.

First you need to find the farthest edge of the graph in the embedding direction.

Polygon:

Method getfarthestedgeindirection* (Self:polygon, direction:vector2d): line2d =    var        bestindex:int = 0        Bestprojection:float32 = self[0] * Direction        projection:float32        #先找出在direction上最远的一个顶点 for    i in 1.. Self.len-1:        projection = self[i] * Direction        if projection > bestprojection:            bestindex = i            bestprojection = projection    #选出与该顶点相邻的两条边, take the smallest projection on direction return let left        = self[(Bestindex + Self.len -1) MoD Self.len] Right        = self[(bestindex + 1) mod Self.len]        mid = Self[bestindex]        leftproj = ABS (left * d irection)        rightproj = ABS (right * direction)    if Leftproj > rightproj:        return Newline2d (left, mid)    else:        return newline2d (Mid, right)

A circle can only get one point, but to unify or return a segment with a length of 0:

Method getfarthestedgeindirection* (Self:circle, direction:vector2d): line2d = let    p = direction.norm () * Self.radiu S    return newline2d (p, p)

You can also write a getfarthestedgeindirection function for various convex shapes, such as sector, so that all convex shapes can be processed. Returns a segment to the straight edge and a point to the arc edge.

So all the convex figure collisions are divided into three cases, point and point (two arc edge collision), point and Line (a curved edge with a straight edge collision), line segments and line segments (two straight edges)

Proc getmanifold* (self:contact): manifold =    let        edge1 = self.collisionedge1        edge2 = Self.collisionedge2        isPoint1 = Edge1.ispoint ()        IsPoint2 = Edge2.ispoint ()    if isPoint1:        if isPoint2:             result = Getpointsmanifold (edge1.a, edge2.a)        else:             result = Getpointlinemanifold (edge1.a, Edge2)    else:        if IsPoint2:             result = Getpointlinemanifold (edge2.a, Edge1)        else:             result = Getlinesmanifold (Edge1, Edge2, self.penetration)    result.penetration = self.penetration    Result.rigida = Self.rigida    result.rigidb = Self.rigidb

 

The actual rigid body collision does not fall into the interior of another object, and the cut-out collision point (edge) looks reasonable when the two graphs are in contact or small overlap.

For Point-to-point situations, you can simply take a two-point midpoint:

Proc Getpointsmanifold (P1, p2:vector2d): manifold =    new (result) let    p = (p1 + p2) * 0.5    Result.add (p)

Point and line segment condition:

If the points on the arc are sandwiched between two points of the segment, then it is a circle that touches an edge on the polygon, can return either the P-point directly, or the midpoint of the P-segment.

Otherwise, a corner of the polygon touches the arc, returning the vertex closest to p from the segment.

Proc Getpointlinemanifold (point:vector2d, line:line2d): manifold =    New (Result)    let        a = line.a        B = Line  . b    if (point-a) * (B-A) < 0: #cos < 0, angle greater than 90 °, p on the outer side of a        result.add (line.a)    elif (point-b) * (a) < 0:        result.add (line.b)    else:        result.add (Point)

The case of two line segments:

Find the side that is more perpendicular to the embedding direction as a "reference edge" and another as the "event side".

Using the reference edge to cut the event edge, the event edge in the outer part of the reference polygon is all cut off, and then the event edge on the left side of the reference side and the right part of the cut off.

With this function, the edge and start are projected on Dir, and the edge projection is cut off from the small part of start.

Proc Clipedge (Edge:manifold, dir:vector2d, start:vector2d): manifold =    New (Result)    let        min = start * dir
   proj1 = Edge.a * dir-min        proj2 = edge.b * dir-min    if proj1 >= 0:        result.add (EDGE.A)    if Proj2 > = 0:        result.add (edge.b)    if proj1 * Proj2 < 0:        Result.add ((edge.b-edge.a) * (proj1/(PROJ1-PROJ2)) + E DGE.A)

Proc Getlinesmanifold (L1, L2:line2d, dir:vector2d): manifold = var refvector:vector2d refedge:line2d Incedge:manifold normal:vector2d Let v1 = l1.b-l1.a v2 = l2.b-l2.a proj1 = ABS (v1 * dir) Proj2 = ABS (v2 * dir) if proj1 < proj2: #投影较小的边更垂直, as reference edge Refedge = L1 Refvector = V        1 Incedge = newmanifold (L2) normal = Tripleproduct (v1, dir.negate (), v1) #得到一个指向 (-dir) direction perpendicular to the V1 vector else: Refedge = L2 Refvector = V2 Incedge = newmanifold (l1) normal = Tripleproduct (v2, dir, v2) in Cedge = Clipedge (Incedge, Normal, refedge.a) #把在参考多边形外部的部分裁剪掉 if incedge.length < 2:return incedge normal = Trip Leproduct (Normal, Refedge.b-refedge.a, normal) #把在a外的部分裁剪掉 Incedge = Clipedge (Incedge, Normal, refedge.a) if inced Ge.length < 2:return Incedge Incedge = Clipedge (Incedge, Normal.negate (), refedge.b) return Incedge

The effect is as follows:

Cut out the collision Point (manifold) (for GJK General change)

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.