220 lines
4.8 KiB
JavaScript
220 lines
4.8 KiB
JavaScript
Pt = Point = class Point {
|
|
constructor(x, y, z) {
|
|
this.is3D = z != undefined
|
|
this.x = x
|
|
this.y = y
|
|
this.z = z
|
|
}
|
|
|
|
equals(pt) { return this.x == pt.x && this.y == pt.y && (!this.is3D || this.z == pt.z) }
|
|
|
|
isIn(arr) { return this.indexIn(arr) != -1 }
|
|
indexIn(arr) { return arr.findIndex((pt) => this.equals(pt)) }
|
|
lastIndexIn(arr) { return arr.findLastIndex((pt) => this.equals(pt)) }
|
|
|
|
up() { return new Point(this.x, this.y - 1) }
|
|
down() { return new Point(this.x, this.y + 1) }
|
|
left() { return new Point(this.x - 1, this.y) }
|
|
right() { return new Point(this.x + 1, this.y) }
|
|
upleft() { return new Point(this.x - 1, this.y - 1) }
|
|
upright() { return new Point(this.x + 1, this.y - 1) }
|
|
downleft() { return new Point(this.x - 1, this.y + 1) }
|
|
downright() { return new Point(this.x + 1, this.y + 1) }
|
|
above() { return new Point(this.x, this.y, this.z - 1) }
|
|
below() { return new Point(this.x, this.y, this.z + 1) }
|
|
|
|
u() { return this.up() }
|
|
d() { return this.down() }
|
|
l() { return this.left() }
|
|
r() { return this.right() }
|
|
ul() { return this.upleft() }
|
|
ur() { return this.upright() }
|
|
dl() { return this.downleft() }
|
|
dr() { return this.downright() }
|
|
|
|
getUnfilteredAdjNeighborsIncSelf() {
|
|
if (!this.is3D) {
|
|
return new PointArray(
|
|
this.u(),
|
|
this.l(),
|
|
this.copy(),
|
|
this.r(),
|
|
this.d())
|
|
} else {
|
|
return new PointArray(
|
|
this.above(),
|
|
this.u(),
|
|
this.l(),
|
|
this.copy(),
|
|
this.r(),
|
|
this.d(),
|
|
this.below())
|
|
}
|
|
}
|
|
|
|
getUnfilteredWingNeighborsIncSelf() {
|
|
if (!this.is3D) {
|
|
console.error("Can't get wing neighbors of 2D point")
|
|
}
|
|
|
|
return new PointArray(
|
|
this.u().above(),
|
|
this.l().above(),
|
|
this.r().above(),
|
|
this.d().above(),
|
|
this.ul(),
|
|
this.ur(),
|
|
this.copy(),
|
|
this.dl(),
|
|
this.dr(),
|
|
this.u().below(),
|
|
this.l().below(),
|
|
this.r().below(),
|
|
this.d().below())
|
|
}
|
|
|
|
getUnfilteredDiagNeighborsIncSelf() {
|
|
if (!this.is3D) {
|
|
return new PointArray(
|
|
this.ul(),
|
|
this.ur(),
|
|
this.copy(),
|
|
this.dl(),
|
|
this.dr())
|
|
} else {
|
|
return new PointArray(
|
|
this.ul().above(),
|
|
this.ur().above(),
|
|
this.dl().above(),
|
|
this.dr().above(),
|
|
this.copy(),
|
|
this.ul().below(),
|
|
this.ur().below(),
|
|
this.dl().below(),
|
|
this.dr().below())
|
|
}
|
|
}
|
|
|
|
getUnfilteredAllNeighborsIncSelf() {
|
|
if (!this.is3D) {
|
|
return new PointArray(
|
|
this.ul(),
|
|
this.u(),
|
|
this.ur(),
|
|
this.l(),
|
|
this.copy(),
|
|
this.r(),
|
|
this.dl(),
|
|
this.d(),
|
|
this.dr())
|
|
} else {
|
|
return new PointArray(
|
|
this.ul().above(),
|
|
this.u().above(),
|
|
this.ur().above(),
|
|
this.l().above(),
|
|
this.above(),
|
|
this.r().above(),
|
|
this.dl().above(),
|
|
this.d().above(),
|
|
this.dr().above(),
|
|
this.ul(),
|
|
this.u(),
|
|
this.ur(),
|
|
this.l(),
|
|
this.copy(),
|
|
this.r(),
|
|
this.dl(),
|
|
this.d(),
|
|
this.dr(),
|
|
this.ul().below(),
|
|
this.u().below(),
|
|
this.ur().below(),
|
|
this.l().below(),
|
|
this.below(),
|
|
this.r().below(),
|
|
this.dl().below(),
|
|
this.d().below(),
|
|
this.dr().below())
|
|
}
|
|
}
|
|
|
|
getUnfilteredAdjNeighbors() { return this.getUnfilteredAdjNeighborsIncSelf().filter((pt) => !this.equals(pt)) }
|
|
getUnfilteredDiagNeighbors() { return this.getUnfilteredDiagNeighborsIncSelf().filter((pt) => !this.equals(pt)) }
|
|
getUnfilteredAllNeighbors() { return this.getUnfilteredAllNeighborsIncSelf().filter((pt) => !this.equals(pt)) }
|
|
|
|
add(pt) { return new Point(this.x + pt.x, this.y + pt.y, this.is3D ? this.z + pt.z : undefined) }
|
|
addMut(pt) {
|
|
this.x += pt.x
|
|
this.y += pt.y
|
|
|
|
if (this.is3D) {
|
|
this.z += pt.z
|
|
}
|
|
|
|
return this
|
|
}
|
|
|
|
sub(pt) { return new Point(this.x - pt.x, this.y - pt.y, this.is3D ? this.z - pt.z : undefined) }
|
|
subMut(pt) {
|
|
this.x -= pt.x
|
|
this.y -= pt.y
|
|
|
|
if (this.is3D) {
|
|
this.z -= pt.z
|
|
}
|
|
|
|
return this
|
|
}
|
|
|
|
mult(n) { return new Point(this.x * n, this.y * n, this.is3D ? this.z * n : undefined) }
|
|
multMut(n) {
|
|
this.x *= n
|
|
this.y *= n
|
|
|
|
if (this.is3D) {
|
|
this.z *= n
|
|
}
|
|
|
|
return this
|
|
}
|
|
|
|
neg(n) { return this.mult(-1) }
|
|
negMut(n) { return this.multMut(-1) }
|
|
|
|
squaredMag() { return this.x * this.x + this.y * this.y + (this.is3D ? this.z * this.z : 0) }
|
|
mag() { return Math.sqrt(this.squaredMag()) }
|
|
|
|
squaredDist(pt) { return this.sub(pt).squaredMag() }
|
|
dist(pt) { return this.sub(pt).mag() }
|
|
|
|
readingOrderCompare(pt) {
|
|
if (this.is3D && this.z < pt.z) {
|
|
return -1
|
|
} else if (this.is3D && this.z > pt.z) {
|
|
return 1
|
|
} else if (this.y < pt.y) {
|
|
return -1
|
|
} else if (this.y > pt.y) {
|
|
return 1
|
|
} else if (this.x < pt.x) {
|
|
return -1
|
|
} else if (this.x > pt.x) {
|
|
return 1
|
|
} else {
|
|
return 0
|
|
}
|
|
}
|
|
|
|
copy() { return new Point(this.x, this.y, this.z) }
|
|
toString() { return this.x + "," + this.y + (this.is3D ? "," + this.z : "") }
|
|
}
|
|
|
|
Point.NONE = new Point(null, null)
|
|
|
|
P = function P(...args) {
|
|
return new Point(...args)
|
|
}
|
|
|
|
|