fix circle

This commit is contained in:
Schluffe
2026-04-06 18:38:31 +02:00
parent e0bd8a2fc7
commit 019304d25a
+51 -12
View File
@@ -24,12 +24,12 @@ type CollisionBuffer = {
type Collide = ( type Collide = (
collision: Collision, collision: Collision,
cid: string,
colliderA: Collider, colliderA: Collider,
positionA: Vector, positionA: Vector,
velocityA: Vector, velocityA: Vector,
colliderB: Collider, colliderB: Collider,
positionB: Vector, positionB: Vector,
delta: number,
) => void; ) => void;
export type Collider = { export type Collider = {
@@ -165,50 +165,89 @@ function sweptAABB(
return time; return time;
} }
function collideWithCirle( function collideWithCircle(
collision: Collision, collision: Collision,
cid: string,
colliderA: Collider, colliderA: Collider,
positionA: Vector, positionA: Vector,
velocityA: Vector, velocityA: Vector,
colliderB: Collider, colliderB: Collider,
positionB: Vector, positionB: Vector,
) {} delta: number,
) {
const ax = positionA.x + colliderA.offset.x;
const ay = positionA.y + colliderA.offset.y;
const bx = positionB.x + colliderB.offset.x;
const by = positionB.y + colliderB.offset.y;
const inflRadius =
(colliderA.body as Circle).radius + (colliderB.body as Circle).radius;
const dx = ax - bx;
const dy = ay - by;
const disX = velocityA.x * delta;
const disY = velocityA.y * delta;
const a = disX * disX + disY * disY;
const b = 2 * (dx * disX + dy * disY);
const c = dx * dx + dy * dy - inflRadius * inflRadius;
let disc = b * b - 4 * a * c;
if (disc >= 0) {
disc = Math.sqrt(disc);
const time = (-b - disc) / (2 * a);
if (time >= 0 && time <= 1) {
const nx = dx + disX * time;
const ny = dy + disY * time;
const inv = 1.0 / Math.sqrt(nx * nx + ny * ny);
collision.normal.x = nx * inv;
collision.normal.y = ny * inv;
collision.time = time;
return;
}
}
collision.cid = "";
collision.time = 0;
collision.normal.x = 0;
collision.normal.y = 0;
}
function collideWithRect( function collideWithRect(
collision: Collision, collision: Collision,
cid: string,
colliderA: Collider, colliderA: Collider,
positionA: Vector, positionA: Vector,
velocityA: Vector, velocityA: Vector,
colliderB: Collider, colliderB: Collider,
positionB: Vector, positionB: Vector,
delta: number,
) {} ) {}
function collideWithPolygon( function collideWithPolygon(
collision: Collision, collision: Collision,
cid: string,
colliderA: Collider, colliderA: Collider,
positionA: Vector, positionA: Vector,
velocityA: Vector, velocityA: Vector,
colliderB: Collider, colliderB: Collider,
positionB: Vector, positionB: Vector,
delta: number,
) {} ) {}
const circleCollide: Array<Collide> = [ const circleCollide: Array<Collide> = [
collideWithCirle, collideWithCircle,
collideWithRect, collideWithRect,
collideWithPolygon, collideWithPolygon,
]; ];
const rectCollide: Array<Collide> = [ const rectCollide: Array<Collide> = [
collideWithCirle, collideWithCircle,
collideWithRect, collideWithRect,
collideWithPolygon, collideWithPolygon,
]; ];
const polygonCollide: Array<Collide> = [ const polygonCollide: Array<Collide> = [
collideWithCirle, collideWithCircle,
collideWithRect, collideWithRect,
collideWithPolygon, collideWithPolygon,
]; ];
@@ -286,36 +325,36 @@ export function moveAndCollide(
case CIRCLE: { case CIRCLE: {
circleCollide[otherColl.shape]( circleCollide[otherColl.shape](
collision, collision,
cid,
selfColl, selfColl,
selfPos, selfPos,
velocity, velocity,
otherColl, otherColl,
otherPos, otherPos,
delta,
); );
break; break;
} }
case RECT: { case RECT: {
rectCollide[otherColl.shape]( rectCollide[otherColl.shape](
collision, collision,
cid,
selfColl, selfColl,
selfPos, selfPos,
velocity, velocity,
otherColl, otherColl,
otherPos, otherPos,
delta,
); );
break; break;
} }
case POLYGON: { case POLYGON: {
polygonCollide[otherColl.shape]( polygonCollide[otherColl.shape](
collision, collision,
cid,
selfColl, selfColl,
selfPos, selfPos,
velocity, velocity,
otherColl, otherColl,
otherPos, otherPos,
delta,
); );
break; break;
} }