Skip to content

Commit

Permalink
undo points based on order added to polygon (#11035)
Browse files Browse the repository at this point in the history
  • Loading branch information
hawkeye217 authored Apr 19, 2024
1 parent 5f15641 commit d6dfa59
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 52 deletions.
84 changes: 39 additions & 45 deletions web/src/components/settings/PolygonCanvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,20 @@ export function PolygonCanvas({

const addPointToPolygon = (polygon: Polygon, newPoint: number[]) => {
const points = polygon.points;
const pointsOrder = polygon.pointsOrder;

const [newPointX, newPointY] = newPoint;
const updatedPoints = [...points];

let updatedPointsOrder: number[];
if (!pointsOrder) {
updatedPointsOrder = [];
} else {
updatedPointsOrder = [...pointsOrder];
}

let insertIndex = points.length;

for (let i = 0; i < points.length; i++) {
const [x1, y1] = points[i];
const [x2, y2] = i === points.length - 1 ? points[0] : points[i + 1];
Expand All @@ -76,48 +87,16 @@ export function PolygonCanvas({
(y1 <= newPointY && newPointY <= y2) ||
(y2 <= newPointY && newPointY <= y1)
) {
const insertIndex = i + 1;
updatedPoints.splice(insertIndex, 0, [newPointX, newPointY]);
insertIndex = i + 1;
break;
}
}
}

return updatedPoints;
};

const isPointNearLineSegment = (
polygon: Polygon,
mousePos: number[],
radius = 10,
) => {
const points = polygon.points;
const [x, y] = mousePos;

for (let i = 0; i < points.length; i++) {
const [x1, y1] = points[i];
const [x2, y2] = i === points.length - 1 ? points[0] : points[i + 1];

const crossProduct = (x - x1) * (x2 - x1) + (y - y1) * (y2 - y1);
if (crossProduct > 0) {
const lengthSquared = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
const dot = (x - x1) * (x2 - x1) + (y - y1) * (y2 - y1);
if (dot < 0 || dot > lengthSquared) {
continue;
}
const lineSegmentDistance = Math.abs(
((y2 - y1) * x - (x2 - x1) * y + x2 * y1 - y2 * x1) /
Math.sqrt(Math.pow(y2 - y1, 2) + Math.pow(x2 - x1, 2)),
);
if (lineSegmentDistance <= radius) {
const midPointX = (x1 + x2) / 2;
const midPointY = (y1 + y2) / 2;
return [midPointX, midPointY];
}
}
}
updatedPoints.splice(insertIndex, 0, [newPointX, newPointY]);
updatedPointsOrder.splice(insertIndex, 0, updatedPoints.length);

return null;
return { updatedPoints, updatedPointsOrder };
};

const isMouseOverFirstPoint = (polygon: Polygon, mousePos: number[]) => {
Expand Down Expand Up @@ -176,18 +155,15 @@ export function PolygonCanvas({
!activePolygon.isFinished &&
!isMouseOverAnyPoint(activePolygon, mousePos)
) {
let updatedPoints;

if (isPointNearLineSegment(activePolygon, mousePos)) {
// we've clicked near a line segment, so add a new point in the right position
updatedPoints = addPointToPolygon(activePolygon, mousePos);
} else {
// Add a new point to the active polygon
updatedPoints = [...activePolygon.points, mousePos];
}
const { updatedPoints, updatedPointsOrder } = addPointToPolygon(
activePolygon,
mousePos,
);

updatedPolygons[activePolygonIndex] = {
...activePolygon,
points: updatedPoints,
pointsOrder: updatedPointsOrder,
};
setPolygons(updatedPolygons);
}
Expand Down Expand Up @@ -318,6 +294,24 @@ export function PolygonCanvas({
e.target.getStage()!.container().style.cursor = "crosshair";
};

useEffect(() => {
if (activePolygonIndex === undefined || !polygons) {
return;
}

const updatedPolygons = [...polygons];
const activePolygon = updatedPolygons[activePolygonIndex];

// add default points order for already completed polygons
if (!activePolygon.pointsOrder && activePolygon.isFinished) {
updatedPolygons[activePolygonIndex] = {
...activePolygon,
pointsOrder: activePolygon.points.map((_, index) => index),
};
setPolygons(updatedPolygons);
}
}, [activePolygonIndex, polygons, setPolygons]);

return (
<Stage
ref={stageRef}
Expand Down
31 changes: 25 additions & 6 deletions web/src/components/settings/PolygonEditControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,31 @@ export default function PolygonEditControls({

const updatedPolygons = [...polygons];
const activePolygon = updatedPolygons[activePolygonIndex];
updatedPolygons[activePolygonIndex] = {
...activePolygon,
points: [...activePolygon.points.slice(0, -1)],
isFinished: false,
};
setPolygons(updatedPolygons);

if (
activePolygon.points.length > 0 &&
activePolygon.pointsOrder &&
activePolygon.pointsOrder.length > 0
) {
const lastPointOrderIndex = activePolygon.pointsOrder.indexOf(
Math.max(...activePolygon.pointsOrder),
);

updatedPolygons[activePolygonIndex] = {
...activePolygon,
points: [
...activePolygon.points.slice(0, lastPointOrderIndex),
...activePolygon.points.slice(lastPointOrderIndex + 1),
],
pointsOrder: [
...activePolygon.pointsOrder.slice(0, lastPointOrderIndex),
...activePolygon.pointsOrder.slice(lastPointOrderIndex + 1),
],
isFinished: false,
};

setPolygons(updatedPolygons);
}
};

const reset = () => {
Expand Down
2 changes: 1 addition & 1 deletion web/src/types/canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export type Polygon = {
type: PolygonType;
objects: string[];
points: number[][];
pointsOrder?: number[];
isFinished: boolean;
// isUnsaved: boolean;
color: number[];
};

Expand Down

0 comments on commit d6dfa59

Please sign in to comment.