2020-06-03 22:39:30 -04:00
|
|
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
2017-04-18 22:22:29 -04:00
|
|
|
|
2017-04-18 17:09:33 -04:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
(function() {
|
|
|
|
|
|
2022-01-31 20:50:19 -05:00
|
|
|
const base = self.base;
|
|
|
|
|
if (base.Slope) return;
|
|
|
|
|
|
|
|
|
|
const { config } = base;
|
|
|
|
|
const ABS = Math.abs,
|
|
|
|
|
DEG2RAD = Math.PI / 180,
|
|
|
|
|
RAD2DEG = 180 / Math.PI;
|
|
|
|
|
|
|
|
|
|
class Slope {
|
|
|
|
|
constructor(p1, p2, dx, dy) {
|
2020-06-03 22:39:30 -04:00
|
|
|
this.dx = p1 && p2 ? p2.x - p1.x : dx;
|
|
|
|
|
this.dy = p1 && p2 ? p2.y - p1.y : dy;
|
|
|
|
|
this.angle = Math.atan2(this.dy, this.dx) * RAD2DEG;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-31 20:50:19 -05:00
|
|
|
toString() {
|
2017-04-18 17:09:33 -04:00
|
|
|
return [this.dx, this.dy, this.angle].join(',');
|
2022-01-31 20:50:19 -05:00
|
|
|
}
|
2017-04-18 17:09:33 -04:00
|
|
|
|
2022-01-31 20:50:19 -05:00
|
|
|
clone() {
|
2020-12-19 23:24:03 -05:00
|
|
|
return new Slope(null, null, this.dx, this.dy);
|
2022-01-31 20:50:19 -05:00
|
|
|
}
|
2020-12-19 23:24:03 -05:00
|
|
|
|
2022-01-31 20:50:19 -05:00
|
|
|
isSame(s) {
|
2017-04-18 17:09:33 -04:00
|
|
|
// if very close to vertical or horizontal, they're the same
|
2022-01-31 20:50:19 -05:00
|
|
|
if (ABS(this.dx) <= config.precision_merge && ABS(s.dx) <= config.precision_merge) return true;
|
|
|
|
|
if (ABS(this.dy) <= config.precision_merge && ABS(s.dy) <= config.precision_merge) return true;
|
2017-04-18 17:09:33 -04:00
|
|
|
// check angle within a range
|
2022-01-31 20:50:19 -05:00
|
|
|
let prec = Math.min(1/Math.sqrt(this.dx * this.dx + this.dy * this.dy), config.precision_slope_merge);
|
|
|
|
|
return angleWithinDelta(this.angle, s.angle, prec || config.precision_slope);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
normal() {
|
2020-06-03 22:39:30 -04:00
|
|
|
let t = this.dx;
|
2017-04-18 17:09:33 -04:00
|
|
|
this.dx = -this.dy;
|
|
|
|
|
this.dy = t;
|
|
|
|
|
this.angle = Math.atan2(this.dy, this.dx) * RAD2DEG;
|
|
|
|
|
return this;
|
2022-01-31 20:50:19 -05:00
|
|
|
}
|
2017-04-18 17:09:33 -04:00
|
|
|
|
2022-01-31 20:50:19 -05:00
|
|
|
invert() {
|
2020-12-19 23:24:03 -05:00
|
|
|
this.dx = -this.dx;
|
|
|
|
|
this.dy = -this.dy;
|
|
|
|
|
this.angle = Math.atan2(this.dy, this.dx) * RAD2DEG;
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-31 20:50:19 -05:00
|
|
|
toUnit() {
|
2020-06-03 22:39:30 -04:00
|
|
|
let max = Math.max(ABS(this.dx), ABS(this.dy));
|
2017-04-18 17:09:33 -04:00
|
|
|
this.dx = this.dx / max;
|
|
|
|
|
this.dy = this.dy / max;
|
|
|
|
|
return this;
|
2022-01-31 20:50:19 -05:00
|
|
|
}
|
2017-04-18 17:09:33 -04:00
|
|
|
|
2022-01-31 20:50:19 -05:00
|
|
|
factor(f) {
|
2017-04-18 17:09:33 -04:00
|
|
|
this.dx *= f;
|
|
|
|
|
this.dy *= f;
|
|
|
|
|
return this;
|
2022-01-31 20:50:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
invert() {
|
2017-04-18 17:09:33 -04:00
|
|
|
this.dx = -this.dx;
|
|
|
|
|
this.dy = -this.dy;
|
2020-11-11 14:40:15 -05:00
|
|
|
this.angle = 180 - this.angle;
|
2017-04-18 17:09:33 -04:00
|
|
|
return this;
|
2022-01-31 20:50:19 -05:00
|
|
|
}
|
2017-04-18 17:09:33 -04:00
|
|
|
|
2022-01-31 20:50:19 -05:00
|
|
|
angleDiff(s2,sign) {
|
2020-12-03 14:46:20 -05:00
|
|
|
const n1 = this.angle;
|
|
|
|
|
const n2 = s2.angle;
|
|
|
|
|
let diff = n2 - n1;
|
|
|
|
|
while (diff < -180) diff += 360;
|
|
|
|
|
while (diff > 180) diff -= 360;
|
|
|
|
|
return sign ? diff : Math.abs(diff);
|
2017-04-18 17:09:33 -04:00
|
|
|
}
|
2022-01-31 20:50:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* returns true if the difference between a & b is less than v
|
|
|
|
|
*/
|
|
|
|
|
function minDeltaABS(a,b,v) {
|
|
|
|
|
return ABS(a-b) < v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function angleWithinDelta(a1, a2, delta) {
|
|
|
|
|
return (ABS(a1-a2) <= delta || 360-ABS(a1-a2) <= delta);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function newSlope(p1, p2, dx, dy) {
|
|
|
|
|
return new Slope(p1, p2, dx, dy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
base.Slope = Slope;
|
|
|
|
|
base.newSlope = newSlope;
|
|
|
|
|
base.newSlopeFromAngle = function(angle) {
|
|
|
|
|
return newSlope(0,0,
|
|
|
|
|
Math.cos(angle * DEG2RAD),
|
|
|
|
|
Math.sin(angle * DEG2RAD)
|
|
|
|
|
);
|
|
|
|
|
};
|
2017-04-18 17:09:33 -04:00
|
|
|
|
|
|
|
|
})();
|