Skip to content
Snippets Groups Projects
Commit d721ca17 authored by Yuriy Maksymets's avatar Yuriy Maksymets
Browse files

Merging of erased intervals

parent 3f9afe67
No related branches found
No related tags found
2 merge requests!57Erasure intervals,!48Intuitive erasing
Pipeline #102539 passed
const { computeErasureIntervals } = require("../src/erasure")
const {
computeErasureIntervals,
combineErasureIntervals,
} = require("../src/erasure")
const sum = (a, b) => a + b
......@@ -22,7 +25,7 @@ describe("erasure", () => {
erasureRadius,
)
expect(erasureIntervals).toStrictEqual({ 0: [0.25, 0.75] })
expect(erasureIntervals).toStrictEqual({ 0: [[0.25, 0.75]] })
})
it("computes complex erasure intervals", () => {
......@@ -36,13 +39,36 @@ describe("erasure", () => {
erasureRadius,
)
expect(erasureIntervals).toStrictEqual({ 0: [0.75, 1], 1: [0, 0.25] })
expect(erasureIntervals).toStrictEqual({ 0: [[0.75, 1]], 1: [[0, 0.25]] })
})
// it('combines erasure intervals', () => {
// const i1 = {0:[0.1,0.5], 1:[0.5,0.6], 2:[0.1,0.2]}
// const i2 = {0:[0.1,0.6], 1:[0.1,0.9]}
it("combines distinct intervals", () => {
const i1 = { 0: [[0.1, 0.6]] }
const i2 = { 0: [[0.7, 0.8]] }
// const combined =
// })
const combined = combineErasureIntervals(i1, i2)
const expected = { 0: [[0.1, 0.6], [0.7, 0.8]] }
expect(combined).toStrictEqual(expected)
})
it("combines overlapping intervals", () => {
const i1 = { 0: [[0.1, 0.6]] }
const i2 = { 0: [[0.5, 0.8]] }
const combined = combineErasureIntervals(i1, i2)
const expected = { 0: [[0.1, 0.8]] }
expect(combined).toStrictEqual(expected)
})
it("combines overlapping inside intervals", () => {
const i1 = { 0: [[0.1, 0.6]] }
const i2 = { 0: [[0.2, 0.3]] }
const combined = combineErasureIntervals(i1, i2)
const expected = { 0: [[0.1, 0.6]] }
expect(combined).toStrictEqual(expected)
})
})
......@@ -5,7 +5,10 @@ import { connect } from "./room.js"
const TEST_ROOM = "imperial"
const { computeErasureIntervals } = require("./erasure")
const {
computeErasureIntervals,
combineErasureIntervals,
} = require("./erasure")
// TODO: switch to curve interpolation that respects mouse points based on velocity
const lineFn = line()
......@@ -79,7 +82,7 @@ const SVG = {
},
}
let TEST_ERASE_INTERVAL = {}
let TEST_ERASE_INTERVAL = { 0: [[0.1, 0.3], [0.4, 0.8]] }
function erasurePoints(pointA, pointB, start, fin) {
if (start >= fin) return
......@@ -121,7 +124,6 @@ const addOrUpdatePathElem = (pathElems, id, points) => {
// Push a fake path split to generate the last path
points.push([-1, -1, false])
const originalID = (i) => i - 1
let subPath = []
let toAdd = undefined
......@@ -164,29 +166,38 @@ const addOrUpdatePathElem = (pathElems, id, points) => {
// Valid point inside a subpath
subPath.push(point)
const eraseInterval = TEST_ERASE_INTERVAL[i]
if (eraseInterval) {
if (i === points.length - 1) {
continue
}
const eraseIntervals = TEST_ERASE_INTERVAL[i]
if (!eraseIntervals) continue
for (const eraseInterval of eraseIntervals) {
if (eraseInterval) {
if (toAdd) {
subPath.push(toAdd)
toAdd = undefined
}
const nextPoint = points[i + 1]
if (i === points.length - 1) {
continue
}
const [start, fin] = erasurePoints(
point,
nextPoint,
eraseInterval[0],
eraseInterval[1],
)
const nextPoint = points[i + 1]
subPath.push(start)
const [start, fin] = erasurePoints(
point,
nextPoint,
eraseInterval[0],
eraseInterval[1],
)
const subpathElem = SVG.create.path()
subpathElem.setAttribute("d", lineFn(subPath))
pathElem.appendChild(subpathElem)
subPath = []
subPath.push(start)
toAdd = fin
const subpathElem = SVG.create.path()
subpathElem.setAttribute("d", lineFn(subPath))
pathElem.appendChild(subpathElem)
subPath = []
toAdd = fin
}
}
}
......@@ -293,7 +304,7 @@ function handleRoomConnectionEstablished(room) {
} else if (currentTool == tools.ERASER) {
room.getPaths().forEach((points, pathID) => {
const t = computeErasureIntervals(points, mousePos, ERASERRADIUS)
TEST_ERASE_INTERVAL = t
TEST_ERASE_INTERVAL = combineErasureIntervals(TEST_ERASE_INTERVAL, t)
room.dispatchEvent(
new CustomEvent("addOrUpdatePath", {
detail: { id: pathID, points },
......
......@@ -95,17 +95,45 @@ function computeErasureIntervals(points, erasureCenter, erasureRadius) {
.reduce(
(acc, { point, i }) => ({
...acc,
[i]: erasureInterval(
point,
points[i + 1],
erasureCenter,
erasureRadius,
),
[i]: [
erasureInterval(point, points[i + 1], erasureCenter, erasureRadius),
],
}),
{},
)
}
function overlaps([s1, e1], [, e2]) {
return s1 <= e2 && s1 <= e1
}
function mergeIntervals(...intervals) {
if (!intervals.length) return []
const sorted = intervals.sort(([a], [b]) => a > b)
let stack = [sorted[0]]
sorted.forEach((x) => {
const top = stack[stack.length - 1]
if (overlaps(x, top)) {
if (x[1] > top[1]) top[1] = x[1]
} else {
stack.push(x)
}
})
return stack
}
function combineErasureIntervals(i1, i2) {
const _i1 = { ...i1 }
Object.keys(i1).forEach((key) => {
if (i2[key]) {
_i1[key] = mergeIntervals(...i1[key], ...i2[key])
}
})
return { ...i2, ..._i1 }
}
module.exports = {
computeErasureIntervals,
combineErasureIntervals,
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment