top of page
Search
cedarcantab

Understanding 2D Physics Engines with Phaser 3, Part 20: Clipping Method

Updated: May 20, 2023


Extending the Clipping Method to deal with Circles


In the prior post we successfully completed the implementation of the clipping method to generate contact points between two colliding convex polygons.



In this post we look at how to extend the code so that it can also return contact points between a polygon and a circle (we will build on the circle class, polygon class and the SAT class from this post here).


Obtaining the Farthest Feature


Extending the code starts off by identifying whether the collision is a polygon vs polygon, polygon vs circle or circle vs circle.


Let us consider the following situation of a convex polygon (rectangle) colliding against a circle.











To start with the conclusion, in case of polygon vs circle collision, there is only one contact point - and that contact point is deemed to be the farthest point along the collision normal on the circumference of the circle.


In terms of implementation, remember from the previous post that the clipping method starts off by identifying the colliding features. In the case of polygon vs polygon collisions, the colliding features are both edges. We amend the piece of code that looks for the farthest features so that if either of the pair of objects is a circle, we take the returned colliding feature of the circle (ie the farthest point) as the contact point. This simple logic returns a robust contact point.


PointFeature

As the getFarthestFeature method for Polygon class returned an EdgeFeature object, we will create a PointFeature object for a circle, which will be the output of the circle equivalent of the getFarthestFeature method.


class PointFeature {
  constructor(v) {
    this.point = new Phaser.Math.Vector2(v.x, v.y);
  }  
  
}

getFarthestFeature method


  getFarthestFeature( v) {
		// obtain the farthest point along the given vector
		var farthest = this.getFarthestPoint(v);
		// for a circle the farthest feature along a vector will always be a vertex
		return new PointFeature(farthest);

  }
	
  getFarthestPoint( vector) {
		// make sure the axis is normalized
		var nAxis = vector.clone().normalize();
		// get the transformed center
		var center = this.position.clone();
		// add the radius along the vector to the center to get the farthest point
		center.x += this.radius * nAxis.x;
		center.y += this.radius * nAxis.y;
		// return the new point
		return center;

  }


ClipingSolver

The only change needed to the ClippingSolver code since the last version is to amend the code identifying the colliding features at the beginning.


 getContact(boxA, boxB, manifold) {
 
    // get the penetration normal
    var n = manifold.normal;
    
    // get the reference feature for the first convex shape
    var e1 = boxA.getFarthestFeature(n);
    // check for vertex
    if (e1 instanceof PointFeature) {
      manifold.contacts.push(e1.point);
      manifold.numContacts = manifold.contacts.length;
      return true;
    }

    var ne = n.clone().negate()
    // get the reference feature for the second convex shape
    var e2 = boxB.getFarthestFeature(ne);
     // check for vertex
     if (e2 instanceof PointFeature) {
      manifold.contacts.push(e2.point);
      manifold.numContacts = manifold.contacts.length;
      return true;
    }


CodePen




3 views0 comments

Recent Posts

See All

p2 naive broadphase

var Broadphase = require('../collision/Broadphase'); module.exports = NaiveBroadphase; /** * Naive broadphase implementation. Does N^2...

sopiro motor constranit

import { Matrix2, Vector2 } from "./math.js"; import { RigidBody } from "./rigidbody.js"; import { Settings } from "./settings.js";...

Comments


記事: Blog2_Post
bottom of page