import { roadService } from "../Service/RoadService"; import { dataService } from "../Service/DataService"; import Constant from "../Constant"; import { mathUtil } from "../Util/MathUtil"; import { elementService } from "../Service/ElementService"; import { coordinate } from "../Coordinate"; export default class MoveRoad { constructor() { this.startMoving = false; this.moveFlag = false; //拖拽墙角的时候,墙角的父亲与其他墙角相交 this.adsorbPointRoads = {}; //拖拽墙角的时候,该墙角与其他墙面相交 this.splitRoadId = null; } setStartMoving(value) { this.startMoving = value; } // 测试要考虑pointId拖拽到包含他的所有墙的另一头 // 这个函数不会删除/拆分/合并墙或者点 movePoint(pointId, position, modifyPoint) { let point = dataService.getPoint(pointId); let linkedPointId = null; let linkedRoadId = null; if (modifyPoint != null) { position = { x: modifyPoint.x, y: modifyPoint.y, }; linkedPointId = modifyPoint.linkedPointId; linkedRoadId = modifyPoint.linkedRoadId; } this.adsorbPointRoads = {}; this.splitRoadId = null; let flag = this.canMoveForPoint( pointId, position, linkedPointId, linkedRoadId ); if (!flag) { if ( this.splitRoadId == null && Object.keys(this.adsorbPointRoads).length > 0 ) { //要吸附一下 const adsorbPointId = Object.keys(this.adsorbPointRoads)[0]; const road = dataService.getRoad(this.adsorbPointRoads[adsorbPointId]); const otherPointId = road.getOtherPointId(pointId); let otherPoint = dataService.getPoint(otherPointId); let modifyPoint = dataService.getPoint(adsorbPointId); let line = mathUtil.createLine1(otherPoint, modifyPoint); position = mathUtil.getJoinLinePoint(position, line); point.setPosition(position); } return false; } let newPosition = null; if (modifyPoint == null) { //90°或者180°纠正 //不考虑当前角度 //当前点的parent只有一个,考虑邻居点 let neighPoints = roadService.getNeighPoints(pointId); if (neighPoints.length == 1) { newPosition = elementService.checkAngle( position, neighPoints[0].vectorId, pointId ); } //当前点的parent有两个 else if (neighPoints.length == 2) { newPosition = elementService.checkAngle( position, neighPoints[0].vectorId, pointId ); if (!newPosition) { newPosition = elementService.checkAngle( position, neighPoints[1].vectorId, pointId ); } } if (newPosition) { flag = this.canMoveForPoint( pointId, newPosition, linkedPointId, linkedRoadId ); if (!flag) { return false; } mathUtil.clonePoint(position, newPosition); } point.setPosition(position); } // 与别的墙角重合 else if ( modifyPoint.hasOwnProperty("linkedPointId") && modifyPoint.linkedPointId != null ) { const roadId = roadService.getRoadId(pointId, modifyPoint.linkedPointId); // pointId与linkedPointId属于同一堵墙,不允许,所以不移动 if (roadId != null) { return false; } else { point.setPosition(modifyPoint); } } // 与别的墙面重合 // 如果墙面的交点与其余墙角的距离过短,那也不允许拖动 else if (modifyPoint.hasOwnProperty("linkedRoadId")) { const road = dataService.getRoad(modifyPoint.linkedRoadId); const startPoint = dataService.getPoint(road.startId); const endPoint = dataService.getPoint(road.endId); // 与其余墙角的距离过短,不允许拖动 if ( mathUtil.getDistance(startPoint, position) < Constant.minRealDis || mathUtil.getDistance(endPoint, position) < Constant.minRealDis ) { return false; } point.setPosition(modifyPoint); } else { if ( modifyPoint.hasOwnProperty("linkedPointIdX") && modifyPoint.linkedPointIdX ) { point.setPosition(position); } if ( modifyPoint.hasOwnProperty("linkedPointIdY") && modifyPoint.linkedPointIdY ) { point.setPosition(position); } } return true; } //拖拽墙角/墙面,被其他墙角吸附 updateForAbsorbRoadPoints() { if (Object.keys(this.adsorbPointRoads).length == 0) { return; } else if (Object.keys(this.adsorbPointRoads).length == 2) { debugger; } let joins = []; let roadId = null; for (let key in this.adsorbPointRoads) { let point = dataService.getPoint(key); joins.push({ join: point, pointId: key, }); roadId = this.adsorbPointRoads[key]; } const road = dataService.getRoad(roadId); const startPoint = dataService.getPoint(road.startId); function sortNumber(a, b) { return ( mathUtil.getDistance(startPoint, a.join) - mathUtil.getDistance(startPoint, b.join) ); } joins = joins.sort(sortNumber.bind(this)); for (let i = 0; i < joins.length; ++i) { const info = joins[i]; const join = info.join; const pointId = info.pointId; roadService.splitRoad(roadId, pointId, "end"); } } getNewPointsForMoveRoad(roadId, dx, dy) { dx = dx / coordinate.res; dy = -dy / coordinate.res; const road = dataService.getRoad(roadId); const startPoint = dataService.getPoint(road.startId); const endPoint = dataService.getPoint(road.endId); const p1 = { x: startPoint.x + dx, y: startPoint.y + dy }; const p2 = { x: endPoint.x + dx, y: endPoint.y + dy }; return { point1: p1, point2: p2, }; } getTwoLimitInfos(roadId, newLine) { const road = dataService.getRoad(roadId); const startPoint = dataService.getPoint(road.startId); const endPoint = dataService.getPoint(road.endId); let startLimitLine, endLimitLine, info; const roadLine = roadService.getMidLine(road); const limitInfos = {}; limitInfos.newStartRoadId = false; // 不需要新建墙 limitInfos.newEndRoadId = false; // 不需要新建墙 // 先处理start if (Object.keys(startPoint.parent).length == 1) { startLimitLine = mathUtil.getVerticalLine(roadLine, startPoint); limitInfos.startRoadId = null; } else if (Object.keys(startPoint.parent).length == 2) { let tempRoad; if (Object.keys(startPoint.parent)[0] == roadId) { tempRoad = dataService.getRoad(Object.keys(startPoint.parent)[1]); } else if (Object.keys(startPoint.parent)[1] == roadId) { tempRoad = dataService.getRoad(Object.keys(startPoint.parent)[0]); } if (!tempRoad) { console.error(352); } const angle = roadService.AngleForRoad(tempRoad.vectorId, roadId); startLimitLine = roadService.getMidLine(tempRoad); limitInfos.startRoadId = tempRoad.vectorId; if (angle > (Constant.maxAngle / 180) * Math.PI) { startLimitLine = mathUtil.getVerticalLine(roadLine, startPoint); limitInfos.startRoadId = null; limitInfos.newStartRoadId = true; } } else { let tempRoad, tempRoadId; info = roadService.roadIdForMinAngle(road.startId, roadId); const road1 = dataService.getRoad(info.min0.roadId); const startPoint1 = dataService.getPoint(road1.startId); const endPoint1 = dataService.getPoint(road1.endId); const road2 = dataService.getRoad(info.min1.roadId); const startPoint2 = dataService.getPoint(road2.startId); const endPoint2 = dataService.getPoint(road2.endId); const join1 = mathUtil.getIntersectionPoint4( startPoint1, endPoint1, newLine ); const join2 = mathUtil.getIntersectionPoint4( startPoint2, endPoint2, newLine ); // 取角度大的 if (join1 == null && join2 == null) { let angle0 = roadService.AngleForRoad(roadId, info.min0.roadId); let angle1 = roadService.AngleForRoad(roadId, info.min1.roadId); if (angle0 > Math.PI) { angle0 = Math.PI - angle0; } if (angle1 > Math.PI) { angle1 = Math.PI - angle1; } if (angle0 < angle1) { tempRoadId = info.min0.roadId; } else { tempRoadId = info.min1.roadId; } limitInfos.newStartRoadId = true; } // 取角度小的 else if (join1 != null && join2 != null) { if (info.min0.angle < info.min1.angle) { tempRoadId = info.min0.roadId; } else { tempRoadId = info.min1.roadId; } } else if (join1 == null && join2 != null) { tempRoadId = info.min1.roadId; } else if (join1 != null && join2 == null) { tempRoadId = info.min0.roadId; } limitInfos.startRoadId = tempRoadId; tempRoad = dataService.getRoad(tempRoadId); const angle = roadService.AngleForRoad(tempRoadId, roadId); startLimitLine = roadService.getMidLine(tempRoad); let join = mathUtil.getIntersectionPoint(startLimitLine, newLine); const tempStartPoint = dataService.getPoint(tempRoad.startId); const tempEndPoint = dataService.getPoint(tempRoad.endId); if ( angle > (Constant.maxAngle / 180) * Math.PI || !mathUtil.isPointOnSegment(join, tempStartPoint, tempEndPoint) ) { startLimitLine = mathUtil.getVerticalLine(roadLine, startPoint); limitInfos.startRoadId = null; limitInfos.newStartRoadId = true; } } // 再处理end if (Object.keys(endPoint.parent).length == 1) { endLimitLine = mathUtil.getVerticalLine(roadLine, endPoint); limitInfos.endRoadId = null; } else if (Object.keys(endPoint.parent).length == 2) { let tempRoad; if (Object.keys(endPoint.parent)[0] == roadId) { tempRoad = dataService.getRoad(Object.keys(endPoint.parent)[1]); } else if (Object.keys(endPoint.parent)[1] == roadId) { tempRoad = dataService.getRoad(Object.keys(endPoint.parent)[0]); } const angle = roadService.AngleForRoad(tempRoad.vectorId, roadId); endLimitLine = roadService.getMidLine(tempRoad); limitInfos.endRoadId = tempRoad.vectorId; if (angle > (Constant.maxAngle / 180) * Math.PI) { endLimitLine = mathUtil.getVerticalLine(roadLine, endPoint); limitInfos.endRoadId = null; limitInfos.newEndRoadId = true; } } else { let tempRoad, tempRoadId; info = dataService.roadIdForMinAngle(road.endId, roadId); const road1 = dataService.getRoad(info.min0.roadId); const startPoint1 = dataService.getPoint(road1.startId); const endPoint1 = dataService.getPoint(road1.endId); const road2 = dataService.getRoad(info.min1.roadId); const startPoint2 = dataService.getPoint(road2.startId); const endPoint2 = dataService.getPoint(road2.endId); const join1 = mathUtil.getIntersectionPoint4( startPoint1, endPoint1, newLine ); const join2 = mathUtil.getIntersectionPoint4( startPoint2, endPoint2, newLine ); // 取角度大的 if (join1 == null && join2 == null) { let angle0 = roadService.AngleForRoad(roadId, info.min0.roadId); let angle1 = roadService.AngleForRoad(roadId, info.min1.roadId); if (angle0 > Math.PI) { angle0 = Math.PI - angle0; } if (angle1 > Math.PI) { angle1 = Math.PI - angle1; } if (angle0 < angle1) { tempRoadId = info.min0.roadId; } else { tempRoadId = info.min1.roadId; } limitInfos.newEndRoadId = true; } // 取角度小的 else if (join1 != null && join2 != null) { if (info.min0.angle < info.min1.angle) { tempRoadId = info.min0.roadId; } else { tempRoadId = info.min1.roadId; } } else if (join1 == null && join2 != null) { tempRoadId = info.min1.roadId; } else if (join1 != null && join2 == null) { tempRoadId = info.min0.roadId; } limitInfos.endRoadId = tempRoadId; tempRoad = dataService.getRoad(tempRoadId); const angle = roadService.AngleForRoad(tempRoadId, roadId); endLimitLine = roadService.getMidLine(tempRoad); let join = mathUtil.getIntersectionPoint(endLimitLine, newLine); const tempStartPoint = dataService.getPoint(tempRoad.start); const tempEndPoint = dataService.getPoint(tempRoad.end); if ( angle > (Constant.maxAngle / 180) * Math.PI || !mathUtil.isPointOnSegment(join, tempStartPoint, tempEndPoint) ) { endLimitLine = mathUtil.getVerticalLine(roadLine, endPoint); limitInfos.endRoadId = null; limitInfos.newEndRoadId = true; } } limitInfos.startLimitLine = startLimitLine; limitInfos.endLimitLine = endLimitLine; return limitInfos; } // 是否可以移动point // 两个判断:拖拽的墙(可能是多个),一方面不能与其他墙相交,另一方面这些墙之间或者与别的墙之间的角度必须大于Constant.minAngle canMoveForPoint(pointId, position, linkedPointId, linkedRoadId) { const point = dataService.getPoint(pointId); // 先判断第二点(这些墙之间或者与别的墙之间的角度必须大于MinAngle) let flag = this.isOKForMinAngleRoad(pointId, position); // 开始考虑第一点 if (flag) { // 不仅仅角度,还有相交 flag = this.isOKForCross( pointId, position, point.parent, linkedPointId, linkedRoadId ); } return flag; } isOKForMinAngleRoad(pointId, position) { const point = dataService.getPoint(pointId); const parent = point.parent; const angle = this.getMinAngle(pointId, position); if (Math.abs(angle) < (Constant.minAngle / 180) * Math.PI) { return false; } // 判断邻居点 for (const key in parent) { const road = dataService.getRoad(key); const otherPointId = road.getOtherPointId(pointId); const info = this.getNeighMinAngle(otherPointId, key, position); if (info && Math.abs(info.angle) < (Constant.minAngle / 180) * Math.PI) { return false; } else { const otherPoint = dataService.getPoint(otherPointId); if (mathUtil.getDistance(position, otherPoint) < Constant.minRealDis) { return false; } } } return true; } //点pointId移动到position后,求出最小角度 getMinAngle(pointId, position) { const point = dataService.getPoint(pointId); const parent = point.parent; let angle = null; if (Object.keys(parent).length == 1) { return 2 * Math.PI; } else if (Object.keys(parent).length == 2) { const road1 = dataService.getRoad(Object.keys(parent)[0]); const road2 = dataService.getRoad(Object.keys(parent)[1]); const otherPointId1 = road1.getOtherPointId(pointId); const otherPoint1 = dataService.getPoint(otherPointId1); const otherPointId2 = road2.getOtherPointId(pointId); const otherPoint2 = dataService.getPoint(otherPointId2); angle = mathUtil.Angle(position, otherPoint1, otherPoint2); return angle; } else { const _position = { x: position.x + 1, y: position.y, }; let angles = []; for (const key in parent) { const road = dataService.getRoad(key); const otherPointId = road.getOtherPointId(pointId); const otherPoint = dataService.getPoint(otherPointId); if (mathUtil.equalPoint(_position, otherPoint)) { angles.push(0); continue; } else { let angle = mathUtil.Angle(position, _position, otherPoint); // 统一按照逆时针顺序 if (otherPoint.y < position.y) { angle = 2 * Math.PI - angle; } angles.push(angle); } } angles = angles.sort(sortNumber); let minAngle = 2 * Math.PI; for (let i = 0; i < angles.length - 1; ++i) { for (let j = i + 1; j < angles.length; ++j) { const _angle = angles[j] - angles[i]; if (_angle < minAngle) { minAngle = _angle; } } } const angle1 = angles[0]; const angle2 = angles[angles.length - 1]; if (angle1 < Math.PI && angle2 > Math.PI) { const dAngle = 2 * Math.PI + angle1 - angle2; if (dAngle < minAngle) { minAngle = dAngle; } } return minAngle; } function sortNumber(a, b) { return a - b; } } // 用于邻居点 // pointId是顶点 // position是roadId相对于pointId另一头的点的坐标,一般发生改变的时候使用这个函数 getNeighMinAngle(otherPointId, roadId, position) { const point1 = dataService.getPoint(otherPointId); const point2 = { x: position.x, y: position.y, }; let pointId3 = null; let point3 = null; let minAngle = null; let result = null; for (const key in point1.parent) { if (key == roadId) { continue; } const road = dataService.getRoad(key); pointId3 = road.getOtherPointId(otherPointId); point3 = dataService.getPoint(pointId3); const angle = mathUtil.Angle(point1, point2, point3); if (minAngle == null || minAngle > angle) { minAngle = angle; result = { angle: minAngle, pointId: pointId3, }; } } return result; } // linkedPointId,linkedRoadId表示吸附 // roadIds是pointId的parent isOKForCross(pointId, position, roadIds, linkedPointId, linkedRoadId) { const roads = dataService.getRoads(); for (const key in roads) { if (roadIds.hasOwnProperty(key)) { continue; } else if (linkedRoadId == key) { continue; } for (const _key in roadIds) { //相连就不用考虑了 if (roadService.isRoadLink(key, _key)) { continue; } const _road = dataService.getRoad(_key); const otherPointId = _road.getOtherPointId(pointId); const otherPoint = dataService.getPoint(otherPointId); const flag = this.isOKForCrossTwoRoad( position, otherPoint, key, linkedPointId, linkedRoadId, _road.vectorId ); // 交叉 if (!flag) { this.adsorbPointRoads = {}; return false; } } } //需要吸附了。 if (Object.keys(this.adsorbPointRoads).length > 0) { return false; } else if (this.splitRoadId != null) { return false; } // 不交叉 return true; } // position1表示拖拽的点的坐标(修复过了的) // position2对应墙的另一头坐标 // roadId表示其余的墙(与position1无关的墙) isOKForCrossTwoRoad( position1, position2, roadId, linkedPointId, linkedRoadId, dragRoadId ) { const road = dataService.getRoad(roadId); const startPoint = dataService.getPoint(road.startId); const endPoint = dataService.getPoint(road.endId); const join = mathUtil.getIntersectionPoint3( position1, position2, startPoint, endPoint ); if (join && road.startId != linkedPointId && road.endId != linkedPointId) { // 交叉了 this.splitRoadId = roadId; return true; } else { if (mathUtil.equalPoint(position1, position2)) { return true; } let line = mathUtil.createLine1(position1, position2); let join1 = mathUtil.getJoinLinePoint(startPoint, line); let join2 = mathUtil.getJoinLinePoint(endPoint, line); if ( mathUtil.getDistance(join1, startPoint) < Constant.minRealDis && mathUtil.PointInSegment(join1, position1, position2) ) { if (road.startId != linkedPointId) { // 交叉了 this.adsorbPointRoads[startPoint.vectorId] = dragRoadId; //为了找到全部的吸附点,暂时返回true,在外面一层再做判断 return true; } } else if ( mathUtil.getDistance(join2, endPoint) < Constant.minRealDis && mathUtil.PointInSegment(join2, position1, position2) ) { if (road.endId != linkedPointId) { // 交叉了 this.adsorbPointRoads[endPoint.vectorId] = dragRoadId; //为了找到全部的吸附点,暂时返回true,在外面一层再做判断 return true; } } line = mathUtil.createLine1(startPoint, endPoint); join1 = mathUtil.getJoinLinePoint(position1, line); join2 = mathUtil.getJoinLinePoint(position2, line); if ( mathUtil.getDistance(join1, position1) < Constant.minRealDis && mathUtil.PointInSegment(join1, startPoint, endPoint) ) { if ( road.startId != linkedPointId && road.endId != linkedPointId && roadId != linkedRoadId ) { // 交叉了 //return false return true; } } else if ( mathUtil.getDistance(join2, position2) < Constant.minRealDis && mathUtil.PointInSegment(join2, startPoint, endPoint) ) { if ( road.startId != linkedPointId && road.endId != linkedPointId && roadId != linkedRoadId ) { // 交叉了 //return false return true; } } } return true; } isOKForCrossTwoRoad2(position1, position2, roadId) { const road = dataService.getRoad(roadId); const startPoint = dataService.getPoint(road.startId); const endPoint = dataService.getPoint(road.endId); let flag = mathUtil.crossTwoLines( position1, position2, startPoint, endPoint, 0.01 ); if (flag) { // 交叉了 return false; } else { if (mathUtil.equalPoint(position1, position2)) { return true; } flag = this.isCoincide(position1, position2, roadId); if (!flag) { return false; } } return true; } isOKForCrossTwoRoad3(position1, position2, roadId) { const road = dataService.getRoad(roadId); const startPoint = dataService.getPoint(road.startId); const endPoint = dataService.getPoint(road.endId); const flag = mathUtil.crossTwoLines( position1, position2, startPoint, endPoint, 0.01 ); if (flag) { // 交叉了 return false; } else { if (mathUtil.equalPoint(position1, position2)) { return true; } let line = mathUtil.createLine1(position1, position2); let join1 = mathUtil.getJoinLinePoint(startPoint, line); const join2 = mathUtil.getJoinLinePoint(endPoint, line); if ( mathUtil.getDistance(join1, startPoint) < Constant.minRealDis && mathUtil.isPointOnSegment(join1, position1, position2) ) { // 交叉了 return false; } else if ( mathUtil.getDistance(join2, endPoint) < Constant.minRealDis && mathUtil.isPointOnSegment(join2, position1, position2) ) { // 交叉了 return false; } line = mathUtil.createLine1(startPoint, endPoint); join1 = mathUtil.getJoinLinePoint(position1, line); if ( mathUtil.getDistance(join1, position1) < Constant.minRealDis && roadService.isContain(road, join1) ) { // 交叉了 return false; } } return true; } isCoincide(position1, position2, roadId) { const road = dataService.getRoad(roadId); const startPoint = dataService.getPoint(road.startId); const endPoint = dataService.getPoint(road.endId); let line = mathUtil.createLine1(position1, position2); let join1 = mathUtil.getJoinLinePoint(startPoint, line); let join2 = mathUtil.getJoinLinePoint(endPoint, line); if ( mathUtil.getDistance(join1, startPoint) < Constant.minRealDis && mathUtil.PointInSegment(join1, position1, position2) ) { // 交叉了 return false; } else if ( mathUtil.getDistance(join2, endPoint) < Constant.minRealDis && mathUtil.PointInSegment(join2, position1, position2) ) { // 交叉了 return false; } line = mathUtil.createLine1(startPoint, endPoint); join1 = mathUtil.getJoinLinePoint(position1, line); join2 = mathUtil.getJoinLinePoint(position2, line); if ( mathUtil.getDistance(join1, position1) < Constant.minRealDis && roadService.isContain(road, join1) ) { // 交叉了 return false; } else if ( mathUtil.getDistance(join2, position2) < Constant.minRealDis && roadService.isContain(road, join2) ) { // 交叉了 return false; } return true; } // 更新virtualPosition(一般是吸附) updateVirtualPosition(pointId, virtualPosition, limitRoadId, needNew) { const limitRoad = dataService.getRoad(limitRoadId); const point = dataService.getPoint(pointId); let otherPointId, otherPoint; let adsorb = false; // 不需要新建墙 if (!needNew) { if (limitRoad != null) { otherPointId = limitRoad.getOtherPointId(pointId); otherPoint = dataService.getPoint(otherPointId); // 会吸附另一头 if ( mathUtil.getDistance(virtualPosition, otherPoint) < Constant.minRealDis || (!roadService.isContain(limitRoad, virtualPosition) && mathUtil.getDistance(virtualPosition, otherPoint) < mathUtil.getDistance(virtualPosition, point)) ) { mathUtil.clonePoint(virtualPosition, otherPoint); adsorb = true; } } } // 需要新建墙 else { // 新建的墙太短,不允许 if (mathUtil.getDistance(point, virtualPosition) < Constant.minRealDis) { return null; } } return { adsorb: adsorb, adsorbPointId: adsorb ? otherPointId : null, virtualPosition: virtualPosition, }; } // 两条线段的夹角,这两条线段分别有一个端点挨的很近 isOKForTwoSegmentsAngle(pointId, pointId1, pointId2) { const point = dataService.getPoint(pointId); const point1 = dataService.getPoint(pointId1); const point2 = dataService.getPoint(pointId2); const dx = point.x - point1.x; const dy = point.y - point1.y; const newPoint2 = { x: dx + point2.x, y: dy + point2.y, }; for (const key in point.parent) { const road = dataService.getRoad(key); const otherPointId = road.getOtherPointId(pointId); const otherPoint = dataService.getPoint(otherPointId); const angle = mathUtil.Angle(point, otherPoint, newPoint2); if (Math.abs(angle) < (Constant.minAngle / 180) * Math.PI) { return false; } } return true; } // 一头吸附后,是否会重合 // pointId属于roadId,当pointId吸附到adsorbPointId时 isCoincideForAdsorbOne(pointId, adsorbPointId, roadId) { if (pointId && adsorbPointId) { const road = dataService.getRoad(roadId); const otherPointId = road.getOtherPointId(pointId); const _roadId = roadService.getRoadId(otherPointId, adsorbPointId); if (_roadId != null) { return true; } } return false; } isCoincideForAdsorbOne2(roadId, adsorbPointId1, adsorbPointId2) { if (adsorbPointId1 && adsorbPointId2) { const _roadId = roadService.getRoadId(adsorbPointId1, adsorbPointId2); if (_roadId != null) { return true; } // 可能吸附的是两堵墙,但是这两堵墙呈180° else { let adsorbPoint = dataService.getPoint(adsorbPointId1); let parent = adsorbPoint.parent; for (const key in parent) { const angle = roadService.AngleForRoad3(roadId, key); if (Math.abs(angle) < (Constant.minAngle / 180) * Math.PI) { return true; } } adsorbPoint = dataService.getPoint(adsorbPointId2); parent = adsorbPoint.parent; for (const key in parent) { const angle = roadService.AngleForRoad3(roadId, key); if (Math.abs(angle) < (Constant.minAngle / 180) * Math.PI) { return true; } } } } return false; } // position1和position2表示road的两个端点坐标(下一步的) // position3和position4表示road的start一边的线段(startPoint——virtualStartPoint) // position5和position6表示road的end一边的线段(endPoint——virtualEndPoint) // adsorbPointId1对应start那一头的吸附点 // adsorbPointId2对应end那一头的吸附点 isOKForCrossForMoveRoad( position1, position2, roadId, startPointId, endPointId, adsorbPointId1, adsorbPointId2 ) { const startPoint = dataService.getPoint(startPointId); const endPoint = dataService.getPoint(endPointId); let flag = true; const roads = dataService.getRoads(); for (const key in roads) { if (key == roadId) { continue; } let flag1 = true; let flag2 = true; const _road = dataService.getRoad(key); if ( adsorbPointId1 && (adsorbPointId1 == _road.startId || adsorbPointId1 == _road.endId) ) { flag1 = false; } if ( adsorbPointId2 && (adsorbPointId2 == _road.startId || adsorbPointId2 == _road.endId) ) { flag2 = false; } if (_road.startId == startPointId || _road.endId == startPointId) { flag1 = false; } if (_road.startId == endPointId || _road.endId == endPointId) { flag2 = false; } // 两头不连 if (flag1 && flag2) { flag = this.isOKForCrossTwoRoad2(position1, position2, key); } if (!flag) { return false; } if ( flag1 && _road.startId != startPointId && _road.endId != startPointId ) { flag = this.isOKForCrossTwoRoad3(position1, startPoint, key); } if (!flag) { return false; } if (flag2 && _road.startId != endPointId && _road.endId != endPointId) { flag = this.isOKForCrossTwoRoad3(position2, endPoint, key); } if (!flag) { return false; } } return flag; } // 更新pointId的坐标 updatePointForMoveRoad(roadId, pointId, virtualInfo, limitRoadId, needNew) { const point = dataService.getPoint(pointId); const road = dataService.getRoad(roadId); // 如果没有约束墙,只有两种情况:一种是不新建墙,另一种是需要新建墙 if (limitRoadId == null) { // 不需要新建墙,这种情况一般是pointId的parent只有一个 if (!needNew) { point.setPosition(virtualInfo.virtualPosition); } // 新建墙 else { this.createRoadForMoveRoad( pointId, roadId, virtualInfo.virtualPosition ); } } else { /* 不新建墙: 1. 更新坐标(一种是当pointId的parent是2个,另一种是三个,但是roadId对应的两堵墙接近180°) 2. 拆分墙 3. 吸附邻居墙的另一个端点 新建墙: */ // 不新建墙 if (!needNew) { if (!virtualInfo.adsorb) { // 只更新坐标 if (Object.keys(point.parent).length == 2) { point.setPosition(virtualInfo.virtualPosition); } else { const info = roadService.roadIdForMinAngle(pointId, roadId); const angle = roadService.AngleForRoad( info.min0.roadId, info.min1.roadId ); // 只更新坐标 if ( Object.keys(point.parent).length == 3 && angle > (Constant.maxAngle / 180) * Math.PI ) { point.setPosition(virtualInfo.virtualPosition); } // 拆分墙 else { const dir = roadService.getDirction(pointId, roadId); // 先断开链接 roadService.subtraRoadFromIntersect(pointId, roadId); const newPointId = road.getPointId(dir); const newPoint = dataService.getPoint(newPointId); // 更新新坐标 newPoint.setPosition(virtualInfo.virtualPosition); // 拆分 roadService.splitRoad(limitRoadId, newPointId, dir); } } } // 吸附邻居墙的另一个端点。 else { roadService.moveTo(pointId, virtualInfo.adsorbPointId); } } // 新建墙 else { this.createRoadForMoveRoad( pointId, roadId, virtualInfo.virtualPosition ); } } } // createRoadForMoveRoad(pointId, roadId, newPosition) { const road = dataService.getRoad(roadId); const dir = roadService.getDirction(pointId, roadId); // 第一步是断开连接 roadService.subtraRoadFromIntersect(pointId, roadId); // 第二步更新端点坐标 const newPointId = road.getPointId(dir); const newPoint = dataService.getPoint(newPointId); newPoint.setPosition(newPosition); // 第三步先新建墙 roadService.create(pointId, newPointId); // 还缺少road和newRoad相交,这需要等另一头的point完成后最后处理 } deleteRoadForLinked(roadId) { const road = dataService.getRoad(roadId); roadService.subtraRoadFromIntersect(road.startId, roadId); roadService.subtraRoadFromIntersect(road.endId, roadId); dataService.deleteRoad(roadId); } } const moveRoad = new MoveRoad(); export { moveRoad };