Last active
September 2, 2017 17:21
-
-
Save feliperohdee/3b86d89a3ef1fcb038a9889cec927628 to your computer and use it in GitHub Desktop.
Set of useful analytic geometry equations I usually use
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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