123 lines
1.8 KiB
JavaScript
123 lines
1.8 KiB
JavaScript
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);
|
|
}
|
|
|
|
sub(y) {
|
|
return new Vec2(this.x - y.x, this.y - y.y);
|
|
}
|
|
|
|
mul(k) {
|
|
return new Vec2(this.x * k, this.y * k);
|
|
}
|
|
|
|
conj() {
|
|
return new Vec2(this.x, -this.y);
|
|
}
|
|
|
|
yx() {
|
|
return new Vec2(this.y, this.x);
|
|
}
|
|
|
|
complexMul(y) {
|
|
return new Vec2(this.x * y.x - this.y * y.y, this.x * y.y + this.y * y.x);
|
|
}
|
|
|
|
complexInv() {
|
|
return this.conj().mul(1 / this.norm());
|
|
}
|
|
|
|
complexDiv(y) {
|
|
return this.complexMul(y.complexInv());
|
|
}
|
|
|
|
addTo(y) {
|
|
this.x += y.x;
|
|
this.y += y.y;
|
|
}
|
|
|
|
subTo(y) {
|
|
this.x -= y.x;
|
|
this.y -= y.y;
|
|
}
|
|
|
|
mulTo(k) {
|
|
this.x *= k;
|
|
this.y *= k;
|
|
}
|
|
|
|
equal(y) {
|
|
return this.x == y.x && this.y == y.y;
|
|
}
|
|
|
|
arg() {
|
|
return Math.atan2(this.y, this.x);
|
|
}
|
|
|
|
abs() {
|
|
return Math.sqrt(this.norm());
|
|
}
|
|
|
|
norm() {
|
|
return sqr(this.x) + sqr(this.y);
|
|
}
|
|
|
|
clone() {
|
|
return new Vec2(this.x, this.y);
|
|
}
|
|
|
|
dot(y) {
|
|
return this.x * y.x + this.y * y.y;
|
|
}
|
|
|
|
cross(y) {
|
|
return this.x * y.y - this.y * y.x;
|
|
}
|
|
}; |