aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx53
1 files changed, 36 insertions, 17 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 76e1646e2..b8d74dff2 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -838,8 +838,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
};
/**
- * Performs segmentation of the ink stroke - creates "segments" or subsections of the current ink stroke at points in which the
- * ink stroke intersects any other ink stroke (including itself).
+ * Erases ink strokes by segments. Locates intersections of the current ink stroke with all other ink strokes (including itself),
+ * then erases the segment that was intersected by the eraser. This is done by creating either 1 or two resulting segments
+ * (this depends on whether the eraser his the middle or end of a stroke), and returning the segments to "redraw."
* @param ink The ink DocumentView intersected by the eraser.
* @param excludeT The index of the curve in the ink document that the eraser intersection occurred.
* @returns The ink stroke represented as a list of segments, excluding the segment in which the eraser intersection occurred.
@@ -851,29 +852,34 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
var segment1: Segment = [];
var segment2: Segment = [];
const { inkData } = (ink?.ComponentView as InkingStroke).inkScaledData();
- // This iterates through all segments of the curve and splits them where they intersect another curve.
- // if 'excludeT' is specified, then any segment containing excludeT will be skipped (ie, deleted)
-
- // find all t values of the curve's intersections
- var intersections: number[] = [];
- var segmentIndexes: number[] = [];
+ var intersections: number[] = []; // list of the ink stroke's intersections
+ var segmentIndexes: number[] = []; // list of indexes of the curve's segment where each intersection occured
+
+ // loops through each segment and adds intersections to the list
for (var i = 0; i < inkData.length - 3; i += 4) {
const inkSegment: Bezier = InkField.Segment(inkData, i);
var currIntersects = this.getInkIntersections(i, ink, inkSegment).sort();
// get current segments intersections (if any) and add the curve index
currIntersects = currIntersects.map(tVal => tVal + Math.floor(i/4));
if (currIntersects.length) {
- intersections = [...intersections, ...currIntersects];
- // segmentIndexes is to keep track of the segment index that corresponds to an intersection
+ intersections = [...intersections, ...currIntersects]
for (var j = 0; j < currIntersects.length; j++) {
segmentIndexes.push(Math.floor(i / 4));
}
}
}
+ // for closed curve bookkeeping
+ var isClosedCurve = false;
+ if (intersections[0] === 0) {
+ isClosedCurve = true;
+ intersections = intersections.slice(1, intersections.length ); // take the 0 intersection out
+ segmentIndexes = segmentIndexes.slice(1, segmentIndexes.length); // same for indexes
+ }
+
if (intersections.length) {
- // this is the indexes of the closest Ts
- const closestTs = this.getClosestTs(intersections, excludeT, 0, intersections.length - 1);
+ // this is the indexes of the closest intersection(s)
+ var closestTs = this.getClosestTs(intersections, excludeT, 0, intersections.length - 1);
// find the segments that need to be split
var splitSegment1 = -1; // stays -1 if left end is deleted
@@ -882,9 +888,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
// if not on the ends
splitSegment1 = segmentIndexes[closestTs[0]];
splitSegment2 = segmentIndexes[closestTs[1]];
- } else if (closestTs[0] === -1) { // for a curve left of intersection
+ } else if (closestTs[0] === -1) { // for a curve before an intersection
splitSegment2 = segmentIndexes[closestTs[1]];
- } else { // for a curve right of intersection
+ } else { // for a curve after an intersection
splitSegment1 = segmentIndexes[closestTs[0]];
}
@@ -892,7 +898,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
var hasSplit = false;
var continueErasing = false;
- // loop through segments again and split if they match the split segments
+ // loop through segments again and split them if they match the split segments
for (var i = 0; i < inkData.length - 3; i += 4) {
const currCurveT = Math.floor(i / 4);
const inkSegment: Bezier = InkField.Segment(inkData, i);
@@ -924,7 +930,10 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
segment2.push(inkSegment.split(intersections[closestTs[1]] - currCurveT, 1));
hasSplit = true;
} else {
- if (hasSplit) {
+ if (isClosedCurve && currCurveT === segmentIndexes.lastElement()) {
+ segment2.push(inkSegment.split(0, intersections.lastElement() - currCurveT));
+ continueErasing = true;
+ } else if (hasSplit && !continueErasing) {
segment2.push(inkSegment);
}
}
@@ -932,8 +941,10 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
if (currCurveT === splitSegment1) {
segment1.push(inkSegment.split(0, intersections[closestTs[0]] - currCurveT));
hasSplit = true;
+ } else if (isClosedCurve && currCurveT === segmentIndexes[1]) {
+ segment1.push(inkSegment.split(intersections[0] - currCurveT, 1));
} else {
- if (!hasSplit) {
+ if (!hasSplit && !isClosedCurve) {
segment1.push(inkSegment);
}
}
@@ -1114,6 +1125,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
return segments;
};
+ /**
+ * Standard logarithmic search function to search a sorted list of tVals for the ones closest to excludeT.
+ * @param tVals list of tvalues (usage is for intersection t values) to search within
+ * @param excludeT the t value of where the eraser intersected the curve
+ * @param startIndex the start index to search from
+ * @param endIndex the end index to search to
+ * @returns 2-item array of the closest tVals indexes
+ */
getClosestTs = (tVals: number[], excludeT: number, startIndex: number, endIndex: number): number[] => {
if (tVals[startIndex] >= excludeT) {
return [-1, startIndex];