jsdk-offical
Version:
JSDK is the most comprehensive TypeScript framework, like JDK.
1,316 lines • 79.2 kB
JavaScript
//# sourceURL=../dist/jsmath.js
//JSDK 2.7.0 MIT
var JS;
(function (JS) {
let math;
(function (math) {
class Coords2 {
static rotate(p, rad) {
let pt = this.rotateX(p, rad);
return this.rotateY(pt, rad);
}
static rotateX(p, rad) {
let x = p[0], y = p[1];
return [x * Math.cos(rad) - y * Math.sin(rad), y];
}
static rotateY(p, rad) {
let x = p[0], y = p[1];
return [x, x * Math.sin(rad) + y * Math.cos(rad)];
}
static translate(p, dx, dy) {
let pt = this.translateX(p, dx);
return this.translateY(pt, dy);
}
static translateX(p, delta) {
let x = p[0], y = p[1];
return [x + delta, y];
}
static translateY(p, delta) {
let x = p[0], y = p[1];
return [x, y + delta];
}
}
math.Coords2 = Coords2;
})(math = JS.math || (JS.math = {}));
})(JS || (JS = {}));
var Coords2 = JS.math.Coords2;
var JS;
(function (JS) {
let math;
(function (math) {
class Floats {
static equal(n1, n2, eps = this.EQUAL_PRECISION) {
let d = n1 - n2, n = d < 0 ? -d : d;
return n <= eps;
}
static greater(n1, n2, eps = this.EQUAL_PRECISION) {
if (this.equal(n1, n2, eps))
return false;
return n1 > n2;
}
static greaterEqual(n1, n2, eps = this.EQUAL_PRECISION) {
if (this.equal(n1, n2, eps))
return true;
return n1 > n2;
}
static less(n1, n2, eps = this.EQUAL_PRECISION) {
if (this.equal(n1, n2, eps))
return false;
return n1 < n2;
}
static lessEqual(n1, n2, eps = this.EQUAL_PRECISION) {
if (this.equal(n1, n2, eps))
return true;
return n1 < n2;
}
}
Floats.EQUAL_PRECISION = 0.0001;
math.Floats = Floats;
})(math = JS.math || (JS.math = {}));
})(JS || (JS = {}));
var Floats = JS.math.Floats;
var JS;
(function (JS) {
let math;
(function (math) {
class Point2 {
constructor(x, y) {
this.x = x || 0;
this.y = y || 0;
}
static toPoint(p) {
return new Point2().set(p);
}
static toArray(p) {
return p instanceof Point2 ? p.toArray() : p;
}
static polar2xy(d, rad) {
let x, y;
switch (rad / Math.PI) {
case 0:
x = d;
y = 0;
break;
case 0.5:
x = 0;
y = d;
break;
case 1:
x = -d;
y = 0;
break;
case 1.5:
x = 0;
y = -d;
break;
case 2:
x = d;
y = 0;
break;
default:
x = d * Math.cos(rad);
y = d * Math.sin(rad);
}
return [x.round(12), y.round(12)];
}
static xy2polar(x, y) {
return {
d: Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)),
a: Point2.radian(x, y)
};
}
static equal(x1, y1, x2, y2) {
if (arguments.length > 3)
return math.Floats.equal(x1, x2) && math.Floats.equal(y1, y2);
if (x1 == void 0 && x1 === y1)
return true;
if (x1 == void 0 || y1 == void 0)
return false;
let px1 = x1[0], py1 = x1[1], px2 = y1[0], py2 = y1[1];
return math.Floats.equal(px1, px2) && math.Floats.equal(py1, py2);
}
static isOrigin(x, y) {
return this.equal(x, y, 0, 0);
}
static distanceSq(x1, y1, x2, y2) {
let dx = x1 - x2, dy = y1 - y2;
return dx * dx + dy * dy;
}
static distance(x1, y1, x2, y2) {
return Math.sqrt(this.distanceSq(x1, y1, x2, y2));
}
static radian(x1, y1, x2, y2) {
let xx = x2 || 0, yy = y2 || 0;
if (this.isOrigin(x1, y1) && Point2.isOrigin(xx, yy))
return 0;
return Math.atan2(y1 - yy, x1 - xx);
}
set(p) {
if (Types.isArray(p)) {
this.x = p[0];
this.y = p[1];
}
else if ('x' in p) {
this.x = p.x;
this.y = p.y;
}
else {
let pp = Point2.polar2xy(p.d, p.a);
this.x = pp[0];
this.y = pp[1];
}
return this;
}
toPolar() {
return Point2.xy2polar(this.x, this.y);
}
toArray() {
return [this.x, this.y];
}
clone() {
return new Point2(this.x, this.y);
}
equals(p) {
return math.Floats.equal(this.x, p.x) && math.Floats.equal(this.y, p.y);
}
radian() {
return Point2.radian(this.x, this.y);
}
distanceSq(x, y) {
return Point2.distanceSq(this.x, this.y, x, y);
}
distance(x, y) {
return Math.sqrt(this.distanceSq(x, y));
}
distanceL1(x, y) {
return Math.abs(this.x - x) + Math.abs(this.y - y);
}
distanceLinf(x, y) {
return Math.max(Math.abs(this.x - x), Math.abs(this.y - y));
}
translate(x, y) {
this.x += x;
this.y += y;
return this;
}
moveTo(x, y) {
this.x = x;
this.y = y;
return this;
}
clamp(min, max) {
let T = this;
if (T.x > max) {
T.x = max;
}
else if (T.x < min) {
T.x = min;
}
if (T.y > max) {
T.y = max;
}
else if (T.y < min) {
T.y = min;
}
return T;
}
clampMin(min) {
let T = this;
if (T.x < min)
T.x = min;
if (T.y < min)
T.y = min;
return T;
}
clampMax(max) {
let T = this;
if (T.x > max)
T.x = max;
if (T.y > max)
T.y = max;
return T;
}
toward(step, rad) {
let p = Point2.polar2xy(step, rad);
return this.translate(p[0], p[1]);
}
}
Point2.ORIGIN = new Point2(0, 0);
math.Point2 = Point2;
})(math = JS.math || (JS.math = {}));
})(JS || (JS = {}));
var Point2 = JS.math.Point2;
var JS;
(function (JS) {
let math;
(function (math) {
let M = Math;
class Point3 {
constructor(x, y, z) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
}
static toPoint(p) {
return new Point3().set(p);
}
static equal(x1, y1, z1, x2, y2, z2) {
return math.Floats.equal(x1, x2) && math.Floats.equal(y1, y2) && math.Floats.equal(z1, z2);
}
static isOrigin(x, y, z) {
return this.equal(x, y, z, 0, 0, 0);
}
static polar2xyz(d, az, ax) {
let tmp = d * M.sin(az);
return [tmp * M.cos(ax), tmp * M.sin(ax), d * M.cos(az)];
}
static xyz2polar(x, y, z) {
let d = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2));
return {
d: d,
az: M.acos(z / d),
ax: M.atan(y / x)
};
}
static distanceSq(x1, y1, z1, x2, y2, z2) {
let dx = x1 - x2, dy = y1 - y2, dz = z1 - z2;
return dx * dx + dy * dy + dz * dz;
}
static distance(x1, y1, z1, x2, y2, z2) {
return Math.sqrt(this.distanceSq(x1, y1, z1, x2, y2, z2));
}
set(p) {
if (Types.isArray(p)) {
this.x = p[0];
this.y = p[1];
this.z = p[2];
}
else {
p = p;
this.x = p.x;
this.y = p.y;
this.z = p.z;
}
return this;
}
equals(p) {
return math.Floats.equal(this.x, p.x) && math.Floats.equal(this.y, p.y) && math.Floats.equal(this.z, p.z);
}
clone() {
return new Point3(this.x, this.y, this.z);
}
distanceSq(p) {
let dx = this.x - p.x, dy = this.y - p.y, dz = this.z - p.z;
return dx * dx + dy * dy + dz * dz;
}
distance(p) {
return Math.sqrt(this.distanceSq(p));
}
distanceL1(p) {
return Math.abs(this.x - p.x) + Math.abs(this.y - p.y) + Math.abs(this.z - p.z);
}
distanceLinf(p) {
let tmp = Math.max(Math.abs(this.x - p.x), Math.abs(this.y - p.y));
return Math.max(tmp, Math.abs(this.z - p.z));
}
toArray() {
return [this.x, this.y, this.z];
}
moveTo(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
return this;
}
clamp(min, max) {
let T = this;
if (T.x > max) {
T.x = max;
}
else if (T.x < min) {
T.x = min;
}
if (T.y > max) {
T.y = max;
}
else if (T.y < min) {
T.y = min;
}
if (T.z > max) {
T.z = max;
}
else if (T.z < min) {
T.z = min;
}
return T;
}
clampMin(min) {
let T = this;
if (T.x < min)
T.x = min;
if (T.y < min)
T.y = min;
if (T.z < min)
T.z = min;
return T;
}
clampMax(max) {
let T = this;
if (T.x > max)
T.x = max;
if (T.y > max)
T.y = max;
if (T.z > max)
T.z = max;
return T;
}
}
math.Point3 = Point3;
})(math = JS.math || (JS.math = {}));
})(JS || (JS = {}));
var Point3 = JS.math.Point3;
var JS;
(function (JS) {
let math;
(function (math) {
let PI = Math.PI;
class Radians {
static rad2deg(rad, limit) {
let r = rad * 180 / PI;
return limit ? this.positive(r) : r;
}
static deg2rad(deg) {
return deg * PI / 180;
}
static positive(rad) {
return rad < 0 ? this.ONE_CYCLE + rad : rad;
}
static equal(rad1, rad2) {
return rad1 == rad2 || math.Floats.equal(this.positive(rad1) % PI, this.positive(rad2) % PI, 1e-12);
}
static reverse(rad) {
return rad < PI ? rad + PI : rad - PI;
}
}
Radians.EAST = 0;
Radians.SOUTH = 0.5 * PI;
Radians.WEST = PI;
Radians.NORTH = 1.5 * PI;
Radians.ONE_CYCLE = 2 * PI;
math.Radians = Radians;
})(math = JS.math || (JS.math = {}));
})(JS || (JS = {}));
var Radians = JS.math.Radians;
var JS;
(function (JS) {
let math;
(function (math) {
class Vector2 {
constructor(x, y) {
this.x = x || 0;
this.y = y || 0;
}
static toVector(p1, p2) {
let l = arguments.length;
if (l == 1) {
let line = p1;
return new Vector2().set(line.p1(), line.p2());
}
else {
return new Vector2().set(p1, p2);
}
}
static whichSide(p1, p2, p) {
let v1 = Vector2.toVector(p1, p), v2 = Vector2.toVector(p2, p), rst = Vector2.cross(v1, v2);
if (math.Floats.equal(0, rst))
return 0;
return rst > 0 ? 1 : -1;
}
static cross(v1, v2) {
return v1.x * v2.y - v2.x * v1.y;
}
static lerp(from, to, amount) {
if (amount < 0 || amount > 1)
throw new RangeError();
let x = from.x + amount * (to.x - from.x), y = from.y + amount * (to.y - from.y);
return new Vector2(x, y);
}
set(f, t) {
let l = arguments.length, isA = Types.isArray(f);
this.x = l == 1 ? f.x : isA ? t[0] - f[0] : t.x - f.x;
this.y = l == 1 ? f.y : isA ? t[1] - f[1] : t.y - f.y;
return this;
}
equals(v) {
if (this.isZero() && v.isZero())
return true;
if (this.isZero() || v.isZero())
return false;
return math.Floats.equal(v.lengthSq(), this.lengthSq()) && math.Radians.equal(v.radian(), this.radian());
}
toString() {
return "(" + this.x + "," + this.y + ")";
}
toArray() {
return [this.x, this.y];
}
clone() {
return new Vector2(this.x, this.y);
}
negate() {
this.x = -this.x;
this.y = -this.y;
return this;
}
add(v) {
this.x += v.x;
this.y += v.y;
return this;
}
sub(v) {
this.x -= v.x;
this.y -= v.y;
return this;
}
mul(n) {
this.x *= n;
this.y *= n;
return this;
}
div(n) {
this.x /= n;
this.y /= n;
return this;
}
lengthSq() {
return this.x * this.x + this.y * this.y;
}
length() {
return Math.sqrt(this.lengthSq());
}
dot(v) {
return this.x * v.x + this.y * v.y;
}
normalize() {
return this.div(this.length());
}
radian() {
return math.Point2.radian(this.x, this.y);
}
_angle(v) {
let vv = Vector2.UnitX, vDot = v.dot(vv) / (v.length() * vv.length());
if (vDot < -1.0)
vDot = -1.0;
if (vDot > 1.0)
vDot = 1.0;
return Math.acos(vDot);
}
angle(v) {
if (v && v.isZero() && this.isZero())
throw new RangeError('Can\'t with zero vector');
return Math.abs(this._angle(this) - this._angle(v));
}
isZero() {
return this.x == 0 && this.y == 0;
}
verticalTo(v) {
return math.Radians.equal(this.angle(v), Math.PI / 2);
}
parallelTo(v) {
let a = this.angle(v);
return math.Radians.equal(a, 0) || math.Radians.equal(a, Math.PI);
}
getNormL() {
return new Vector2(this.y, -this.x);
}
getNormR() {
return new Vector2(-this.y, this.x);
}
getProject(v) {
var dp = this.dot(v), vv = v.lengthSq();
return new Vector2((dp / vv) * v.x, (dp / vv) * v.y);
}
_rebound(v, leftSide) {
if (this.parallelTo(v))
return this.clone();
let n = leftSide ? v.getNormL() : v.getNormR(), p = this.getProject(n);
return p.sub(this).mul(2).add(this);
}
getReboundL(v) {
return this._rebound(v, true);
}
getReboundR(v) {
return this._rebound(v, false);
}
abs() {
this.x = Math.abs(this.x);
this.y = Math.abs(this.y);
return this;
}
}
Vector2.Zero = new Vector2(0, 0);
Vector2.One = new Vector2(1, 1);
Vector2.UnitX = new Vector2(1, 0);
Vector2.UnitY = new Vector2(0, 1);
math.Vector2 = Vector2;
})(math = JS.math || (JS.math = {}));
})(JS || (JS = {}));
var Vector2 = JS.math.Vector2;
var JS;
(function (JS) {
let math;
(function (math) {
class Vector3 {
constructor(x, y, z) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
}
static toVector(p1, p2) {
return new Vector3().set(p1, p2);
}
static cross(v1, v2) {
let x = v1.y * v2.z - v1.z * v2.y, y = v2.x * v1.z - v2.z * v1.x, z = v1.x * v2.y - v1.y * v2.x;
return new Vector3(x, y, z);
}
static lerp(from, to, amount) {
if (amount < 0 || amount > 1)
throw new RangeError();
let x = from.x + amount * (to.x - from.x), y = from.y + amount * (to.y - from.y), z = from.z + amount * (to.z - from.z);
return new Vector3(x, y, z);
}
set(f, t) {
if (t == void 0) {
this.x = f.x;
this.y = f.y;
this.z = f.z;
}
else {
let is = Types.isArray(f), ff = is ? math.Point3.toPoint(f) : f, tt = is ? math.Point3.toPoint(t) : t;
this.x = tt.x - ff.x;
this.y = tt.y - ff.y;
this.z = tt.z - ff.z;
}
return this;
}
equals(v) {
return math.Floats.equal(v.lengthSq(), this.lengthSq()) && this.x / v.x == this.y / v.y && this.y / v.y == this.z / v.z;
}
toString() {
return "(" + this.x + "," + this.y + "," + this.z + ")";
}
toArray() {
return [this.x, this.y, this.z];
}
clone() {
return new Vector3(this.x, this.y, this.z);
}
negate() {
this.x = -this.x;
this.y = -this.y;
this.z = -this.z;
return this;
}
add(v) {
this.x += v.x;
this.y += v.y;
this.z += v.z;
return this;
}
sub(v) {
this.x -= v.x;
this.y -= v.y;
this.z -= v.z;
return this;
}
mul(n) {
this.x *= n;
this.y *= n;
this.z *= n;
return this;
}
div(n) {
this.x /= n;
this.y /= n;
this.z /= n;
return this;
}
lengthSq() {
return (this.x * this.x + this.y * this.y + this.z * this.z);
}
length() {
return Math.sqrt(this.lengthSq());
}
dot(v) {
return this.x * v.x + this.y * v.y + this.z * v.z;
}
normalize() {
return this.div(this.length());
}
abs() {
this.x = Math.abs(this.x);
this.y = Math.abs(this.y);
this.z = Math.abs(this.z);
return this;
}
}
Vector3.Zero = new Vector3(0, 0, 0);
Vector3.One = new Vector3(1, 1, 1);
Vector3.UnitX = new Vector3(1, 0, 0);
Vector3.UnitY = new Vector3(0, 1, 0);
Vector3.UnitZ = new Vector3(0, 0, 1);
math.Vector3 = Vector3;
})(math = JS.math || (JS.math = {}));
})(JS || (JS = {}));
var Vector3 = JS.math.Vector3;
var JS;
(function (JS) {
let math;
(function (math) {
let geom;
(function (geom) {
let AngleType;
(function (AngleType) {
AngleType[AngleType["ACUTE"] = 0] = "ACUTE";
AngleType[AngleType["RIGHT"] = 1] = "RIGHT";
AngleType[AngleType["OBTUSE"] = 2] = "OBTUSE";
AngleType[AngleType["UNKNOWN"] = 3] = "UNKNOWN";
})(AngleType = geom.AngleType || (geom.AngleType = {}));
let ArcType;
(function (ArcType) {
ArcType[ArcType["OPEN"] = 0] = "OPEN";
ArcType[ArcType["PIE"] = 1] = "PIE";
})(ArcType = geom.ArcType || (geom.ArcType = {}));
let P = math.Point2, V = math.Vector2;
class Shapes {
static crossPoints(line, sh, unClosed) {
let isLine = !(line instanceof geom.Segment), vs = sh.vertexes(), ps = [], size = vs.length, isCollinear = vs.some((p1, i) => {
let b;
if (unClosed) {
if (i == size - 1)
return false;
b = new geom.Segment().set(p1, vs[i + 1]);
}
else {
b = new geom.Segment().set(p1, vs[i < size - 1 ? i + 1 : 0]);
}
if (geom.Line.isCollinearLine(b, line))
return true;
let cp = isLine ? b.crossLine(line) : b.crossSegment(line);
if (cp && ps.findIndex(p => {
return P.equal(p, cp);
}) < 0)
ps.push(cp);
return false;
});
return isCollinear ? [] : ps;
}
static inShape(p, sh, unClosed) {
let vs = sh.vertexes(), size = vs.length, p0 = p instanceof P ? p.toArray() : p, first = 0;
return vs.every((p1, i) => {
let p2;
if (unClosed) {
if (i == size - 1)
return true;
p2 = vs[i + 1];
}
else {
p2 = vs[i < size - 1 ? i + 1 : 0];
}
let s = V.whichSide(p1, p2, p0);
if (s == 0)
return false;
if (i == 0)
first = s;
return s * first > 0;
});
}
static onShape(p, sh, unClosed) {
let vs = sh.vertexes(), size = vs.length, p0 = p instanceof P ? p.toArray() : p;
if (size == 2) {
let p1 = vs[0], p2 = vs[1];
return geom.Segment.inSegment(p1, p2, p0);
}
return vs.some((p1, i) => {
let p2;
if (unClosed) {
if (i == size - 1)
return false;
p2 = vs[i + 1];
}
else {
p2 = vs[i < size - 1 ? i + 1 : 0];
}
return geom.Segment.inSegment(p1, p2, p0);
});
}
}
geom.Shapes = Shapes;
})(geom = math.geom || (math.geom = {}));
})(math = JS.math || (JS.math = {}));
})(JS || (JS = {}));
var Shapes = JS.math.geom.Shapes;
var AngleType = JS.math.geom.AngleType;
var ArcType = JS.math.geom.ArcType;
var JS;
(function (JS) {
let math;
(function (math) {
let P = math.Point2, V = math.Vector2;
let geom;
(function (geom) {
class Line {
constructor(x1, y1, x2, y2) {
this.x1 = x1 || 0;
this.y1 = y1 || 0;
this.x2 = x2 || 0;
this.y2 = y2 || 0;
}
static toLine(p1, p2) {
return new Line().set(p1, p2);
}
static slope(p1, p2) {
let a = p2[0] - p1[0], b = p2[1] - p1[1];
return a == 0 ? null : b / a;
}
static position(p1, p2, p3, p4) {
let T = this, same1 = P.equal(p1, p2), same2 = P.equal(p3, p4);
if (same1 && same2)
return 0;
if (same1 && !same2)
return T.isCollinear(p1, p3, p4) ? 0 : -1;
if (!same1 && same2)
return T.isCollinear(p1, p2, p3) ? 0 : -1;
let k1 = T.slope(p1, p2), k2 = T.slope(p3, p4);
if ((k1 == null && k2 === 0) || (k2 == null && k1 === 0))
return 2;
if ((k1 == null && k2 == null) || math.Floats.equal(k1, k2)) {
return V.whichSide(p1, p2, p3) == 0 ? 0 : -1;
}
else {
return math.Floats.equal(k1 * k2, -1) ? 2 : 1;
}
}
static isCollinear(p1, p2, p3) {
return V.whichSide(p1, p2, p3) == 0;
}
static isCollinearLine(l1, l2) {
let p1 = l1.p1(), p2 = l1.p2(), p3 = l2.p1(), p4 = l2.p2();
return this.isCollinear(p1, p2, p3) && this.isCollinear(p1, p2, p4);
}
static distanceSqToPoint(p1, p2, p) {
let x1 = p1[0], y1 = p1[1], x2 = p2[0], y2 = p2[1], px = p[0], py = p[1];
x2 -= x1;
y2 -= y1;
px -= x1;
py -= y1;
let dot = px * x2 + py * y2, proj = dot * dot / (x2 * x2 + y2 * y2), lenSq = px * px + py * py - proj;
if (lenSq < 0)
lenSq = 0;
return lenSq;
}
static distanceToPoint(p1, p2, p) {
return Math.sqrt(this.distanceSqToPoint(p1, p2, p));
}
toSegment() {
return new geom.Segment(this.x1, this.y1, this.x2, this.y2);
}
toVector() {
return new V(this.x2 - this.x1, this.y2 - this.y1);
}
p1(x, y) {
if (x == void 0)
return [this.x1, this.y1];
this.x1 = x;
this.y1 = y;
return this;
}
p2(x, y) {
if (x == void 0)
return [this.x2, this.y2];
this.x2 = x;
this.y2 = y;
return this;
}
vertexes(ps) {
if (arguments.length == 0) {
return [this.p1(), this.p2()];
}
let p1 = ps[0], p2 = ps[1];
this.p1(p1[0], p1[1]);
return this.p2(p2[0], p2[1]);
}
set(pt1, pt2) {
let len = arguments.length, p1 = len == 1 ? pt1.p1() : pt1, p2 = len == 1 ? pt1.p2() : pt2;
this.x1 = p1[0];
this.y1 = p1[1];
this.x2 = p2[0];
this.y2 = p2[1];
return this;
}
clone() {
return new Line(this.x1, this.y1, this.x2, this.y2);
}
equals(s) {
return Line.position(s.p1(), s.p2(), this.p1(), this.p2()) == 0;
}
isEmpty() {
return this.x1 == 0 && this.y1 == 0 && this.x2 == 0 && this.y2 == 0;
}
inside(s) {
let T = this;
if (!s || T.isEmpty())
return false;
if (Types.isArray(s))
return Line.isCollinear(T.p1(), T.p2(), s);
if (s.isEmpty())
return false;
return s.vertexes().every(p => {
return T.inside(p);
});
}
onside(p) {
return this.inside(p);
}
intersects(s) {
if (!s || this.isEmpty() || s.isEmpty())
return false;
let pos = Line.position(this.p1(), this.p2(), s.p1(), s.p2());
if (pos < 0)
return false;
if (s instanceof geom.Segment) {
return s.crossLine(this) != null;
}
else {
return true;
}
}
bounds() {
return null;
}
slope() {
return (this.y2 - this.y1) / (this.x2 - this.x1);
}
perimeter() {
return Infinity;
}
_cpOfLinePoint(p1, p2, p3) {
let p1p2 = V.toVector(p1, p2), p1p3 = V.toVector(p1, p3), p = p1p3.getProject(p1p2), d = p.length(), pp = P.polar2xy(d, p.radian());
return [pp[0] + p1[0], pp[1] + p1[1]];
}
_cpOfLineLine(p1, p2, p3, p4) {
let x1 = p1[0], y1 = p1[1], x2 = p2[0], y2 = p2[1], x3 = p3[0], y3 = p3[1], x4 = p4[0], y4 = p4[1];
if (Line.position(p1, p2, p3, p4) < 1)
return null;
let x = ((x1 - x2) * (x3 * y4 - x4 * y3) - (x3 - x4) * (x1 * y2 - x2 * y1)) / ((x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4)), y = ((y1 - y2) * (x3 * y4 - x4 * y3) - (x1 * y2 - x2 * y1) * (y3 - y4)) / ((y1 - y2) * (x3 - x4) - (x1 - x2) * (y3 - y4));
return [x, y];
}
_cpOfLineRay(p1, p2, p3, rad) {
let p4 = P.toPoint(p3).toward(10, rad).toArray(), p = this._cpOfLineLine(p1, p2, p3, p4);
if (!p)
return null;
return V.toVector(p3, p4).parallelTo(V.toVector(p3, p)) ? p : null;
}
crossPoint(p) {
return this._cpOfLinePoint(this.p1(), this.p2(), p);
}
crossLine(l) {
return this._cpOfLineLine(this.p1(), this.p2(), l.p1(), l.p2());
}
crossRay(p, rad) {
return this._cpOfLineRay(this.p1(), this.p2(), p, rad);
}
}
Line.X = new Line(0, 0, 1, 0);
Line.Y = new Line(0, 0, 0, 1);
geom.Line = Line;
})(geom = math.geom || (math.geom = {}));
})(math = JS.math || (JS.math = {}));
})(JS || (JS = {}));
var Line = JS.math.geom.Line;
var JS;
(function (JS) {
let math;
(function (math) {
let geom;
(function (geom) {
let M = Math, P = math.Point2, L = geom.Line, V = math.Vector2;
let relativeCCW = function (x1, y1, x2, y2, px, py) {
x2 -= x1;
y2 -= y1;
px -= x1;
py -= y1;
let ccw = px * y2 - py * x2;
if (ccw == 0.0) {
ccw = px * x2 + py * y2;
if (ccw > 0.0) {
px -= x2;
py -= y2;
ccw = px * x2 + py * y2;
if (ccw < 0.0) {
ccw = 0.0;
}
}
}
return (ccw < 0.0) ? -1 : ((ccw > 0.0) ? 1 : 0);
}, inDiagonalRect = (p1, p2, p) => {
if (P.equal(p, p1) || P.equal(p, p2))
return true;
return M.min(p1[0], p2[0]) <= p[0] && p[0] <= M.max(p1[0], p2[0])
&& M.min(p1[1], p2[1]) <= p[1] && p[1] <= M.max(p1[1], p2[1]);
};
class Segment extends geom.Line {
static toSegment(p1, p2) {
return new Segment().set(p1, p2);
}
static inSegment(p1, p2, p) {
return inDiagonalRect(p1, p2, p) && V.whichSide(p1, p2, p) == 0;
}
static distanceSqToPoint(p1, p2, p) {
let x1 = p1[0], y1 = p1[1], x2 = p2[0], y2 = p2[1], px = p[0], py = p[1];
x2 -= x1;
y2 -= y1;
px -= x1;
py -= y1;
let dot = px * x2 + py * y2, proj;
if (dot <= 0.0) {
proj = 0.0;
}
else {
px = x2 - px;
py = y2 - py;
dot = px * x2 + py * y2;
if (dot <= 0.0) {
proj = 0.0;
}
else {
proj = dot * dot / (x2 * x2 + y2 * y2);
}
}
let lenSq = px * px + py * py - proj;
if (lenSq < 0)
lenSq = 0;
return lenSq;
}
static distanceToPoint(p1, p2, p) {
return M.sqrt(this.distanceSqToPoint(p1, p2, p));
}
static intersect(p1, p2, p3, p4) {
let x1 = p1[0], y1 = p1[1], x2 = p2[0], y2 = p2[1], x3 = p3[0], y3 = p3[1], x4 = p4[0], y4 = p4[1];
return ((relativeCCW(x1, y1, x2, y2, x3, y3) *
relativeCCW(x1, y1, x2, y2, x4, y4) <= 0)
&& (relativeCCW(x3, y3, x4, y4, x1, y1) *
relativeCCW(x3, y3, x4, y4, x2, y2) <= 0));
}
toLine() {
return new geom.Line(this.x1, this.y1, this.x2, this.y2);
}
equals(s, isStrict) {
let p1 = [this.x1, this.y1], p2 = [this.x2, this.y2], p3 = [s.x1, s.y1], p4 = [s.x2, s.y2];
if (isStrict)
return P.equal(p1, p3) && P.equal(p2, p4);
return (P.equal(p1, p3) && P.equal(p2, p4)) || (P.equal(p1, p4) && P.equal(p2, p3));
}
inside(s) {
let T = this;
if (!s || T.isEmpty())
return false;
if (Types.isArray(s))
return geom.Shapes.onShape(s, T);
if (s.isEmpty())
return false;
if (s instanceof Segment)
return T.inside([s.x1, s.y1]) && T.inside([s.x2, s.y2]);
}
intersects(s) {
if (!s || this.isEmpty() || s.isEmpty())
return false;
let pos = L.position(this.p1(), this.p2(), s.p1(), s.p2());
if (pos < 0)
return false;
if (s instanceof Segment) {
return s.crossSegment(this) != null;
}
else {
return true;
}
}
bounds() {
let T = this, minX = M.min(T.x1, T.x2), maxX = M.max(T.x1, T.x2), minY = M.min(T.y1, T.y2), maxY = M.max(T.y1, T.y2);
return new geom.Rect(minX, minY, maxX - minX, maxY - minY);
}
perimeter() {
return P.distance(this.x1, this.y1, this.x2, this.y2);
}
ratioPoint(ratio) {
let p1 = this.p1(), p2 = this.p2();
return [(p1[0] + ratio * p2[0]) / (1 + ratio),
(p1[1] + ratio * p2[1]) / (1 + ratio)];
}
midPoint() {
return this.ratioPoint(1);
}
_cpOfSS(s1, s2) {
let p = s1.toLine().crossLine(s2.toLine());
if (!p)
return null;
return s1.inside(p) && s2.inside(p) ? p : null;
}
_cpOfSL(s1, s2) {
let p = s1.toLine().crossLine(s2);
if (!p)
return null;
return s1.inside(p) ? p : null;
}
_cpOfSR(s1, p3, rad) {
let p4 = P.toPoint(p3).toward(10, rad).toArray(), p = this._cpOfSL(s1, L.toLine(p3, p4));
if (!p)
return null;
return V.toVector(p3, p4).parallelTo(V.toVector(p3, p)) ? p : null;
}
crossSegment(s) {
return this._cpOfSS(this, s);
}
crossLine(l) {
return this._cpOfSL(this, l);
}
crossRay(p, rad) {
return this._cpOfSR(this, p, rad);
}
}
geom.Segment = Segment;
})(geom = math.geom || (math.geom = {}));
})(math = JS.math || (JS.math = {}));
})(JS || (JS = {}));
var Segment = JS.math.geom.Segment;
var JS;
(function (JS) {
let math;
(function (math) {
let geom;
(function (geom) {
let M = Math, N = Number;
class Polygon {
constructor(points) {
this._points = points || [];
}
isEmpty() {
return this._points.length == 0;
}
numberVertexes() {
return this._points.length;
}
clone() {
return new Polygon(this._points.slice());
}
_contains(x, y) {
let T = this, len = T.numberVertexes();
if (len <= 2 || !T.bounds().inside([x, y]))
return false;
let hits = 0, lastx = T._points[len - 1][0], lasty = T._points[len - 1][1], curx, cury;
for (let i = 0; i < len; lastx = curx, lasty = cury, i++) {
let pi = T._points[i], pj = T._points[i < len - 1 ? i + 1 : 0];
if (geom.Segment.inSegment(pi, pj, [x, y]))
return false;
curx = pi[0];
cury = pi[1];
if (cury == lasty) {
continue;
}
let leftx;
if (curx < lastx) {
if (x >= lastx) {
continue;
}
leftx = curx;
}
else {
if (x >= curx) {
continue;
}
leftx = lastx;
}
let test1, test2;
if (cury < lasty) {
if (y < cury || y >= lasty) {
continue;
}
if (x < leftx) {
hits++;
continue;
}
test1 = x - curx;
test2 = y - cury;
}
else {
if (y < lasty || y >= cury) {
continue;
}
if (x < leftx) {
hits++;
continue;
}
test1 = x - lastx;
test2 = y - lasty;
}
if (test1 < (test2 / (lasty - cury) * (lastx - curx))) {
hits++;
}
}
return ((hits & 1) != 0);
}
inside(s) {
return s && !this.isEmpty() && this._contains(s[0], s[1]);
}
onside(p) {
return !this.isEmpty() && geom.Shapes.onShape(p, this);
}
intersects(s) {
if (!s || this.isEmpty() || s.isEmpty())
return false;
let size = this.numberVertexes();
return this._points.some((p, i) => {
let x1 = p[0], y1 = p[1], px = this._points[i < size - 1 ? (i + 1) : 0];
return s.intersects(new geom.Segment(x1, y1, px[0], px[1]));
});
}
bounds() {
if (this.numberVertexes() == 0)
return new geom.Rect();
if (this._bounds == null)
this._calculateBounds();
return this._bounds.bounds();
}
_calculateBounds() {
let minX = N.MAX_VALUE, minY = N.MAX_VALUE, maxX = N.MIN_VALUE, maxY = N.MIN_VALUE;
this._points.forEach(p => {
minX = M.min(minX, p[0]);
maxX = M.max(maxX, p[0]);
minY = M.min(minY, p[1]);
maxY = M.max(maxY, p[1]);
});
this._bounds = new geom.Rect(minX, minY, maxX - minX, maxY - minY);
}
_updateBounds(x, y) {
let T = this;
if (x < T._bounds.x) {
T._bounds.w = T._bounds.w + (T._bounds.x - x);
T._bounds.x = x;
}
else {
T._bounds.w = M.max(T._bounds.w, x - T._bounds.x);
}
if (y < T._bounds.y) {
T._bounds.h = T._bounds.h + (T._bounds.y - y);
T._bounds.y = y;
}
else {
T._bounds.h = M.max(T._bounds.h, y - T._bounds.y);
}
}
addPoint(x, y) {
this._points.push([x, y]);
if (this._bounds != null)
this._updateBounds(x, y);
return this;
}
vertexes(ps) {
if (arguments.length == 0)
return this._points;
this._points = ps;
return this;
}
perimeter() {
if (this._len != void 0)
return this._len;
this._len = 0;
let size = this.numberVertexes();
if (size < 2)
return 0;
this._points.forEach((p, i) => {
let x1 = p[0], y1 = p[1], px = this._points[i < size - 1 ? (i + 1) : 0];
this._len += math.Point2.distance(x1, y1, px[0], px[1]);
});
return this._len;
}
equals(s) {
let ps = s.vertexes();
if (ps.length != this.numberVertexes())
return false;
return this._points.every((p, i) => {
let pi = ps[i];
return math.Point2.equal(p[0], p[1], pi[0], pi[1]);
});
}
}
geom.Polygon = Polygon;
})(geom = math.geom || (math.geom = {}));
})(math = JS.math || (JS.math = {}));
})(JS || (JS = {}));
var Polygon = JS.math.geom.Polygon;
var JS;
(function (JS) {
let math;
(function (math) {
let geom;
(function (geom) {
let M = Math, F = math.Floats, P = math.Point2, V = math.Vector2, R = math.Radians, S = geom.Segment;
class CirArc {
constructor(type, x, y, r, sAngle, eAngle, dir = 1) {
this.type = type || geom.ArcType.OPEN;
this.x = x || 0;
this.y = y || 0;
this.r = r || 0;
this.sAngle = sAngle || 0;
this.eAngle = eAngle || 0;
this.dir = dir == void 0 ? 1 : dir;
}
static toArc(type, c, r, sAngle, eAngle, dir = 1) {
return new CirArc(type, c[0], c[1], r, sAngle, eAngle, dir);
}
isEmpty() {
return this.r <= 0 || this.sAngle === this.eAngle;
}
center(x, y) {
if (x == void 0)
return [this.x, this.y];
this.x = x;
this.y = y;
return this;
}
set(s) {
this.type = s.type;
this.x = s.x;
this.y = s.y;
this.r = s.r;
this.sAngle = s.sAngle;
this.eAngle = s.eAngle;
this.dir = s.dir;
return this;
}
clone() {
return new CirArc(this.type, this.x, this.y, this.r, this.sAngle, this.eAngle, this.dir);
}
equals(s) {
return s.type == this.type && P.equal(s.x, s.y, this.x, this.y) && F.equal(this.r, s.r) && F.equal(this.sAngle, s.sAngle) && F.equal(this.eAngle, s.eAngle) && this.dir === s.dir;
}
_inAngle(p, ps, cache) {
let pc = ps[0], pa = ps[1], pb = ps[2];
if (S.inSegment(pc, pa, p) || S.inSegment(pc, pb, p))
return false;
let va = !cache ? V.toVector(pc, pa) : cache.va, vb = !cache ? V.toVector(pc, pb) : cache.vb, vp = V.toVector(pc, p), realAngle = !cache ? R.deg2rad(this.angle()) : cache.realRad, minAngle = !cache ? va.angle(vb) : cache.minRad, is = R.equal(minAngle, vp.angle(va) + vp.angle(vb));
return F.equal(realAngle, minAngle) ? is : !is;
}
inside(s) {
if (!s || this.isEmpty())
return false;
if (Types.isArray(s)) {
if (this.type == geom.ArcType.OPEN) {
return (F.equal(this.r * this.r, P.distanceSq(s[0], s[1], this.x, this.y))) && this._inAngle(s, this.vertexes());
}
else {
return new geom.Circle(this.x, this.y, this.r).inside(s) && this._inAngle(s, this.vertexes());
}
}
if (s.isEmpty())
return fa