123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149 |
- // 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 };
|