// import { mathUtil } from "../Util/MathUtil.js/index.js"; // import SingleDoor from "../Geometry/SingleDoor.js"; // import DoubleDoor from "../Geometry/DoubleDoor.js"; // import SlideDoor from "../Geometry/SlideDoor.js"; // import SingleWindow from "../Geometry/SingleWindow.js"; // import FrenchWindow from "../Geometry/FrenchWindow.js"; // import BayWindow from "../Geometry/BayWindow.js"; // import Pass from "../Geometry/Pass.js"; import { coordinate } from "../Coordinate"; import { dataService } from "./DataService.js"; // import { wallService } from "./WallService.js"; import VectorType from "../enum/VectorType.js"; import Constant from "../Constant"; // import { moveSymbol } from "../Controls/MoveSymbol.js"; import { stateService } from "./StateService.js"; export class SymbolService { constructor() { this.enterImg = null; } // 新建symbol createSymbol(start, end, geoType, parent, symbolId) { let symbol = null; switch (geoType) { case VectorType.BayWindow: symbol = new BayWindow(start, end, symbolId); break; case VectorType.FrenchWindow: symbol = new FrenchWindow(start, end, symbolId); break; case VectorType.SingleDoor: symbol = new SingleDoor(start, end, symbolId); break; case VectorType.DoubleDoor: symbol = new DoubleDoor(start, end, symbolId); break; case VectorType.SlideDoor: symbol = new SlideDoor(start, end, symbolId); break; case VectorType.SingleWindow: symbol = new SingleWindow(start, end, symbolId); break; case VectorType.Pass: symbol = new Pass(start, end, symbolId); break; } if (symbol != null) { symbol.setSymbolParent(parent); symbol.setPoints2d(); this.setPosition3d(symbol); dataService.addSymbol(symbol); } if (parent) { const wall = dataService.getWall(parent); wallService.addChildren(wall, symbol.vectorId); } symbol.len = mathUtil.getDistance(start, end); return symbol; } addSymbol(position, symbolType, wallId) { const symbolLen = this.getDefaultSymbolLen(symbolType); const wall = dataService.getWall(wallId); const wallLine = wallService.getLine(wall); position = mathUtil.getJoinLinePoint(position, wallLine); // const twoParallels = mathUtil.getParallelLineForDistance(vSymbolLine, symbolLen / 2) // const point1 = mathUtil.getIntersectionPoint(twoParallels.line1, wallLine) // const point2 = mathUtil.getIntersectionPoint(twoParallels.line2, wallLine) // 不能超出墙的范围 // const newPositions = this.getNewForContainSymbols(point1, point2, wallId) // if (wallService.isContain(wall, point1) && wallService.isContain(wall, point2) && newPositions != null && !newPositions.collision) { // const symbol = this.createSymbol(point1, point2, symbolType, wallId) // return symbol.vectorId // } const newPositions = this.getNewPosForSymbol( position, wallId, null, symbolLen ); if (newPositions.state) { const symbol = this.createSymbol( newPositions.position1, newPositions.position2, symbolType, wallId ); return symbol.vectorId; } return null; } setPosition3d(symbol) { const mid = { x: (symbol.startPoint.x + symbol.endPoint.x) / 2, y: (symbol.startPoint.y + symbol.endPoint.y) / 2, }; const height = dataService.getFloorHeight(); symbol.position3d = { x: mid.x, y: height, z: -1 * mid.y, }; } isSymbol(geoType) { switch (geoType) { case "BayWindow": return true; case "FrenchWindow": return true; case "SingleDoor": return true; case "DoubleDoor": return true; case "SlideDoor": return true; case "SingleWindow": return true; case "Pass": return true; } return false; } getDefaultSymbolLen(geoType) { let len = 0; switch (geoType) { case "BayWindow": len = 1.5; break; case "FrenchWindow": len = 1.5; break; case "SingleDoor": len = 0.8; break; case "DoubleDoor": len = 1.5; break; case "SlideDoor": len = 1.5; break; case "SingleWindow": len = 0.8; break; case "Pass": len = 0.8; break; } return len; } //从墙上去掉symbol的所属 deleteSymbolForWall(wall, symbolId) { if (wall) { let index = wall.children.indexOf(symbolId); if (index > -1) { wall.children.splice(index, 1); } let symbol = dataService.getSymbol(symbolId); symbol.parent = null; } } deleteSymbol(symbolId) { const symbol = dataService.getSymbol(symbolId); if (symbol.parent) { let wall = dataService.getWall(symbol.parent); this.deleteSymbolForWall(wall, symbolId); } dataService.deleteSymbol(symbolId); } // 更新symbol的归属 changeSymbolForBelong(symbolId, wallId) { const symbol = dataService.getSymbol(symbolId); const parentId = symbol.parent; const parent = dataService.getWall(parentId); this.deleteSymbolForWall(parent, symbolId); symbol.setSymbolParent(wallId); let wall = dataService.getWall(wallId); wallService.addChildren(wall, symbolId); } // 拆分墙的时候,symbol也要相应的改变 // wall拆分成wallId1和wallId2,一般情况wallId和wallId1是相同的 reBelongForSplitWall(wallId, wallId1, wallId2) { const wall = dataService.getWall(wallId); for (let i = 0; i < wall.children.length; ++i) { const symbolId = wall.children[i]; if (wallId != wallId1 && this.isContainSymbolForWall(symbolId, wallId1)) { this.changeSymbolForBelong(symbolId, wallId1); } else if ( wallId != wallId2 && this.isContainSymbolForWall(symbolId, wallId2) ) { this.changeSymbolForBelong(symbolId, wallId2); } } } // wallId对应的墙是否包含symbol isContainSymbolForWall(symbolId, wallId) { const wall = dataService.getWall(wallId); const symbol = dataService.getSymbol(symbolId); const point = { x: (symbol.startPoint.x + symbol.endPoint.x) / 2, y: (symbol.startPoint.y + symbol.endPoint.y) / 2, }; if (wallService.isContain(wall, point)) { return true; } } // 更新symbol的归属 // 墙可能删除了,也可能合并了等等 changeSymbolForBelong(symbolId, wallId) { const symbol = dataService.getSymbol(symbolId); const parentId = symbol.parent; let parent = dataService.getWall(parentId); this.deleteSymbolForWall(parent, symbolId); symbol.setSymbolParent(wallId); let wall = dataService.getWall(wallId); wallService.addChildren(wall, symbolId); } // 墙角pointId移动的时候,周围的symbol都跟着变化 updateSymbolsPositionsForWallCorner(pointId) { const point = dataService.getPoint(pointId); const parent = point.parent; for (const key in parent) { this.updateSymbolsPositionsForWall(key); } } // wallId对应的wall改变的时候,上面的symbol也跟着改变 updateSymbolsPositionsForWall(wallId) { const wall = dataService.getWall(wallId); const symbolIds = wall.children; for (let i = 0; i < symbolIds.length; ++i) { const symbol = dataService.getSymbol(symbolIds[i]); this.updateSEForChangeWall(symbol); } } // 更新Symbold的startPoint,endPoint和points2d,随着wall来 updateSEForChangeWall(symbol) { const symbolId = symbol.vectorId; //const symbol = dataService.getSymbol(symbolId); const wall = dataService.getWall(symbol.parent); const startPoint = dataService.getPoint(wall.start); const endPoint = dataService.getPoint(wall.end); const line = mathUtil.createLine1(startPoint, endPoint); const newStart = mathUtil.getJoinLinePoint(symbol.startPoint, line); const newEnd = mathUtil.getJoinLinePoint(symbol.endPoint, line); const dif = { x: 0, y: 0 }; const min = 0.001; //不要超出一点 let containFlag = true; if (!wallService.isContain(wall, newStart)) { // symbol的start与wall的start挨的近 if ( mathUtil.getDistance(newStart, startPoint) < mathUtil.getDistance(newStart, endPoint) ) { dif.x = startPoint.x - newStart.x; dif.y = startPoint.y - newStart.y; } else { dif.x = endPoint.x - newStart.x; dif.y = endPoint.y - newStart.y; } newStart.x += dif.x; newStart.y += dif.y; if ( wallService.isContain(wall, { x: newEnd.x + dif.x, y: newEnd.y + dif.y, }) ) { newEnd.x += dif.x; newEnd.y += dif.y; } containFlag = false; } else if (!wallService.isContain(wall, newEnd)) { if ( mathUtil.getDistance(newEnd, startPoint) < mathUtil.getDistance(newEnd, endPoint) ) { dif.x = startPoint.x - newEnd.x; dif.y = startPoint.y - newEnd.y; } else { dif.x = endPoint.x - newEnd.x; dif.y = endPoint.y - newEnd.y; } newEnd.x += dif.x; newEnd.y += dif.y; if ( wallService.isContain(wall, { x: newStart.x + dif.x, y: newStart.y + dif.y, }) ) { newStart.x += dif.x; newStart.y += dif.y; } containFlag = false; } // 是否与wall上别的symbol部分重合 if (!containFlag) { this.updateSEForCollideSymbols(symbolId, newStart, newEnd); } else { this.setPosition(symbol, newStart, "start"); this.setPosition(symbol, newEnd, "end"); symbol.setPoints2d(); } } //需要考虑碰撞 updateSEForCollideSymbols(symbolId, newStart, newEnd) { const symbol = dataService.getSymbol(symbolId); // 是否与wall上别的symbol部分重合 const newPositions = this.getNewForContainSymbols( newStart, newEnd, symbol.parent, symbolId ); // if (newPositions != null) { // this.setPosition(symbol, newPositions.position1, 'start') // this.setPosition(symbol, newPositions.position2, 'end') // symbol.setPoints2d() // } // if (mathUtil.getDistance(symbol.startPoint, symbol.endPoint) < Constant.minSymbolLen) { // this.deleteSymbol(symbolId) // } if (newPositions != null) { if ( mathUtil.getDistance(newPositions.position1, newPositions.position2) < Constant.minSymbolLen ) { this.deleteSymbol(symbolId); } else { this.setPosition(symbol, newPositions.position1, "start"); this.setPosition(symbol, newPositions.position2, "end"); symbol.setPoints2d(); } } } //position1, position2表示exceptSymbolId新的坐标 getNewForContainSymbols(position1, position2, wallId, exceptSymbolId) { const min = 0.01; const wall = dataService.getWall(wallId); let points = []; for (let i = 0; i < wall.children.length; ++i) { const symbolId = wall.children[i]; if (symbolId == exceptSymbolId) { continue; } const symbol = dataService.getSymbol(symbolId); points.push({ x: symbol.startPoint.x, y: symbol.startPoint.y, index: 1, vectorId: symbolId, }); points.push({ x: symbol.endPoint.x, y: symbol.endPoint.y, index: 2, vectorId: symbolId, }); } points.push({ x: position1.x, y: position1.y, index: 1, vectorId: exceptSymbolId, }); points.push({ x: position2.x, y: position2.y, index: 2, vectorId: exceptSymbolId, }); const startPoint = dataService.getPoint(wall.start); points = points.sort(sortNumber.bind(this)); function sortNumber(a, b) { return ( mathUtil.getDistance(startPoint, a) - mathUtil.getDistance(startPoint, b) ); } for (let i = 0; i < points.length - 1; ++i) { if (points[i].vectorId == exceptSymbolId) { if (i == 0 || i == points.length - 2) { if ( mathUtil.getDistance(points[i], points[i + 1]) < Constant.minSymbolLen ) { return null; } else if (points[i + 1].vectorId == exceptSymbolId) { return { position1: position1, position2: { x: points[i + 1].x, y: points[i + 1].y }, }; } else if (points[i + 1].vectorId != exceptSymbolId) { return { position1: position1, position2: { x: points[i + 1].x, y: points[i + 1].y }, collision: true, }; } } //不在其他symbol内部 else if ( points[i + 1].vectorId == exceptSymbolId && points[i - 1].vectorId != points[i + 2].vectorId ) { if ( mathUtil.getDistance( { x: points[i - 1].x, y: points[i - 1].y }, { x: points[i + 2].x, y: points[i + 2].y } ) < Constant.minSymbolLen ) { return null; } else { return { position1: { x: points[i - 1].x, y: points[i - 1].y }, position2: { x: points[i + 2].x, y: points[i + 2].y }, //collision: true, }; } } } } return null; } getNewPosForSymbol(point, wallId, exceptSymbolId, currentSymbolLen) { const wall = dataService.getWall(wallId); const startPoint = dataService.getPoint(wall.start); const endPoint = dataService.getPoint(wall.end); const wallLine = wallService.getLine(wall); const vSymbolLine = mathUtil.getVerticalLine(wallLine, point); let symbolLen = currentSymbolLen; if (exceptSymbolId) { const currentSymbol = dataService.getSymbol(exceptSymbolId); symbolLen = currentSymbol.len; } const twoParallels = mathUtil.getParallelLineForDistance( vSymbolLine, symbolLen / 2 ); let point1 = mathUtil.getIntersectionPoint(twoParallels.line1, wallLine); let point2 = mathUtil.getIntersectionPoint(twoParallels.line2, wallLine); //如果在墙外部,就平移到墙内部 if (mathUtil.getDistance(startPoint, endPoint) < symbolLen) { mathUtil.clonePoint(point1, startPoint); mathUtil.clonePoint(point2, endPoint); } else { let dx, dy; let _point1 = {}; let _point2 = {}; if (!wallService.isContain(wall, point1)) { dx = startPoint.x - point1.x; dy = startPoint.y - point1.y; _point2.x = point2.x + dx; _point2.y = point2.y + dy; if (!wallService.isContain(wall, _point2)) { dx = endPoint.x - point1.x; dy = endPoint.y - point1.y; point2.x += dx; point2.y += dy; mathUtil.clonePoint(point1, endPoint); } else { point2.x += dx; point2.y += dy; mathUtil.clonePoint(point1, startPoint); } } else if (!wallService.isContain(wall, point2)) { dx = startPoint.x - point2.x; dy = startPoint.y - point2.y; _point1.x = point1.x + dx; _point1.y = point1.y + dy; if (!wallService.isContain(wall, _point1)) { dx = endPoint.x - point2.x; dy = endPoint.y - point2.y; point1.x += dx; point1.y += dy; mathUtil.clonePoint(point2, endPoint); } else { point1.x += dx; point1.y += dy; mathUtil.clonePoint(point2, startPoint); } } } let points = []; for (let i = 0; i < wall.children.length; ++i) { const symbolId = wall.children[i]; if (symbolId == exceptSymbolId) { continue; } const symbol = dataService.getSymbol(symbolId); points.push({ x: symbol.startPoint.x, y: symbol.startPoint.y, index: 1, //表示start vectorId: symbolId, }); points.push({ x: symbol.endPoint.x, y: symbol.endPoint.y, index: 2, //表示end vectorId: symbolId, }); } points.push({ x: startPoint.x, y: startPoint.y, index: 1, vectorId: wallId, type: VectorType.Wall, }); points.push({ x: endPoint.x, y: endPoint.y, index: 2, vectorId: wallId, type: VectorType.Wall, }); points = points.sort(sortNumber.bind(this)); function sortNumber(a, b) { return ( mathUtil.getDistance(startPoint, a) - mathUtil.getDistance(startPoint, b) ); } let flag = true; for (let i = 0; i < points.length - 1; ++i) { if (mathUtil.isContainForSegment(point, points[i], points[i + 1])) { if (mathUtil.getDistance(points[i], points[i + 1]) > symbolLen) { //完全在一个symbol内部或者symbol内有其他的symbol if ( points[i].vectorId == points[i + 1].vectorId && points[i].type != VectorType.Wall ) { return { position1: point1, position2: point2, collision: true, state: false, }; } //完全在wall内部 else if ( points[i].vectorId == points[i + 1].vectorId && points[i].type == VectorType.Wall ) { return { position1: point1, position2: point2, collision: true, state: true, }; } //一端在墙/门/窗外部 else if ( !mathUtil.isContainForSegment(point1, points[i], points[i + 1]) || !mathUtil.isContainForSegment(point2, points[i], points[i + 1]) ) { return { position1: point1, position2: point2, collision: true, state: false, }; } } else if ( mathUtil.getDistance(points[i], points[i + 1]) < Constant.minSymbolLen ) { return { position1: point1, position2: point2, collision: true, state: false, }; } //大于最小距离,小于本来的长度。 else if (points[i].vectorId != points[i + 1].vectorId) { return { position1: { x: points[i].x, y: points[i].y }, position2: { x: points[i + 1].x, y: points[i + 1].y }, collision: true, state: true, }; } //完全在一个symbol内部 else if ( points[i].vectorId == points[i + 1].vectorId && points[i].type != VectorType.Wall ) { return { position1: point1, position2: point2, collision: true, state: false, }; } else if ( points[i].vectorId == points[i + 1].vectorId && points[i].type == VectorType.Wall ) { return { position1: { x: points[i].x, y: points[i].y }, position2: { x: points[i + 1].x, y: points[i + 1].y }, collision: true, state: true, }; } flag = false; } else if (mathUtil.getDistance(point, points[i]) < Constant.minAdsorb) { return { position1: point1, position2: point2, collision: true, state: false, }; } } if (flag) { return { position1: point1, position2: point2, collision: false, state: true, }; } else { //console.error(566) return { position1: point1, position2: point2, collision: false, state: true, }; } // return { // position1: point1, // position2: point2, // collision: false, // state: true, // } } setPosition(symbol, position, dir) { if (dir == "start") { mathUtil.clonePoint(symbol.startPoint, position); } else if (dir == "end") { mathUtil.clonePoint(symbol.endPoint, position); } } // 只考虑symbol的端点可能不在墙面上了,这时候要更新 // 用在移动墙面的时候,邻居墙的symbols可能要变 updateSymbolsPositionsForNeighWall(wallId) { const wall = dataService.getWall(wallId); const symbolIds = wall.children; for (let i = 0; i < symbolIds.length; ++i) { this.updateSEForWallSize(symbolIds[i]); } } // 更新symbol的start或者end,一般是symbol的端点在墙外了 updateSEForWallSize(symbolId) { const symbol = dataService.getSymbol(symbolId); const wall = dataService.getWall(symbol.parent); const startPoint = dataService.getPoint(wall.start); const endPoint = dataService.getPoint(wall.end); const newStart = { x: symbol.startPoint.x, y: symbol.startPoint.y, }; const newEnd = { x: symbol.endPoint.x, y: symbol.endPoint.y, }; const dif = { x: 0, y: 0 }; if (!wallService.isContain(wall, newStart)) { // symbol的start与wall的start挨的近 if ( mathUtil.getDistance(newStart, startPoint) < mathUtil.getDistance(newStart, endPoint) ) { dif.x = startPoint.x - newStart.x; dif.y = startPoint.y - newStart.y; } else { dif.x = endPoint.x - newStart.x; dif.y = endPoint.y - newStart.y; } newStart.x += dif.x; newStart.y += dif.y; } else if (!wallService.isContain(wall, newEnd)) { if ( mathUtil.getDistance(newEnd, startPoint) < mathUtil.getDistance(newEnd, endPoint) ) { dif.x = startPoint.x - newEnd.x; dif.y = startPoint.y - newEnd.y; } else { dif.x = endPoint.x - newEnd.x; dif.y = endPoint.y - newEnd.y; } newEnd.x += dif.x; newEnd.y += dif.y; } else { return null; } this.updateSEForCollideSymbols(symbolId, newStart, newEnd); } updateSymbolForLen(symbolId, len) { const symbol = dataService.getSymbol(symbolId); const start = symbol.startPoint; const end = symbol.endPoint; const line = mathUtil.createLine1(start, end); const midPoint = { x: (start.x + end.x) / 2, y: (start.y + end.y) / 2 }; const vertLine = mathUtil.getVerticalLine(line, midPoint); const wall = dataService.getWall(symbol.parent); const startPoint = dataService.getPoint(wall.start); const endPoint = dataService.getPoint(wall.end); if (len == null || typeof len === "undefined") { len = mathUtil.getDistance(start, end); const distance = mathUtil.getDistance(startPoint, endPoint); if (len > distance) { len = distance; } } const lines = mathUtil.getParallelLineForDistance(vertLine, len / 2); const join1 = mathUtil.getIntersectionPoint(lines.line1, line); const join2 = mathUtil.getIntersectionPoint(lines.line2, line); const symbolInfo = {}; if ( mathUtil.getDistance(start, join1) < mathUtil.getDistance(start, join2) ) { symbolInfo.start = join1; symbolInfo.end = join2; } else { symbolInfo.start = join2; symbolInfo.end = join1; } let startFlag = false; let endFlag = false; let dx, dy; const nearestPosition = this.getNearestPosition( symbol.parent, symbolId, true ); if ( nearestPosition.startPosition != null && mathUtil.PointInSegment( nearestPosition.startPosition, symbolInfo.start, symbolInfo.end ) ) { // start堵住了,end需要增加 //dx = symbolInfo.end.x - symbol.endPoint.x //dy = symbolInfo.end.y - symbol.endPoint.y dx = symbolInfo.start.x - nearestPosition.startPosition.x; dy = symbolInfo.start.y - nearestPosition.startPosition.y; mathUtil.clonePoint(symbolInfo.start, nearestPosition.startPosition); symbolInfo.end.x -= dx; symbolInfo.end.y -= dy; startFlag = true; } if ( nearestPosition.endPosition != null && mathUtil.PointInSegment( nearestPosition.endPosition, symbolInfo.start, symbolInfo.end ) ) { // end堵住了,start需要增加 dx = symbolInfo.end.x - nearestPosition.endPosition.x; dy = symbolInfo.end.y - nearestPosition.endPosition.y; mathUtil.clonePoint(symbolInfo.end, nearestPosition.endPosition); if (!startFlag) { symbolInfo.start.x -= dx; symbolInfo.start.y -= dy; //这时候可能start又超出范围了 if ( mathUtil.PointInSegment( nearestPosition.startPosition, symbolInfo.start, symbolInfo.end ) ) { mathUtil.clonePoint(symbolInfo.start, nearestPosition.startPosition); startFlag = true; } } endFlag = true; } symbolInfo.vectorId = symbolId; mathUtil.clonePoint(symbol.startPoint, symbolInfo.start); mathUtil.clonePoint(symbol.endPoint, symbolInfo.end); symbol.setPoints2d(); return { block: startFlag & endFlag, start: symbolInfo.start, end: symbolInfo.end, }; } getNearestPosition(wallId, symbolId, isExceedWall, position1, position2) { const wall = dataService.getWall(wallId); const startPoint = dataService.getPoint(wall.start); const endPoint = dataService.getPoint(wall.end); const symbolIds = wall.children; let symbol = dataService.getSymbol(symbolId); if (!symbol && !symbolId) { symbol = {}; symbol = { struct: {}, }; symbol.startPoint = position1; symbol.endPoint = position2; } let minSdis = 10000; let minEdis = 10000; let startPosition = null; let endPosition = null; // 与startPosition同属symbol端点(另一头) let startPosition2 = null; // 与endPosition同属symbol端点(另一头) let endPosition2 = null; for (let i = 0; i < symbolIds.length; ++i) { if (symbolIds[i] == symbolId) { continue; } const otherSymbol = dataService.getSymbol(symbolIds[i]); const dis1 = mathUtil.getDistance( symbol.startPoint, otherSymbol.startPoint ); const dis2 = mathUtil.getDistance( symbol.startPoint, otherSymbol.endPoint ); if (minSdis > Math.min(dis1, dis2)) { if (dis1 < dis2) { startPosition = otherSymbol.startPoint; startPosition2 = otherSymbol.endPoint; } else { startPosition = otherSymbol.endPoint; startPosition2 = otherSymbol.startPoint; } if ( mathUtil.getDistance(symbol.startPoint, startPosition) > mathUtil.getDistance(symbol.endPoint, startPosition) ) { startPosition = null; startPosition2 = null; } else { minSdis = Math.min(dis1, dis2); } } const dis3 = mathUtil.getDistance( symbol.endPoint, otherSymbol.startPoint ); const dis4 = mathUtil.getDistance(symbol.endPoint, otherSymbol.endPoint); if (minEdis > Math.min(dis3, dis4)) { if (dis3 < dis4) { endPosition = otherSymbol.startPoint; endPosition2 = otherSymbol.endPoint; } else { endPosition = otherSymbol.endPoint; endPosition2 = otherSymbol.startPoint; } if ( mathUtil.getDistance(symbol.endPoint, endPosition) > mathUtil.getDistance(symbol.startPoint, endPosition) ) { endPosition = null; endPosition2 = null; } else { minEdis = Math.min(dis3, dis4); } } } if (isExceedWall) { if (startPosition == null) { if ( mathUtil.getDistance(startPoint, symbol.startPoint) > mathUtil.getDistance(startPoint, symbol.endPoint) ) { startPosition = endPoint; startPosition2 = endPoint; } else { startPosition = startPoint; startPosition2 = startPoint; } } if (endPosition == null) { if ( mathUtil.getDistance(startPoint, symbol.startPoint) > mathUtil.getDistance(startPoint, symbol.endPoint) ) { endPosition = startPoint; endPosition2 = startPoint; } else { endPosition = endPoint; endPosition2 = endPoint; } } } return { startPosition: startPosition, startPosition2: startPosition2, endPosition: endPosition, endPosition2: endPosition2, }; } // point是目标点,selectState表示start还是end // 只是不允许start和end互换位置 moveSymbolSinglePoint(targetPosition, symbolId, selectState) { const symbol = dataService.getSymbol(symbolId); const symbolLine = mathUtil.createLine1(symbol.startPoint, symbol.endPoint); const vSymbolLine = mathUtil.getVerticalLine(symbolLine, targetPosition); targetPosition = mathUtil.getIntersectionPoint(vSymbolLine, symbolLine); const midPoint = { x: (symbol.startPoint.x + symbol.endPoint.x) / 2, y: (symbol.startPoint.y + symbol.endPoint.y) / 2, }; // 是否超过了wall外 const wall = dataService.getWall(symbol.parent); const startPoint = dataService.getPoint(wall.start); const endPoint = dataService.getPoint(wall.end); if (selectState == "start") { // symbol的start和end位置交换了 if (!mathUtil.PointInSegment(midPoint, targetPosition, symbol.endPoint)) { return null; } else { // start-start if ( mathUtil.getDistance(symbol.startPoint, startPoint) < mathUtil.getDistance(symbol.endPoint, startPoint) ) { // 超出了 if ( mathUtil.getDistance(targetPosition, midPoint) > mathUtil.getDistance(startPoint, midPoint) ) { mathUtil.clonePoint(targetPosition, startPoint); } } // start-end else { // 超出了 if ( mathUtil.getDistance(targetPosition, midPoint) > mathUtil.getDistance(endPoint, midPoint) ) { mathUtil.clonePoint(targetPosition, endPoint); } } } } else if (selectState == "end") { // symbol的start和end位置交换了 if ( !mathUtil.PointInSegment(midPoint, targetPosition, symbol.startPoint) ) { return null; } else { // start-start if ( mathUtil.getDistance(symbol.endPoint, endPoint) < mathUtil.getDistance(symbol.startPoint, endPoint) ) { // 超出了 if ( mathUtil.getDistance(targetPosition, midPoint) > mathUtil.getDistance(endPoint, midPoint) ) { mathUtil.clonePoint(targetPosition, endPoint); } } // start-end else { // 超出了 if ( mathUtil.getDistance(targetPosition, midPoint) > mathUtil.getDistance(startPoint, midPoint) ) { mathUtil.clonePoint(targetPosition, startPoint); } } } } return { dir: selectState, position: targetPosition, }; } setSymbolInfo(symbolInfo) { let symbol = dataService.getSymbol(symbolInfo.vectorId); symbol.openSide = symbolInfo.openSide; symbol.startPoint = symbolInfo.start; symbol.endPoint = symbolInfo.end; symbol.points2d = JSON.parse(JSON.stringify(symbolInfo.points2d)); symbol.enter = symbolInfo.enter; symbol.parent = symbolInfo.parent; return symbol; } setEnterImg(img) { this.enterImg = img; } getEnterImg() { return this.enterImg; } createSymbolFromPanorama(raycaster, geoType, panoId) { //console.log(raycaster, geoType) let joinsInfo = []; const start = { x: raycaster.ray.origin.x, y: -1 * raycaster.ray.origin.z, }; // const end = { // x: raycaster.ray.origin.x + raycaster.ray.direction.x, // y: -1 * (raycaster.ray.origin.z + raycaster.ray.direction.z), // } const walls = dataService.getWalls(); for (const wallId in walls) { const wall = dataService.getWall(wallId); const startPoint = dataService.getPoint(wall.start); const endPoint = dataService.getPoint(wall.end); const join = mathUtil.raySegmentIntersection( start, raycaster.ray.direction, startPoint, endPoint ); if (join != null) { joinsInfo.push({ wallId: wallId, join: join, }); } } if (joinsInfo.length > 0) { joinsInfo = joinsInfo.sort(sortNumber.bind(this)); function sortNumber(a, b) { return ( mathUtil.getDistance(start, a.join) - mathUtil.getDistance(start, b.join) ); } const symbolId = this.addSymbol( joinsInfo[0].join, geoType, joinsInfo[0].wallId ); if (symbolId != null) { moveSymbol.moveFullSymbol( joinsInfo[0].join, symbolId, joinsInfo[0].wallId ); const symbol = dataService.getSymbol(symbolId); return symbolId; } else { console.error("漫游模式下添加门/窗:门/窗区域太小,加不上"); return null; } } else { console.error("漫游模式下添加门/窗:没有与任何墙相交"); return null; } } } const symbolService = new SymbolService(); export { symbolService };