Skip to content

Instantly share code, notes, and snippets.

@macrozone
Created December 19, 2017 15:05
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 macrozone/d25824762e22a8dedb08ca6ceb59a1fd to your computer and use it in GitHub Desktop.
Save macrozone/d25824762e22a8dedb08ca6ceb59a1fd to your computer and use it in GitHub Desktop.
// @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