- Object
-
- Gjk
-
- All Implemented Interfaces:
DistanceDetector
,NarrowphaseDetector
,RaycastDetector
public class Gjk extends Object implements NarrowphaseDetector, DistanceDetector, RaycastDetector
Implementation of the Gilbert-Johnson-Keerthi (GJK) algorithm for collision detection.Gjk
is an algorithm used to find minimum distance from oneConvex
Shape
to another, but can also be used to determine whether or not they intersect.Gjk
uses a specific mathematical construct called theMinkowskiSum
. TheMinkowskiSum
of twoConvex
Shape
s create anotherConvex
Shape
. If the shapes are labeled A and B, theMinkowskiSum
is the convex hull of adding every point in A to every point in B.Now, if we subtract every point in A and every point in B, we still end up with a
Convex
Shape
, but we also get another interesting property. If the twoConvex
Shape
s are penetrating one another (overlapping) then theMinkowskiSum
, using the difference operator, will contain the origin.Computing the
MinkowskiSum
directly would not be very efficient and performance would be directly linked to the number of vertices each shape contained (n*m subtractions). In addition, curved shapes have an infinite number of vertices.That said, it's not necessary to compute the
MinkowskiSum
. Instead, to determine whether the origin is contained in theMinkowskiSum
we iteratively create aShape
inside theMinkowskiSum
that encloses the origin. This is called the simplex and for 2D it will be a triangle. If we can enclose the origin using a shape contained within theMinkowskiSum
, then we can conclude that the origin is contained within theMinkowskiSum
, and that the two shapes are penetrating. If we cannot, then the shapes are separated.To create a shape inside the
MinkowskiSum
, we use what is called a support function. The support function returns a point on the edge of theMinkowskiSum
farthest in a given direction. This can be obtained by taking the farthest point in shape A minus the farthest point in shape B in the opposite direction.If the
MinkowskiSum
is:A - B
then the support function would be:(farthest point in direction D in A) - (farthest point in direction -D in B)
With this we can obtain a point which is on the edge of theMinkowskiSum
shape in any direction. Next we iteratively create these points so that we create a shape (triangle in the 2d case) that encloses the origin.Algorithm psuedo-code:
// get a point farthest in the direction // choose some random direction (selection of the initial direction can // determine the speed at which the algorithm terminates) Point p = support(A, B, direction); // add it to the simplex simplex.addPoint(p); // negate the direction direction = -direction; // make sure the point we are about to add is actually past the origin // if its not past the origin then that means we can never enclose the origin // therefore its not in the Minkowski sum and therefore there is no penetration. while (p = support(A, B, direction).dot(direction) > 0) { // if the point is past the origin then add it to the simplex simplex.add(p); // then check to see if the simplex contains the origin // passing back a new search direction if it does not if (check(simplex, direction)) { return true; } } return false;
The last method to discuss is the check method. This method can be implemented in any fashion, however, if the simplex points are stored in a way that we always know what point was added last, many optimizations can be done. For these optimizations please refer to the source documentation oncheckSimplex(List, Vector2)
.Once
Gjk
has found that the twoCollisionBody
s are penetrating it will exit and hand off the resulting simplex to aMinkowskiPenetrationSolver
to find the collision depth and normal.Gjk
's defaultMinkowskiPenetrationSolver
isEpa
.The
Gjk
algorithm's original intent was to find the minimum distance between twoConvex
Shape
s. Refer todistance(Convex, Transform, Convex, Transform, Separation)
for details on the implementation.- Since:
- 1.0.0
- Version:
- 4.0.0
- Author:
- William Bittle
- See Also:
Epa
, GJK (Gilbert-Johnson-Keerthi), GJK - Distance & Closest Points
-
-
Field Summary
Fields Modifier and Type Field Description static double
DEFAULT_DETECT_EPSILON
The default epsilon in meters for collision detectionstatic double
DEFAULT_DISTANCE_EPSILON
The default epsilon in meters for distance checksstatic int
DEFAULT_MAX_ITERATIONS
The defaultGjk
maximum iterationsstatic double
DEFAULT_RAYCAST_EPSILON
The default epsilon in meters for raycast checks
-
Constructor Summary
Constructors Constructor Description Gjk()
Default constructor.Gjk(MinkowskiPenetrationSolver minkowskiPenetrationSolver)
Optional constructor.
-
Method Summary
All Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description boolean
detect(Convex convex1, Transform transform1, Convex convex2, Transform transform2)
boolean
detect(Convex convex1, Transform transform1, Convex convex2, Transform transform2, Penetration penetration)
Returns true if the twoConvex
Shape
s intersect and fills thePenetration
object with the penetration vector and depth.boolean
distance(Convex convex1, Transform transform1, Convex convex2, Transform transform2, Separation separation)
Returns true if the twoConvex
Shape
s are separated and fills the givenSeparation
object with the minimum distance vector, distance, and closest points.double
getDetectEpsilon()
Returns theGjk
detect epsilon.double
getDistanceEpsilon()
Returns theGjk
distance epsilon.int
getMaxDetectIterations()
Returns the maximum number of iterations theGjk
collision detection algorithm will perform before returning that two convex shapes are not overlapping.int
getMaxDistanceIterations()
Returns the maximum number of iterations theGjk
distance algorithm will perform before returning the distance between two separated convex shapes.int
getMaxIterations()
Deprecated.replaced withgetMaxDistanceIterations()
since 3.3.0int
getMaxRaycastIterations()
Returns the maximum number of iterations theGjk
raycast algorithm will perform before returning that the ray and the convex are not overlapping.MinkowskiPenetrationSolver
getMinkowskiPenetrationSolver()
Returns theMinkowskiPenetrationSolver
used to obtain the penetration vector and depth.double
getRaycastEpsilon()
Returns theGjk
raycast epsilon.boolean
raycast(Ray ray, double maxLength, Convex convex, Transform transform, Raycast raycast)
void
setDetectEpsilon(double detectEpsilon)
The minimum distance to determine that two shapes are not colliding.void
setDistanceEpsilon(double distanceEpsilon)
The minimum distance between two iterations of theGjk
distance algorithm.void
setMaxDetectIterations(int maxIterations)
Sets the maximum number of iterations theGjk
collision detection algorithm will perform when before return that two convex shapes are not overlapping.void
setMaxDistanceIterations(int maxIterations)
Sets the maximum number of iterations theGjk
distance algorithm will perform when determining the distance between two convex shapes.void
setMaxIterations(int maxIterations)
Deprecated.replaced withsetMaxDistanceIterations(int)
since 3.3.0void
setMaxRaycastIterations(int maxIterations)
Sets the maximum number of iterations theGjk
raycast algorithm will perform when checking whether the ray intersects the convex.void
setMinkowskiPenetrationSolver(MinkowskiPenetrationSolver minkowskiPenetrationSolver)
Sets theMinkowskiPenetrationSolver
used to obtain the penetration vector and depth.void
setRaycastEpsilon(double raycastEpsilon)
The minimum distance between the ray and convex for theGjk
raycast algorithm.
-
-
-
Field Detail
-
DEFAULT_MAX_ITERATIONS
public static final int DEFAULT_MAX_ITERATIONS
The defaultGjk
maximum iterations- See Also:
- Constant Field Values
-
DEFAULT_DETECT_EPSILON
public static final double DEFAULT_DETECT_EPSILON
The default epsilon in meters for collision detection- See Also:
- Constant Field Values
-
DEFAULT_DISTANCE_EPSILON
public static final double DEFAULT_DISTANCE_EPSILON
The default epsilon in meters for distance checks
-
DEFAULT_RAYCAST_EPSILON
public static final double DEFAULT_RAYCAST_EPSILON
The default epsilon in meters for raycast checks
-
-
Constructor Detail
-
Gjk
public Gjk()
Default constructor.
-
Gjk
public Gjk(MinkowskiPenetrationSolver minkowskiPenetrationSolver)
Optional constructor.- Parameters:
minkowskiPenetrationSolver
- theMinkowskiPenetrationSolver
to use- Throws:
NullPointerException
- if minkowskiPenetrationSolver is null
-
-
Method Detail
-
detect
public boolean detect(Convex convex1, Transform transform1, Convex convex2, Transform transform2, Penetration penetration)
Description copied from interface:NarrowphaseDetector
Returns true if the twoConvex
Shape
s intersect and fills thePenetration
object with the penetration vector and depth.
-
detect
public boolean detect(Convex convex1, Transform transform1, Convex convex2, Transform transform2)
Description copied from interface:NarrowphaseDetector
Returns true if the twoConvex
Shape
s intersect.Used to quickly test if two
Convex
Shape
s intersect without incurring the cost of determiningPenetration
.
-
distance
public boolean distance(Convex convex1, Transform transform1, Convex convex2, Transform transform2, Separation separation)
Description copied from interface:DistanceDetector
Returns true if the twoConvex
Shape
s are separated and fills the givenSeparation
object with the minimum distance vector, distance, and closest points.- Specified by:
distance
in interfaceDistanceDetector
- Parameters:
convex1
- the firstShape
transform1
- the firstShape
'sTransform
convex2
- the secondShape
transform2
- the secondShape
'sTransform
separation
- theSeparation
object to fill- Returns:
- boolean true if the
Convex
Shape
s are separated
-
raycast
public boolean raycast(Ray ray, double maxLength, Convex convex, Transform transform, Raycast raycast)
Description copied from interface:RaycastDetector
Performs a ray cast given aRay
and aConvex
Shape
returning true if the ray passes through the convex shape.The raycast parameter is used to stored the results of the raycast when returning true.
Returns false if the start position of the ray lies inside the given convex.
- Specified by:
raycast
in interfaceRaycastDetector
- Parameters:
ray
- theRay
maxLength
- the maximum length of the ray; 0 for infinite lengthconvex
- theConvex
Shape
transform
- theConvex
Shape
'sTransform
raycast
- the ray cast result- Returns:
- boolean true if the
Ray
passes through theConvex
Shape
-
getMaxDetectIterations
public int getMaxDetectIterations()
Returns the maximum number of iterations theGjk
collision detection algorithm will perform before returning that two convex shapes are not overlapping.- Returns:
- int the number of
Gjk
detect iterations - Since:
- 3.3.0
- See Also:
setMaxDetectIterations(int)
-
setMaxDetectIterations
public void setMaxDetectIterations(int maxIterations)
Sets the maximum number of iterations theGjk
collision detection algorithm will perform when before return that two convex shapes are not overlapping.Valid values are in the range [5, ∞].
- Parameters:
maxIterations
- the maximum number ofGjk
detect iterations- Throws:
IllegalArgumentException
- if maxIterations is less than 5- Since:
- 3.3.0
-
getMaxDistanceIterations
public int getMaxDistanceIterations()
Returns the maximum number of iterations theGjk
distance algorithm will perform before returning the distance between two separated convex shapes.- Returns:
- int the number of
Gjk
distance iterations - Since:
- 3.3.0
- See Also:
setMaxDistanceIterations(int)
-
setMaxDistanceIterations
public void setMaxDistanceIterations(int maxIterations)
Sets the maximum number of iterations theGjk
distance algorithm will perform when determining the distance between two convex shapes.Valid values are in the range [5, ∞].
- Parameters:
maxIterations
- the maximum number ofGjk
distance iterations- Throws:
IllegalArgumentException
- if maxIterations is less than 5- Since:
- 3.3.0
-
getMaxRaycastIterations
public int getMaxRaycastIterations()
Returns the maximum number of iterations theGjk
raycast algorithm will perform before returning that the ray and the convex are not overlapping.- Returns:
- int the number of
Gjk
raycast iterations - Since:
- 3.3.0
- See Also:
setMaxRaycastIterations(int)
-
setMaxRaycastIterations
public void setMaxRaycastIterations(int maxIterations)
Sets the maximum number of iterations theGjk
raycast algorithm will perform when checking whether the ray intersects the convex.Valid values are in the range [5, ∞].
- Parameters:
maxIterations
- the maximum number ofGjk
raycast iterations- Throws:
IllegalArgumentException
- if maxIterations is less than 5- Since:
- 3.3.0
-
getDetectEpsilon
public double getDetectEpsilon()
Returns theGjk
detect epsilon.- Returns:
- double the
Gjk
detect epsilon - Since:
- 3.3.0
- See Also:
setDetectEpsilon(double)
-
setDetectEpsilon
public void setDetectEpsilon(double detectEpsilon)
The minimum distance to determine that two shapes are not colliding.Valid values are in the range [0, ∞].
- Parameters:
detectEpsilon
- theGjk
detect epsilon- Throws:
IllegalArgumentException
- if detectEpsilon is less than zero- Since:
- 3.3.0
-
getRaycastEpsilon
public double getRaycastEpsilon()
Returns theGjk
raycast epsilon.- Returns:
- double the
Gjk
raycast epsilon - Since:
- 3.3.0
- See Also:
setRaycastEpsilon(double)
-
setRaycastEpsilon
public void setRaycastEpsilon(double raycastEpsilon)
The minimum distance between the ray and convex for theGjk
raycast algorithm.Valid values are in the range (0, ∞].
- Parameters:
raycastEpsilon
- theGjk
raycast epsilon- Throws:
IllegalArgumentException
- if raycastEpsilon is less than or equal to zero- Since:
- 3.3.0
-
getDistanceEpsilon
public double getDistanceEpsilon()
Returns theGjk
distance epsilon.- Returns:
- double the
Gjk
distance epsilon - See Also:
setDistanceEpsilon(double)
-
setDistanceEpsilon
public void setDistanceEpsilon(double distanceEpsilon)
The minimum distance between two iterations of theGjk
distance algorithm.Valid values are in the range (0, ∞].
- Parameters:
distanceEpsilon
- theGjk
distance epsilon- Throws:
IllegalArgumentException
- if distanceEpsilon is less than or equal to zero
-
getMinkowskiPenetrationSolver
public MinkowskiPenetrationSolver getMinkowskiPenetrationSolver()
Returns theMinkowskiPenetrationSolver
used to obtain the penetration vector and depth.- Returns:
MinkowskiPenetrationSolver
-
setMinkowskiPenetrationSolver
public void setMinkowskiPenetrationSolver(MinkowskiPenetrationSolver minkowskiPenetrationSolver)
Sets theMinkowskiPenetrationSolver
used to obtain the penetration vector and depth.- Parameters:
minkowskiPenetrationSolver
- theMinkowskiPenetrationSolver
- Throws:
NullPointerException
- if minkowskiPenetrationSolver is null
-
getMaxIterations
@Deprecated public int getMaxIterations()
Deprecated.replaced withgetMaxDistanceIterations()
since 3.3.0Returns the maximum number of iterations theGjk
algorithm will perform when computing the distance between two separated bodies.- Returns:
- int the number of
Gjk
distance iterations - See Also:
setMaxIterations(int)
-
setMaxIterations
@Deprecated public void setMaxIterations(int maxIterations)
Deprecated.replaced withsetMaxDistanceIterations(int)
since 3.3.0Sets the maximum number of iterations theGjk
algorithm will perform when computing the distance between two separated bodies.Valid values are in the range [5, ∞].
- Parameters:
maxIterations
- the maximum number ofGjk
iterations- Throws:
IllegalArgumentException
- if maxIterations is less than 5
-
-