| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914 |
- //----------------------- Quick SVG LIBRARY --------------------------------------------------
- //----------------------- V1.0 Licence MIT ---------------------------------------------------
- //----------------------- Author : Patrick RASPINO--------------------------------------------
- //----------------------- 11/08/16 -----------------------------------------------------------
- // 'use strict';
- var qSVG = {
- create: function(id, shape, attrs) {
- var shape = $(document.createElementNS("http://www.w3.org/2000/svg", shape));
- for (var k in attrs) {
- shape.attr(k, attrs[k]);
- }
- if (id != 'none') {
- $("#" + id).append(shape);
- }
- return shape;
- },
- angleDeg: function(cx, cy, ex, ey) {
- var dy = ey - cy;
- var dx = ex - cx;
- var theta = Math.atan2(dy, dx); // range (-PI, PI]
- theta *= 180 / Math.PI; // rads to degs, range (-180, 180]
- if (theta < 0) theta = 360 + theta; // range [0, 360)
- return theta;
- },
- angle: function(x1, y1, x2, y2, x3, y3) {
- var x1 = parseInt(x1);
- var y1 = parseInt(y1);
- var x2 = parseInt(x2);
- var y2 = parseInt(y2);
- var anglerad;
- if (!x3) {
- if (x1 - x2 == 0) anglerad = Math.PI / 2;
- else {
- anglerad = Math.atan((y1 - y2) / (x1 - x2));
- }
- var angledeg = anglerad * 180 / Math.PI;
- } else {
- var x3 = parseInt(x3);
- var y3 = parseInt(y3);
- var a = Math.sqrt(Math.pow(Math.abs(x2 - x1), 2) + Math.pow(Math.abs(y2 - y1), 2));
- var b = Math.sqrt(Math.pow(Math.abs(x2 - x3), 2) + Math.pow(Math.abs(y2 - y3), 2));
- var c = Math.sqrt(Math.pow(Math.abs(x3 - x1), 2) + Math.pow(Math.abs(y3 - y1), 2));
- if (a == 0 || b == 0) anglerad = Math.PI / 2;
- else {
- anglerad = Math.acos((Math.pow(a, 2) + Math.pow(b, 2) - Math.pow(c, 2)) / (2 * a * b));
- }
- angledeg = (360 * anglerad) / (2*Math.PI);
- }
- return ({
- rad: anglerad,
- deg: angledeg
- });
- },
- getAngle: function(el1, el2) {
- return ({
- rad: Math.atan2(el2.y - el1.y, el2.x - el1.x),
- deg: Math.atan2(el2.y - el1.y, el2.x - el1.x)* 180 / Math.PI
- });
- },
- middle: function(xo, yo, xd, yd) {
- var x1 = parseInt(xo);
- var y1 = parseInt(yo);
- var x2 = parseInt(xd);
- var y2 = parseInt(yd);
- var middleX = Math.abs(x1 + x2) / 2;
- var middleY = Math.abs(y1 + y2) / 2;
- return ({
- x: middleX,
- y: middleY
- });
- },
- triangleArea: function(fp, sp, tp) {
- var A = 0;
- var B = 0;
- var C = 0;
- var p = 0;
- A = qSVG.measure(fp, sp);
- B = qSVG.measure(sp, tp);
- C = qSVG.measure(tp, fp);
- p = (A + B + C) / 2;
- return (Math.sqrt(p*(p-A)*(p-B)*(p-C)));
- },
- measure: function(po, pt) {
- return Math.sqrt(Math.pow(po.x - pt.x, 2) + Math.pow(po.y - pt.y, 2));
- },
- gap: function(po, pt) {
- return Math.pow(po.x - pt.x, 2) + Math.pow(po.y - pt.y, 2);
- },
- pDistance(point, pointA, pointB) {
- var x = point.x;
- var y = point.y;
- var x1 = pointA.x;
- var y1 = pointA.y;
- var x2 = pointB.x;
- var y2 = pointB.y;
- var A = x - x1;
- var B = y - y1;
- var C = x2 - x1;
- var D = y2 - y1;
- var dot = A * C + B * D;
- var len_sq = C * C + D * D;
- var param = -1;
- if (len_sq != 0) //in case of 0 length line
- param = dot / len_sq;
- var xx, yy;
- if (param < 0) {
- xx = x1;
- yy = y1;
- }
- else if (param > 1) {
- xx = x2;
- yy = y2;
- }
- else {
- xx = x1 + param * C;
- yy = y1 + param * D;
- }
- var dx = x - xx;
- var dy = y - yy;
- return ({
- x: xx,
- y: yy,
- distance: Math.sqrt(dx * dx + dy * dy)
- });
- },
- nearPointOnEquation: function(equation, point) { // Y = Ax + B ---- equation {A:val, B:val}
- var pointA = {};
- var pointB = {};
- if (equation.A == 'h') {
- return ({
- x: point.x,
- y: equation.B,
- distance: Math.abs(equation.B - point.y)
- });
- }
- else if (equation.A == 'v') {
- return ({
- x: equation.B,
- y: point.y,
- distance: Math.abs(equation.B - point.x)
- });
- }
- else {
- pointA.x = point.x;
- pointA.y = (equation.A * point.x) + equation.B;
- pointB.x = (point.y - equation.B)/equation.A;
- pointB.y = point.y;
- return qSVG.pDistance(point, pointA, pointB);
- }
- },
- circlePath: function(cx, cy, r){
- return 'M '+cx+' '+cy+' m -'+r+', 0 a '+r+','+r+' 0 1,0 '+(r*2)+',0 a '+r+','+r+' 0 1,0 -'+(r*2)+',0';
- },
- createEquation: function(x0, y0, x1, y1) {
- if (x1 - x0 == 0) {
- return ({
- A: 'v',
- B: x0
- });}
- else if (y1 - y0 == 0) {
- return ({
- A: 'h',
- B: y0
- });}
- else {
- return ({
- A: (y1 - y0) / (x1 - x0),
- B: y1 - (x1 * ((y1 - y0) / (x1 - x0)))
- });}
- },
- perpendicularEquation: function(equation, x1, y1) {
- if (typeof(equation.A) != "string") {
- return ({
- A: (-1 / equation.A),
- B: y1 - ((-1 / equation.A) * x1)
- });}
- if (equation.A == 'h') {
- return ({
- A: 'v',
- B: x1
- });}
- if (equation.A == 'v') {
- return ({
- A: 'h',
- B: y1
- });}
- },
- angleBetweenEquations: function(m1, m2) {
- if (m1 == 'h') m1 = 0;
- if (m2 == 'h') m2 = 0;
- if (m1 == 'v') m1 = 10000;
- if (m2 == 'v') m2 = 10000;
- var angleRad = Math.atan(Math.abs((m2 - m1) / (1 + (m1 * m2))));
- return (360 * angleRad) / (2*Math.PI);
- },
- // type array return [x,y] ---- type object return {x:x, y:y}
- intersectionOfEquations: function(equation1, equation2, type = "array", message = false) {
- var retArray;
- var retObj;
- if (equation1.A == equation2.A) {
- retArray = false;
- retObj = false;
- }
- if (equation1.A == 'v' && equation2.A == 'h') {
- retArray = [equation1.B, equation2.B];
- retObj = {x: equation1.B, y: equation2.B};
- }
- if (equation1.A == 'h' && equation2.A == 'v') {
- retArray = [equation2.B, equation1.B];
- retObj = {x: equation2.B, y: equation1.B};
- }
- if (equation1.A == 'h' && equation2.A != 'v' && equation2.A != 'h') {
- retArray = [(equation1.B - equation2.B)/equation2.A, equation1.B];
- retObj = {x: (equation1.B - equation2.B)/equation2.A, y: equation1.B};
- }
- if (equation1.A == 'v' && equation2.A != 'v' && equation2.A != 'h') {
- retArray = [equation1.B, (equation2.A * equation1.B) + equation2.B];
- retObj = {x: equation1.B, y: (equation2.A * equation1.B) + equation2.B};
- }
- if (equation2.A == 'h' && equation1.A != 'v' && equation1.A != 'h') {
- retArray = [(equation2.B - equation1.B)/equation1.A, equation2.B];
- retObj = {x: (equation2.B - equation1.B)/equation1.A, y: equation2.B};
- }
- if (equation2.A == 'v' && equation1.A != 'v' && equation1.A != 'h') {
- retArray = [equation2.B, (equation1.A * equation2.B) + equation1.B];
- retObj = {x: equation2.B, y: (equation1.A * equation2.B) + equation1.B};
- }
- if (equation1.A != 'h' && equation1.A != 'v' && equation2.A != 'v' && equation2.A != 'h') {
- var xT = (equation2.B - equation1.B) / (equation1.A - equation2.A);
- var yT = (equation1.A * xT) + equation1.B;
- retArray = [xT, yT];
- retObj = {x: xT, y: yT};
- }
- if (type == "array") return retArray;
- else return retObj;
- },
- vectorXY: function(obj1, obj2) {
- return ({
- x: obj2.x - obj1.x,
- y: obj2.y - obj1.y
- });
- },
- vectorAngle: function(v1, v2) {
- return (Math.atan2((v2.y-v1.y),(v2.x-v1.x))+Math.PI/2) * (180/Math.PI);
- },
- vectorDeter: function(v1, v2) {
- return (v1.x * v2.y)-(v1.y * v2.x);
- },
- btwn: function(a, b1, b2, round = false) {
- if (round) {
- a = Math.round(a);
- b1 = Math.round(b1);
- b2 = Math.round(b2);
- }
- if ((a >= b1) && (a <= b2)) { return true; }
- if ((a >= b2) && (a <= b1)) { return true; }
- return false;
- },
- nearPointFromPath: function(Pathsvg, point, range = Infinity) {
- var pathLength = Pathsvg.getTotalLength();
- if (pathLength>0) {
- var precision = 40;
- var best;
- var bestLength;
- var bestDistance = Infinity;
- for (var scan, scanLength = 0, scanDistance; scanLength <= pathLength; scanLength += precision) {
- scan = Pathsvg.getPointAtLength(scanLength);
- scanDistance = qSVG.gap(scan, point);
- if (scanDistance < bestDistance) {
- best = scan, bestLength = scanLength, bestDistance = scanDistance;
- }
- }
- // binary search for precise estimate
- precision /= 2;
- while (precision > 1) {
- var before,
- after,
- beforeLength,
- afterLength,
- beforeDistance,
- afterDistance;
- if ((beforeLength = bestLength - precision) >= 0 && (beforeDistance = qSVG.gap(before = Pathsvg.getPointAtLength(beforeLength), point)) < bestDistance) {
- best = before, bestLength = beforeLength, bestDistance = beforeDistance;
- } else if ((afterLength = bestLength + precision) <= pathLength && (afterDistance = qSVG.gap(after = Pathsvg.getPointAtLength(afterLength), point)) < bestDistance) {
- best = after, bestLength = afterLength, bestDistance = afterDistance;
- } else {
- precision /= 2;
- }
- }
- if (bestDistance <= (range*range)) {
- return ({
- x: best.x,
- y: best.y,
- length: bestLength,
- distance: bestDistance,
- seg: Pathsvg.getPathSegAtLength(bestLength)
- });
- } else {
- return false;
- }
- }else {
- return false;
- }
- },
- // ON PATH RETURN FALSE IF 0 NODE ON PATHSVG WITH POINT coords
- // RETURN INDEX ARRAY OF NODEs onPoint
- getNodeFromPath: function(Pathsvg, point, except = ['']) {
- var nodeList = Pathsvg.getPathData();
- var k = 0;
- var nodes = [];
- var countNode = 0;
- for (k = 0; k < nodeList.length; k++) {
- if (nodeList[k].values[0] == point.x && nodeList[k].values[1] == point.y && nodeList[k].type != 'Z') {
- if (except.indexOf(k) == -1) {
- countNode++;
- nodes.push(k);
- }
- }
- }
- if (countNode == 0) return false;
- else return nodes;
- },
- // RETURN ARRAY [{x,y}, {x,y}, ...] OF REAL COORDS POLYGON INTO WALLS, THICKNESS PARAM
- polygonIntoWalls: function(vertex, surface) {
- var vertexArray = surface;
- var wall = [];
- var polygon = [];
- for (var rr = 0; rr < vertexArray.length; rr++) {
- polygon.push({x: vertex[vertexArray[rr]].x, y: vertex[vertexArray[rr]].y});
- }
- // FIND EDGE (WALLS HERE) OF THESE TWO VERTEX
- for (var i = 0 ; i < vertexArray.length-1; i++) {
- for (var segStart = 0; segStart < vertex[vertexArray[i+1]].segment.length; segStart++) {
- for (var segEnd = 0; segEnd < vertex[vertexArray[i]].segment.length; segEnd++) {
- if (vertex[vertexArray[i+1]].segment[segStart] == vertex[vertexArray[i]].segment[segEnd]) {
- wall.push({x1: vertex[vertexArray[i]].x, y1: vertex[vertexArray[i]].y, x2: vertex[vertexArray[i+1]].x, y2: vertex[vertexArray[i+1]].y, segment: vertex[vertexArray[i+1]].segment[segStart]});
- }
- }
- }
- }
- // CALC INTERSECS OF EQ PATHS OF THESE TWO WALLS.
- var inside = [];
- var outside = [];
- for (var i = 0; i < wall.length; i++) {
- var inter = [];
- var edge = wall[i];
- if (i < wall.length - 1) var nextEdge = wall[i+1];
- else var nextEdge = wall[0];
- var angleEdge = Math.atan2(edge.y2 - edge.y1, edge.x2 - edge.x1);
- var angleNextEdge = Math.atan2(nextEdge.y2 - nextEdge.y1, nextEdge.x2 - nextEdge.x1);
- var edgeThicknessX = (WALLS[edge.segment].thick/2) * Math.sin(angleEdge);
- var edgeThicknessY = (WALLS[edge.segment].thick/2) * Math.cos(angleEdge);
- var nextEdgeThicknessX = (WALLS[nextEdge.segment].thick/2) * Math.sin(angleNextEdge);
- var nextEdgeThicknessY = (WALLS[nextEdge.segment].thick/2) * Math.cos(angleNextEdge);
- var eqEdgeUp = qSVG.createEquation(edge.x1 + edgeThicknessX, edge.y1 - edgeThicknessY, edge.x2 + edgeThicknessX, edge.y2 - edgeThicknessY);
- var eqEdgeDw = qSVG.createEquation(edge.x1 - edgeThicknessX, edge.y1 + edgeThicknessY, edge.x2 - edgeThicknessX, edge.y2 + edgeThicknessY);
- var eqNextEdgeUp = qSVG.createEquation(nextEdge.x1 + nextEdgeThicknessX, nextEdge.y1 - nextEdgeThicknessY, nextEdge.x2 + nextEdgeThicknessX, nextEdge.y2 - nextEdgeThicknessY);
- var eqNextEdgeDw = qSVG.createEquation(nextEdge.x1 - nextEdgeThicknessX, nextEdge.y1 + nextEdgeThicknessY, nextEdge.x2 - nextEdgeThicknessX, nextEdge.y2 + nextEdgeThicknessY);
- angleEdge = angleEdge * (180 / Math.PI);
- angleNextEdge = angleNextEdge * (180 / Math.PI);
- if (eqEdgeUp.A != eqNextEdgeUp.A) {
- inter.push(qSVG.intersectionOfEquations(eqEdgeUp, eqNextEdgeUp, "object"));
- inter.push(qSVG.intersectionOfEquations(eqEdgeDw, eqNextEdgeDw, "object"));
- }
- else {
- inter.push({x: edge.x2 + edgeThicknessX, y: edge.y2 - edgeThicknessY});
- inter.push({x: edge.x2 - edgeThicknessX, y: edge.y2 + edgeThicknessY});
- }
- for (var ii = 0;ii < inter.length; ii++) {
- if (qSVG.rayCasting(inter[ii], polygon)) inside.push(inter[ii]);
- else outside.push(inter[ii]);
- }
- }
- inside.push(inside[0]);
- outside.push(outside[0]);
- return {inside: inside, outside: outside};
- },
- area: function(coordss) {
- if (coordss.length < 2) return false;
- var realArea = 0;
- var j = (coordss.length)-1;
- for (var i = 0; i < coordss.length; i++) {
- realArea = realArea + ((coordss[j].x + coordss[i].x) * (coordss[j].y - coordss[i].y));
- j = i;
- }
- realArea = realArea / 2;
- return Math.abs(realArea.toFixed(2));
- },
- areaRoom: function (vertex, coords, digit = 2) {
- var vertexArray = coords;
- var roughArea = 0;
- var j = (vertexArray.length)-2;
- for (var i = 0; i < vertexArray.length-1; i++) {
- roughArea = roughArea + ((vertex[vertexArray[j]].x + vertex[vertexArray[i]].x) * (vertex[vertexArray[j]].y - vertex[vertexArray[i]].y));
- j = i;
- }
- roughArea = roughArea / 2;
- return Math.abs(roughArea.toFixed(digit));
- },
- perimeterRoom: function (coords, digit = 2) {
- var vertexArray = coords;
- var roughRoom = 0;
- for (i = 0; i < vertexArray.length-1; i++) {
- added = qSVG.measure(vertex[vertexArray[i]], vertex[vertexArray[i+1]]);
- roughRoom = roughRoom + added;
- }
- return roughRoom.toFixed(digit);
- },
- // H && V PROBLEM WHEN TWO SEGMENT ARE v/-> == I/->
- junctionList: function(WALLS) {
- var junction = [];
- var segmentJunction = [];
- var junctionChild = [];
- // JUNCTION ARRAY LIST ALL SEGMENT INTERSECTIONS
- for (var i = 0; i < WALLS.length; i++) {
- var equation1 = qSVG.createEquation(WALLS[i].start.x, WALLS[i].start.y, WALLS[i].end.x, WALLS[i].end.y);
- for (var v = 0; v < WALLS.length; v++) {
- if (v != i) {
- var equation2 = qSVG.createEquation(WALLS[v].start.x, WALLS[v].start.y, WALLS[v].end.x, WALLS[v].end.y);
- var intersec;
- if (intersec = qSVG.intersectionOfEquations(equation1, equation2)) {
- if (WALLS[i].end.x == WALLS[v].start.x && WALLS[i].end.y == WALLS[v].start.y || WALLS[i].start.x == WALLS[v].end.x && WALLS[i].start.y == WALLS[v].end.y) {
- if (WALLS[i].end.x == WALLS[v].start.x && WALLS[i].end.y == WALLS[v].start.y) {
- junction.push({segment:i, child: v, values: [WALLS[v].start.x, WALLS[v].start.y], type: "natural"});
- }
- if (WALLS[i].start.x == WALLS[v].end.x && WALLS[i].start.y == WALLS[v].end.y) {
- junction.push({segment:i, child: v, values: [WALLS[i].start.x, WALLS[i].start.y], type: "natural"});
- }
- }
- else {
- if (qSVG.btwn(intersec[0], WALLS[i].start.x, WALLS[i].end.x, 'round') && qSVG.btwn(intersec[1], WALLS[i].start.y, WALLS[i].end.y, 'round') && qSVG.btwn(intersec[0], WALLS[v].start.x, WALLS[v].end.x, 'round') && qSVG.btwn(intersec[1], WALLS[v].start.y, WALLS[v].end.y, 'round')) {
- intersec[0] = intersec[0];
- intersec[1] = intersec[1];
- junction.push({segment:i, child: v, values: [intersec[0], intersec[1]], type: "intersection"});
- }
- }
- }
- // IF EQ1 == EQ 2 FIND IF START OF SECOND SEG == END OF FIRST seg (eq.A maybe values H ou V)
- if ((Math.abs(equation1.A) == Math.abs(equation2.A) || equation1.A == equation2.A) && equation1.B == equation2.B) {
- if (WALLS[i].end.x == WALLS[v].start.x && WALLS[i].end.y == WALLS[v].start.y) {
- junction.push({segment:i, child: v, values: [WALLS[v].start.x, WALLS[v].start.y], type: "natural"});
- }
- if (WALLS[i].start.x == WALLS[v].end.x && WALLS[i].start.y == WALLS[v].end.y) {
- junction.push({segment:i, child: v, values: [WALLS[i].start.x, WALLS[i].start.y], type: "natural"});
- }
- }
- }
- }
- }
- return junction;
- },
- vertexList: function(junction, segment) {
- var vertex = [];
- var vertextest = [];
- for (var jj = 0; jj < junction.length; jj++) {
- var found = true;
- for (var vv = 0; vv < vertex.length; vv++) {
- if ((Math.round(junction[jj].values[0]) == Math.round(vertex[vv].x)) && (Math.round(junction[jj].values[1]) == Math.round(vertex[vv].y))) {
- found = false;
- vertex[vv].segment.push(junction[jj].segment);
- break;
- }
- else {
- found = true;
- }
- }
- if (found) {
- vertex.push({x: Math.round(junction[jj].values[0]), y: Math.round(junction[jj].values[1]), segment: [junction[jj].segment], bypass:0, type: junction[jj].type});
- }
- }
- var toClean = [];
- for (var ss = 0; ss < vertex.length; ss++) {
- vertex[ss].child = [];
- vertex[ss].removed = [];
- for (var sg = 0; sg < vertex[ss].segment.length; sg++) {
- for (var sc = 0; sc < vertex.length; sc++) {
- if (sc != ss) {
- for (var scg = 0; scg < vertex[sc].segment.length; scg++) {
- if (vertex[sc].segment[scg] == vertex[ss].segment[sg]) {
- vertex[ss].child.push({id: sc, angle: Math.floor(qSVG.getAngle(vertex[ss], vertex[sc]).deg)});
- }
- }
- }
- }
- }
- toClean = [];
- for (var fr = 0; fr < vertex[ss].child.length-1; fr++) {
- for (var ft = fr+1; ft < vertex[ss].child.length; ft++) {
- if (fr != ft && typeof(vertex[ss].child[fr])!='undefined') {
- found = true;
- if (qSVG.btwn(vertex[ss].child[ft].angle, vertex[ss].child[fr].angle+3, vertex[ss].child[fr].angle-3, 'round') && found)
- {
- var dOne = qSVG.gap(vertex[ss], vertex[vertex[ss].child[ft].id]);
- var dTwo = qSVG.gap(vertex[ss], vertex[vertex[ss].child[fr].id]);
- if (dOne > dTwo) {
- toClean.push(ft);
- }
- else {
- toClean.push(fr);
- }
- }
- }
- }
- }
- toClean.sort(function(a, b) {
- return b-a;
- });
- toClean.push(-1);
- for (var cc = 0; cc < toClean.length-1; cc++) {
- if (toClean[cc] > toClean[(cc+1)]) {
- vertex[ss].removed.push(vertex[ss].child[toClean[cc]].id);
- vertex[ss].child.splice(toClean[cc], 1);
- }
- }
- }
- vertexTest = vertex;
- return vertex;
- },
- //*******************************************************
- //* @arr1, arr2 = Array to compare *
- //* @app = add function pop() or shift() to @arr1, arr2 *
- //* False if arr1.length != arr2.length *
- //* False if value into arr1[] != arr2[] - no order *
- //* *****************************************************
- arrayCompare: function(arr1, arr2, app) {
- // if (arr1.length != arr2.length) return false;
- var minus = 0;
- var start = 0;
- if (app == 'pop') {
- minus = 1;
- }
- if (app == 'shift') {
- start = 1;
- }
- var coordCounter = arr1.length - minus - start;
- for (var iFirst = start; iFirst < arr1.length-minus; iFirst++) {
- for (var iSecond = start; iSecond < arr2.length-minus; iSecond++) {
- if (arr1[iFirst] == arr2[iSecond]) {
- coordCounter--;
- }
- }
- }
- if (coordCounter == 0) return true;
- else return false;
- },
- vectorVertex: function(vex1, vex2, vex3) {
- var vCurr = qSVG.vectorXY(vex1, vex2);
- var vNext = qSVG.vectorXY(vex2, vex3);
- var Na = Math.sqrt((vCurr.x * vCurr.x) + (vCurr.y * vCurr.y));
- var Nb = Math.sqrt((vNext.x * vNext.x) + (vNext.y * vNext.y));
- var C = ((vCurr.x * vNext.x) + (vCurr.y * vNext.y)) / (Na * Nb);
- var S = ((vCurr.x * vNext.y) - (vCurr.y * vNext.x));
- var BAC = Math.sign(S) * Math.acos(C);
- return BAC*(180 / Math.PI );
- },
- segmentTree: function(VERTEX_NUMBER, vertex) {
- var TREELIST = [VERTEX_NUMBER];
- WAY = [];
- var COUNT = vertex.length;
- var ORIGIN = VERTEX_NUMBER;
- tree(TREELIST, ORIGIN, COUNT);
- return WAY;
- function tree(TREELIST, ORIGIN, COUNT) {
- if (TREELIST.length == 0) return;
- var TREETEMP = [];
- COUNT--;
- for (var k = 0;k < TREELIST.length; k++) {
- var found = true;
- var WRO = TREELIST[k];
- var WRO_ARRAY = WRO.toString().split('-');
- var WR = WRO_ARRAY[WRO_ARRAY.length - 1];
- for (var v = 0; v < vertex[WR].child.length; v++) {
- if (vertex[WR].child[v].id == ORIGIN && COUNT < (vertex.length - 1) && WRO_ARRAY.length > 2) { // WAYS HYPER
- WAY.push(WRO+"-"+ORIGIN); // WAYS
- found = false;
- break;
- }
- }
- if (found) {
- var bestToAdd;
- var bestDet = 0;
- var nextVertex = -1;
- // var nextVertexValue = 360;
- var nextDeterValue = Infinity;
- var nextDeterVal = 0;
- var nextFlag = 0;
- if (vertex[WR].child.length == 1) {
- if (WR == ORIGIN && COUNT == (vertex.length - 1)) {
- TREETEMP.push(WRO+'-'+vertex[WR].child[0].id);
- }
- if (WR != ORIGIN && COUNT < (vertex.length - 1)) {
- TREETEMP.push(WRO+'-'+vertex[WR].child[0].id);
- }
- }
- else {
- for (var v = 0; v < vertex[WR].child.length && vertex[WR].child.length > 0; v++) {
- if (WR == ORIGIN && COUNT == (vertex.length - 1)) { // TO INIT FUNCTION -> // CLOCKWISE Research
- var vDet = qSVG.vectorVertex({x: 0, y: -1}, vertex[WR], vertex[vertex[WR].child[v].id]);
- if (vDet >= nextDeterVal ) {
- nextFlag = 1;
- nextDeterVal = vDet;
- nextVertex = vertex[WR].child[v].id;
- }
- if (Math.sign(vDet) == -1 && nextFlag == 0) {
- if (vDet < nextDeterValue && Math.sign(nextDeterValue) > -1) {
- nextDeterValue = vDet;
- nextVertex = vertex[WR].child[v].id;
- }
- if (vDet > nextDeterValue && Math.sign(nextDeterValue) == -1) {
- nextDeterValue = vDet;
- nextVertex = vertex[WR].child[v].id;
- }
- }
- }
- if (WR != ORIGIN && WRO_ARRAY[WRO_ARRAY.length-2] != vertex[WR].child[v].id && COUNT < (vertex.length - 1)) { // COUNTERCLOCKWISE Research
- var vDet = qSVG.vectorVertex(vertex[WRO_ARRAY[WRO_ARRAY.length-2]], vertex[WR], vertex[vertex[WR].child[v].id]);
- if (vDet < nextDeterValue && nextFlag == 0) {
- nextDeterValue = vDet;
- nextVertex = vertex[WR].child[v].id;
- }
- if (Math.sign(vDet) == -1) {
- nextFlag = 1;
- if (vDet <= nextDeterValue) {
- nextDeterValue = vDet;
- nextVertex = vertex[WR].child[v].id;
- }
- }
- }
- }
- if (nextVertex != -1) TREETEMP.push(WRO+'-'+nextVertex);
- }
- }
- }
- if (COUNT > 0) tree(TREETEMP, ORIGIN, COUNT);
- }
- },
- polygonize: function(segment) {
- junction = qSVG.junctionList(segment);
- vertex = qSVG.vertexList(junction, segment);
- var vertexCopy = qSVG.vertexList(junction, segment);
- var edgesChild = [];
- for (var j = 0; j < vertex.length; j++) {
- for (var vv = 0; vv < vertex[j].child.length; vv++) {
- edgesChild.push([j, vertex[j].child[vv].id]);
- }
- }
- var polygons = [];
- var WAYS;
- for (var jc = 0; jc < edgesChild.length; jc++) {
- var bestVertex = 0;
- var bestVertexValue = Infinity;
- for (var j = 0; j < vertex.length; j++) {
- if (vertex[j].x < bestVertexValue && vertex[j].child.length > 1 && vertex[j].bypass == 0) {
- bestVertexValue = vertex[j].x;
- bestVertex = j;
- }
- if (vertex[j].x == bestVertexValue && vertex[j].child.length > 1 && vertex[j].bypass == 0) {
- if (vertex[j].y > vertex[bestVertex].y) {
- bestVertexValue = vertex[j].x;
- bestVertex = j;
- }
- }
- }
- // console.log("%c%s", "background: yellow; font-size: 14px;","RESEARCH WAY FOR STARTING VERTEX "+bestVertex);
- WAYS = qSVG.segmentTree(bestVertex, vertex);
- if (WAYS.length == 0) {
- vertex[bestVertex].bypass = 1;
- }
- if (WAYS.length > 0) {
- var tempSurface = WAYS[0].split('-');
- var lengthRoom = qSVG.areaRoom(vertex, tempSurface);
- var bestArea = parseInt(lengthRoom);
- var found = true;
- for (var sss = 0; sss < polygons.length; sss++) {
- if (qSVG.arrayCompare(polygons[sss].way, tempSurface, 'pop') ) {
- found = false;
- vertex[bestVertex].bypass = 1;
- break;
- }
- }
- if (bestArea < 360) {
- vertex[bestVertex].bypass = 1;
- }
- if (vertex[bestVertex].bypass == 0) { // <-------- TO REVISE IMPORTANT !!!!!!!! bestArea Control ???
- var realCoords = qSVG.polygonIntoWalls(vertex, tempSurface);
- var realArea = qSVG.area(realCoords.inside);
- var outsideArea = qSVG.area(realCoords.outside);
- var coords = [];
- for (var rr = 0; rr < tempSurface.length; rr++) {
- coords.push({x: vertex[tempSurface[rr]].x, y: vertex[tempSurface[rr]].y});
- }
- // WARNING -> FAKE
- if (realCoords.inside.length != realCoords.outside) {
- polygons.push({way: tempSurface, coords: coords, coordsOutside: realCoords.outside, coordsInside: realCoords.inside, area: realArea, outsideArea: outsideArea, realArea: bestArea});
- }
- else { // REAL INSIDE POLYGONE -> ROOM
- polygons.push({way: tempSurface, coords: realCoords.inside, coordsOutside: realCoords.outside, area: realArea, outsideArea: outsideArea, realArea: bestArea});
- }
- // REMOVE FIRST POINT OF WAY ON CHILDS FIRST VERTEX
- for (var aa = 0; aa < vertex[bestVertex].child.length; aa++) {
- if (vertex[bestVertex].child[aa].id == tempSurface[1]) {
- vertex[bestVertex].child.splice(aa, 1);
- }
- }
- // REMOVE FIRST VERTEX OF WAY ON CHILDS SECOND VERTEX
- for (var aa = 0; aa < vertex[tempSurface[1]].child.length; aa++) {
- if (vertex[tempSurface[1]].child[aa].id == bestVertex) {
- vertex[tempSurface[1]].child.splice(aa, 1);
- }
- }
- //REMOVE FILAMENTS ?????
- do {
- var looping = 0;
- for (var aa = 0; aa < vertex.length; aa++) {
- if (vertex[aa].child.length == 1) {
- looping = 1;
- vertex[aa].child = [];
- for (var ab = 0; ab < vertex.length; ab++) { // OR MAKE ONLY ON THE WAY tempSurface ?? BETTER ??
- for (var ac = 0; ac < vertex[ab].child.length; ac++) {
- if (vertex[ab].child[ac].id == aa) {
- vertex[ab].child.splice(ac, 1);
- }
- }
- }
- }
- }
- }
- while (looping == 1);
- }
- }
- }
- //SUB AREA(s) ON POLYGON CONTAINS OTHERS FREE POLYGONS (polygon without commonSideEdge)
- for (var pp = 0; pp < polygons.length; pp++) {
- var inside = [];
- for (var free = 0; free < polygons.length; free++) {
- if (pp != free) {
- var polygonFree = polygons[free].coords;
- var countCoords = polygonFree.length;
- var found = true;
- for (pf = 0; pf < countCoords; pf++) {
- found = qSVG.rayCasting(polygonFree[pf], polygons[pp].coords);
- if (!found) {
- break;
- }
- }
- if (found) {
- inside.push(free);
- polygons[pp].area = polygons[pp].area - polygons[free].outsideArea;
- }
- }
- }
- polygons[pp].inside = inside;
- }
- return {polygons : polygons, vertex : vertex};
- },
- diffArray : function(arr1, arr2) {
- return arr1.concat(arr2).filter(function (val) {
- if (!(arr1.includes(val) && arr2.includes(val)))
- return val;
- });
- },
- diffObjIntoArray : function(arr1, arr2) {
- var count = 0;
- for (var k =0; k <arr1.length-1;k++) {
- for (var n=0; n<arr2.length-1;n++) {
- if (isObjectsEquals(arr1[k], arr2[n])) {
- count++;
- }
- }
- }
- var waiting = arr1.length-1;
- if (waiting < arr2.length-1) waiting = arr2.length;
- return waiting-count;
- },
- rayCasting: function(point, polygon) {
- var x = point.x, y = point.y;
- var inside = false;
- for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
- var xi = polygon[i].x, yi = polygon[i].y;
- var xj = polygon[j].x, yj = polygon[j].y;
- var intersect = ((yi > y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
- if (intersect) inside = !inside;
- }
- return inside;
- },
- //polygon = [{x1,y1}, {x2,y2}, ...]
- polygonVisualCenter: function(room) {
- var polygon = room.coords;
- var insideArray = room.inside;
- var sample = 80;
- var grid = [];
- //BOUNDING BOX OF POLYGON
- var minX, minY, maxX, maxY;
- for (var i = 0; i < polygon.length; i++) {
- var p = polygon[i];
- if (!i || p.x < minX) minX = p.x;
- if (!i || p.y < minY) minY = p.y;
- if (!i || p.x > maxX) maxX = p.x;
- if (!i || p.y > maxY) maxY = p.y;
- }
- var width = maxX - minX;
- var height = maxY - minY;
- //INIT GRID
- var sampleWidth = Math.floor(width / sample);
- var sampleHeight = Math.floor(height / sample);
- for (var hh = 0; hh < sample; hh++) {
- for (var ww = 0; ww < sample; ww++) {
- var posX = minX + (ww * sampleWidth);
- var posY = minY + (hh * sampleHeight);
- if (qSVG.rayCasting({x: posX, y: posY}, polygon)) {
- var found = true;
- for (var ii = 0; ii < insideArray.length; ii++) {
- if (qSVG.rayCasting({x: posX, y: posY}, ROOM[insideArray[ii]].coordsOutside)) {
- found = false;
- break;
- }
- }
- if (found) {
- grid.push({x: posX, y: posY});
- }
- }
- }
- }
- var bestRange = 0;
- var bestMatrix;
- for (var matrix = 0; matrix < grid.length; matrix++) {
- var minDistance = Infinity;
- for (var pp = 0; pp < polygon.length-1; pp++) {
- var scanDistance = qSVG.pDistance(grid[matrix], polygon[pp], polygon[pp+1]);
- if (scanDistance.distance < minDistance) {
- minDistance = scanDistance.distance;
- }
- }
- if (minDistance > bestRange) {
- bestMatrix = matrix;
- bestRange = minDistance;
- }
- }
- return grid[bestMatrix];
- },
- textOnDiv: function(label, pos, styled, div) {
- if (typeof(pos) != 'undefined') {
- var text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
- text.setAttributeNS(null, 'x', pos.x);
- text.setAttributeNS(null, 'y', pos.y);
- text.setAttribute("style","fill:"+styled.color+";font-weight:"+styled.fontWeight+";font-size:"+styled.fontSize);
- text.setAttributeNS(null, 'text-anchor', 'middle');
- text.textContent = label;
- document.getElementById(div).appendChild(text);
- }
- }
- };
- //----------------------- END Quick SVG LIBRARY --------------------------------------------------s
|