【发布时间】:2021-07-03 01:42:30
【问题描述】:
我目前正在画布中绘制两个随机多边形,并希望找到它们的交点,这样我就可以使用这些 x 和 y 坐标在最后将多边形合并为一个。即使多边形相互交叉,它的坐标也不匹配。如果有什么方法可以找到,请告诉我?
const Canvas: React.FC = () => {
const canvasRef = useRef<HTMLCanvasElement>(null);
const [drawingState, setDrawingState] = useState<boolean>(false);
const [startingStateX, setStartingStateX] = useState(0);
const [startingStateY, setStartingStateY] = useState(0);
const [currentDrawing, setCurrentDrawing] = useState<number[][]>([]);
const [drawnObject, setDrawnObject] = useState<number[][][]>([]);
const { current } = canvasRef;
let ctx: CanvasRenderingContext2D | null;
if (current !== null) {
ctx = current.getContext("2d");
}
const initiateDrawing = (x: number, y: number) => {
setDrawingState(true);
setStartingStateX(x);
setStartingStateY(y);
draw(x, y);
};
const draw = (x: number, y: number) => {
if (drawingState && ctx !== null) {
ctx.lineWidth = 1;
ctx.lineCap = "round";
ctx.lineTo(x, y);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(x, y);
setCurrentDrawing((prev: number[][]) => [...prev, [x, y]]);
}
};
const endDrawing = () => {
setDrawingState(false);
if (ctx !== null) {
ctx.lineWidth = 1;
ctx.lineCap = "round";
ctx.lineTo(startingStateX, startingStateY);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
setDrawnObject((prev: number[][][]) => [...prev, currentDrawing]);
setCurrentDrawing([]);
}
};
return (
<>
<div id="canvasWrapper">
<canvas
onMouseDown={(e) => initiateDrawing(e.clientX, e.clientY)}
onMouseUp={endDrawing}
onMouseMove={(e) => draw(e.clientX, e.clientY)}
ref={canvasRef}
width={window.innerWidth * 0.8}
height={window.innerHeight}
/>
</div>
<List drawnObject={drawnObject} />
</>
);
};
export default Canvas;
底部是我找到交叉点的逻辑。
interface listProps {
drawnObject: number[][][];
}
const List: React.FC<listProps> = (props: listProps) => {
const [clickedPolygon, setClickedPolygon] = useState<number[][][]>([]);
const [clickedIndex, setClickedIndex] = useState<number[]>([]);
const handleClickedPolygon = (index: number, polygon: number[][]) => {
const checkIndex = clickedIndex.indexOf(index);
if (checkIndex === -1) {
setClickedIndex((prev: number[]) => [...prev, index]);
setClickedPolygon((prev: number[][][]) => [
...prev,
props.drawnObject[index],
]);
} else {
const updatedIndexList = clickedIndex.filter((el) => el !== index);
setClickedIndex(updatedIndexList);
const updatedPolygonList = clickedPolygon.filter((el, i) => i !== index);
setClickedPolygon(updatedPolygonList);
}
};
const findCrossingPoint = () => {
const maxIndex = clickedPolygon.reduce(
(acc, cur, idx, arr) => (arr[acc].length >= cur.length ? acc : idx),
0
);
const startPolygon = clickedPolygon[maxIndex];
for (let i = 0; i < startPolygon.length; i++) {
for (let j = 0; j < clickedPolygon.length; j++) {
if (j !== maxIndex) {
for (let k = 0; k < clickedPolygon[j].length; k++) {
if (
startPolygon[i][0] === clickedPolygon[j][k][0] &&
startPolygon[i][1] === clickedPolygon[j][k][1]
) {
console.log(startPolygon[i][0]);
}
}
}
}
}
};
return (
<div id="listContainer">
{props.drawnObject.length !== 0 &&
props.drawnObject.map((object, index) => (
<div key={index} className="object">
<input
id="object"
type="checkbox"
onClick={() => handleClickedPolygon(index, object)}
/>
<label htmlFor="object">Polygon {index}</label>
</div>
))}
{props.drawnObject.length !== 0 && (
<div id="buttonContainer">
<div onClick={findCrossingPoint}>merge selected</div>
<div onClick={() => console.log(props.drawnObject)}>export all</div>
</div>
)}
</div>
);
};
export default List;
【问题讨论】:
-
不确定您的问题是什么,但由于使用了不存在的事件,您提供的代码将无法正常工作。
onMouseDown、onMouseUp和onMouseMove,应该是onmousedown、onmouseup和onmousemove,由于某种原因,所有 DOM 事件都只使用小写名称(猜测某个地方的人没有得到camelCase备忘录制定规格时)
标签: javascript reactjs html5-canvas