Skip to content

Instantly share code, notes, and snippets.

@feliperohdee
Last active September 2, 2017 17:21
Show Gist options
  • Save feliperohdee/3b86d89a3ef1fcb038a9889cec927628 to your computer and use it in GitHub Desktop.
Save feliperohdee/3b86d89a3ef1fcb038a9889cec927628 to your computer and use it in GitHub Desktop.
Set of useful analytic geometry equations I usually use
import _ from 'lodash';
export const degToRad = x => {
return x / 180 * Math.PI;
};
export const radToDeg = x => {
return x / Math.PI * 180;
};
export const diag = (width, height) => {
return Math.sqrt((width ** 2) + (height ** 2));
};
// based on https://www.nayuki.io/page/numerically-stable-law-of-cosines
export const diagAngle = (diag, width, height) => {
const temp = (diag * diag + width * width - height * height) / (2 * diag * width);
if (-1 <= temp && temp <= 0.9999999) {
return this.radToDeg(Math.acos(temp));
} else if (temp <= 1) {
return this.radToDeg(Math.sqrt((height * height - (diag - width) * (diag - width)) / (diag * width)));
}
return 0;
};
export const vectorsFromCenter = (angle, width, height) => {
const diagSize = diag(width, height);
const bottomRightAngle = (angle + diagAngle(diagSize, width, height)) % 360;
const bottomLeftAngle = ((angle + 90) + diagAngle(diagSize, height, width)) % 360;
const bottomRightSin = Math.sin(degToRad(bottomRightAngle));
const bottomRightCos = Math.cos(degToRad(bottomRightAngle));
const bottomLeftSin = Math.sin(degToRad(bottomLeftAngle));
const bottomLeftCos = Math.cos(degToRad(bottomLeftAngle));
const bottomRight = {
top: _.round((diagSize / 2) * bottomRightSin, 2),
left: _.round((diagSize / 2) * bottomRightCos, 2)
};
const bottomLeft = {
top: _.round((diagSize / 2) * bottomLeftSin, 2),
left: _.round((diagSize / 2) * bottomLeftCos, 2)
};
const topRight = {
top: -bottomLeft.top,
left: -bottomLeft.left
};
const topLeft = {
top: -bottomRight.top,
left: -bottomRight.left
};
return {
diagSize,
bottomRightAngle,
bottomLeftAngle,
bottomLeft,
bottomRight,
topLeft,
topRight
};
};
export const rotateVector = (centerLeft, centerTop, left, top, angle) => {
const rad = degToRad(angle);
const cos = Math.cos(rad);
const sin = Math.sin(rad);
const newLeft = (cos * (left - centerLeft)) + (sin * (top - centerTop)) + centerLeft;
const newTop = (cos * (top - centerTop)) - (sin * (left - centerLeft)) + centerTop;
return {
left: newLeft,
top: newTop
};
};
export const vectorsFromCenterThrottled = _.throttle(vectorsFromCenter, 10);
export const pointInMatrix = (point, matrix) => {
const [x, y] = point;
let inside = false;
for (let i = 0, j = matrix.length - 1; i < matrix.length; j = i++) {
const xi = matrix[i][0];
const yi = matrix[i][1];
const xj = matrix[j][0];
const yj = matrix[j][1];
const intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) {
inside = !inside
}
}
return inside;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment