MoveRoad.js 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414
  1. import { roadService } from "../Service/RoadService";
  2. import { dataService } from "../Service/DataService";
  3. import Constant from "../Constant";
  4. import { mathUtil } from "../Util/MathUtil";
  5. import { elementService } from "../Service/ElementService";
  6. import { coordinate } from "../Coordinate";
  7. export default class MoveRoad {
  8. constructor() {
  9. this.startMoving = false;
  10. this.moveFlag = false;
  11. //拖拽墙角的时候,墙角的父亲与其他墙角相交
  12. this.adsorbPointRoads = {};
  13. //拖拽墙角的时候,该墙角与其他墙面相交
  14. this.splitRoadId = null;
  15. }
  16. setStartMoving(value) {
  17. this.startMoving = value;
  18. }
  19. // 测试要考虑pointId拖拽到包含他的所有墙的另一头
  20. // 这个函数不会删除/拆分/合并墙或者点
  21. movePoint(pointId, position, modifyPoint) {
  22. let point = dataService.getPoint(pointId);
  23. let linkedPointId = null;
  24. let linkedRoadId = null;
  25. if (modifyPoint != null) {
  26. position = {
  27. x: modifyPoint.x,
  28. y: modifyPoint.y,
  29. };
  30. linkedPointId = modifyPoint.linkedPointId;
  31. linkedRoadId = modifyPoint.linkedRoadId;
  32. }
  33. this.adsorbPointRoads = {};
  34. this.splitRoadId = null;
  35. let flag = this.canMoveForPoint(
  36. pointId,
  37. position,
  38. linkedPointId,
  39. linkedRoadId
  40. );
  41. if (!flag) {
  42. if (
  43. this.splitRoadId == null &&
  44. Object.keys(this.adsorbPointRoads).length > 0
  45. ) {
  46. //要吸附一下
  47. const adsorbPointId = Object.keys(this.adsorbPointRoads)[0];
  48. const road = dataService.getRoad(this.adsorbPointRoads[adsorbPointId]);
  49. const otherPointId = road.getOtherPointId(pointId);
  50. let otherPoint = dataService.getPoint(otherPointId);
  51. let modifyPoint = dataService.getPoint(adsorbPointId);
  52. let line = mathUtil.createLine1(otherPoint, modifyPoint);
  53. position = mathUtil.getJoinLinePoint(position, line);
  54. point.setPosition(position);
  55. }
  56. return false;
  57. }
  58. let newPosition = null;
  59. if (modifyPoint == null) {
  60. //90°或者180°纠正
  61. //不考虑当前角度
  62. //当前点的parent只有一个,考虑邻居点
  63. let neighPoints = roadService.getNeighPoints(pointId);
  64. if (neighPoints.length == 1) {
  65. newPosition = elementService.checkAngle(
  66. position,
  67. neighPoints[0].vectorId,
  68. pointId
  69. );
  70. }
  71. //当前点的parent有两个
  72. else if (neighPoints.length == 2) {
  73. newPosition = elementService.checkAngle(
  74. position,
  75. neighPoints[0].vectorId,
  76. pointId
  77. );
  78. if (!newPosition) {
  79. newPosition = elementService.checkAngle(
  80. position,
  81. neighPoints[1].vectorId,
  82. pointId
  83. );
  84. }
  85. }
  86. if (newPosition) {
  87. flag = this.canMoveForPoint(
  88. pointId,
  89. newPosition,
  90. linkedPointId,
  91. linkedRoadId
  92. );
  93. if (!flag) {
  94. return false;
  95. }
  96. mathUtil.clonePoint(position, newPosition);
  97. }
  98. point.setPosition(position);
  99. }
  100. // 与别的墙角重合
  101. else if (
  102. modifyPoint.hasOwnProperty("linkedPointId") &&
  103. modifyPoint.linkedPointId != null
  104. ) {
  105. const roadId = roadService.getRoadId(pointId, modifyPoint.linkedPointId);
  106. // pointId与linkedPointId属于同一堵墙,不允许,所以不移动
  107. if (roadId != null) {
  108. return false;
  109. } else {
  110. point.setPosition(modifyPoint);
  111. }
  112. }
  113. // 与别的墙面重合
  114. // 如果墙面的交点与其余墙角的距离过短,那也不允许拖动
  115. else if (modifyPoint.hasOwnProperty("linkedRoadId")) {
  116. const road = dataService.getRoad(modifyPoint.linkedRoadId);
  117. const startPoint = dataService.getPoint(road.startId);
  118. const endPoint = dataService.getPoint(road.endId);
  119. // 与其余墙角的距离过短,不允许拖动
  120. if (
  121. mathUtil.getDistance(startPoint, position) < Constant.minRealDis ||
  122. mathUtil.getDistance(endPoint, position) < Constant.minRealDis
  123. ) {
  124. return false;
  125. }
  126. point.setPosition(modifyPoint);
  127. } else {
  128. if (
  129. modifyPoint.hasOwnProperty("linkedPointIdX") &&
  130. modifyPoint.linkedPointIdX
  131. ) {
  132. point.setPosition(position);
  133. }
  134. if (
  135. modifyPoint.hasOwnProperty("linkedPointIdY") &&
  136. modifyPoint.linkedPointIdY
  137. ) {
  138. point.setPosition(position);
  139. }
  140. }
  141. return true;
  142. }
  143. // // 拖拽墙面
  144. // moveRoadPlane(roadId, dx, dy) {
  145. // // 1表示可以继续移动,2表示不能移动(启动距离还不够),3表示wallId被删除了,4表示重新开始移动(需要达到一定距离才能启动),5表示不能移动(不合适)
  146. // let MoveState = 1;
  147. // let road = dataService.getRoad(roadId);
  148. // let startPointId = road.startId;
  149. // let endPointId = road.endId;
  150. // let startPoint = dataService.getPoint(road.startId);
  151. // let endPoint = dataService.getPoint(road.endId);
  152. // // 不考虑约束的情况,得到移动后的坐标
  153. // const newpts = this.getNewPointsForMoveRoad(roadId, dx, dy);
  154. // let newLine = mathUtil.createLine1(newpts.point1, newpts.point2);
  155. // // 获取约束信息,包括:是否新建墙,受约束的侧墙
  156. // const limit = this.getTwoLimitInfos(roadId, newLine);
  157. // this.needUpdateRoom = false;
  158. // // 不考虑吸附的情况下,经过约束条件后,得到的新的移动后的坐标
  159. // let virtualStartPoint = mathUtil.getIntersectionPoint(
  160. // newLine,
  161. // limit.startLimitLine
  162. // );
  163. // let virtualEndPoint = mathUtil.getIntersectionPoint(
  164. // newLine,
  165. // limit.endLimitLine
  166. // );
  167. // // 刚刚开始移动的时候,或者吸附后再移动的时候,都需要积累一点移动距离才能真正开始移动
  168. // if (
  169. // !this.startMoving &&
  170. // (mathUtil.getDistance(startPoint, virtualStartPoint) <
  171. // Constant.minRealDis ||
  172. // mathUtil.getDistance(endPoint, virtualEndPoint) < Constant.minRealDis)
  173. // ) {
  174. // this.moveFlag = false;
  175. // MoveState = 2;
  176. // return MoveState;
  177. // }
  178. // this.setStartMoving(true);
  179. // // 判断是否会吸附到邻居墙的另一头端点,同时确保新的坐标在邻居墙内
  180. // let startInfo = this.updateVirtualPosition(
  181. // road.startId,
  182. // virtualStartPoint,
  183. // limit.startWallId,
  184. // limit.newStartWallId
  185. // );
  186. // let endInfo = this.updateVirtualPosition(
  187. // road.endId,
  188. // virtualEndPoint,
  189. // limit.endWallId,
  190. // limit.newEndWallId
  191. // );
  192. // if (startInfo == null || endInfo == null) {
  193. // this.moveFlag = false;
  194. // MoveState = 2;
  195. // this.setStartMoving(false);
  196. // return MoveState;
  197. // }
  198. // // 判断wallId的 1端/2端 吸附后,是否和别的墙重合
  199. // let coincideFlag = false;
  200. // // wallId的长度,可能会很短,要删除
  201. // let distance = null;
  202. // // 如果一头被吸附,另一头的坐标还要再次调整
  203. // if (startInfo.adsorb && !endInfo.adsorb) {
  204. // // 先更新newLine
  205. // newLine = mathUtil.createLine3(newLine, startInfo.virtualPosition);
  206. // // 需要判断夹角,如果接近0,则不能移动
  207. // const flag = this.isOKForTwoSegmentsAngle(
  208. // startInfo.adsorbPointId,
  209. // road.startId,
  210. // road.endId
  211. // );
  212. // if (!flag) {
  213. // this.moveFlag = false;
  214. // MoveState = 5;
  215. // return MoveState;
  216. // }
  217. // // 更新virtualEndPoint
  218. // virtualEndPoint = mathUtil.getIntersectionPoint(
  219. // newLine,
  220. // limit.endLimitLine
  221. // );
  222. // // 再次判断是否吸附
  223. // endInfo = this.updateVirtualPosition(
  224. // road.endId,
  225. // virtualEndPoint,
  226. // limit.endWallId,
  227. // limit.newEndWallId
  228. // );
  229. // if (endInfo == null) {
  230. // endInfo = {
  231. // adsorb: false,
  232. // adsorbPointId: null,
  233. // virtualPosition: virtualEndPoint,
  234. // };
  235. // }
  236. // // 一头吸附后,wallId可能和别的墙重合
  237. // coincideFlag = this.isCoincideForAdsorbOne(
  238. // road.startId,
  239. // startInfo.adsorbPointId,
  240. // roadId
  241. // );
  242. // distance = mathUtil.getDistance(
  243. // startInfo.virtualPosition,
  244. // virtualEndPoint
  245. // );
  246. // MoveState = 4;
  247. // this.needUpdateRoom = true;
  248. // this.setStartMoving(false);
  249. // } else if (!startInfo.adsorb && endInfo.adsorb) {
  250. // newLine = mathUtil.createLine3(newLine, endInfo.virtualPosition);
  251. // // 需要判断夹角,如果接近0,则不能移动
  252. // const flag = this.isOKForTwoSegmentsAngle(
  253. // endInfo.adsorbPointId,
  254. // road.endId,
  255. // road.startId
  256. // );
  257. // if (!flag) {
  258. // this.moveFlag = false;
  259. // MoveState = 5;
  260. // return MoveState;
  261. // }
  262. // virtualStartPoint = mathUtil.getIntersectionPoint(
  263. // newLine,
  264. // limit.startLimitLine
  265. // );
  266. // startInfo = this.updateVirtualPosition(
  267. // road.startId,
  268. // virtualStartPoint,
  269. // limit.startWallId,
  270. // limit.newStartWallId
  271. // );
  272. // if (startInfo == null) {
  273. // startInfo = {
  274. // adsorb: false,
  275. // adsorbPointId: null,
  276. // virtualPosition: virtualStartPoint,
  277. // };
  278. // }
  279. // coincideFlag = this.isCoincideForAdsorbOne(
  280. // road.endId,
  281. // endInfo.adsorbPointId,
  282. // roadId
  283. // );
  284. // distance = mathUtil.getDistance(
  285. // endInfo.virtualPosition,
  286. // virtualStartPoint
  287. // );
  288. // MoveState = 4;
  289. // this.needUpdateRoom = true;
  290. // this.setStartMoving(false);
  291. // }
  292. // // 两头同时吸附呢,wallId可能和别的墙重合
  293. // if (startInfo && endInfo && startInfo.adsorb && endInfo.adsorb) {
  294. // coincideFlag = this.isCoincideForAdsorbOne2(
  295. // roadId,
  296. // startInfo.adsorbPointId,
  297. // endInfo.adsorbPointId
  298. // );
  299. // distance = mathUtil.getDistance(
  300. // startInfo.virtualPosition,
  301. // endInfo.virtualPosition
  302. // );
  303. // this.setStartMoving(false);
  304. // if (coincideFlag) {
  305. // this.moveFlag = false;
  306. // MoveState = 5;
  307. // return MoveState;
  308. // }
  309. // MoveState = 4;
  310. // this.needUpdateRoom = true;
  311. // } else {
  312. // distance = mathUtil.getDistance(virtualStartPoint, virtualEndPoint);
  313. // if (distance < Constant.minRealDis) {
  314. // // 执行deleteWallForLinked后start和end会变,所以提前保存
  315. // this.deleteWallForLinked(roadId);
  316. // startPoint = dataService.getPoint(startPointId);
  317. // endPoint = dataService.getPoint(endPointId);
  318. // if (!startPoint || !endPoint) {
  319. // this.moveFlag = false;
  320. // MoveState = 3;
  321. // this.needUpdateRoom = true;
  322. // return MoveState;
  323. // }
  324. // if (
  325. // (Object.keys(startPoint.parent).length > 1 &&
  326. // Object.keys(endPoint.parent).length == 1) ||
  327. // (Object.keys(startPoint.parent).length == 1 &&
  328. // Object.keys(endPoint.parent).length == 1)
  329. // ) {
  330. // roadService.moveTo(endPointId, startPointId);
  331. // } else if (
  332. // Object.keys(startPoint.parent).length == 1 &&
  333. // Object.keys(endPoint.parent).length > 1
  334. // ) {
  335. // roadService.moveTo(startPointId, endPointId);
  336. // }
  337. // this.moveFlag = false;
  338. // MoveState = 3;
  339. // this.needUpdateRoom = true;
  340. // return MoveState;
  341. // }
  342. // }
  343. // startPointId = road.startId;
  344. // endPointId = road.endId;
  345. // // 是否交叉
  346. // const crossFlag = this.isOKForCrossForMoveRoad(
  347. // virtualStartPoint,
  348. // virtualEndPoint,
  349. // roadId,
  350. // startPointId,
  351. // endPointId,
  352. // startInfo.adsorbPointId,
  353. // endInfo.adsorbPointId
  354. // );
  355. // // ok
  356. // if (!crossFlag) {
  357. // MoveState = 2;
  358. // this.moveFlag = false;
  359. // this.setStartMoving(false);
  360. // return MoveState;
  361. // }
  362. // // 要删除墙了
  363. // if (coincideFlag || (distance != null && distance < Constant.minRealDis)) {
  364. // this.deleteWallForLinked(roadId);
  365. // MoveState = 3;
  366. // // 删除完墙,邻居墙可能会合并
  367. // roadService.mergeWallForPoint(startPointId);
  368. // roadService.mergeWallForPoint(endPointId);
  369. // this.moveFlag = false;
  370. // this.needUpdateRoom = true;
  371. // return MoveState;
  372. // } else {
  373. // // 要删除墙了
  374. // const join = mathUtil.getIntersectionPoint3(
  375. // startPoint,
  376. // virtualStartPoint,
  377. // endPoint,
  378. // virtualEndPoint
  379. // );
  380. // if (join != null) {
  381. // startPoint.setPosition(join);
  382. // endPoint.setPosition(join);
  383. // roadService.moveTo(startPointId, endPointId);
  384. // MoveState = 3;
  385. // this.moveFlag = false;
  386. // this.needUpdateRoom = true;
  387. // return MoveState;
  388. // }
  389. // }
  390. // let overlapFlag = false;
  391. // if (!limit.newStartWallId && startInfo.adsorbPointId) {
  392. // overlapFlag = roadService.isOverlapForMergePoint(
  393. // startPointId,
  394. // startInfo.adsorbPointId
  395. // );
  396. // } else if (!limit.newEndWallId && endInfo.adsorbPointId) {
  397. // overlapFlag = roadService.isOverlapForMergePoint(
  398. // endPointId,
  399. // endInfo.adsorbPointId
  400. // );
  401. // }
  402. // if (overlapFlag) {
  403. // this.moveFlag = false;
  404. // MoveState = 5;
  405. // return MoveState;
  406. // }
  407. // // 到了这一步,端点的新坐标已经确定了,这里开始更新端点坐标
  408. // // 这里需要升级优化,因为 updatePointForMoveWall方法里也更新了edge,这个其实不需要的。
  409. // this.updatePointForMoveRoad(
  410. // roadId,
  411. // startPointId,
  412. // startInfo,
  413. // limit.startWallId,
  414. // limit.newStartWallId
  415. // );
  416. // this.updatePointForMoveRoad(
  417. // roadId,
  418. // endPointId,
  419. // endInfo,
  420. // limit.endWallId,
  421. // limit.newEndWallId
  422. // );
  423. // road = dataService.getRoad(roadId);
  424. // if (road == null) {
  425. // MoveState = 3;
  426. // this.moveFlag = false;
  427. // this.needUpdateRoom = true;
  428. // // console.log(271)
  429. // return MoveState;
  430. // }
  431. // // 更新symbols
  432. // symbolService.updateSymbolsPositionsForWall(roadId);
  433. // // 更新邻居墙的symbols
  434. // startPoint = dataService.getPoint(road.startId);
  435. // endPoint = dataService.getPoint(road.endId);
  436. // for (const key in startPoint.parent) {
  437. // symbolService.updateSymbolsPositionsForNeighWall(key);
  438. // }
  439. // for (const key in endPoint.parent) {
  440. // symbolService.updateSymbolsPositionsForNeighWall(key);
  441. // }
  442. // if (MoveState == 1) {
  443. // this.moveFlag = true;
  444. // } else {
  445. // this.moveFlag = false;
  446. // }
  447. // return MoveState;
  448. // }
  449. //拖拽墙角/墙面,被其他墙角吸附
  450. updateForAbsorbRoadPoints() {
  451. if (Object.keys(this.adsorbPointRoads).length == 0) {
  452. return;
  453. } else if (Object.keys(this.adsorbPointRoads).length == 2) {
  454. debugger;
  455. }
  456. let joins = [];
  457. let roadId = null;
  458. for (let key in this.adsorbPointRoads) {
  459. let point = dataService.getPoint(key);
  460. joins.push({
  461. join: point,
  462. pointId: key,
  463. });
  464. roadId = this.adsorbPointRoads[key];
  465. }
  466. const road = dataService.getRoad(roadId);
  467. const startPoint = dataService.getPoint(road.startId);
  468. function sortNumber(a, b) {
  469. return (
  470. mathUtil.getDistance(startPoint, a.join) -
  471. mathUtil.getDistance(startPoint, b.join)
  472. );
  473. }
  474. joins = joins.sort(sortNumber.bind(this));
  475. for (let i = 0; i < joins.length; ++i) {
  476. const info = joins[i];
  477. const join = info.join;
  478. const pointId = info.pointId;
  479. roadService.splitRoad(roadId, pointId, "end");
  480. }
  481. }
  482. getNewPointsForMoveRoad(roadId, dx, dy) {
  483. dx = dx / coordinate.res;
  484. dy = -dy / coordinate.res;
  485. const road = dataService.getRoad(roadId);
  486. const startPoint = dataService.getPoint(road.startId);
  487. const endPoint = dataService.getPoint(road.endId);
  488. const p1 = { x: startPoint.x + dx, y: startPoint.y + dy };
  489. const p2 = { x: endPoint.x + dx, y: endPoint.y + dy };
  490. return {
  491. point1: p1,
  492. point2: p2,
  493. };
  494. }
  495. getTwoLimitInfos(roadId, newLine) {
  496. const road = dataService.getRoad(roadId);
  497. const startPoint = dataService.getPoint(road.startId);
  498. const endPoint = dataService.getPoint(road.endId);
  499. let startLimitLine, endLimitLine, info;
  500. const roadLine = roadService.getMidLine(road);
  501. const limitInfos = {};
  502. limitInfos.newStartRoadId = false; // 不需要新建墙
  503. limitInfos.newEndRoadId = false; // 不需要新建墙
  504. // 先处理start
  505. if (Object.keys(startPoint.parent).length == 1) {
  506. startLimitLine = mathUtil.getVerticalLine(roadLine, startPoint);
  507. limitInfos.startRoadId = null;
  508. } else if (Object.keys(startPoint.parent).length == 2) {
  509. let tempRoad;
  510. if (Object.keys(startPoint.parent)[0] == roadId) {
  511. tempRoad = dataService.getRoad(Object.keys(startPoint.parent)[1]);
  512. } else if (Object.keys(startPoint.parent)[1] == roadId) {
  513. tempRoad = dataService.getRoad(Object.keys(startPoint.parent)[0]);
  514. }
  515. if (!tempRoad) {
  516. console.error(352);
  517. }
  518. const angle = roadService.AngleForRoad(tempRoad.vectorId, roadId);
  519. startLimitLine = roadService.getMidLine(tempRoad);
  520. limitInfos.startRoadId = tempRoad.vectorId;
  521. if (angle > (Constant.maxAngle / 180) * Math.PI) {
  522. startLimitLine = mathUtil.getVerticalLine(roadLine, startPoint);
  523. limitInfos.startRoadId = null;
  524. limitInfos.newStartRoadId = true;
  525. }
  526. } else {
  527. let tempRoad, tempRoadId;
  528. info = roadService.roadIdForMinAngle(road.startId, roadId);
  529. const road1 = dataService.getRoad(info.min0.roadId);
  530. const startPoint1 = dataService.getPoint(road1.startId);
  531. const endPoint1 = dataService.getPoint(road1.endId);
  532. const road2 = dataService.getRoad(info.min1.roadId);
  533. const startPoint2 = dataService.getPoint(road2.startId);
  534. const endPoint2 = dataService.getPoint(road2.endId);
  535. const join1 = mathUtil.getIntersectionPoint4(
  536. startPoint1,
  537. endPoint1,
  538. newLine
  539. );
  540. const join2 = mathUtil.getIntersectionPoint4(
  541. startPoint2,
  542. endPoint2,
  543. newLine
  544. );
  545. // 取角度大的
  546. if (join1 == null && join2 == null) {
  547. let angle0 = roadService.AngleForRoad(roadId, info.min0.roadId);
  548. let angle1 = roadService.AngleForRoad(roadId, info.min1.roadId);
  549. if (angle0 > Math.PI) {
  550. angle0 = Math.PI - angle0;
  551. }
  552. if (angle1 > Math.PI) {
  553. angle1 = Math.PI - angle1;
  554. }
  555. if (angle0 < angle1) {
  556. tempRoadId = info.min0.roadId;
  557. } else {
  558. tempRoadId = info.min1.roadId;
  559. }
  560. limitInfos.newStartRoadId = true;
  561. }
  562. // 取角度小的
  563. else if (join1 != null && join2 != null) {
  564. if (info.min0.angle < info.min1.angle) {
  565. tempRoadId = info.min0.roadId;
  566. } else {
  567. tempRoadId = info.min1.roadId;
  568. }
  569. } else if (join1 == null && join2 != null) {
  570. tempRoadId = info.min1.roadId;
  571. } else if (join1 != null && join2 == null) {
  572. tempRoadId = info.min0.roadId;
  573. }
  574. limitInfos.startRoadId = tempRoadId;
  575. tempRoad = dataService.getRoad(tempRoadId);
  576. const angle = roadService.AngleForRoad(tempRoadId, roadId);
  577. startLimitLine = roadService.getMidLine(tempRoad);
  578. let join = mathUtil.getIntersectionPoint(startLimitLine, newLine);
  579. const tempStartPoint = dataService.getPoint(tempRoad.startId);
  580. const tempEndPoint = dataService.getPoint(tempRoad.endId);
  581. if (
  582. angle > (Constant.maxAngle / 180) * Math.PI ||
  583. !mathUtil.isPointOnSegment(join, tempStartPoint, tempEndPoint)
  584. ) {
  585. startLimitLine = mathUtil.getVerticalLine(roadLine, startPoint);
  586. limitInfos.startRoadId = null;
  587. limitInfos.newStartRoadId = true;
  588. }
  589. }
  590. // 再处理end
  591. if (Object.keys(endPoint.parent).length == 1) {
  592. endLimitLine = mathUtil.getVerticalLine(roadLine, endPoint);
  593. limitInfos.endRoadId = null;
  594. } else if (Object.keys(endPoint.parent).length == 2) {
  595. let tempRoad;
  596. if (Object.keys(endPoint.parent)[0] == roadId) {
  597. tempRoad = dataService.getRoad(Object.keys(endPoint.parent)[1]);
  598. } else if (Object.keys(endPoint.parent)[1] == roadId) {
  599. tempRoad = dataService.getRoad(Object.keys(endPoint.parent)[0]);
  600. }
  601. const angle = roadService.AngleForRoad(tempRoad.vectorId, roadId);
  602. endLimitLine = roadService.getMidLine(tempRoad);
  603. limitInfos.endRoadId = tempRoad.vectorId;
  604. if (angle > (Constant.maxAngle / 180) * Math.PI) {
  605. endLimitLine = mathUtil.getVerticalLine(roadLine, endPoint);
  606. limitInfos.endRoadId = null;
  607. limitInfos.newEndRoadId = true;
  608. }
  609. } else {
  610. let tempRoad, tempRoadId;
  611. info = dataService.roadIdForMinAngle(road.endId, roadId);
  612. const road1 = dataService.getRoad(info.min0.roadId);
  613. const startPoint1 = dataService.getPoint(road1.startId);
  614. const endPoint1 = dataService.getPoint(road1.endId);
  615. const road2 = dataService.getRoad(info.min1.roadId);
  616. const startPoint2 = dataService.getPoint(road2.startId);
  617. const endPoint2 = dataService.getPoint(road2.endId);
  618. const join1 = mathUtil.getIntersectionPoint4(
  619. startPoint1,
  620. endPoint1,
  621. newLine
  622. );
  623. const join2 = mathUtil.getIntersectionPoint4(
  624. startPoint2,
  625. endPoint2,
  626. newLine
  627. );
  628. // 取角度大的
  629. if (join1 == null && join2 == null) {
  630. let angle0 = roadService.AngleForRoad(roadId, info.min0.roadId);
  631. let angle1 = roadService.AngleForRoad(roadId, info.min1.roadId);
  632. if (angle0 > Math.PI) {
  633. angle0 = Math.PI - angle0;
  634. }
  635. if (angle1 > Math.PI) {
  636. angle1 = Math.PI - angle1;
  637. }
  638. if (angle0 < angle1) {
  639. tempRoadId = info.min0.roadId;
  640. } else {
  641. tempRoadId = info.min1.roadId;
  642. }
  643. limitInfos.newEndRoadId = true;
  644. }
  645. // 取角度小的
  646. else if (join1 != null && join2 != null) {
  647. if (info.min0.angle < info.min1.angle) {
  648. tempRoadId = info.min0.roadId;
  649. } else {
  650. tempRoadId = info.min1.roadId;
  651. }
  652. } else if (join1 == null && join2 != null) {
  653. tempRoadId = info.min1.roadId;
  654. } else if (join1 != null && join2 == null) {
  655. tempRoadId = info.min0.roadId;
  656. }
  657. limitInfos.endRoadId = tempRoadId;
  658. tempRoad = dataService.getRoad(tempRoadId);
  659. const angle = roadService.AngleForRoad(tempRoadId, roadId);
  660. endLimitLine = roadService.getMidLine(tempRoad);
  661. let join = mathUtil.getIntersectionPoint(endLimitLine, newLine);
  662. const tempStartPoint = dataService.getPoint(tempRoad.start);
  663. const tempEndPoint = dataService.getPoint(tempRoad.end);
  664. if (
  665. angle > (Constant.maxAngle / 180) * Math.PI ||
  666. !mathUtil.isPointOnSegment(join, tempStartPoint, tempEndPoint)
  667. ) {
  668. endLimitLine = mathUtil.getVerticalLine(roadLine, endPoint);
  669. limitInfos.endRoadId = null;
  670. limitInfos.newEndRoadId = true;
  671. }
  672. }
  673. limitInfos.startLimitLine = startLimitLine;
  674. limitInfos.endLimitLine = endLimitLine;
  675. return limitInfos;
  676. }
  677. // 是否可以移动point
  678. // 两个判断:拖拽的墙(可能是多个),一方面不能与其他墙相交,另一方面这些墙之间或者与别的墙之间的角度必须大于Constant.minAngle
  679. canMoveForPoint(pointId, position, linkedPointId, linkedRoadId) {
  680. const point = dataService.getPoint(pointId);
  681. // 先判断第二点(这些墙之间或者与别的墙之间的角度必须大于MinAngle)
  682. let flag = this.isOKForMinAngleRoad(pointId, position);
  683. // 开始考虑第一点
  684. if (flag) {
  685. // 不仅仅角度,还有相交
  686. flag = this.isOKForCross(
  687. pointId,
  688. position,
  689. point.parent,
  690. linkedPointId,
  691. linkedRoadId
  692. );
  693. }
  694. return flag;
  695. }
  696. isOKForMinAngleRoad(pointId, position) {
  697. const point = dataService.getPoint(pointId);
  698. const parent = point.parent;
  699. const angle = this.getMinAngle(pointId, position);
  700. if (Math.abs(angle) < (Constant.minAngle / 180) * Math.PI) {
  701. return false;
  702. }
  703. // 判断邻居点
  704. for (const key in parent) {
  705. const road = dataService.getRoad(key);
  706. const otherPointId = road.getOtherPointId(pointId);
  707. const info = this.getNeighMinAngle(otherPointId, key, position);
  708. if (info && Math.abs(info.angle) < (Constant.minAngle / 180) * Math.PI) {
  709. return false;
  710. } else {
  711. const otherPoint = dataService.getPoint(otherPointId);
  712. if (mathUtil.getDistance(position, otherPoint) < Constant.minRealDis) {
  713. return false;
  714. }
  715. }
  716. }
  717. return true;
  718. }
  719. //点pointId移动到position后,求出最小角度
  720. getMinAngle(pointId, position) {
  721. const point = dataService.getPoint(pointId);
  722. const parent = point.parent;
  723. let angle = null;
  724. if (Object.keys(parent).length == 1) {
  725. return 2 * Math.PI;
  726. } else if (Object.keys(parent).length == 2) {
  727. const road1 = dataService.getRoad(Object.keys(parent)[0]);
  728. const road2 = dataService.getRoad(Object.keys(parent)[1]);
  729. const otherPointId1 = road1.getOtherPointId(pointId);
  730. const otherPoint1 = dataService.getPoint(otherPointId1);
  731. const otherPointId2 = road2.getOtherPointId(pointId);
  732. const otherPoint2 = dataService.getPoint(otherPointId2);
  733. angle = mathUtil.Angle(position, otherPoint1, otherPoint2);
  734. return angle;
  735. } else {
  736. const _position = {
  737. x: position.x + 1,
  738. y: position.y,
  739. };
  740. let angles = [];
  741. for (const key in parent) {
  742. const road = dataService.getRoad(key);
  743. const otherPointId = road.getOtherPointId(pointId);
  744. const otherPoint = dataService.getPoint(otherPointId);
  745. if (mathUtil.equalPoint(_position, otherPoint)) {
  746. angles.push(0);
  747. continue;
  748. } else {
  749. let angle = mathUtil.Angle(position, _position, otherPoint);
  750. // 统一按照逆时针顺序
  751. if (otherPoint.y < position.y) {
  752. angle = 2 * Math.PI - angle;
  753. }
  754. angles.push(angle);
  755. }
  756. }
  757. angles = angles.sort(sortNumber);
  758. let minAngle = 2 * Math.PI;
  759. for (let i = 0; i < angles.length - 1; ++i) {
  760. for (let j = i + 1; j < angles.length; ++j) {
  761. const _angle = angles[j] - angles[i];
  762. if (_angle < minAngle) {
  763. minAngle = _angle;
  764. }
  765. }
  766. }
  767. const angle1 = angles[0];
  768. const angle2 = angles[angles.length - 1];
  769. if (angle1 < Math.PI && angle2 > Math.PI) {
  770. const dAngle = 2 * Math.PI + angle1 - angle2;
  771. if (dAngle < minAngle) {
  772. minAngle = dAngle;
  773. }
  774. }
  775. return minAngle;
  776. }
  777. function sortNumber(a, b) {
  778. return a - b;
  779. }
  780. }
  781. // 用于邻居点
  782. // pointId是顶点
  783. // position是wallId相对于pointId另一头的点的坐标,一般发生改变的时候使用这个函数
  784. getNeighMinAngle(otherPointId, roadId, position) {
  785. const point1 = dataService.getPoint(otherPointId);
  786. const point2 = {
  787. x: position.x,
  788. y: position.y,
  789. };
  790. let pointId3 = null;
  791. let point3 = null;
  792. let minAngle = null;
  793. let result = null;
  794. for (const key in point1.parent) {
  795. if (key == roadId) {
  796. continue;
  797. }
  798. const road = dataService.getRoad(key);
  799. pointId3 = road.getOtherPointId(otherPointId);
  800. point3 = dataService.getPoint(pointId3);
  801. const angle = mathUtil.Angle(point1, point2, point3);
  802. if (minAngle == null || minAngle > angle) {
  803. minAngle = angle;
  804. result = {
  805. angle: minAngle,
  806. pointId: pointId3,
  807. };
  808. }
  809. }
  810. return result;
  811. }
  812. // linkedPointId,linkedWallId表示吸附
  813. // wallIds是pointId的parent
  814. isOKForCross(pointId, position, roadIds, linkedPointId, linkedRoadId) {
  815. const roads = dataService.getRoads();
  816. for (const key in roads) {
  817. if (roadIds.hasOwnProperty(key)) {
  818. continue;
  819. } else if (linkedRoadId == key) {
  820. continue;
  821. }
  822. for (const _key in roadIds) {
  823. //相连就不用考虑了
  824. if (roadService.isRoadLink(key, _key)) {
  825. continue;
  826. }
  827. const _road = dataService.getRoad(_key);
  828. const otherPointId = _road.getOtherPointId(pointId);
  829. const otherPoint = dataService.getPoint(otherPointId);
  830. const flag = this.isOKForCrossTwoRoad(
  831. position,
  832. otherPoint,
  833. key,
  834. linkedPointId,
  835. linkedRoadId,
  836. _road.vectorId
  837. );
  838. // 交叉
  839. if (!flag) {
  840. this.adsorbPointRoads = {};
  841. return false;
  842. }
  843. }
  844. }
  845. //需要吸附了。
  846. if (Object.keys(this.adsorbPointRoads).length > 0) {
  847. return false;
  848. } else if (this.splitRoadId != null) {
  849. return false;
  850. }
  851. // 不交叉
  852. return true;
  853. }
  854. // position1表示拖拽的点的坐标(修复过了的)
  855. // position2对应墙的另一头坐标
  856. // roadId表示其余的墙(与position1无关的墙)
  857. isOKForCrossTwoRoad(
  858. position1,
  859. position2,
  860. roadId,
  861. linkedPointId,
  862. linkedRoadId,
  863. dragRoadId
  864. ) {
  865. const road = dataService.getRoad(roadId);
  866. const startPoint = dataService.getPoint(road.startId);
  867. const endPoint = dataService.getPoint(road.endId);
  868. const join = mathUtil.getIntersectionPoint3(
  869. position1,
  870. position2,
  871. startPoint,
  872. endPoint
  873. );
  874. if (join && road.startId != linkedPointId && road.endId != linkedPointId) {
  875. // 交叉了
  876. this.splitRoadId = roadId;
  877. return true;
  878. } else {
  879. if (mathUtil.equalPoint(position1, position2)) {
  880. return true;
  881. }
  882. let line = mathUtil.createLine1(position1, position2);
  883. let join1 = mathUtil.getJoinLinePoint(startPoint, line);
  884. let join2 = mathUtil.getJoinLinePoint(endPoint, line);
  885. if (
  886. mathUtil.getDistance(join1, startPoint) < Constant.minRealDis &&
  887. mathUtil.PointInSegment(join1, position1, position2)
  888. ) {
  889. if (road.startId != linkedPointId) {
  890. // 交叉了
  891. this.adsorbPointRoads[startPoint.vectorId] = dragRoadId;
  892. //为了找到全部的吸附点,暂时返回true,在外面一层再做判断
  893. return true;
  894. }
  895. } else if (
  896. mathUtil.getDistance(join2, endPoint) < Constant.minRealDis &&
  897. mathUtil.PointInSegment(join2, position1, position2)
  898. ) {
  899. if (road.endId != linkedPointId) {
  900. // 交叉了
  901. this.adsorbPointRoads[endPoint.vectorId] = dragRoadId;
  902. //为了找到全部的吸附点,暂时返回true,在外面一层再做判断
  903. return true;
  904. }
  905. }
  906. line = mathUtil.createLine1(startPoint, endPoint);
  907. join1 = mathUtil.getJoinLinePoint(position1, line);
  908. join2 = mathUtil.getJoinLinePoint(position2, line);
  909. if (
  910. mathUtil.getDistance(join1, position1) < Constant.minRealDis &&
  911. mathUtil.PointInSegment(join1, startPoint, endPoint)
  912. ) {
  913. if (
  914. road.startId != linkedPointId &&
  915. road.endId != linkedPointId &&
  916. roadId != linkedRoadId
  917. ) {
  918. // 交叉了
  919. //return false
  920. return true;
  921. }
  922. } else if (
  923. mathUtil.getDistance(join2, position2) < Constant.minRealDis &&
  924. mathUtil.PointInSegment(join2, startPoint, endPoint)
  925. ) {
  926. if (
  927. road.startId != linkedPointId &&
  928. road.endId != linkedPointId &&
  929. roadId != linkedRoadId
  930. ) {
  931. // 交叉了
  932. //return false
  933. return true;
  934. }
  935. }
  936. }
  937. return true;
  938. }
  939. isOKForCrossTwoRoad2(position1, position2, roadId) {
  940. const road = dataService.getRoad(roadId);
  941. const startPoint = dataService.getPoint(road.startId);
  942. const endPoint = dataService.getPoint(road.endId);
  943. let flag = mathUtil.crossTwoLines(
  944. position1,
  945. position2,
  946. startPoint,
  947. endPoint,
  948. 0.01
  949. );
  950. if (flag) {
  951. // 交叉了
  952. return false;
  953. } else {
  954. if (mathUtil.equalPoint(position1, position2)) {
  955. return true;
  956. }
  957. flag = this.isCoincide(position1, position2, roadId);
  958. if (!flag) {
  959. return false;
  960. }
  961. }
  962. return true;
  963. }
  964. isOKForCrossTwoRoad3(position1, position2, roadId) {
  965. const road = dataService.getRoad(roadId);
  966. const startPoint = dataService.getPoint(road.startId);
  967. const endPoint = dataService.getPoint(road.endId);
  968. const flag = mathUtil.crossTwoLines(
  969. position1,
  970. position2,
  971. startPoint,
  972. endPoint,
  973. 0.01
  974. );
  975. if (flag) {
  976. // 交叉了
  977. return false;
  978. } else {
  979. if (mathUtil.equalPoint(position1, position2)) {
  980. return true;
  981. }
  982. let line = mathUtil.createLine1(position1, position2);
  983. let join1 = mathUtil.getJoinLinePoint(startPoint, line);
  984. const join2 = mathUtil.getJoinLinePoint(endPoint, line);
  985. if (
  986. mathUtil.getDistance(join1, startPoint) < Constant.minRealDis &&
  987. mathUtil.isPointOnSegment(join1, position1, position2)
  988. ) {
  989. // 交叉了
  990. return false;
  991. } else if (
  992. mathUtil.getDistance(join2, endPoint) < Constant.minRealDis &&
  993. mathUtil.isPointOnSegment(join2, position1, position2)
  994. ) {
  995. // 交叉了
  996. return false;
  997. }
  998. line = mathUtil.createLine1(startPoint, endPoint);
  999. join1 = mathUtil.getJoinLinePoint(position1, line);
  1000. if (
  1001. mathUtil.getDistance(join1, position1) < Constant.minRealDis &&
  1002. roadService.isContain(road, join1)
  1003. ) {
  1004. // 交叉了
  1005. return false;
  1006. }
  1007. }
  1008. return true;
  1009. }
  1010. isCoincide(position1, position2, roadId) {
  1011. const road = dataService.getRoad(roadId);
  1012. const startPoint = dataService.getPoint(road.startId);
  1013. const endPoint = dataService.getPoint(road.endId);
  1014. let line = mathUtil.createLine1(position1, position2);
  1015. let join1 = mathUtil.getJoinLinePoint(startPoint, line);
  1016. let join2 = mathUtil.getJoinLinePoint(endPoint, line);
  1017. if (
  1018. mathUtil.getDistance(join1, startPoint) < Constant.minRealDis &&
  1019. mathUtil.PointInSegment(join1, position1, position2)
  1020. ) {
  1021. // 交叉了
  1022. return false;
  1023. } else if (
  1024. mathUtil.getDistance(join2, endPoint) < Constant.minRealDis &&
  1025. mathUtil.PointInSegment(join2, position1, position2)
  1026. ) {
  1027. // 交叉了
  1028. return false;
  1029. }
  1030. line = mathUtil.createLine1(startPoint, endPoint);
  1031. join1 = mathUtil.getJoinLinePoint(position1, line);
  1032. join2 = mathUtil.getJoinLinePoint(position2, line);
  1033. if (
  1034. mathUtil.getDistance(join1, position1) < Constant.minRealDis &&
  1035. roadService.isContain(road, join1)
  1036. ) {
  1037. // 交叉了
  1038. return false;
  1039. } else if (
  1040. mathUtil.getDistance(join2, position2) < Constant.minRealDis &&
  1041. roadService.isContain(road, join2)
  1042. ) {
  1043. // 交叉了
  1044. return false;
  1045. }
  1046. return true;
  1047. }
  1048. // 更新virtualPosition(一般是吸附)
  1049. updateVirtualPosition(pointId, virtualPosition, limitRoadId, needNew) {
  1050. const limitRoad = dataService.getRoad(limitRoadId);
  1051. const point = dataService.getPoint(pointId);
  1052. let otherPointId, otherPoint;
  1053. let adsorb = false;
  1054. // 不需要新建墙
  1055. if (!needNew) {
  1056. if (limitRoad != null) {
  1057. otherPointId = limitRoad.getOtherPointId(pointId);
  1058. otherPoint = dataService.getPoint(otherPointId);
  1059. // 会吸附另一头
  1060. if (
  1061. mathUtil.getDistance(virtualPosition, otherPoint) <
  1062. Constant.minRealDis ||
  1063. (!roadService.isContain(limitRoad, virtualPosition) &&
  1064. mathUtil.getDistance(virtualPosition, otherPoint) <
  1065. mathUtil.getDistance(virtualPosition, point))
  1066. ) {
  1067. mathUtil.clonePoint(virtualPosition, otherPoint);
  1068. adsorb = true;
  1069. }
  1070. }
  1071. }
  1072. // 需要新建墙
  1073. else {
  1074. // 新建的墙太短,不允许
  1075. if (mathUtil.getDistance(point, virtualPosition) < Constant.minRealDis) {
  1076. return null;
  1077. }
  1078. }
  1079. return {
  1080. adsorb: adsorb,
  1081. adsorbPointId: adsorb ? otherPointId : null,
  1082. virtualPosition: virtualPosition,
  1083. };
  1084. }
  1085. // 两条线段的夹角,这两条线段分别有一个端点挨的很近
  1086. isOKForTwoSegmentsAngle(pointId, pointId1, pointId2) {
  1087. const point = dataService.getPoint(pointId);
  1088. const point1 = dataService.getPoint(pointId1);
  1089. const point2 = dataService.getPoint(pointId2);
  1090. const dx = point.x - point1.x;
  1091. const dy = point.y - point1.y;
  1092. const newPoint2 = {
  1093. x: dx + point2.x,
  1094. y: dy + point2.y,
  1095. };
  1096. for (const key in point.parent) {
  1097. const road = dataService.getRoad(key);
  1098. const otherPointId = road.getOtherPointId(pointId);
  1099. const otherPoint = dataService.getPoint(otherPointId);
  1100. const angle = mathUtil.Angle(point, otherPoint, newPoint2);
  1101. if (Math.abs(angle) < (Constant.minAngle / 180) * Math.PI) {
  1102. return false;
  1103. }
  1104. }
  1105. return true;
  1106. }
  1107. // 一头吸附后,是否会重合
  1108. // pointId属于wallId,当pointId吸附到adsorbPointId时
  1109. isCoincideForAdsorbOne(pointId, adsorbPointId, roadId) {
  1110. if (pointId && adsorbPointId) {
  1111. const road = dataService.getRoad(roadId);
  1112. const otherPointId = road.getOtherPointId(pointId);
  1113. const _roadId = roadService.getRoadId(otherPointId, adsorbPointId);
  1114. if (_roadId != null) {
  1115. return true;
  1116. }
  1117. }
  1118. return false;
  1119. }
  1120. isCoincideForAdsorbOne2(roadId, adsorbPointId1, adsorbPointId2) {
  1121. if (adsorbPointId1 && adsorbPointId2) {
  1122. const _roadId = roadService.getRoadId(adsorbPointId1, adsorbPointId2);
  1123. if (_roadId != null) {
  1124. return true;
  1125. }
  1126. // 可能吸附的是两堵墙,但是这两堵墙呈180°
  1127. else {
  1128. let adsorbPoint = dataService.getPoint(adsorbPointId1);
  1129. let parent = adsorbPoint.parent;
  1130. for (const key in parent) {
  1131. const angle = roadService.AngleForRoad3(roadId, key);
  1132. if (Math.abs(angle) < (Constant.minAngle / 180) * Math.PI) {
  1133. return true;
  1134. }
  1135. }
  1136. adsorbPoint = dataService.getPoint(adsorbPointId2);
  1137. parent = adsorbPoint.parent;
  1138. for (const key in parent) {
  1139. const angle = roadService.AngleForRoad3(roadId, key);
  1140. if (Math.abs(angle) < (Constant.minAngle / 180) * Math.PI) {
  1141. return true;
  1142. }
  1143. }
  1144. }
  1145. }
  1146. return false;
  1147. }
  1148. // position1和position2表示wall的两个端点坐标(下一步的)
  1149. // position3和position4表示wall的start一边的线段(startPoint——virtualStartPoint)
  1150. // position5和position6表示wall的end一边的线段(endPoint——virtualEndPoint)
  1151. // adsorbPointId1对应start那一头的吸附点
  1152. // adsorbPointId2对应end那一头的吸附点
  1153. isOKForCrossForMoveRoad(
  1154. position1,
  1155. position2,
  1156. roadId,
  1157. startPointId,
  1158. endPointId,
  1159. adsorbPointId1,
  1160. adsorbPointId2
  1161. ) {
  1162. const startPoint = dataService.getPoint(startPointId);
  1163. const endPoint = dataService.getPoint(endPointId);
  1164. let flag = true;
  1165. const roads = dataService.getRoads();
  1166. for (const key in roads) {
  1167. if (key == roadId) {
  1168. continue;
  1169. }
  1170. let flag1 = true;
  1171. let flag2 = true;
  1172. const _road = dataService.getRoad(key);
  1173. if (
  1174. adsorbPointId1 &&
  1175. (adsorbPointId1 == _road.startId || adsorbPointId1 == _road.endId)
  1176. ) {
  1177. flag1 = false;
  1178. }
  1179. if (
  1180. adsorbPointId2 &&
  1181. (adsorbPointId2 == _road.startId || adsorbPointId2 == _road.endId)
  1182. ) {
  1183. flag2 = false;
  1184. }
  1185. if (_road.startId == startPointId || _road.endId == startPointId) {
  1186. flag1 = false;
  1187. }
  1188. if (_road.startId == endPointId || _road.endId == endPointId) {
  1189. flag2 = false;
  1190. }
  1191. // 两头不连
  1192. if (flag1 && flag2) {
  1193. flag = this.isOKForCrossTwoRoad2(position1, position2, key);
  1194. }
  1195. if (!flag) {
  1196. return false;
  1197. }
  1198. if (
  1199. flag1 &&
  1200. _road.startId != startPointId &&
  1201. _road.endId != startPointId
  1202. ) {
  1203. flag = this.isOKForCrossTwoRoad3(position1, startPoint, key);
  1204. }
  1205. if (!flag) {
  1206. return false;
  1207. }
  1208. if (flag2 && _road.startId != endPointId && _road.endId != endPointId) {
  1209. flag = this.isOKForCrossTwoRoad3(position2, endPoint, key);
  1210. }
  1211. if (!flag) {
  1212. return false;
  1213. }
  1214. }
  1215. return flag;
  1216. }
  1217. // 更新pointId的坐标
  1218. updatePointForMoveRoad(roadId, pointId, virtualInfo, limitRoadId, needNew) {
  1219. const point = dataService.getPoint(pointId);
  1220. const road = dataService.getRoad(roadId);
  1221. // 如果没有约束墙,只有两种情况:一种是不新建墙,另一种是需要新建墙
  1222. if (limitRoadId == null) {
  1223. // 不需要新建墙,这种情况一般是pointId的parent只有一个
  1224. if (!needNew) {
  1225. point.setPosition(virtualInfo.virtualPosition);
  1226. }
  1227. // 新建墙
  1228. else {
  1229. this.createRoadForMoveRoad(
  1230. pointId,
  1231. roadId,
  1232. virtualInfo.virtualPosition
  1233. );
  1234. }
  1235. } else {
  1236. /*
  1237. 不新建墙:
  1238. 1. 更新坐标(一种是当pointId的parent是2个,另一种是三个,但是roadId对应的两堵墙接近180°)
  1239. 2. 拆分墙
  1240. 3. 吸附邻居墙的另一个端点
  1241. 新建墙:
  1242. */
  1243. // 不新建墙
  1244. if (!needNew) {
  1245. if (!virtualInfo.adsorb) {
  1246. // 只更新坐标
  1247. if (Object.keys(point.parent).length == 2) {
  1248. point.setPosition(virtualInfo.virtualPosition);
  1249. } else {
  1250. const info = roadService.roadIdForMinAngle(pointId, roadId);
  1251. const angle = roadService.AngleForRoad(
  1252. info.min0.roadId,
  1253. info.min1.roadId
  1254. );
  1255. // 只更新坐标
  1256. if (
  1257. Object.keys(point.parent).length == 3 &&
  1258. angle > (Constant.maxAngle / 180) * Math.PI
  1259. ) {
  1260. point.setPosition(virtualInfo.virtualPosition);
  1261. }
  1262. // 拆分墙
  1263. else {
  1264. const dir = roadService.getDirction(pointId, roadId);
  1265. // 先断开链接
  1266. roadService.subtraRoadFromIntersect(pointId, roadId);
  1267. const newPointId = road.getPointId(dir);
  1268. const newPoint = dataService.getPoint(newPointId);
  1269. // 更新新坐标
  1270. newPoint.setPosition(virtualInfo.virtualPosition);
  1271. // 拆分
  1272. roadService.splitRoad(limitRoadId, newPointId, dir);
  1273. }
  1274. }
  1275. }
  1276. // 吸附邻居墙的另一个端点。
  1277. else {
  1278. roadService.moveTo(pointId, virtualInfo.adsorbPointId);
  1279. }
  1280. }
  1281. // 新建墙
  1282. else {
  1283. this.createRoadForMoveRoad(
  1284. pointId,
  1285. roadId,
  1286. virtualInfo.virtualPosition
  1287. );
  1288. }
  1289. }
  1290. }
  1291. //
  1292. createRoadForMoveRoad(pointId, roadId, newPosition) {
  1293. const road = dataService.getRoad(roadId);
  1294. const dir = roadService.getDirction(pointId, roadId);
  1295. // 第一步是断开连接
  1296. roadService.subtraRoadFromIntersect(pointId, roadId);
  1297. // 第二步更新端点坐标
  1298. const newPointId = road.getPointId(dir);
  1299. const newPoint = dataService.getPoint(newPointId);
  1300. newPoint.setPosition(newPosition);
  1301. // 第三步先新建墙
  1302. roadService.create(pointId, newPointId);
  1303. // 还缺少road和newRoad相交,这需要等另一头的point完成后最后处理
  1304. }
  1305. deleteRoadForLinked(roadId) {
  1306. const road = dataService.getRoad(roadId);
  1307. roadService.subtraRoadFromIntersect(road.startId, roadId);
  1308. roadService.subtraRoadFromIntersect(road.endId, roadId);
  1309. dataService.deleteRoad(roadId);
  1310. }
  1311. }
  1312. const moveRoad = new MoveRoad();
  1313. export { moveRoad };