aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx357
1 files changed, 239 insertions, 118 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 70b21309e..76e1646e2 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -846,171 +846,292 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
*/
@action
segmentInkStroke = (ink: DocumentView, excludeT: number): Segment[] => {
- // const segments: Segment[] = [];
- // var segment: Segment = [];
- // var segment2: Segment = [];
- // var startSegmentT = 0;
- // const { inkData } = (ink?.ComponentView as InkingStroke).inkScaledData();
+
+ const segments: Segment[] = [];
+ 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)
- // var hasSplit = false;
- // var continueErasing = false;
+ // find all t values of the curve's intersections
+ var intersections: number[] = [];
+ var segmentIndexes: number[] = [];
+ 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
+ for (var j = 0; j < currIntersects.length; j++) {
+ segmentIndexes.push(Math.floor(i / 4));
+ }
+ }
+ }
+
+ if (intersections.length) {
+ // this is the indexes of the closest Ts
+ const 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
+ var splitSegment2 = -1; // stays -1 if right end is deleted
+ if (closestTs[0] !== -1 && closestTs[1] !== -1) {
+ // if not on the ends
+ splitSegment1 = segmentIndexes[closestTs[0]];
+ splitSegment2 = segmentIndexes[closestTs[1]];
+ } else if (closestTs[0] === -1) { // for a curve left of intersection
+ splitSegment2 = segmentIndexes[closestTs[1]];
+ } else { // for a curve right of intersection
+ splitSegment1 = segmentIndexes[closestTs[0]];
+ }
+
+ // so here splitSegment1 and splitSegment2 will be the index(es) of the segment(s) to split
+
+ var hasSplit = false;
+ var continueErasing = false;
+ // loop through segments again and split 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);
+
+ // case where the current curve is the first to split
+ if (splitSegment1 !== -1 && splitSegment2 !== -1) {
+ if (splitSegment1 === splitSegment2 && splitSegment1 === currCurveT) {
+ // if it's the same segment
+ segment1.push(inkSegment.split(0, intersections[closestTs[0]] - currCurveT));
+ segment2.push(inkSegment.split(intersections[closestTs[1]] - currCurveT, 1));
+ hasSplit = true;
+ } else if (splitSegment1 === currCurveT) {
+ segment1.push(inkSegment.split(0, intersections[closestTs[0]] - currCurveT));
+ continueErasing = true;
+ } else if (splitSegment2 === currCurveT) {
+ segment2.push(inkSegment.split(intersections[closestTs[1]] - currCurveT, 1));
+ continueErasing = false;
+ hasSplit = true;
+ } else {
+ if (!continueErasing && !hasSplit) {
+ // segment doesn't get pushed if continueErasing is true
+ segment1.push(inkSegment);
+ } else if (!continueErasing && hasSplit) {
+ segment2.push(inkSegment);
+ }
+ }
+ } else if (splitSegment1 === -1) { // case where left end is erased
+ if (currCurveT === splitSegment2) {
+ segment2.push(inkSegment.split(intersections[closestTs[1]] - currCurveT, 1));
+ hasSplit = true;
+ } else {
+ if (hasSplit) {
+ segment2.push(inkSegment);
+ }
+ }
+ } else { // case where right end is erased
+ if (currCurveT === splitSegment1) {
+ segment1.push(inkSegment.split(0, intersections[closestTs[0]] - currCurveT));
+ hasSplit = true;
+ } else {
+ if (!hasSplit) {
+ segment1.push(inkSegment);
+ }
+ }
+ }
+ }
+ }
+
+ // push 1 or both segments if they are not empty
+ if (segment1.length && (Math.abs(segment1[0].points[0].x - segment1[0].points.lastElement().x) > 0.5 || Math.abs(segment1[0].points[0].y - segment1[0].points.lastElement().y) > 0.5)) {
+ segments.push(segment1);
+ }
+ if (segment2.length && (Math.abs(segment2[0].points[0].x - segment2[0].points.lastElement().x) > 0.5 || Math.abs(segment2[0].points[0].y - segment2[0].points.lastElement().y) > 0.5)) {
+ segments.push(segment2);
+ }
+
+ return segments;
+
+ // var deletedSegments = [];
// for (var i = 0; i < inkData.length - 3; i += 4) {
+ // const segmentStartT = Math.floor(i/4);
// const inkSegment: Bezier = InkField.Segment(inkData, i);
// const tVals: number[] = this.getInkIntersections(i, ink, inkSegment).sort();
- // console.log("TVALS", tVals);
- // if (tVals.length) {
- // if ((!hasSplit) && ((excludeT <= tVals[0]) ||
- // (excludeT > tVals[0] && excludeT < tVals.lastElement()) || continueErasing)) {
+ // if (excludeT > segmentStartT && excludeT < segmentStartT + 1) {
+ // if (tVals.length) {
// const closestTs = this.getClosestTs(tVals, excludeT, 0, tVals.length - 1);
// if (closestTs[0] != -1 && closestTs[1] != -1) {
// segment1.push(inkSegment.split(0, closestTs[0]));
// segment2.push(inkSegment.split(closestTs[1]).right);
+ // deletedSegments.push(inkSegment.split(closestTs[0], closestTs[1]));
// } else if (closestTs[0] == -1) {
// segment2.push(inkSegment.split(closestTs[1]).right);
- // continueErasing = !continueErasing;
+ // deletedSegments.push(inkSegment.split(closestTs[1]).left);
+ // if (excludeT > tVals[0]) {
+ // continueErasing = !continueErasing;
+ // }
// } else {
- // segment1.push(inkSegment.split(0, closestTs[0]));
+ // continueErasing ? segment2.push(inkSegment.split(closestTs[0]).right) : segment1.push(inkSegment.split(0, closestTs[0]));
+ // continueErasing ? deletedSegments.push(inkSegment.split(closestTs[0]).left) : deletedSegments.push(inkSegment.split(closestTs[0]).right);
// continueErasing = !continueErasing;
// }
// if (!continueErasing) {
// hasSplit = true;
// }
- // // segment1 = [];
- // // segment2 = [];
+ // } else if (hasSplit) {
+ // segment2.push(inkSegment);
+ // } else {
+ // continueErasing = true;
// }
- // else {
- // if (hasSplit) {
- // segment2.push(inkSegment);
- // } else {
- // segment1.push(inkSegment);
- // }
- // }
- // } else if (hasSplit) {
- // segment2.push(inkSegment);
// } else {
- // continueErasing = true;
+ // hasSplit ? segment1.push(inkSegment) : segment2.push(inkSegment);
// }
- // }
+
+ // if (tVals.length) {
+ // if (!hasSplit) {
+ // if (excludeT <= tVals[0] || (excludeT > tVals[0] && excludeT < tVals.lastElement()) || excludeT > tVals.lastElement() || continueErasing) {
+ // const closestTs = this.getClosestTs(tVals, excludeT, 0, tVals.length - 1);
+ // if (closestTs[0] != -1 && closestTs[1] != -1) {
+ // segment1.push(inkSegment.split(0, closestTs[0]));
+ // segment2.push(inkSegment.split(closestTs[1]).right);
+ // deletedSegments.push(inkSegment.split(closestTs[0], closestTs[1]));
+ // } else if (closestTs[0] == -1) {
+ // segment2.push(inkSegment.split(closestTs[1]).right);
+ // deletedSegments.push(inkSegment.split(closestTs[1]).left);
+ // if (excludeT > tVals[0]) {
+ // continueErasing = !continueErasing;
+ // }
+ // } else {
+ // continueErasing ? segment2.push(inkSegment.split(closestTs[0]).right) : segment1.push(inkSegment.split(0, closestTs[0]));
+ // continueErasing ? deletedSegments.push(inkSegment.split(closestTs[0]).left) : deletedSegments.push(inkSegment.split(closestTs[0]).right);
+ // continueErasing = !continueErasing;
+ // }
+ // if (!continueErasing) {
+ // hasSplit = true;
+ // }
+ // } else {
+ // if (hasSplit) {
+ // segment2.push(inkSegment);
+ // } else {
+ // segment1.push(inkSegment);
+ // }
+ // }
+ // } else if (excludeT > tVals[0] && excludeT < tVals.lastElement()) {
+ // // here we know hasSplit is true (but it shouldnt be!)
+ // segment1 = [...deletedSegments];
+ // deletedSegments = [];
+ // hasSplit = false;
+ // const closestTs = this.getClosestTs(tVals, excludeT, 0, tVals.length - 1);
+ // if (closestTs[0] != -1 && closestTs[1] != -1) {
+ // segment1.push(inkSegment.split(0, closestTs[0]));
+ // segment2.push(inkSegment.split(closestTs[1]).right);
+ // } else if (closestTs[0] == -1) {
+ // segment2.push(inkSegment.split(closestTs[1]).right);
+ // if (excludeT > tVals[0]) {
+ // continueErasing = !continueErasing;
+ // }
+ // }
+ // } else {
+ // segment2.push(inkSegment);
+ // }
+ // } else if (hasSplit) {
+ // segment2.push(inkSegment);
+ // } else {
+ // continueErasing = true;
+ // }
- // if (segment1.length && (Math.abs(segment1[0].points[0].x - segment1[0].points.lastElement().x) > 0.5 || Math.abs(segment1[0].points[0].y - segment1[0].points.lastElement().y) > 0.5)) {
- // segments.push(segment1);
- // }
- // if (segment2.length && (Math.abs(segment2[0].points[0].x - segment2[0].points.lastElement().x) > 0.5 || Math.abs(segment2[0].points[0].y - segment2[0].points.lastElement().y) > 0.5)) {
- // segments.push(segment2);
- // }
- // if (excludeT < startSegmentT || excludeT > inkData.length / 4) {
- // segment1.length && segments.push(segment1);
+
+
+
+ // if (hasSplit && i + 4 >= lastIteration && ((excludeT > tVals[0] && excludeT < tVals.lastElement()) || (excludeT > tVals.lastElement()))) {
+ // // here we know hasSplit is true (but it shouldnt be!)
+ // segment1 = [...deletedSegments];
+ // deletedSegments = [];
+ // hasSplit = false;
+ // const closestTs = this.getClosestTs(tVals, excludeT, 0, tVals.length - 1);
+ // if (closestTs[0] != -1 && closestTs[1] != -1) {
+ // segment1.push(inkSegment.split(0, closestTs[0]));
+ // segment2.push(inkSegment.split(closestTs[1]).right);
+ // } else if (closestTs[0] == -1) {
+ // segment2.push(inkSegment.split(closestTs[1]).right);
+ // if (excludeT > tVals[0]) {
+ // continueErasing = !continueErasing;
+ // }
+ // }
+ // }
// }
- // const tVals = []
+
+
+ // const segments: Segment[] = [];
+ // var segment1: Segment = [];
+ // var segment2: Segment = [];
+ // var startSegmentT = 0;
+ // var hasSplit = false;
+ // 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)
// for (var i = 0; i < inkData.length - 3; i += 4) {
// const inkSegment = InkField.Segment(inkData, i);
// // Getting all t-value intersections of the current curve with all other curves.
- // tVals.push(this.getInkIntersections(i, ink, inkSegment));
- // tVals.sort();
-
- // if (tVals.length) {
- // const docCurveTVal = tVals.lastElement() + Math.floor(i / 4);
- // if (excludeT > docCurveTVal) {
- // continue;
- // } else {
- // const closestTs = this.getClosestTs(tVals, excludeT, 0, tVals.length - 1);
- // segment.push(inkSegment.split(0, closestTs[0]));
- // if (segment.length && (Math.abs(segment[0].points[0].x - segment[0].points.lastElement().x) > 0.5 || Math.abs(segment[0].points[0].y - segment[0].points.lastElement().y) > 0.5)) {
- // segments.push(segment);
- // }
- // }
-
- // const closestT = this.getClosestT(tVals, excludeT, 0, tVals.length - 1);
- // if (closestT != undefined) {
- // var startSegmentT = closestT[0]
- // const localStartTVal = startSegmentT - Math.floor(i / 4);
- // segment.push(inkSegment.split(localStartTVal < 0 ? 0 : localStartTVal, startSegmentT))
- // if (segment.length && (Math.abs(segment[0].points[0].x - segment[0].points.lastElement().x) > 0.5 || Math.abs(segment[0].points[0].y - segment[0].points.lastElement().y) > 0.5)) {
- // segments.push(segment);
+ // const tVals = this.getInkIntersections(i, ink, inkSegment).sort();
+ // if (tVals.length) {
+ // tVals.forEach((t, index) => {
+ // const docCurveTVal = t + Math.floor(i / 4);
+ // if (excludeT < startSegmentT || excludeT > docCurveTVal) {
+ // const localStartTVal = startSegmentT - Math.floor(i / 4);
+ // if (!hasSplit) {
+ // t !== (localStartTVal < 0 ? 0 : localStartTVal) && segment1.push(inkSegment.split(localStartTVal < 0 ? 0 : localStartTVal, t));
+ // } else {
+ // t !== (localStartTVal < 0 ? 0 : localStartTVal) && segment2.push(inkSegment.split(localStartTVal < 0 ? 0 : localStartTVal, t));
+ // }
+ // // if (segment.length && (Math.abs(segment[0].points[0].x - segment[0].points.lastElement().x) > 0.5 || Math.abs(segment[0].points[0].y - segment[0].points.lastElement().y) > 0.5)) segments.push(segment);
// }
- // const split = inkSegment.split(closestT[1]).right;
- // if (split && (Math.abs(split.points[0].x - split.points.lastElement().x) > 0.5 || Math.abs(split.points[0].y - split.points.lastElement().y) > 0.5)) {
- // segments.push([split]);
+ // // start a new segment from the intersection t value
+ // if (tVals.length - 1 === index) {
+ // const split = inkSegment.split(t).right;
+ // if (!hasSplit) {
+ // if (split && (Math.abs(split.points[0].x - split.points.lastElement().x) > 0.5 || Math.abs(split.points[0].y - split.points.lastElement().y) > 0.5)) segment1.push(split);
+ // } else {
+ // if (split && (Math.abs(split.points[0].x - split.points.lastElement().x) > 0.5 || Math.abs(split.points[0].y - split.points.lastElement().y) > 0.5)) segment2.push(split);
+ // }
// }
- // }
+ // startSegmentT = docCurveTVal;
+ // });
// } else {
- // segment.push(inkSegment);
- // segments.push(segment);
+ // if (!hasSplit) {
+ // segment1.push(inkSegment);
+ // } else {
+ // segment2.push(inkSegment);
+ // }
// }
// }
- const segments: Segment[] = [];
- var segment1: Segment = [];
- var segment2: Segment = [];
- var startSegmentT = 0;
- var hasSplit = false;
- 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)
- for (var i = 0; i < inkData.length - 3; i += 4) {
- const inkSegment = InkField.Segment(inkData, i);
- // Getting all t-value intersections of the current curve with all other curves.
- const tVals = this.getInkIntersections(i, ink, inkSegment).sort();
- if (tVals.length) {
- tVals.forEach((t, index) => {
- const docCurveTVal = t + Math.floor(i / 4);
- if (excludeT < startSegmentT || excludeT > docCurveTVal) {
- const localStartTVal = startSegmentT - Math.floor(i / 4);
- if (!hasSplit) {
- t !== (localStartTVal < 0 ? 0 : localStartTVal) && segment1.push(inkSegment.split(localStartTVal < 0 ? 0 : localStartTVal, t));
- } else {
- t !== (localStartTVal < 0 ? 0 : localStartTVal) && segment2.push(inkSegment.split(localStartTVal < 0 ? 0 : localStartTVal, t));
- }
- // if (segment.length && (Math.abs(segment[0].points[0].x - segment[0].points.lastElement().x) > 0.5 || Math.abs(segment[0].points[0].y - segment[0].points.lastElement().y) > 0.5)) segments.push(segment);
- }
- // start a new segment from the intersection t value
- if (tVals.length - 1 === index) {
- const split = inkSegment.split(t).right;
- if (!hasSplit) {
- if (split && (Math.abs(split.points[0].x - split.points.lastElement().x) > 0.5 || Math.abs(split.points[0].y - split.points.lastElement().y) > 0.5)) segment1.push(split);
- } else {
- if (split && (Math.abs(split.points[0].x - split.points.lastElement().x) > 0.5 || Math.abs(split.points[0].y - split.points.lastElement().y) > 0.5)) segment2.push(split);
- }
- }
- startSegmentT = docCurveTVal;
- });
- } else {
- if (!hasSplit) {
- segment1.push(inkSegment);
- } else {
- segment2.push(inkSegment);
- }
- }
- }
- if (segment1.length && (Math.abs(segment1[0].points[0].x - segment1[0].points.lastElement().x) > 0.5 || Math.abs(segment1[0].points[0].y - segment1[0].points.lastElement().y) > 0.5)) {
- segments.push(segment1);
- }
- if (segment2.length && (Math.abs(segment2[0].points[0].x - segment2[0].points.lastElement().x) > 0.5 || Math.abs(segment2[0].points[0].y - segment2[0].points.lastElement().y) > 0.5)) {
- segments.push(segment2);
- }
+ // if (segment1.length && (Math.abs(segment1[0].points[0].x - segment1[0].points.lastElement().x) > 0.5 || Math.abs(segment1[0].points[0].y - segment1[0].points.lastElement().y) > 0.5)) {
+ // segments.push(segment1);
+ // }
+ // if (segment2.length && (Math.abs(segment2[0].points[0].x - segment2[0].points.lastElement().x) > 0.5 || Math.abs(segment2[0].points[0].y - segment2[0].points.lastElement().y) > 0.5)) {
+ // segments.push(segment2);
+ // }
return segments;
};
getClosestTs = (tVals: number[], excludeT: number, startIndex: number, endIndex: number): number[] => {
if (tVals[startIndex] >= excludeT) {
- return [-1, tVals[startIndex]];
+ return [-1, startIndex];
}
else if (tVals[endIndex] < excludeT) {
- return [tVals[endIndex], -1];
+ return [endIndex, -1];
}
else {
- const mid = Math.floor(startIndex + endIndex / 2);
+ const mid = Math.floor((startIndex + endIndex) / 2);
if (excludeT >= tVals[mid]) {
if (mid + 1 <= endIndex && tVals[mid + 1] > excludeT) {
- return [tVals[mid], tVals[mid + 1]];
+ return [mid, mid + 1];
} else {
return this.getClosestTs(tVals, excludeT, mid + 1, endIndex);
}
} else {
- if (mid - 1 <= startIndex && tVals[mid - 1] < excludeT) {
- return [tVals[mid - 1], tVals[mid]];
+ if (mid - 1 >= startIndex && tVals[mid - 1] < excludeT) {
+ return [mid - 1, mid];
} else {
return this.getClosestTs(tVals, excludeT, startIndex, mid - 1);
}