add Circle

This commit is contained in:
ez_lcw 2023-07-04 19:02:02 +08:00
parent f904019d40
commit e78ee9eda3
2 changed files with 55 additions and 1 deletions

View File

@ -2,12 +2,50 @@ function sqr(x) {
return x * x;
}
export class Circle {
constructor(o, r) {
this.o = o;
this.r = r;
}
clone() {
return new Circle(this.o.clone(), this.r);
}
equal(c) {
return this.o.equal(c.o) && this.r == c.r;
}
static intersect(a, b) {
return a.o.sub(b.o).norm() <= sqr(a.r + b.r);
}
static collisionElimation(a, b) {
if (!Circle.intersect(a, b)) { return false; }
const d = a.o.distanceTo(b.o);
const ad = (sqr(a.r) - sqr(b.r) + sqr(d)) / (2 * d);
const bd = d - ad;
const v = b.o.sub(a.o);
a.o.subTo(v.adjust(a.r - ad));
b.o.addTo(v.adjust(b.r - bd));
return true;
}
}
export class Vec2 {
constructor(x, y) {
this.x = x || 0;
this.y = y || 0;
}
adjust(len) {
return this.mul(len / this.abs());
}
distanceTo(b) {
return this.sub(b).abs();
}
add(y) {
return new Vec2(this.x + y.x, this.y + y.y);
}

View File

@ -1,5 +1,5 @@
import assert from 'node:assert';
import { Vec2 } from '../src/2d.js';
import { Vec2, Circle } from '../src/2d.js';
describe('Vec2', function () {
it('construct', function() {
@ -49,4 +49,20 @@ describe('Vec2', function () {
assert.equal(p.dot(q), 10);
assert.equal(p.cross(q), -10);
});
it('circle intersect', function() {
let c1 = new Circle(new Vec2(0, 0), 1);
let c2 = new Circle(new Vec2(0, 1.5), 1);
let c3 = new Circle(new Vec2(2, 2), 1);
assert.ok(Circle.intersect(c1, c2));
assert.ok(!Circle.intersect(c1, c3));
});
it('circle collision elimation', function() {
let c1 = new Circle(new Vec2(0, 0), 1);
let c2 = new Circle(new Vec2(0, 1.5), 1);
assert.ok(Circle.collisionElimation(c1, c2));
assert.ok(c1.equal(new Circle(new Vec2(0, -.25), 1)));
assert.ok(c2.equal(new Circle(new Vec2(0, 1.75), 1)));
});
});