Skip to content

Instantly share code, notes, and snippets.

@stonetip
Created February 14, 2018 18:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stonetip/e79254e001bda862119e97d7646e4c66 to your computer and use it in GitHub Desktop.
Save stonetip/e79254e001bda862119e97d7646e4c66 to your computer and use it in GitHub Desktop.
Demo using newer ecmascript features to calculate angle and direction from a set of coordinates
class Vector {
constructor(a, b) {
if (a instanceof Point && b instanceof Point) {
this.x = b.x - a.x;
this.y = b.y - a.y;
this.z = b.z - a.z;
}
else {
this.x = a || 0;
this.y = b || 0;
this.z = z || 0;
}
}
}
class Point {
constructor(x, y, z) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
}
}
function radToDeg(radVal) {
return radVal * 180 / Math.PI;
}
const testCoordSet = [
[-114.946645, 48.068177],
[-114.962833, 48.068179],
[-114.962799, 48.061004],
[-114.957446, 48.06105],
[-114.957454, 48.064635],
[-114.946694, 48.064577]
];
// Generate our test set of points - using map because we need to return a new collection
const testPts = testCoordSet.map(coord => new Point(...coord));
console.log(testPts);
const overallRunTimeStart = performance.now();
// Using forEach because we're not returning anything. In practice, further
// operations could benefit from map because we can chain
testPts.forEach((pt, index, array) => {
console.log(`\r\n${index}`);
const pointA = array[index === 0 ? array.length - 1 : index - 1]; // If at beginning, left is the last point in the array
const pointB = pt;
const pointC = array[index === array.length - 1 ? 0 : index + 1]; // If at end, right is the first point in the array
const vectorAB = new Vector(pointA, pointB);
const vectorCB = new Vector(pointC, pointB);
console.log("vectorAB:", vectorAB);
console.log("vectorCB:", vectorCB);
// Stay in radians until the final result is calculated
const absAngleABRad = Math.atan2(vectorAB.y, vectorAB.x);
console.log(`absAngleABRad: ${absAngleABRad}`);
const absAngleCBRad = Math.atan2(vectorCB.y, vectorCB.x);
console.log(`absAngleCBRad: ${absAngleCBRad}`);
const angularDiffRad = absAngleABRad - absAngleCBRad;
console.log(`angularDiffRad: ${angularDiffRad}`);
const angularDiffRadNormalized = Math.atan2(Math.sin(angularDiffRad), Math.cos(angularDiffRad));
console.log(`angularDiffRadNorm: ${angularDiffRadNormalized}`);
const angleDeg = radToDeg(angularDiffRadNormalized);
console.warn(`angleDeg: ${angleDeg}`);
});
// old school
//for (let i = 0; i < testPts.length; i++) {
// console.log(`\r\n${i}`);
// const pointA = testPts[i === 0 ? testPts.length - 1 : i - 1]; // If at beginning, left is the last point in the array
// const pointB = testPts[i];
// const pointC = testPts[i === testPts.length - 1 ? 0 : i + 1]; // If at end, right is the first point in the array
// const vectorAB = new Vector(pointA, pointB);
// const vectorCB = new Vector(pointC, pointB);
// console.log("vectorAB:", vectorAB);
// console.log("vectorCB:", vectorCB);
// // Stay in radians until the final result is calculated
// const absAngleABRad = Math.atan2(vectorAB.y, vectorAB.x);
// console.log(`absAngleABRad: ${absAngleABRad}`);
// const absAngleCBRad = Math.atan2(vectorCB.y, vectorCB.x);
// console.log(`absAngleCBRad: ${absAngleCBRad}`);
// const angularDiffRad = absAngleABRad - absAngleCBRad;
// console.log(`angularDiffRad: ${angularDiffRad}`);
// const angularDiffRadNormalized = Math.atan2(Math.sin(angularDiffRad), Math.cos(angularDiffRad));
// console.log(`angularDiffRadNorm: ${angularDiffRadNormalized}`);
// const angleDeg = radToDeg(angularDiffRadNormalized);
// console.warn(`angleDeg: ${angleDeg}`);
//}
const overallRuntimeEnd = performance.now();
console.log(`Overall run took ${overallRuntimeEnd - overallRunTimeStart} milliseconds.`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment