openarras/src/2d.js
2023-07-04 19:33:22 +08:00

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;
}
};