Handle curve selections properly for overlapping shapes

This commit is contained in:
Skyler Lehmkuhl 2024-11-20 10:33:17 -05:00
parent 75884e0d7d
commit 78f03c2a12
1 changed files with 52 additions and 49 deletions

View File

@ -303,26 +303,28 @@ function setProperty(context, path, value) {
function selectCurve(context, mouse) { function selectCurve(context, mouse) {
let mouseTolerance = 15; let mouseTolerance = 15;
let closestDist = mouseTolerance;
let closestCurve = undefined
let closestShape = undefined
for (let shape of context.activeObject.currentFrame.shapes) { for (let shape of context.activeObject.currentFrame.shapes) {
if (mouse.x > shape.boundingBox.x.min - mouseTolerance && if (mouse.x > shape.boundingBox.x.min - mouseTolerance &&
mouse.x < shape.boundingBox.x.max + mouseTolerance && mouse.x < shape.boundingBox.x.max + mouseTolerance &&
mouse.y > shape.boundingBox.y.min - mouseTolerance && mouse.y > shape.boundingBox.y.min - mouseTolerance &&
mouse.y < shape.boundingBox.y.max + mouseTolerance) { mouse.y < shape.boundingBox.y.max + mouseTolerance) {
let closestDist = mouseTolerance;
let closest = undefined
for (let curve of shape.curves) { for (let curve of shape.curves) {
let dist = vectorDist(mouse, curve.project(mouse)) let dist = vectorDist(mouse, curve.project(mouse))
if (dist <= closestDist ) { if (dist <= closestDist ) {
closestDist = dist closestDist = dist
closest = curve closestCurve = curve
closestShape = shape
} }
} }
if (closest) {
return {curve:closest, shape:shape}
} else {
return undefined
} }
} }
if (closestCurve) {
return {curve:closestCurve, shape:closestShape}
} else {
return undefined
} }
} }
@ -645,50 +647,50 @@ class Shape {
} }
} }
let epsilon = 0.01 let epsilon = 0.01
let newCurves = [] let newCurves = []
let intersectMap = {} let intersectMap = {}
for (let i=0; i<this.curves.length-1; i++) { for (let i=0; i<this.curves.length-1; i++) {
for (let j=i+1; j<this.curves.length; j++) { for (let j=i+1; j<this.curves.length; j++) {
let intersects = this.curves[i].intersects(this.curves[j]) let intersects = this.curves[i].intersects(this.curves[j])
console.log(intersects) console.log(intersects)
if (intersects.length) { if (intersects.length) {
intersectMap[i] ||= [] intersectMap[i] ||= []
intersectMap[j] ||= [] intersectMap[j] ||= []
for(let intersect of intersects) { for(let intersect of intersects) {
let [t1, t2] = intersect.split("/") let [t1, t2] = intersect.split("/")
intersectMap[i].push(parseFloat(t1)) intersectMap[i].push(parseFloat(t1))
intersectMap[j].push(parseFloat(t2)) intersectMap[j].push(parseFloat(t2))
}
}
}
} }
for (let lst in intersectMap) { }
for (let i=1; i<intersectMap[lst].length; i++) { }
if (Math.abs(intersectMap[lst][i] - intersectMap[lst][i-1]) < epsilon) { }
intersectMap[lst].splice(i,1) for (let lst in intersectMap) {
i-- for (let i=1; i<intersectMap[lst].length; i++) {
} if (Math.abs(intersectMap[lst][i] - intersectMap[lst][i-1]) < epsilon) {
} intersectMap[lst].splice(i,1)
} i--
for (let i=this.curves.length-1; i>=0; i--) { }
if (i in intersectMap) { }
intersectMap[i].sort().reverse() }
let remainingFraction = 1 for (let i=this.curves.length-1; i>=0; i--) {
let remainingCurve = this.curves[i] if (i in intersectMap) {
for (let t of intersectMap[i]) { intersectMap[i].sort().reverse()
let split = remainingCurve.split(t / remainingFraction) let remainingFraction = 1
remainingFraction = t let remainingCurve = this.curves[i]
newCurves.push(split.right) for (let t of intersectMap[i]) {
remainingCurve = split.left let split = remainingCurve.split(t / remainingFraction)
} remainingFraction = t
newCurves.push(remainingCurve) newCurves.push(split.right)
remainingCurve = split.left
}
newCurves.push(remainingCurve)
} else { } else {
newCurves.push(this.curves[i]) newCurves.push(this.curves[i])
} }
} }
newCurves.reverse() newCurves.reverse()
this.curves = newCurves this.curves = newCurves
this.recalculateBoundingBox() this.recalculateBoundingBox()
} }
draw(context) { draw(context) {
@ -1108,6 +1110,7 @@ function stage() {
} }
} else { } else {
let selection = selectCurve(context, mouse) let selection = selectCurve(context, mouse)
console.log(selection)
if (selection) { if (selection) {
context.activeCurve = { context.activeCurve = {
current: selection.curve, current: selection.curve,