add Circle
This commit is contained in:
parent
f904019d40
commit
e78ee9eda3
38
src/2d.js
38
src/2d.js
@ -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);
|
||||
}
|
||||
|
@ -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)));
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user