collideEdgeAndCircle method
void
collideEdgeAndCircle(
- Manifold manifold,
- EdgeShape edgeA,
- Transform xfA,
- CircleShape circleB,
- Transform xfB,
Implementation
void collideEdgeAndCircle(
Manifold manifold,
EdgeShape edgeA,
Transform xfA,
CircleShape circleB,
Transform xfB,
) {
manifold.pointCount = 0;
// Compute circle in frame of edge
// Vec2 Q = MulT(xfA, Mul(xfB, circleB.p));
_temp.setFrom(Transform.mulVec2(xfB, circleB.position));
_q.setFrom(Transform.mulTransVec2(xfA, _temp));
final a = edgeA.vertex1;
final b = edgeA.vertex2;
_e
..setFrom(b)
..sub(a);
// Barycentric coordinates
final u = _e.dot(
_temp
..setFrom(b)
..sub(_q),
);
final v = _e.dot(
_temp
..setFrom(_q)
..sub(a),
);
final radius = edgeA.radius + circleB.radius;
_cf.indexB = 0;
_cf.typeB = ContactIDType.vertex.index & 0xFF;
// Region A
if (v <= 0.0) {
final P = a;
_d
..setFrom(_q)
..sub(P);
final dd = _d.dot(_d);
if (dd > radius * radius) {
return;
}
// Is there an edge connected to A?
if (edgeA.hasVertex0) {
final a1 = edgeA.vertex0;
final b1 = a;
_e1
..setFrom(b1)
..sub(a1);
final u1 = _e1.dot(
_temp
..setFrom(b1)
..sub(_q),
);
// Is the circle in Region AB of the previous edge?
if (u1 > 0.0) {
return;
}
}
_cf.indexA = 0;
_cf.typeA = ContactIDType.vertex.index & 0xFF;
manifold.pointCount = 1;
manifold.type = ManifoldType.circles;
manifold.localNormal.setZero();
manifold.localPoint.setFrom(P);
// manifold.points[0].id.key = 0;
manifold.points[0].id.set(_cf);
manifold.points[0].localPoint.setFrom(circleB.position);
return;
}
// Region B
if (u <= 0.0) {
final p = b;
_d
..setFrom(_q)
..sub(p);
final dd = _d.dot(_d);
if (dd > radius * radius) {
return;
}
// Is there an edge connected to B?
if (edgeA.hasVertex3) {
final b2 = edgeA.vertex3;
final a2 = b;
final e2 = _e1;
e2
..setFrom(b2)
..sub(a2);
final v2 = e2.dot(
_temp
..setFrom(_q)
..sub(a2),
);
// Is the circle in Region AB of the next edge?
if (v2 > 0.0) {
return;
}
}
_cf.indexA = 1;
_cf.typeA = ContactIDType.vertex.index & 0xFF;
manifold.pointCount = 1;
manifold.type = ManifoldType.circles;
manifold.localNormal.setZero();
manifold.localPoint.setFrom(p);
manifold.points[0].id.set(_cf);
manifold.points[0].localPoint.setFrom(circleB.position);
return;
}
// Region AB
final den = _e.dot(_e);
assert(den > 0.0);
// Vec2 P = (1.0f / den) * (u * A + v * B);
_p
..setFrom(a)
..scale(u)
..add(
_temp
..setFrom(b)
..scale(v),
);
_p.scale(1.0 / den);
_d
..setFrom(_q)
..sub(_p);
final dd = _d.dot(_d);
if (dd > radius * radius) {
return;
}
_n.x = -_e.y;
_n.y = _e.x;
if (_n.dot(
_temp
..setFrom(_q)
..sub(a),
) <
0.0) {
_n.setValues(-_n.x, -_n.y);
}
_n.normalize();
_cf.indexA = 0;
_cf.typeA = ContactIDType.face.index & 0xFF;
manifold.pointCount = 1;
manifold.type = ManifoldType.faceA;
manifold.localNormal.setFrom(_n);
manifold.localPoint.setFrom(a);
// manifold.points[0].id.key = 0;
manifold.points[0].id.set(_cf);
manifold.points[0].localPoint.setFrom(circleB.position);
}