Created
December 19, 2017 15:05
-
-
Save macrozone/d25824762e22a8dedb08ca6ceb59a1fd to your computer and use it in GitHub Desktop.
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
// @flow | |
// TODO: use proper vector library | |
import type { Plane, Ray, Vector3 } from '../../types' | |
export const UP = { | |
x: 0, | |
y: 1, | |
z: 0, | |
} | |
export const distance = (a: Vector3, b: Vector3): number => | |
Math.sqrt((b.x - a.x) ** 2 + (b.y - a.y) ** 2 + (b.z - a.z) ** 2) | |
export const center = (a: Vector3, b: Vector3): Vector3 => ({ | |
x: (b.x + a.x) / 2, | |
y: (b.y + a.y) / 2, | |
z: (b.z + a.z) / 2, | |
}) | |
export const diff = (a: Vector3, b: Vector3) => ({ | |
x: b.x - a.x, | |
y: b.y - a.y, | |
z: b.z - a.z, | |
}) | |
export const add = (a: Vector3, b: Vector3) => ({ | |
x: b.x + a.x, | |
y: b.y + a.y, | |
z: b.z + a.z, | |
}) | |
export const multiply = (a: Vector3, s: number) => ({ | |
x: a.x * s, | |
y: a.y * s, | |
z: a.z * s, | |
}) | |
export const cross = (a: Vector3, b: Vector3) => ({ | |
x: a.y * b.z - a.z * b.y, | |
y: a.z * b.x - a.x * b.z, | |
z: a.x * b.y - a.y * b.x, | |
}) | |
export const dot = (a: Vector3, b: Vector3) => a.x * b.x + a.y * b.y + a.z * b.z | |
export const length = (a: Vector3) => Math.hypot(...Object.values(a)) | |
export const normalize = (v: Vector3): Vector3 => multiply(v, 1 / length(v)) | |
export const shiftY = (p: Vector3, amount: number = 0) => ({ | |
...p, | |
y: p.y + amount, | |
}) | |
/** | |
* Returns the angle (rad) of the given line relative to the x axis. | |
* | |
* @param {Point} start | |
* @param {Point} end | |
*/ | |
export const getLineAngle = (start: Vector3, end: Vector3) => { | |
const d = diff(end, start) | |
const theta = Math.atan2(d.z, d.x) | |
return Math.PI - theta | |
} | |
export const nearestPointOnLineToPoint = ( | |
line: { | |
a: Vector3, | |
b: Vector3, | |
}, | |
point: Vector3, | |
) => { | |
const { a, b } = line | |
const ab = diff(a, b) | |
const ap = diff(a, point) | |
// thx https://gamedev.stackexchange.com/a/72529 | |
// A + dot(AP,AB) / dot(AB,AB) * AB | |
return add(a, multiply(ab, dot(ap, ab) / dot(ab, ab))) | |
} | |
// thx https://github.com/mattdesl/ray-plane-intersection | |
export const intersectPlaneWithRay = ( | |
{ normal, point }: Plane, | |
{ origin, direction }: Ray, | |
) => { | |
const dist = -dot(normal, point) | |
const denom = dot(direction, normal) | |
if (denom !== 0) { | |
const t = -(dot(origin, normal) + dist) / denom | |
if (t < 0) { | |
return null | |
} | |
const scaled = multiply(direction, t) | |
return add(origin, scaled) | |
} else if (dot(normal, origin) + dist === 0) { | |
return origin | |
} | |
return null | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment