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;
|
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 {
|
export class Vec2 {
|
||||||
constructor(x, y) {
|
constructor(x, y) {
|
||||||
this.x = x || 0;
|
this.x = x || 0;
|
||||||
this.y = y || 0;
|
this.y = y || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adjust(len) {
|
||||||
|
return this.mul(len / this.abs());
|
||||||
|
}
|
||||||
|
|
||||||
|
distanceTo(b) {
|
||||||
|
return this.sub(b).abs();
|
||||||
|
}
|
||||||
|
|
||||||
add(y) {
|
add(y) {
|
||||||
return new Vec2(this.x + y.x, this.y + y.y);
|
return new Vec2(this.x + y.x, this.y + y.y);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import assert from 'node:assert';
|
import assert from 'node:assert';
|
||||||
import { Vec2 } from '../src/2d.js';
|
import { Vec2, Circle } from '../src/2d.js';
|
||||||
|
|
||||||
describe('Vec2', function () {
|
describe('Vec2', function () {
|
||||||
it('construct', function() {
|
it('construct', function() {
|
||||||
@ -49,4 +49,20 @@ describe('Vec2', function () {
|
|||||||
assert.equal(p.dot(q), 10);
|
assert.equal(p.dot(q), 10);
|
||||||
assert.equal(p.cross(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