| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948 |
- var editor = {
- wall: function (start, end, type, thick) {
- this.thick = thick;
- this.start = start;
- this.end = end;
- this.type = type;
- this.parent = null;
- this.child = null;
- this.angle = 0;
- this.equations = {};
- this.coords = [];
- this.backUp = false;
- },
- // RETURN OBJECTS ARRAY INDEX OF WALLS [WALL1, WALL2, n...] WALLS WITH THIS NODE, EXCEPT PARAM = OBJECT WALL
- getWallNode: function (coords, except = false) {
- var nodes = [];
- for (var k in WALLS) {
- if (!isObjectsEquals(WALLS[k], except)) {
- if (isObjectsEquals(WALLS[k].start, coords)) {
- nodes.push({ wall: WALLS[k], type: "start" });
- }
- if (isObjectsEquals(WALLS[k].end, coords)) {
- nodes.push({ wall: WALLS[k], type: "end" });
- }
- }
- }
- if (nodes.length == 0) return false;
- else return nodes;
- },
- wallsComputing: function (WALLS, action = false) {
- // IF ACTION == MOVE -> equation2 exist !!!!!
- $('#boxwall').empty();
- $('#boxArea').empty();
- for (var vertice = 0; vertice < WALLS.length; vertice++) {
- var wall = WALLS[vertice];
- if (wall.parent != null) {
- if (!isObjectsEquals(wall.parent.start, wall.start) && !isObjectsEquals(wall.parent.end, wall.start)) {
- wall.parent = null;
- }
- }
- if (wall.child != null) {
- if (!isObjectsEquals(wall.child.start, wall.end) && !isObjectsEquals(wall.child.end, wall.end)) {
- wall.child = null;
- }
- }
- }
- for (var vertice = 0; vertice < WALLS.length; vertice++) {
- var wall = WALLS[vertice];
- if (wall.parent != null) {
- if (isObjectsEquals(wall.parent.start, wall.start)) {
- var previousWall = wall.parent;
- var previousWallStart = previousWall.end;
- var previousWallEnd = previousWall.start;
- }
- if (isObjectsEquals(wall.parent.end, wall.start)) {
- var previousWall = wall.parent;
- var previousWallStart = previousWall.start;
- var previousWallEnd = previousWall.end;
- }
- }
- else {
- var S = editor.getWallNode(wall.start, wall);
- // if (wallInhibation && isObjectsEquals(wall, wallInhibation)) S = false;
- for (var k in S) {
- var eqInter = editor.createEquationFromWall(S[k].wall);
- var angleInter = 90; // TO PASS TEST
- if (action == "move") {
- angleInter = qSVG.angleBetweenEquations(eqInter.A, equation2.A);
- }
- if (S[k].type == 'start' && S[k].wall.parent == null && angleInter > 20 && angleInter < 160) {
- wall.parent = S[k].wall;
- S[k].wall.parent = wall;
- var previousWall = wall.parent;
- var previousWallStart = previousWall.end;
- var previousWallEnd = previousWall.start;
- }
- if (S[k].type == 'end' && S[k].wall.child == null && angleInter > 20 && angleInter < 160) {
- wall.parent = S[k].wall;
- S[k].wall.child = wall;
- var previousWall = wall.parent;
- var previousWallStart = previousWall.start;
- var previousWallEnd = previousWall.end;
- }
- }
- }
- if (wall.child != null) {
- if (isObjectsEquals(wall.child.end, wall.end)) {
- var nextWall = wall.child;
- var nextWallStart = nextWall.end;
- var nextWallEnd = nextWall.start;
- }
- else {
- var nextWall = wall.child;
- var nextWallStart = nextWall.start;
- var nextWallEnd = nextWall.end;
- }
- }
- else {
- var E = editor.getWallNode(wall.end, wall);
- // if (wallInhibation && isObjectsEquals(wall, wallInhibation)) E = false;
- for (var k in E) {
- var eqInter = editor.createEquationFromWall(E[k].wall);
- var angleInter = 90; // TO PASS TEST
- if (action == "move") {
- angleInter = qSVG.angleBetweenEquations(eqInter.A, equation2.A);
- }
- if (E[k].type == 'end' && E[k].wall.child == null && angleInter > 20 && angleInter < 160) {
- wall.child = E[k].wall;
- E[k].wall.child = wall;
- var nextWall = wall.child;
- var nextWallStart = nextWall.end;
- var nextWallEnd = nextWall.start;
- }
- if (E[k].type == 'start' && E[k].wall.parent == null && angleInter > 20 && angleInter < 160) {
- wall.child = E[k].wall;
- E[k].wall.parent = wall;
- var nextWall = wall.child;
- var nextWallStart = nextWall.start;
- var nextWallEnd = nextWall.end;
- }
- }
- }
- var angleWall = Math.atan2(wall.end.y - wall.start.y, wall.end.x - wall.start.x);
- wall.angle = angleWall;
- var wallThickX = (wall.thick / 2) * Math.sin(angleWall);
- var wallThickY = (wall.thick / 2) * Math.cos(angleWall);
- var eqWallUp = qSVG.createEquation(wall.start.x + wallThickX, wall.start.y - wallThickY, wall.end.x + wallThickX, wall.end.y - wallThickY);
- var eqWallDw = qSVG.createEquation(wall.start.x - wallThickX, wall.start.y + wallThickY, wall.end.x - wallThickX, wall.end.y + wallThickY);
- var eqWallBase = qSVG.createEquation(wall.start.x, wall.start.y, wall.end.x, wall.end.y);
- wall.equations = { up: eqWallUp, down: eqWallDw, base: eqWallBase };
- var dWay;
- // WALL STARTED
- if (wall.parent == null) {
- var eqP = qSVG.perpendicularEquation(eqWallUp, wall.start.x, wall.start.y);
- var interUp = qSVG.intersectionOfEquations(eqWallUp, eqP, "object");
- var interDw = qSVG.intersectionOfEquations(eqWallDw, eqP, "object");
- wall.coords = [interUp, interDw];
- dWay = "M" + interUp.x + "," + interUp.y + " L" + interDw.x + "," + interDw.y + " ";
- }
- else {
- var eqP = qSVG.perpendicularEquation(eqWallUp, wall.start.x, wall.start.y);
- // var previousWall = wall.parent;
- // var previousWallStart = previousWall.start;
- // var previousWallEnd = previousWall.end;
- var anglePreviousWall = Math.atan2(previousWallEnd.y - previousWallStart.y, previousWallEnd.x - previousWallStart.x);
- var previousWallThickX = (previousWall.thick / 2) * Math.sin(anglePreviousWall);
- var previousWallThickY = (previousWall.thick / 2) * Math.cos(anglePreviousWall);
- var eqPreviousWallUp = qSVG.createEquation(previousWallStart.x + previousWallThickX, previousWallStart.y - previousWallThickY, previousWallEnd.x + previousWallThickX, previousWallEnd.y - previousWallThickY);
- var eqPreviousWallDw = qSVG.createEquation(previousWallStart.x - previousWallThickX, previousWallStart.y + previousWallThickY, previousWallEnd.x - previousWallThickX, previousWallEnd.y + previousWallThickY);
- if (Math.abs(anglePreviousWall - angleWall) > 0.09) {
- var interUp = qSVG.intersectionOfEquations(eqWallUp, eqPreviousWallUp, "object");
- var interDw = qSVG.intersectionOfEquations(eqWallDw, eqPreviousWallDw, "object");
- if (eqWallUp.A == eqPreviousWallUp.A) {
- interUp = { x: wall.start.x + wallThickX, y: wall.start.y - wallThickY };
- interDw = { x: wall.start.x - wallThickX, y: wall.start.y + wallThickY };
- }
- var miter = qSVG.gap(interUp, { x: previousWallEnd.x, y: previousWallEnd.y });
- if (miter > 1000) {
- var interUp = qSVG.intersectionOfEquations(eqP, eqWallUp, "object");
- var interDw = qSVG.intersectionOfEquations(eqP, eqWallDw, "object");
- }
- }
- if (Math.abs(anglePreviousWall - angleWall) <= 0.09) {
- var interUp = qSVG.intersectionOfEquations(eqP, eqWallUp, "object");
- var interDw = qSVG.intersectionOfEquations(eqP, eqWallDw, "object");
- }
- wall.coords = [interUp, interDw];
- dWay = "M" + interUp.x + "," + interUp.y + " L" + interDw.x + "," + interDw.y + " ";
- }
- // WALL FINISHED
- if (wall.child == null) {
- var eqP = qSVG.perpendicularEquation(eqWallUp, wall.end.x, wall.end.y);
- var interUp = qSVG.intersectionOfEquations(eqWallUp, eqP, "object");
- var interDw = qSVG.intersectionOfEquations(eqWallDw, eqP, "object");
- wall.coords.push(interDw, interUp);
- dWay = dWay + "L" + interDw.x + "," + interDw.y + " L" + interUp.x + "," + interUp.y + " Z";
- }
- else {
- var eqP = qSVG.perpendicularEquation(eqWallUp, wall.end.x, wall.end.y);
- // var nextWall = wall.child;
- // var nextWallStart = nextWall.start;
- // var nextWallEnd = nextWall.end;
- var angleNextWall = Math.atan2(nextWallEnd.y - nextWallStart.y, nextWallEnd.x - nextWallStart.x);
- var nextWallThickX = (nextWall.thick / 2) * Math.sin(angleNextWall);
- var nextWallThickY = (nextWall.thick / 2) * Math.cos(angleNextWall);
- var eqNextWallUp = qSVG.createEquation(nextWallStart.x + nextWallThickX, nextWallStart.y - nextWallThickY, nextWallEnd.x + nextWallThickX, nextWallEnd.y - nextWallThickY);
- var eqNextWallDw = qSVG.createEquation(nextWallStart.x - nextWallThickX, nextWallStart.y + nextWallThickY, nextWallEnd.x - nextWallThickX, nextWallEnd.y + nextWallThickY);
- if (Math.abs(angleNextWall - angleWall) > 0.09) {
- var interUp = qSVG.intersectionOfEquations(eqWallUp, eqNextWallUp, "object");
- var interDw = qSVG.intersectionOfEquations(eqWallDw, eqNextWallDw, "object");
- if (eqWallUp.A == eqNextWallUp.A) {
- interUp = { x: wall.end.x + wallThickX, y: wall.end.y - wallThickY };
- interDw = { x: wall.end.x - wallThickX, y: wall.end.y + wallThickY };
- }
- var miter = qSVG.gap(interUp, { x: nextWallStart.x, y: nextWallStart.y });
- if (miter > 1000) {
- var interUp = qSVG.intersectionOfEquations(eqWallUp, eqP, "object");
- var interDw = qSVG.intersectionOfEquations(eqWallDw, eqP, "object");
- }
- }
- if (Math.abs(angleNextWall - angleWall) <= 0.09) {
- var interUp = qSVG.intersectionOfEquations(eqWallUp, eqP, "object");
- var interDw = qSVG.intersectionOfEquations(eqWallDw, eqP, "object");
- }
- wall.coords.push(interDw, interUp);
- dWay = dWay + "L" + interDw.x + "," + interDw.y + " L" + interUp.x + "," + interUp.y + " Z";
- }
- wall.graph = editor.makeWall(dWay);
- $('#boxwall').append(wall.graph);
- }
- },
- makeWall: function (way) {
- var wallScreen = qSVG.create('none', 'path', {
- d: way,
- stroke: "none",
- fill: colorWall,
- "stroke-width": 1,
- "stroke-linecap": "butt",
- "stroke-linejoin": "miter",
- "stroke-miterlimit": 4,
- "fill-rule": "nonzero"
- });
- return wallScreen;
- },
- invisibleWall: function (wallToInvisble = false) {
- if (!wallToInvisble) wallToInvisble = binder.wall;
- // Use the provided wall instead of an external variable to avoid undefined access
- var objWall = editor.objFromWall(wallToInvisble);
- if (objWall.length == 0) {
- wallToInvisble.type = "separate";
- wallToInvisble.backUp = wallToInvisble.thick;
- wallToInvisble.thick = 0.07;
- editor.architect(WALLS);
- mode = "select_mode";
- $('#panel').show(200);
- save();
- return true;
- }
- else {
- $('#boxinfo').html('Les murs contenant des portes ou des fenêtres ne peuvent être une séparation !');
- return false;
- }
- },
- visibleWall: function (wallToInvisble = false) {
- if (!wallToInvisble) wallToInvisble = binder.wall;
- wallToInvisble.type = "normal";
- wallToInvisble.thick = wallToInvisble.backUp;
- wallToInvisble.backUp = false;
- editor.architect(WALLS);
- mode = "select_mode";
- $('#panel').show(200);
- save();
- return true;
- },
- architect: function (WALLS) {
- editor.wallsComputing(WALLS);
- Rooms = qSVG.polygonize(WALLS);
- $('#boxRoom').empty();
- $('#boxSurface').empty();
- editor.roomMaker(Rooms);
- return true;
- },
- splitWall: function (wallToSplit = false) {
- if (!wallToSplit) wallToSplit = binder.wall;
- var eqWall = editor.createEquationFromWall(wallToSplit);
- var wallToSplitLength = qSVG.gap(wallToSplit.start, wallToSplit.end);
- var newWalls = [];
- for (var k in WALLS) {
- var eq = editor.createEquationFromWall(WALLS[k]);
- var inter = qSVG.intersectionOfEquations(eqWall, eq, 'obj');
- if (qSVG.btwn(inter.x, binder.wall.start.x, binder.wall.end.x, 'round') && qSVG.btwn(inter.y, binder.wall.start.y, binder.wall.end.y, 'round') && qSVG.btwn(inter.x, WALLS[k].start.x, WALLS[k].end.x, 'round') && qSVG.btwn(inter.y, WALLS[k].start.y, WALLS[k].end.y, 'round')) {
- var distance = qSVG.gap(wallToSplit.start, inter);
- if (distance > 5 && distance < wallToSplitLength) newWalls.push({ distance: distance, coords: inter });
- }
- }
- newWalls.sort(function (a, b) {
- return (a.distance - b.distance).toFixed(2);
- });
- var initCoords = wallToSplit.start;
- var initThick = wallToSplit.thick;
- // CLEAR THE WALL BEFORE PIECES RE-BUILDER
- for (var k in WALLS) {
- if (isObjectsEquals(WALLS[k].child, wallToSplit)) WALLS[k].child = null;
- if (isObjectsEquals(WALLS[k].parent, wallToSplit)) { WALLS[k].parent = null; }
- }
- WALLS.splice(WALLS.indexOf(wallToSplit), 1);
- var wall;
- for (var k in newWalls) {
- wall = new editor.wall(initCoords, newWalls[k].coords, "normal", initThick);
- WALLS.push(wall);
- wall.child = WALLS[WALLS.length];
- initCoords = newWalls[k].coords;
- }
- // LAST WALL ->
- wall = new editor.wall(initCoords, wallToSplit.end, "normal", initThick);
- WALLS.push(wall);
- editor.architect(WALLS);
- mode = "select_mode";
- $('#panel').show(200);
- save();
- return true;
- },
- nearWallNode: function (snap, range = Infinity, except = ['']) {
- var best;
- var bestWall;
- var scan;
- var i = 0;
- var scanDistance;
- var bestDistance = Infinity;
- for (var k = 0; k < WALLS.length; k++) {
- if (except.indexOf(WALLS[k]) == -1) {
- scanStart = WALLS[k].start;
- scanEnd = WALLS[k].end;
- scanDistance = qSVG.measure(scanStart, snap);
- if (scanDistance < bestDistance) {
- best = scanStart;
- bestDistance = scanDistance;
- bestWall = k;
- }
- scanDistance = qSVG.measure(scanEnd, snap);
- if (scanDistance < bestDistance) {
- best = scanEnd;
- bestDistance = scanDistance;
- bestWall = k;
- }
- }
- }
- if (bestDistance <= range) {
- return ({
- x: best.x,
- y: best.y,
- bestWall: bestWall
- });
- } else {
- return false;
- }
- },
- // USING WALLS SUPER WALL OBJECTS ARRAY
- rayCastingWall: function (snap) {
- var wallList = [];
- for (var i = 0; i < WALLS.length; i++) {
- // Defensive: skip walls without full coords
- if (!WALLS[i] || !WALLS[i].coords || WALLS[i].coords.length < 4) continue;
- var polygon = [];
- for (var pp = 0; pp < 4; pp++) {
- polygon.push({ x: WALLS[i].coords[pp].x, y: WALLS[i].coords[pp].y }); // FOR Z
- }
- if (qSVG.rayCasting(snap, polygon)) {
- wallList.push(WALLS[i]); // Return EDGES Index
- }
- }
- if (wallList.length == 0) return false;
- else {
- if (wallList.length == 1) return wallList[0];
- else return wallList;
- }
- },
- stickOnWall: function (snap) {
- if (WALLS.length == 0) return false;
- var wallDistance = Infinity;
- var wallSelected = {};
- var result;
- if (WALLS.length == 0) return false;
- for (var e = 0; e < WALLS.length; e++) {
- var eq1 = qSVG.createEquation(WALLS[e].coords[0].x, WALLS[e].coords[0].y, WALLS[e].coords[3].x, WALLS[e].coords[3].y);
- result1 = qSVG.nearPointOnEquation(eq1, snap);
- var eq2 = qSVG.createEquation(WALLS[e].coords[1].x, WALLS[e].coords[1].y, WALLS[e].coords[2].x, WALLS[e].coords[2].y);
- result2 = qSVG.nearPointOnEquation(eq2, snap);
- if (result1.distance < wallDistance && qSVG.btwn(result1.x, WALLS[e].coords[0].x, WALLS[e].coords[3].x) && qSVG.btwn(result1.y, WALLS[e].coords[0].y, WALLS[e].coords[3].y)) {
- wallDistance = result1.distance;
- wallSelected = { wall: WALLS[e], x: result1.x, y: result1.y, distance: result1.distance };
- }
- if (result2.distance < wallDistance && qSVG.btwn(result2.x, WALLS[e].coords[1].x, WALLS[e].coords[2].x) && qSVG.btwn(result2.y, WALLS[e].coords[1].y, WALLS[e].coords[2].y)) {
- wallDistance = result2.distance;
- wallSelected = { wall: WALLS[e], x: result2.x, y: result2.y, distance: result2.distance };
- }
- }
- var vv = editor.nearVertice(snap);
- if (vv.distance < wallDistance) {
- var eq1 = qSVG.createEquation(vv.number.coords[0].x, vv.number.coords[0].y, vv.number.coords[3].x, vv.number.coords[3].y);
- result1 = qSVG.nearPointOnEquation(eq1, vv);
- var eq2 = qSVG.createEquation(vv.number.coords[1].x, vv.number.coords[1].y, vv.number.coords[2].x, vv.number.coords[2].y);
- result2 = qSVG.nearPointOnEquation(eq2, vv);
- if (result1.distance < wallDistance && qSVG.btwn(result1.x, vv.number.coords[0].x, vv.number.coords[3].x) && qSVG.btwn(result1.y, vv.number.coords[0].y, vv.number.coords[3].y)) {
- wallDistance = result1.distance;
- wallSelected = { wall: vv.number, x: result1.x, y: result1.y, distance: result1.distance };
- }
- if (result2.distance < wallDistance && qSVG.btwn(result2.x, vv.number.coords[1].x, vv.number.coords[2].x) && qSVG.btwn(result2.y, vv.number.coords[1].y, vv.number.coords[2].y)) {
- wallDistance = result2.distance;
- wallSelected = { wall: vv.number, x: result2.x, y: result2.y, distance: result2.distance };
- }
- }
- return wallSelected;
- },
- // RETURN OBJDATA INDEX LIST FROM AN WALL
- objFromWall: function (wall, typeObj = false) {
- var objList = [];
- // Defensive: if wall is undefined or malformed, return empty list
- if (!wall || !wall.start || !wall.end) return objList;
- for (var scan = 0; scan < OBJDATA.length; scan++) {
- var search;
- if (OBJDATA[scan].family == 'inWall') {
- var eq = qSVG.createEquation(wall.start.x, wall.start.y, wall.end.x, wall.end.y);
- search = qSVG.nearPointOnEquation(eq, OBJDATA[scan]);
- if (search.distance < 0.01 && qSVG.btwn(OBJDATA[scan].x, wall.start.x, wall.end.x) && qSVG.btwn(OBJDATA[scan].y, wall.start.y, wall.end.y)) objList.push(OBJDATA[scan]);
- // WARNING 0.01 TO NO COUNT OBJECT ON LIMITS OF THE EDGE !!!!!!!!!!!! UGLY CODE( MOUSE PRECISION)
- // TRY WITH ANGLE MAYBE ???
- }
- }
- return objList;
- },
- createEquationFromWall: function (wall) {
- return qSVG.createEquation(wall.start.x, wall.start.y, wall.end.x, wall.end.y);
- },
- // WALLS SUPER ARRAY
- rayCastingWalls: function (snap) {
- var wallList = [];
- for (var i = 0; i < WALLS.length; i++) {
- // Defensive: skip walls without full coords
- if (!WALLS[i] || !WALLS[i].coords || WALLS[i].coords.length < 4) continue;
- var polygon = [];
- for (var pp = 0; pp < 4; pp++) {
- polygon.push({ x: WALLS[i].coords[pp].x, y: WALLS[i].coords[pp].y }); // FOR Z
- }
- if (qSVG.rayCasting(snap, polygon)) {
- wallList.push(WALLS[i]); // Return EDGES Index
- }
- }
- if (wallList.length == 0) return false;
- else {
- if (wallList.length == 1) return wallList[0];
- else return wallList;
- }
- },
- inWallRib2: function (wall, option = false) {
- if (!option) $('#boxRib').empty();
- ribMaster = [];
- var emptyArray = [];
- ribMaster.push(emptyArray);
- ribMaster.push(emptyArray);
- var inter;
- var distance;
- var cross;
- var angleTextValue = wall.angle * (180 / Math.PI);
- var objWall = editor.objFromWall(wall); // LIST OBJ ON EDGE
- ribMaster[0].push({ wall: wall, crossObj: false, side: 'up', coords: wall.coords[0], distance: 0 });
- ribMaster[1].push({ wall: wall, crossObj: false, side: 'down', coords: wall.coords[1], distance: 0 });
- for (var ob in objWall) {
- var objTarget = objWall[ob];
- objTarget.up = [
- qSVG.nearPointOnEquation(wall.equations.up, objTarget.limit[0]),
- qSVG.nearPointOnEquation(wall.equations.up, objTarget.limit[1])
- ];
- objTarget.down = [
- qSVG.nearPointOnEquation(wall.equations.down, objTarget.limit[0]),
- qSVG.nearPointOnEquation(wall.equations.down, objTarget.limit[1])
- ];
- distance = qSVG.measure(wall.coords[0], objTarget.up[0]) / meter;
- ribMaster[0].push({ wall: wall, crossObj: ob, side: 'up', coords: objTarget.up[0], distance: distance.toFixed(2) });
- distance = qSVG.measure(wall.coords[0], objTarget.up[1]) / meter;
- ribMaster[0].push({ wall: wall, crossObj: ob, side: 'up', coords: objTarget.up[1], distance: distance.toFixed(2) });
- distance = qSVG.measure(wall.coords[1], objTarget.down[0]) / meter;
- ribMaster[1].push({ wall: wall, crossObj: ob, side: 'down', coords: objTarget.down[0], distance: distance.toFixed(2) });
- distance = qSVG.measure(wall.coords[1], objTarget.down[1]) / meter;
- ribMaster[1].push({ wall: wall, crossObj: ob, side: 'down', coords: objTarget.down[1], distance: distance.toFixed(2) });
- }
- distance = qSVG.measure(wall.coords[0], wall.coords[3]) / meter;
- ribMaster[0].push({ wall: wall, crossObj: false, side: 'up', coords: wall.coords[3], distance: distance });
- distance = qSVG.measure(wall.coords[1], wall.coords[2]) / meter;
- ribMaster[1].push({ wall: wall, crossObj: false, side: 'down', coords: wall.coords[2], distance: distance });
- ribMaster[0].sort(function (a, b) {
- return (a.distance - b.distance).toFixed(2);
- });
- ribMaster[1].sort(function (a, b) {
- return (a.distance - b.distance).toFixed(2);
- });
- for (var t in ribMaster) {
- for (var n = 1; n < ribMaster[t].length; n++) {
- var found = true;
- var shift = -5;
- var valueText = Math.abs(ribMaster[t][n - 1].distance - ribMaster[t][n].distance);
- var angleText = angleTextValue;
- if (found) {
- if (ribMaster[t][n - 1].side == 'down') { shift = -shift + 10; }
- if (angleText > 89 || angleText < -89) {
- angleText -= 180;
- if (ribMaster[t][n - 1].side == 'down') { shift = -5; }
- else shift = -shift + 10;
- }
- sizeText[n] = document.createElementNS('http://www.w3.org/2000/svg', 'text');
- var startText = qSVG.middle(ribMaster[t][n - 1].coords.x, ribMaster[t][n - 1].coords.y, ribMaster[t][n].coords.x, ribMaster[t][n].coords.y);
-
- // Check for valid coordinates before setting attributes
- if (startText && !isNaN(startText.x) && !isNaN(startText.y)) {
- sizeText[n].setAttributeNS(null, 'x', startText.x);
- sizeText[n].setAttributeNS(null, 'y', (startText.y) + shift);
- sizeText[n].setAttributeNS(null, 'text-anchor', 'middle');
- sizeText[n].setAttributeNS(null, 'font-family', 'roboto');
- sizeText[n].setAttributeNS(null, 'stroke', '#ffffff');
- sizeText[n].textContent = valueText.toFixed(2);
- if (sizeText[n].textContent < 1) {
- sizeText[n].setAttributeNS(null, 'font-size', '0.8em');
- sizeText[n].textContent = sizeText[n].textContent.substring(1, sizeText[n].textContent.length);
- }
- else sizeText[n].setAttributeNS(null, 'font-size', '1em');
- sizeText[n].setAttributeNS(null, 'stroke-width', '0.4px');
- sizeText[n].setAttributeNS(null, 'fill', '#666666');
- sizeText[n].setAttribute("transform", "rotate(" + angleText + " " + startText.x + "," + (startText.y) + ")");
- } else {
- // Skip creating text element if coordinates are invalid
- console.warn('Invalid coordinates for size text element:', startText);
- }
- $('#boxRib').append(sizeText[n]);
- }
- }
- }
- },
- // value can be "text label", "step number in stair", etc...
- obj2D: function (family, classe, type, pos, angle, angleSign, size, hinge = 'normal', thick, value) {
- this.family = family // inWall, stick, collision, free
- this.class = classe; // door, window, energy, stair, measure, text ?
- this.type = type; // simple, double, simpleSlide, aperture, doubleSlide, fixed, switch, lamp....
- this.x = pos.x;
- this.y = pos.y;
- this.angle = angle;
- this.angleSign = angleSign;
- this.limit = [];
- this.hinge = hinge; // normal, reverse
- this.graph = qSVG.create('none', 'g');
- this.scale = { x: 1, y: 1 };
- this.value = value;
- this.size = size;
- this.thick = thick;
- this.width = (this.size / meter).toFixed(2);
- this.height = (this.thick / meter).toFixed(2);
- // Validate size and thick values before calling carpentryCalc
- var validSize = isNaN(size) ? 60 : size;
- var validThick = isNaN(thick) ? 20 : thick;
-
- var cc = carpentryCalc(classe, type, validSize, validThick, value);
- var blank;
- for (var tt = 0; tt < cc.length; tt++) {
- if (cc[tt].path) {
- // Validate path string before creating SVG element
- var pathString = cc[tt].path;
- if (pathString && !pathString.includes('NaN')) {
- blank = qSVG.create('none', 'path', {
- d: pathString,
- "stroke-width": 1,
- fill: cc[tt].fill,
- stroke: cc[tt].stroke,
- 'stroke-dasharray': cc[tt].strokeDashArray,
- opacity: cc[tt].opacity
- });
- } else {
- console.warn('Skipping path creation due to NaN values:', pathString);
- continue;
- }
- }
- if (cc[tt].text) {
- blank = qSVG.create("none", "text", {
- x: cc[tt].x,
- y: cc[tt].y,
- 'font-size': cc[tt].fontSize,
- stroke: cc[tt].stroke,
- "stroke-width": cc[tt].strokeWidth,
- 'font-family': 'roboto',
- 'text-anchor': 'middle',
- fill: cc[tt].fill
- });
- blank[0].textContent = cc[tt].text;
- }
- this.graph.append(blank);
- } // ENDFOR
- var bbox = this.graph.get(0).getBoundingClientRect();
- bbox.x = (bbox.x * factor) - (offset.left * factor) + originX_viewbox;
- bbox.y = (bbox.y * factor) - (offset.top * factor) + originY_viewbox;
- bbox.origin = { x: this.x, y: this.y };
- this.bbox = bbox;
- this.realBbox = [{ x: -this.size / 2, y: -this.thick / 2 }, { x: this.size / 2, y: -this.thick / 2 }, { x: this.size / 2, y: this.thick / 2 }, { x: -this.size / 2, y: this.thick / 2 }];
- if (family == "byObject") this.family = cc.family;
- this.params = cc.params; // (bindBox, move, resize, rotate)
- cc.params.width ? this.size = cc.params.width : this.size = size;
- cc.params.height ? this.thick = cc.params.height : this.thick = thick;
- this.update = function () {
- this.width = (this.size / meter).toFixed(2);
- this.height = (this.thick / meter).toFixed(2);
-
- // Validate size and thick values before calling carpentryCalc
- var validSize = isNaN(this.size) ? 60 : this.size;
- var validThick = isNaN(this.thick) ? 20 : this.thick;
-
- cc = carpentryCalc(this.class, this.type, validSize, validThick, this.value);
- for (var tt = 0; tt < cc.length; tt++) {
- if (cc[tt].path) {
- // Validate path string before setting attribute
- var pathString = cc[tt].path;
- if (pathString && !pathString.includes('NaN')) {
- this.graph.find('path')[tt].setAttribute("d", pathString);
- } else {
- console.warn('Invalid path string with NaN values:', pathString);
- }
- }
- else {
- // this.graph.find('text').context.textContent = cc[tt].text;
- }
- }
- var hingeStatus = this.hinge; // normal - reverse
- var hingeUpdate;
- if (hingeStatus == 'normal') hingeUpdate = 1;
- else hingeUpdate = -1;
- this.graph.attr({ "transform": "translate(" + (this.x) + "," + (this.y) + ") rotate(" + this.angle + ",0,0) scale(" + hingeUpdate + ", 1)" });
- var bbox = this.graph.get(0).getBoundingClientRect();
- bbox.x = (bbox.x * factor) - (offset.left * factor) + originX_viewbox;
- bbox.y = (bbox.y * factor) - (offset.top * factor) + originY_viewbox;
- bbox.origin = { x: this.x, y: this.y };
- this.bbox = bbox;
- if (this.class == "text" && this.angle == 0) {
- this.realBbox = [
- { x: this.bbox.x, y: this.bbox.y }, { x: this.bbox.x + this.bbox.width, y: this.bbox.y }, { x: this.bbox.x + this.bbox.width, y: this.bbox.y + this.bbox.height }, { x: this.bbox.x, y: this.bbox.y + this.bbox.height }];
- this.size = this.bbox.width;
- this.thick = this.bbox.height;
- }
- var angleRadian = -(this.angle) * (Math.PI / 180);
- this.realBbox = [{ x: -this.size / 2, y: -this.thick / 2 }, { x: this.size / 2, y: -this.thick / 2 }, { x: this.size / 2, y: this.thick / 2 }, { x: -this.size / 2, y: this.thick / 2 }];
- var newRealBbox = [{ x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }];
- newRealBbox[0].x = (this.realBbox[0].y * Math.sin(angleRadian) + this.realBbox[0].x * Math.cos(angleRadian)) + this.x;
- newRealBbox[1].x = (this.realBbox[1].y * Math.sin(angleRadian) + this.realBbox[1].x * Math.cos(angleRadian)) + this.x;
- newRealBbox[2].x = (this.realBbox[2].y * Math.sin(angleRadian) + this.realBbox[2].x * Math.cos(angleRadian)) + this.x;
- newRealBbox[3].x = (this.realBbox[3].y * Math.sin(angleRadian) + this.realBbox[3].x * Math.cos(angleRadian)) + this.x;
- newRealBbox[0].y = (this.realBbox[0].y * Math.cos(angleRadian) - this.realBbox[0].x * Math.sin(angleRadian)) + this.y;
- newRealBbox[1].y = (this.realBbox[1].y * Math.cos(angleRadian) - this.realBbox[1].x * Math.sin(angleRadian)) + this.y;
- newRealBbox[2].y = (this.realBbox[2].y * Math.cos(angleRadian) - this.realBbox[2].x * Math.sin(angleRadian)) + this.y;
- newRealBbox[3].y = (this.realBbox[3].y * Math.cos(angleRadian) - this.realBbox[3].x * Math.sin(angleRadian)) + this.y;
- this.realBbox = newRealBbox;
- return true;
- }
- },
- roomMaker: function (Rooms) {
- globalArea = 0;
- var oldVertexNumber = [];
- if (Rooms.polygons.length == 0) ROOM = [];
- for (var pp = 0; pp < Rooms.polygons.length; pp++) {
- var foundRoom = false;
- var roomId;
- for (var rr = 0; rr < ROOM.length; rr++) {
- roomId = rr;
- var countCoords = Rooms.polygons[pp].coords.length;
- var diffCoords = qSVG.diffObjIntoArray(Rooms.polygons[pp].coords, ROOM[rr].coords);
- if (Rooms.polygons[pp].way.length == ROOM[rr].way.length) {
- if (qSVG.diffArray(Rooms.polygons[pp].way, ROOM[rr].way).length == 0 || diffCoords == 0) {
- countCoords = 0;
- }
- }
- if (Rooms.polygons[pp].way.length == ROOM[rr].way.length + 1) {
- if (qSVG.diffArray(Rooms.polygons[pp].way, ROOM[rr].way).length == 1 || diffCoords == 2) {
- countCoords = 0;
- }
- }
- if (Rooms.polygons[pp].way.length == ROOM[rr].way.length - 1) {
- if (qSVG.diffArray(Rooms.polygons[pp].way, ROOM[rr].way).length == 1) {
- countCoords = 0;
- }
- }
- if (countCoords == 0) {
- foundRoom = true;
- ROOM[rr].area = Rooms.polygons[pp].area;
- ROOM[rr].inside = Rooms.polygons[pp].inside;
- ROOM[rr].coords = Rooms.polygons[pp].coords;
- ROOM[rr].coordsOutside = Rooms.polygons[pp].coordsOutside;
- ROOM[rr].way = Rooms.polygons[pp].way;
- ROOM[rr].coordsInside = Rooms.polygons[pp].coordsInside;
- break;
- }
- }
- if (!foundRoom) {
- ROOM.push({ coords: Rooms.polygons[pp].coords, coordsOutside: Rooms.polygons[pp].coordsOutside, coordsInside: Rooms.polygons[pp].coordsInside, inside: Rooms.polygons[pp].inside, way: Rooms.polygons[pp].way, area: Rooms.polygons[pp].area, surface: '', name: '', color: 'gradientWhite', showSurface: true, action: 'add' });
- }
- }
- var toSplice = [];
- for (var rr = 0; rr < ROOM.length; rr++) {
- var found = true;
- for (var pp = 0; pp < Rooms.polygons.length; pp++) {
- var countRoom = ROOM[rr].coords.length;
- var diffCoords = qSVG.diffObjIntoArray(Rooms.polygons[pp].coords, ROOM[rr].coords);
- if (Rooms.polygons[pp].way.length == ROOM[rr].way.length) {
- if (qSVG.diffArray(Rooms.polygons[pp].way, ROOM[rr].way).length == 0 || diffCoords == 0) {
- countRoom = 0;
- }
- }
- if (Rooms.polygons[pp].way.length == ROOM[rr].way.length + 1) {
- if (qSVG.diffArray(Rooms.polygons[pp].way, ROOM[rr].way).length == 1 || diffCoords == 2) {
- countRoom = 0;
- }
- }
- if (Rooms.polygons[pp].way.length == ROOM[rr].way.length - 1) {
- if (qSVG.diffArray(Rooms.polygons[pp].way, ROOM[rr].way).length == 1) {
- countRoom = 0;
- }
- }
- if (countRoom == 0) { found = true; break; }
- else found = false;
- }
- if (!found) toSplice.push(rr);
- }
- toSplice.sort(function (a, b) {
- return b - a;
- });
- for (var ss = 0; ss < toSplice.length; ss++) {
- ROOM.splice(toSplice[ss], 1);
- }
- $('#boxRoom').empty();
- $('#boxSurface').empty();
- $('#boxArea').empty();
- for (var rr = 0; rr < ROOM.length; rr++) {
- if (ROOM[rr].action == 'add') globalArea = globalArea + ROOM[rr].area;
- var pathSurface = ROOM[rr].coords;
- var pathCreate = "M" + pathSurface[0].x + "," + pathSurface[0].y;
- for (var p = 1; p < pathSurface.length; p++) {
- pathCreate = pathCreate + " " + "L" + pathSurface[p].x + "," + pathSurface[p].y;
- }
- if (ROOM[rr].inside.length > 0) {
- for (var ins = 0; ins < ROOM[rr].inside.length; ins++) {
- pathCreate = pathCreate + " M" + Rooms.polygons[ROOM[rr].inside[ins]].coords[Rooms.polygons[ROOM[rr].inside[ins]].coords.length - 1].x + "," + Rooms.polygons[ROOM[rr].inside[ins]].coords[Rooms.polygons[ROOM[rr].inside[ins]].coords.length - 1].y;
- for (var free = Rooms.polygons[ROOM[rr].inside[ins]].coords.length - 2; free > -1; free--) {
- pathCreate = pathCreate + " L" + Rooms.polygons[ROOM[rr].inside[ins]].coords[free].x + "," + Rooms.polygons[ROOM[rr].inside[ins]].coords[free].y;
- }
- }
- }
- qSVG.create('boxRoom', 'path', {
- d: pathCreate,
- fill: 'url(#' + ROOM[rr].color + ')',
- 'fill-opacity': 1, stroke: 'none', 'fill-rule': 'evenodd', class: 'room'
- });
- qSVG.create('boxSurface', 'path', {
- d: pathCreate,
- fill: '#fff', 'fill-opacity': 1, stroke: 'none', 'fill-rule': 'evenodd', class: 'room'
- });
- var centroid = qSVG.polygonVisualCenter(ROOM[rr]);
- if (ROOM[rr].name != '') {
- var styled = { color: '#343938' };
- if (ROOM[rr].color == 'gradientBlack' || ROOM[rr].color == 'gradientBlue') styled.color = 'white';
- qSVG.textOnDiv(ROOM[rr].name, centroid, styled, 'boxArea');
- }
- if (ROOM[rr].name != '') centroid.y = centroid.y + 20;
- var area = ((ROOM[rr].area) / (meter * meter)).toFixed(2) + ' m²';
- var styled = { color: '#343938', fontSize: '18px', fontWeight: 'normal' };
- if (ROOM[rr].surface != '') {
- styled.fontWeight = 'bold';
- area = ROOM[rr].surface + ' m²';
- }
- if (ROOM[rr].color == 'gradientBlack' || ROOM[rr].color == 'gradientBlue') styled.color = 'white';
- if (ROOM[rr].showSurface) qSVG.textOnDiv(area, centroid, styled, 'boxArea');
- }
- if (globalArea <= 0) {
- globalArea = 0;
- $('#areaValue').html('');
- }
- else {
- $('#areaValue').html('<i class="fa fa-map-o" aria-hidden="true"></i> ' + (globalArea / 3600).toFixed(1) + ' m²');
- }
- },
- rayCastingRoom: function (point) {
- var x = point.x, y = point.y;
- var roomGroup = [];
- for (var polygon = 0; polygon < ROOM.length; polygon++) {
- var inside = qSVG.rayCasting(point, ROOM[polygon].coords);
- if (inside) {
- roomGroup.push(polygon);
- }
- }
- if (roomGroup.length > 0) {
- var bestArea = ROOM[roomGroup[0]].area;
- var roomTarget;
- for (var siz = 0; siz < roomGroup.length; siz++) {
- if (ROOM[roomGroup[siz]].area <= bestArea) {
- bestArea = ROOM[roomGroup[siz]].area;
- roomTarget = ROOM[roomGroup[siz]];
- }
- }
- return roomTarget;
- }
- else {
- return false;
- }
- },
- nearVertice: function (snap, range = 10000) {
- var bestDistance = Infinity;
- var bestVertice;
- for (var i = 0; i < WALLS.length; i++) {
- var distance1 = qSVG.gap(snap, { x: WALLS[i].start.x, y: WALLS[i].start.y });
- var distance2 = qSVG.gap(snap, { x: WALLS[i].end.x, y: WALLS[i].end.y });
- if (distance1 < distance2 && distance1 < bestDistance) {
- bestDistance = distance1;
- bestVertice = { number: WALLS[i], x: WALLS[i].start.x, y: WALLS[i].start.y, distance: Math.sqrt(bestDistance) };
- }
- if (distance2 < distance1 && distance2 < bestDistance) {
- bestDistance = distance2;
- bestVertice = { number: WALLS[i], x: WALLS[i].end.x, y: WALLS[i].end.y, distance: Math.sqrt(bestDistance) };
- }
- }
- if (bestDistance < range * range) return bestVertice;
- else return false;
- },
- nearWall: function (snap, range = Infinity) {
- var wallDistance = Infinity;
- var wallSelected = {};
- var result;
- if (WALLS.length == 0) return false;
- for (var e = 0; e < WALLS.length; e++) {
- var eq = qSVG.createEquation(WALLS[e].start.x, WALLS[e].start.y, WALLS[e].end.x, WALLS[e].end.y);
- result = qSVG.nearPointOnEquation(eq, snap);
- if (result.distance < wallDistance && qSVG.btwn(result.x, WALLS[e].start.x, WALLS[e].end.x) && qSVG.btwn(result.y, WALLS[e].start.y, WALLS[e].end.y)) {
- wallDistance = result.distance;
- wallSelected = { wall: WALLS[e], x: result.x, y: result.y, distance: result.distance };
- }
- }
- var vv = editor.nearVertice(snap);
- if (vv.distance < wallDistance) {
- wallDistance = vv.distance;
- wallSelected = { wall: vv.number, x: vv.x, y: vv.y, distance: vv.distance };
- }
- if (wallDistance <= range) return wallSelected;
- else return false;
- },
- showScaleBox: function () {
- if (ROOM.length > 0) {
- var minX, minY, maxX, maxY;
- for (var i = 0; i < WALLS.length; i++) {
- var px = WALLS[i].start.x;
- var py = WALLS[i].start.y;
- if (!i || px < minX) minX = px;
- if (!i || py < minY) minY = py;
- if (!i || px > maxX) maxX = px;
- if (!i || py > maxY) maxY = py;
- var px = WALLS[i].end.x;
- var py = WALLS[i].end.y;
- if (!i || px < minX) minX = px;
- if (!i || py < minY) minY = py;
- if (!i || px > maxX) maxX = px;
- if (!i || py > maxY) maxY = py;
- }
- var width = maxX - minX;
- var height = maxY - minY;
- var labelWidth = ((maxX - minX) / meter).toFixed(2);
- var labelHeight = ((maxY - minY) / meter).toFixed(2);
- var sideRight = 'm' + (maxX + 40) + ',' + minY;
- sideRight = sideRight + ' l60,0 m-40,10 l10,-10 l10,10 m-10,-10';
- sideRight = sideRight + ' l0,' + height;
- sideRight = sideRight + ' m-30,0 l60,0 m-40,-10 l10,10 l10,-10';
- sideRight = sideRight + 'M' + (minX) + ',' + (minY - 40);
- sideRight = sideRight + ' l0,-60 m10,40 l-10,-10 l10,-10 m-10,10';
- sideRight = sideRight + ' l' + width + ',0';
- sideRight = sideRight + ' m0,30 l0,-60 m-10,40 l10,-10 l-10,-10';
- $('#boxScale').empty();
- qSVG.create('boxScale', 'path', {
- d: sideRight,
- stroke: "#555",
- fill: "none",
- "stroke-width": 0.3,
- "stroke-linecap": "butt",
- "stroke-linejoin": "miter",
- "stroke-miterlimit": 4,
- "fill-rule": "nonzero"
- });
- var text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
- text.setAttributeNS(null, 'x', (maxX + 70));
- text.setAttributeNS(null, 'y', ((maxY + minY) / 2) + 35);
- text.setAttributeNS(null, 'fill', '#555');
- text.setAttributeNS(null, 'text-anchor', 'middle');
- text.textContent = labelHeight + ' m';
- text.setAttribute("transform", "rotate(270 " + (maxX + 70) + "," + (maxY + minY) / 2 + ")");
- $('#boxScale').append(text);
- var text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
- text.setAttributeNS(null, 'x', (maxX + minX) / 2);
- text.setAttributeNS(null, 'y', (minY - 95));
- text.setAttributeNS(null, 'fill', '#555');
- text.setAttributeNS(null, 'text-anchor', 'middle');
- text.textContent = labelWidth + ' m';
- $('#boxScale').append(text);
- }
- }
- // END EDITOR
- }
|