More utils cleanup
This commit is contained in:
parent
bdafae3db6
commit
062dbafc36
1 changed files with 63 additions and 53 deletions
116
utils/utils.ts
116
utils/utils.ts
|
@ -1094,6 +1094,24 @@ export function rotatePoint(A: number[], B: number[], angle: number): number[] {
|
||||||
return [nx + B[0], ny + B[1]]
|
return [nx + B[0], ny + B[1]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clamp radians within 0 and 2PI
|
||||||
|
* @param r
|
||||||
|
*/
|
||||||
|
export function clampRadians(r: number): number {
|
||||||
|
return (Math.PI * 2 + r) % (Math.PI * 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clamp rotation to even segments.
|
||||||
|
* @param r
|
||||||
|
* @param segments
|
||||||
|
*/
|
||||||
|
export function clampToRotationToSegments(r: number, segments: number): number {
|
||||||
|
const seg = (Math.PI * 2) / segments
|
||||||
|
return Math.floor((clampRadians(r) + seg / 2) / seg) * seg
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is angle c between angles a and b?
|
* Is angle c between angles a and b?
|
||||||
* @param a
|
* @param a
|
||||||
|
@ -1486,6 +1504,44 @@ export function getCurvePoints(
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simplify a line (using Ramer-Douglas-Peucker algorithm).
|
||||||
|
* @param points An array of points as [x, y, ...][]
|
||||||
|
* @param tolerance The minimum line distance (also called epsilon).
|
||||||
|
* @returns Simplified array as [x, y, ...][]
|
||||||
|
*/
|
||||||
|
export function simplify(points: number[][], tolerance = 1): number[][] {
|
||||||
|
const len = points.length,
|
||||||
|
a = points[0],
|
||||||
|
b = points[len - 1],
|
||||||
|
[x1, y1] = a,
|
||||||
|
[x2, y2] = b
|
||||||
|
|
||||||
|
if (len > 2) {
|
||||||
|
let distance = 0
|
||||||
|
let index = 0
|
||||||
|
const max = Math.hypot(y2 - y1, x2 - x1)
|
||||||
|
|
||||||
|
for (let i = 1; i < len - 1; i++) {
|
||||||
|
const [x0, y0] = points[i],
|
||||||
|
d = Math.abs((y2 - y1) * x0 - (x2 - x1) * y0 + x2 * y1 - y2 * x1) / max
|
||||||
|
|
||||||
|
if (distance > d) continue
|
||||||
|
|
||||||
|
distance = d
|
||||||
|
index = i
|
||||||
|
}
|
||||||
|
|
||||||
|
if (distance > tolerance) {
|
||||||
|
const l0 = simplify(points.slice(0, index + 1), tolerance)
|
||||||
|
const l1 = simplify(points.slice(index + 1), tolerance)
|
||||||
|
return l0.concat(l1.slice(1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [a, b]
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------- Browser and DOM ---------------- */
|
/* ----------------- Browser and DOM ---------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1506,6 +1562,13 @@ export function isDarwin(): boolean {
|
||||||
return /Mac|iPod|iPhone|iPad/.test(window.navigator.platform)
|
return /Mac|iPod|iPhone|iPad/.test(window.navigator.platform)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get whether the current device is a mobile device.
|
||||||
|
*/
|
||||||
|
export function isMobile(): boolean {
|
||||||
|
return _isMobile().any
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get whether an event is command (mac) or control (pc).
|
* Get whether an event is command (mac) or control (pc).
|
||||||
* @param e
|
* @param e
|
||||||
|
@ -1633,59 +1696,6 @@ export async function postJsonToEndpoint(
|
||||||
return await d.json()
|
return await d.json()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------ Intersections ----------------- */
|
|
||||||
|
|
||||||
export function isMobile(): boolean {
|
|
||||||
return _isMobile().any
|
|
||||||
}
|
|
||||||
|
|
||||||
export function clampRadians(r: number): number {
|
|
||||||
return (Math.PI * 2 + r) % (Math.PI * 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function clampToRotationToSegments(r: number, segments: number): number {
|
|
||||||
const seg = (Math.PI * 2) / segments
|
|
||||||
return Math.floor((clampRadians(r) + seg / 2) / seg) * seg
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simplify a line (using Ramer-Douglas-Peucker algorithm).
|
|
||||||
* @param points An array of points as [x, y, ...][]
|
|
||||||
* @param tolerance The minimum line distance (also called epsilon).
|
|
||||||
* @returns Simplified array as [x, y, ...][]
|
|
||||||
*/
|
|
||||||
export function simplify(points: number[][], tolerance = 1): number[][] {
|
|
||||||
const len = points.length,
|
|
||||||
a = points[0],
|
|
||||||
b = points[len - 1],
|
|
||||||
[x1, y1] = a,
|
|
||||||
[x2, y2] = b
|
|
||||||
|
|
||||||
if (len > 2) {
|
|
||||||
let distance = 0
|
|
||||||
let index = 0
|
|
||||||
const max = Math.hypot(y2 - y1, x2 - x1)
|
|
||||||
|
|
||||||
for (let i = 1; i < len - 1; i++) {
|
|
||||||
const [x0, y0] = points[i],
|
|
||||||
d = Math.abs((y2 - y1) * x0 - (x2 - x1) * y0 + x2 * y1 - y2 * x1) / max
|
|
||||||
|
|
||||||
if (distance > d) continue
|
|
||||||
|
|
||||||
distance = d
|
|
||||||
index = i
|
|
||||||
}
|
|
||||||
|
|
||||||
if (distance > tolerance) {
|
|
||||||
const l0 = simplify(points.slice(0, index + 1), tolerance)
|
|
||||||
const l1 = simplify(points.slice(index + 1), tolerance)
|
|
||||||
return l0.concat(l1.slice(1))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return [a, b]
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turn an array of points into a path of quadradic curves.
|
* Turn an array of points into a path of quadradic curves.
|
||||||
* @param stroke ;
|
* @param stroke ;
|
||||||
|
|
Loading…
Reference in a new issue