1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414 |
- 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;
- }
- // // 拖拽墙面
- // moveRoadPlane(roadId, dx, dy) {
- // // 1表示可以继续移动,2表示不能移动(启动距离还不够),3表示wallId被删除了,4表示重新开始移动(需要达到一定距离才能启动),5表示不能移动(不合适)
- // let MoveState = 1;
- // let road = dataService.getRoad(roadId);
- // let startPointId = road.startId;
- // let endPointId = road.endId;
- // let startPoint = dataService.getPoint(road.startId);
- // let endPoint = dataService.getPoint(road.endId);
- // // 不考虑约束的情况,得到移动后的坐标
- // const newpts = this.getNewPointsForMoveRoad(roadId, dx, dy);
- // let newLine = mathUtil.createLine1(newpts.point1, newpts.point2);
- // // 获取约束信息,包括:是否新建墙,受约束的侧墙
- // const limit = this.getTwoLimitInfos(roadId, newLine);
- // this.needUpdateRoom = false;
- // // 不考虑吸附的情况下,经过约束条件后,得到的新的移动后的坐标
- // let virtualStartPoint = mathUtil.getIntersectionPoint(
- // newLine,
- // limit.startLimitLine
- // );
- // let virtualEndPoint = mathUtil.getIntersectionPoint(
- // newLine,
- // limit.endLimitLine
- // );
- // // 刚刚开始移动的时候,或者吸附后再移动的时候,都需要积累一点移动距离才能真正开始移动
- // if (
- // !this.startMoving &&
- // (mathUtil.getDistance(startPoint, virtualStartPoint) <
- // Constant.minRealDis ||
- // mathUtil.getDistance(endPoint, virtualEndPoint) < Constant.minRealDis)
- // ) {
- // this.moveFlag = false;
- // MoveState = 2;
- // return MoveState;
- // }
- // this.setStartMoving(true);
- // // 判断是否会吸附到邻居墙的另一头端点,同时确保新的坐标在邻居墙内
- // let startInfo = this.updateVirtualPosition(
- // road.startId,
- // virtualStartPoint,
- // limit.startWallId,
- // limit.newStartWallId
- // );
- // let endInfo = this.updateVirtualPosition(
- // road.endId,
- // virtualEndPoint,
- // limit.endWallId,
- // limit.newEndWallId
- // );
- // if (startInfo == null || endInfo == null) {
- // this.moveFlag = false;
- // MoveState = 2;
- // this.setStartMoving(false);
- // return MoveState;
- // }
- // // 判断wallId的 1端/2端 吸附后,是否和别的墙重合
- // let coincideFlag = false;
- // // wallId的长度,可能会很短,要删除
- // let distance = null;
- // // 如果一头被吸附,另一头的坐标还要再次调整
- // if (startInfo.adsorb && !endInfo.adsorb) {
- // // 先更新newLine
- // newLine = mathUtil.createLine3(newLine, startInfo.virtualPosition);
- // // 需要判断夹角,如果接近0,则不能移动
- // const flag = this.isOKForTwoSegmentsAngle(
- // startInfo.adsorbPointId,
- // road.startId,
- // road.endId
- // );
- // if (!flag) {
- // this.moveFlag = false;
- // MoveState = 5;
- // return MoveState;
- // }
- // // 更新virtualEndPoint
- // virtualEndPoint = mathUtil.getIntersectionPoint(
- // newLine,
- // limit.endLimitLine
- // );
- // // 再次判断是否吸附
- // endInfo = this.updateVirtualPosition(
- // road.endId,
- // virtualEndPoint,
- // limit.endWallId,
- // limit.newEndWallId
- // );
- // if (endInfo == null) {
- // endInfo = {
- // adsorb: false,
- // adsorbPointId: null,
- // virtualPosition: virtualEndPoint,
- // };
- // }
- // // 一头吸附后,wallId可能和别的墙重合
- // coincideFlag = this.isCoincideForAdsorbOne(
- // road.startId,
- // startInfo.adsorbPointId,
- // roadId
- // );
- // distance = mathUtil.getDistance(
- // startInfo.virtualPosition,
- // virtualEndPoint
- // );
- // MoveState = 4;
- // this.needUpdateRoom = true;
- // this.setStartMoving(false);
- // } else if (!startInfo.adsorb && endInfo.adsorb) {
- // newLine = mathUtil.createLine3(newLine, endInfo.virtualPosition);
- // // 需要判断夹角,如果接近0,则不能移动
- // const flag = this.isOKForTwoSegmentsAngle(
- // endInfo.adsorbPointId,
- // road.endId,
- // road.startId
- // );
- // if (!flag) {
- // this.moveFlag = false;
- // MoveState = 5;
- // return MoveState;
- // }
- // virtualStartPoint = mathUtil.getIntersectionPoint(
- // newLine,
- // limit.startLimitLine
- // );
- // startInfo = this.updateVirtualPosition(
- // road.startId,
- // virtualStartPoint,
- // limit.startWallId,
- // limit.newStartWallId
- // );
- // if (startInfo == null) {
- // startInfo = {
- // adsorb: false,
- // adsorbPointId: null,
- // virtualPosition: virtualStartPoint,
- // };
- // }
- // coincideFlag = this.isCoincideForAdsorbOne(
- // road.endId,
- // endInfo.adsorbPointId,
- // roadId
- // );
- // distance = mathUtil.getDistance(
- // endInfo.virtualPosition,
- // virtualStartPoint
- // );
- // MoveState = 4;
- // this.needUpdateRoom = true;
- // this.setStartMoving(false);
- // }
- // // 两头同时吸附呢,wallId可能和别的墙重合
- // if (startInfo && endInfo && startInfo.adsorb && endInfo.adsorb) {
- // coincideFlag = this.isCoincideForAdsorbOne2(
- // roadId,
- // startInfo.adsorbPointId,
- // endInfo.adsorbPointId
- // );
- // distance = mathUtil.getDistance(
- // startInfo.virtualPosition,
- // endInfo.virtualPosition
- // );
- // this.setStartMoving(false);
- // if (coincideFlag) {
- // this.moveFlag = false;
- // MoveState = 5;
- // return MoveState;
- // }
- // MoveState = 4;
- // this.needUpdateRoom = true;
- // } else {
- // distance = mathUtil.getDistance(virtualStartPoint, virtualEndPoint);
- // if (distance < Constant.minRealDis) {
- // // 执行deleteWallForLinked后start和end会变,所以提前保存
- // this.deleteWallForLinked(roadId);
- // startPoint = dataService.getPoint(startPointId);
- // endPoint = dataService.getPoint(endPointId);
- // if (!startPoint || !endPoint) {
- // this.moveFlag = false;
- // MoveState = 3;
- // this.needUpdateRoom = true;
- // return MoveState;
- // }
- // if (
- // (Object.keys(startPoint.parent).length > 1 &&
- // Object.keys(endPoint.parent).length == 1) ||
- // (Object.keys(startPoint.parent).length == 1 &&
- // Object.keys(endPoint.parent).length == 1)
- // ) {
- // roadService.moveTo(endPointId, startPointId);
- // } else if (
- // Object.keys(startPoint.parent).length == 1 &&
- // Object.keys(endPoint.parent).length > 1
- // ) {
- // roadService.moveTo(startPointId, endPointId);
- // }
- // this.moveFlag = false;
- // MoveState = 3;
- // this.needUpdateRoom = true;
- // return MoveState;
- // }
- // }
- // startPointId = road.startId;
- // endPointId = road.endId;
- // // 是否交叉
- // const crossFlag = this.isOKForCrossForMoveRoad(
- // virtualStartPoint,
- // virtualEndPoint,
- // roadId,
- // startPointId,
- // endPointId,
- // startInfo.adsorbPointId,
- // endInfo.adsorbPointId
- // );
- // // ok
- // if (!crossFlag) {
- // MoveState = 2;
- // this.moveFlag = false;
- // this.setStartMoving(false);
- // return MoveState;
- // }
- // // 要删除墙了
- // if (coincideFlag || (distance != null && distance < Constant.minRealDis)) {
- // this.deleteWallForLinked(roadId);
- // MoveState = 3;
- // // 删除完墙,邻居墙可能会合并
- // roadService.mergeWallForPoint(startPointId);
- // roadService.mergeWallForPoint(endPointId);
- // this.moveFlag = false;
- // this.needUpdateRoom = true;
- // return MoveState;
- // } else {
- // // 要删除墙了
- // const join = mathUtil.getIntersectionPoint3(
- // startPoint,
- // virtualStartPoint,
- // endPoint,
- // virtualEndPoint
- // );
- // if (join != null) {
- // startPoint.setPosition(join);
- // endPoint.setPosition(join);
- // roadService.moveTo(startPointId, endPointId);
- // MoveState = 3;
- // this.moveFlag = false;
- // this.needUpdateRoom = true;
- // return MoveState;
- // }
- // }
- // let overlapFlag = false;
- // if (!limit.newStartWallId && startInfo.adsorbPointId) {
- // overlapFlag = roadService.isOverlapForMergePoint(
- // startPointId,
- // startInfo.adsorbPointId
- // );
- // } else if (!limit.newEndWallId && endInfo.adsorbPointId) {
- // overlapFlag = roadService.isOverlapForMergePoint(
- // endPointId,
- // endInfo.adsorbPointId
- // );
- // }
- // if (overlapFlag) {
- // this.moveFlag = false;
- // MoveState = 5;
- // return MoveState;
- // }
- // // 到了这一步,端点的新坐标已经确定了,这里开始更新端点坐标
- // // 这里需要升级优化,因为 updatePointForMoveWall方法里也更新了edge,这个其实不需要的。
- // this.updatePointForMoveRoad(
- // roadId,
- // startPointId,
- // startInfo,
- // limit.startWallId,
- // limit.newStartWallId
- // );
- // this.updatePointForMoveRoad(
- // roadId,
- // endPointId,
- // endInfo,
- // limit.endWallId,
- // limit.newEndWallId
- // );
- // road = dataService.getRoad(roadId);
- // if (road == null) {
- // MoveState = 3;
- // this.moveFlag = false;
- // this.needUpdateRoom = true;
- // // console.log(271)
- // return MoveState;
- // }
- // // 更新symbols
- // symbolService.updateSymbolsPositionsForWall(roadId);
- // // 更新邻居墙的symbols
- // startPoint = dataService.getPoint(road.startId);
- // endPoint = dataService.getPoint(road.endId);
- // for (const key in startPoint.parent) {
- // symbolService.updateSymbolsPositionsForNeighWall(key);
- // }
- // for (const key in endPoint.parent) {
- // symbolService.updateSymbolsPositionsForNeighWall(key);
- // }
- // if (MoveState == 1) {
- // this.moveFlag = true;
- // } else {
- // this.moveFlag = false;
- // }
- // return MoveState;
- // }
- //拖拽墙角/墙面,被其他墙角吸附
- 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是wallId相对于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,linkedWallId表示吸附
- // wallIds是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属于wallId,当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表示wall的两个端点坐标(下一步的)
- // position3和position4表示wall的start一边的线段(startPoint——virtualStartPoint)
- // position5和position6表示wall的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 };
|