|
@@ -1,19 +1,34 @@
|
|
|
|
+import { MathUtils, Vector2 } from "three";
|
|
import { DEV } from "../../../env";
|
|
import { DEV } from "../../../env";
|
|
import {
|
|
import {
|
|
getLineIntersection,
|
|
getLineIntersection,
|
|
getLineDist,
|
|
getLineDist,
|
|
getLineNearPointDist,
|
|
getLineNearPointDist,
|
|
|
|
+ getDire2Angle,
|
|
|
|
+ getLineDire,
|
|
|
|
+ getVerticalDire,
|
|
|
|
+ createLineByDire,
|
|
|
|
+ getLineProjection,
|
|
} from "../../../shared/math";
|
|
} from "../../../shared/math";
|
|
-import { WholeLineAttrib, WholeLinePointAttrib } from "../view/";
|
|
|
|
|
|
+import {
|
|
|
|
+ WholeLineAttrib,
|
|
|
|
+ WholeLineLineAttrib,
|
|
|
|
+ WholeLinePointAttrib,
|
|
|
|
+} from "../view/";
|
|
import {
|
|
import {
|
|
WHOLE_LINE_POINT_EQ_DIST,
|
|
WHOLE_LINE_POINT_EQ_DIST,
|
|
WHOLE_LINE_POINT_MERGE_DIST,
|
|
WHOLE_LINE_POINT_MERGE_DIST,
|
|
} from "./constant";
|
|
} from "./constant";
|
|
import {
|
|
import {
|
|
|
|
+ generateWholeLineLineId,
|
|
|
|
+ generateWholeLinePointId,
|
|
|
|
+ getWholeLineLinesRawByPoint,
|
|
|
|
+ getWholeLineLinesRawByPointId,
|
|
getWholeLinePoint,
|
|
getWholeLinePoint,
|
|
getWholeLinePoints,
|
|
getWholeLinePoints,
|
|
getWholeLinePolygonLines,
|
|
getWholeLinePolygonLines,
|
|
getWholeLinePolygonLinesByPoint,
|
|
getWholeLinePolygonLinesByPoint,
|
|
|
|
+ wholeLineAddLineByPointIds,
|
|
wholeLineLineAddPoint,
|
|
wholeLineLineAddPoint,
|
|
wholeLineReplacePoint,
|
|
wholeLineReplacePoint,
|
|
} from "./whole-line-base";
|
|
} from "./whole-line-base";
|
|
@@ -353,7 +368,7 @@ export const spliceWholeLineLineByPoint = (
|
|
config: WholeLineAttrib,
|
|
config: WholeLineAttrib,
|
|
pointId: string
|
|
pointId: string
|
|
) => {
|
|
) => {
|
|
- spliceWholeLineLineByLines(
|
|
|
|
|
|
+ return spliceWholeLineLineByLines(
|
|
config,
|
|
config,
|
|
getWholeLinePolygonLinesByPoint(config, pointId).reduce((t, c) => {
|
|
getWholeLinePolygonLinesByPoint(config, pointId).reduce((t, c) => {
|
|
t.push(...c.lines);
|
|
t.push(...c.lines);
|
|
@@ -435,3 +450,160 @@ export const mergeWholeLinePointsByPoint = (
|
|
change,
|
|
change,
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 获取挪动线段当前线段两点的位置
|
|
|
|
+ * @param config
|
|
|
|
+ * @param lineAttrib
|
|
|
|
+ * @param initPosition 线段初始位置
|
|
|
|
+ * @param move 移动向量
|
|
|
|
+ */
|
|
|
|
+export const moveWholeLineLine = (
|
|
|
|
+ config: WholeLineAttrib,
|
|
|
|
+ lineAttrib: WholeLineLineAttrib,
|
|
|
|
+ initPosition: number[][],
|
|
|
|
+ move: number[],
|
|
|
|
+ maxAngle = 160
|
|
|
|
+) => {
|
|
|
|
+ console.log(lineAttrib);
|
|
|
|
+ const linePointIds = lineAttrib.pointIds;
|
|
|
|
+ const moveDire = new Vector2(move[0], move[1]).normalize().toArray();
|
|
|
|
+ const pointJointLineDires: (number[] | null)[] = [];
|
|
|
|
+ const poinJointLineIds: (string | null)[] = [];
|
|
|
|
+ const isSplitPoints: boolean[] = [];
|
|
|
|
+
|
|
|
|
+ // 获取参考线段,夹角最小,雨move向量夹角最小的优先
|
|
|
|
+ for (let i = 0; i < 2; i++) {
|
|
|
|
+ const curPointId = linePointIds[i];
|
|
|
|
+ const joinLines = getWholeLineLinesRawByPointId(config, curPointId).filter(
|
|
|
|
+ (line) =>
|
|
|
|
+ !(
|
|
|
|
+ line.pointIds.includes(linePointIds[0]) &&
|
|
|
|
+ line.pointIds.includes(linePointIds[1])
|
|
|
|
+ )
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ const line = getWholeLinePoints(config, [
|
|
|
|
+ linePointIds[i],
|
|
|
|
+ linePointIds[i === 0 ? 1 : 0],
|
|
|
|
+ ]);
|
|
|
|
+ const lineDire = getLineDire([line[0].x, line[0].y, line[1].x, line[1].y]);
|
|
|
|
+
|
|
|
|
+ let invAngle = Number.MAX_VALUE;
|
|
|
|
+ let invSelectLineId: string;
|
|
|
|
+ let invSelectLineDire: number[] | null = null;
|
|
|
|
+
|
|
|
|
+ let alongAngle = -Number.MAX_VALUE;
|
|
|
|
+ let alongSelectLineId: string;
|
|
|
|
+ let alongSelectLineDire: number[] | null;
|
|
|
|
+
|
|
|
|
+ for (let { pointIds: joinPointIds, id } of joinLines) {
|
|
|
|
+ joinPointIds = [
|
|
|
|
+ linePointIds[i],
|
|
|
|
+ ...joinPointIds.filter((id) => id !== linePointIds[i]),
|
|
|
|
+ ];
|
|
|
|
+ const joinLine = getWholeLinePoints(config, joinPointIds);
|
|
|
|
+ const joinLineDire = getLineDire([
|
|
|
|
+ joinLine[0].x,
|
|
|
|
+ joinLine[0].y,
|
|
|
|
+ joinLine[1].x,
|
|
|
|
+ joinLine[1].y,
|
|
|
|
+ ]);
|
|
|
|
+ // if (["10", "14"].includes(id)) {
|
|
|
|
+ // continue;
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ const currentAngle = getDire2Angle(lineDire, joinLineDire);
|
|
|
|
+ // 逆时针
|
|
|
|
+ if (currentAngle > 0) {
|
|
|
|
+ if (currentAngle < invAngle) {
|
|
|
|
+ invAngle = currentAngle;
|
|
|
|
+ invSelectLineId = id;
|
|
|
|
+ invSelectLineDire = joinLineDire;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ if (currentAngle > alongAngle) {
|
|
|
|
+ alongAngle = currentAngle;
|
|
|
|
+ alongSelectLineId = id;
|
|
|
|
+ alongSelectLineDire = joinLineDire;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ let pointJointLineDire: number[] | null = null;
|
|
|
|
+ let angle: number | null = null;
|
|
|
|
+ let selectLineId: string | null = null;
|
|
|
|
+
|
|
|
|
+ if (!invSelectLineDire || !alongSelectLineDire) {
|
|
|
|
+ pointJointLineDire = invSelectLineDire || alongSelectLineDire;
|
|
|
|
+ selectLineId = invSelectLineId || alongSelectLineId;
|
|
|
|
+ angle = invAngle | alongAngle;
|
|
|
|
+ } else if (
|
|
|
|
+ Math.abs(getDire2Angle(moveDire, invSelectLineDire)) <
|
|
|
|
+ Math.abs(getDire2Angle(moveDire, alongSelectLineDire))
|
|
|
|
+ ) {
|
|
|
|
+ pointJointLineDire = invSelectLineDire;
|
|
|
|
+ selectLineId = invSelectLineId;
|
|
|
|
+ angle = invAngle;
|
|
|
|
+ } else {
|
|
|
|
+ pointJointLineDire = alongSelectLineDire;
|
|
|
|
+ selectLineId = alongSelectLineId;
|
|
|
|
+ angle = alongAngle;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ let isSplitPoint = joinLines.length > 2;
|
|
|
|
+ // 需要判定,如果参考线与当前线段夹角超过多少则不适合作为参考线
|
|
|
|
+ if (
|
|
|
|
+ pointJointLineDire !== null &&
|
|
|
|
+ Math.abs(MathUtils.radToDeg(angle)) > maxAngle
|
|
|
|
+ ) {
|
|
|
|
+ selectLineId = null;
|
|
|
|
+ pointJointLineDire = getVerticalDire(pointJointLineDire);
|
|
|
|
+ isSplitPoint = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pointJointLineDires.push(pointJointLineDire);
|
|
|
|
+ poinJointLineIds.push(selectLineId);
|
|
|
|
+ isSplitPoints.push(isSplitPoint);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const positions = [
|
|
|
|
+ [initPosition[0][0] + move[0], initPosition[0][1] + move[1]],
|
|
|
|
+ [initPosition[1][0] + move[0], initPosition[1][1] + move[1]],
|
|
|
|
+ ];
|
|
|
|
+ const pointAttribs = getWholeLinePoints(config, lineAttrib.pointIds);
|
|
|
|
+ if (pointJointLineDires[0] || !pointJointLineDires[1]) {
|
|
|
|
+ for (let i = 0; i < pointJointLineDires.length; i++) {
|
|
|
|
+ const joinDire =
|
|
|
|
+ pointJointLineDires[i] === null
|
|
|
|
+ ? pointJointLineDires[0] || pointJointLineDires[1]
|
|
|
|
+ : pointJointLineDires[i];
|
|
|
|
+ const isSplit = isSplitPoints[i];
|
|
|
|
+ const joinLine = createLineByDire(joinDire, initPosition[i], 10);
|
|
|
|
+
|
|
|
|
+ if (isSplit) {
|
|
|
|
+ const addPointId = generateWholeLinePointId(config);
|
|
|
|
+ config.points.push({
|
|
|
|
+ ...pointAttribs[i],
|
|
|
|
+ id: addPointId,
|
|
|
|
+ });
|
|
|
|
+ config.lines.forEach((line) => {
|
|
|
|
+ if (line === lineAttrib) return;
|
|
|
|
+ const ndx = line.pointIds.indexOf(pointAttribs[i].id);
|
|
|
|
+ if (~ndx) {
|
|
|
|
+ line.pointIds[ndx] = addPointId;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ console.log(wholeLineLineAddPoint(config, pointAttribs, addPointId));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ positions[i] = getLineProjection(joinLine, positions[i]).point;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // console.log(positions);
|
|
|
|
+ pointAttribs[0].x = positions[0][0];
|
|
|
|
+ pointAttribs[0].y = positions[0][1];
|
|
|
|
+ pointAttribs[1].x = positions[1][0];
|
|
|
|
+ pointAttribs[1].y = positions[1][1];
|
|
|
|
+};
|