intersectCirclePolygon static method

({double depth, Vector2 normal}) intersectCirclePolygon(
  1. ShapeHitbox shapeA,
  2. CircleHitbox shapeB,
  3. PositionComponent other, {
  4. bool inverted = false,
})

Implementation

static ({Vector2 normal, double depth}) intersectCirclePolygon(
  ShapeHitbox shapeA,
  CircleHitbox shapeB,
  PositionComponent other, {
  bool inverted = false,
}) {
  var normal = Vector2.zero();
  var depth = double.maxFinite;
  var axis = Vector2.zero();
  var axisDepth = 0.0;

  final vertices = CollisionUtil.getPolygonVertices(shapeA);

  for (var i = 0; i < vertices.length; i++) {
    final va = vertices[i];
    final vb = vertices[(i + 1) % vertices.length];

    final edge = vb - va;
    axis = Vector2(-edge.y, edge.x);
    axis = axis.normalized();

    final pA = CollisionUtil.projectVertices(vertices, axis);
    final pB = CollisionUtil.projectCircle(
      shapeB.absoluteCenter,
      shapeB.radius,
      axis,
    );

    axisDepth = min(pB.max - pA.min, pA.max - pB.min);

    if (axisDepth < depth) {
      depth = axisDepth;
      normal = axis;
    }
  }

  final cpIndex = CollisionUtil.findClosesPointOnPolygon(
    shapeB.absoluteCenter,
    vertices,
  );
  final cp = vertices[cpIndex];

  axis = cp - shapeB.absoluteCenter;
  axis = axis.normalized();

  final pA = CollisionUtil.projectVertices(vertices, axis);
  final pB = CollisionUtil.projectCircle(
    shapeB.absoluteCenter,
    shapeB.radius,
    axis,
  );

  axisDepth = min(pB.max - pA.min, pA.max - pB.min);

  if (axisDepth < depth) {
    depth = axisDepth;
    normal = axis;
  }

  final direction = inverted
      ? shapeA.absoluteCenter - shapeB.absoluteCenter
      : shapeB.absoluteCenter - shapeA.absoluteCenter;

  if (direction.dot(normal) < 0) {
    normal = -normal;
  }

  return (normal: normal, depth: depth);
}