tldraw/utils/bounds.ts

95 lines
2 KiB
TypeScript
Raw Normal View History

2021-06-21 13:13:16 +00:00
import { Bounds } from 'types'
2021-06-21 21:35:28 +00:00
import { pointInBounds } from './hitTests'
import { intersectPolygonBounds } from './intersections'
2021-05-13 18:22:16 +00:00
/**
* Get whether two bounds collide.
* @param a Bounds
* @param b Bounds
* @returns
*/
2021-06-21 21:35:28 +00:00
export function boundsCollide(a: Bounds, b: Bounds): boolean {
2021-05-13 18:22:16 +00:00
return !(
a.maxX < b.minX ||
a.minX > b.maxX ||
a.maxY < b.minY ||
a.minY > b.maxY
)
}
/**
* Get whether the bounds of A contain the bounds of B. A perfect match will return true.
* @param a Bounds
* @param b Bounds
* @returns
*/
2021-06-21 21:35:28 +00:00
export function boundsContain(a: Bounds, b: Bounds): boolean {
2021-05-13 18:22:16 +00:00
return (
a.minX < b.minX && a.minY < b.minY && a.maxY > b.maxY && a.maxX > b.maxX
)
}
/**
* Get whether the bounds of A are contained by the bounds of B.
* @param a Bounds
* @param b Bounds
* @returns
*/
2021-06-21 21:35:28 +00:00
export function boundsContained(a: Bounds, b: Bounds): boolean {
2021-05-13 18:22:16 +00:00
return boundsContain(b, a)
}
2021-05-18 08:32:20 +00:00
/**
* Get whether a set of points are all contained by a bounding box.
* @returns
*/
2021-06-21 21:35:28 +00:00
export function boundsContainPolygon(a: Bounds, points: number[][]): boolean {
2021-05-18 08:32:20 +00:00
return points.every((point) => pointInBounds(point, a))
}
/**
* Get whether a polygon collides a bounding box.
* @param points
* @param b
*/
2021-06-21 21:35:28 +00:00
export function boundsCollidePolygon(a: Bounds, points: number[][]): boolean {
2021-05-18 08:32:20 +00:00
return intersectPolygonBounds(points, a).length > 0
}
2021-05-13 18:22:16 +00:00
/**
* Get whether two bounds are identical.
* @param a Bounds
* @param b Bounds
* @returns
*/
2021-06-21 21:35:28 +00:00
export function boundsAreEqual(a: Bounds, b: Bounds): boolean {
2021-05-13 18:22:16 +00:00
return !(
b.maxX !== a.maxX ||
b.minX !== a.minX ||
b.maxY !== a.maxY ||
b.minY !== a.minY
)
}
2021-05-23 08:30:20 +00:00
export function getRotatedEllipseBounds(
x: number,
y: number,
rx: number,
ry: number,
rotation: number
2021-06-21 21:35:28 +00:00
): Bounds {
2021-05-23 08:30:20 +00:00
const c = Math.cos(rotation)
const s = Math.sin(rotation)
const w = Math.hypot(rx * c, ry * s)
const h = Math.hypot(rx * s, ry * c)
return {
minX: x + rx - w,
minY: y + ry - h,
maxX: x + rx + w,
maxY: y + ry + h,
width: w * 2,
height: h * 2,
}
}