Skip to content

Instantly share code, notes, and snippets.

@Guseyn
Created April 29, 2020 12:15
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 Guseyn/5ba7ed3e8068fed3807e76d4ce62e091 to your computer and use it in GitHub Desktop.
Save Guseyn/5ba7ed3e8068fed3807e76d4ce62e091 to your computer and use it in GitHub Desktop.
Bezier Bounding Box
'use strict'
// based on the same code in python https://gist.github.com/internetimagery/642b9cfa8488ba9a4d7c
const boundsOfCurve = (x0, y0, x1, y1, x2, y2, x3, y3) => {
const tvalues = []
const bounds = [[], []]
const points = []
for (let i = 0; i <= 1; i++) {
let b
let a
let c
if (i === 0) {
b = 6 * y0 - 12 * y1 + 6 * y2
a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3
c = 3 * y1 - 3 * y0
} else {
b = 6 * x0 - 12 * x1 + 6 * x2
a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3
c = 3 * x1 - 3 * x0
}
if (Math.abs(a) < 0.000001) {
if (Math.abs(b) < 0.000001) {
continue
}
const t = -c / b
if (t > 0 && t < 1) {
tvalues.push(t)
}
continue
}
const b2ac = b * b - 4 * c * a
if (b2ac < 0) {
continue
}
const sqrtb2ac = Math.sqrt(b2ac)
const t1 = (-b + sqrtb2ac) / (2 * a)
if (t1 > 0 && t1 < 1) {
tvalues.push(t1)
}
const t2 = (-b - sqrtb2ac) / (2 * a)
if (t2 > 0 && t2 < 1) {
tvalues.push(t2)
}
}
let j = tvalues.length
while (j !== 0) {
j -= 1
const t = tvalues[j]
const mt = 1 - t
const x = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3)
bounds[0].push(x)
const y = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3)
bounds[1].push(y)
points.push({ 'x': x, 'y': y })
}
tvalues.push(0, 1)
points.push(
{
'x': x0,
'y': y0
},
{
'x': x3,
'y': y3
}
)
bounds[0].push(x0, x3)
bounds[1].push(y0, y3)
return {
'top': Math.min(...bounds[1]),
'right': Math.max(...bounds[0]),
'bottom': Math.max(...bounds[1]),
'left': Math.min(...bounds[0]),
'points': points,
'tvalues': tvalues
}
}
console.log(boundsOfCurve(532, 333, 117, 305, 28, 93, 265, 42))
// Output:
/* {
top: 42,
right: 532,
bottom: 333,
left: 135.77684049079755,
points: [
{ x: 135.77684049079755, y: 144.86387466397255 },
{ x: 532, y: 333 },
{ x: 265, y: 42 }
],
tvalues: [ 0.6365030674846626, 0, 1 ]
} */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment