diff --git a/padded-salient-points.jpg b/padded-salient-points.jpg new file mode 100644 index 0000000..c208528 Binary files /dev/null and b/padded-salient-points.jpg differ diff --git a/src/components/ConcernementMapItem.vue b/src/components/ConcernementMapItem.vue index f797a24..627bbe1 100644 --- a/src/components/ConcernementMapItem.vue +++ b/src/components/ConcernementMapItem.vue @@ -63,7 +63,8 @@ export default { constraint: null, is_hover: false, // - paper_objects: {} + paper_main_object: {}, + paper_groups: {} } }, props: ['concernement', 'is_opened'], @@ -80,13 +81,6 @@ export default { this.id = this.concernement.id this.entites = this.concernement.entites this.entites_byid = this.concernement.entites_byid - // console.log(`ConcernementsMapItem ${this.concernement.id} $route`, this.id, this.$route); - // if (this.$route.name === 'concernement' - // && parseInt(this.$route.params.id) === this.id - // && typeof this.$route.params.eid !== "undefined") { - // // console.log("we have an entity"); - // this.opened_entite_id = parseInt(this.$route.params.eid); - // } // disable concernement if less than 3 entite if(this.entites.length < 3){ @@ -100,12 +94,6 @@ export default { this.initCanvasMap() } } - - // if (this.salientPoints.length > 3) { // do not build item if it doesn't get enougth salient points - // } else { - // this.hideShowConcernement(this.concernement.id, false); - // } - }, // mounted() { // console.log(`ConcernementsMapItem ${this.concernement.id} mounted`, this.canvasMap.canvas); @@ -240,7 +228,7 @@ export default { getJarvisEnvelopeConvexe(){ // console.log(`getJarvisEnvelopeConvexe ${this.id}`, this.entites.length); // https://www.geeksforgeeks.org/convex-hull-using-jarvis-algorithm-or-wrapping/ - // the most left point + // find the most left point let l, min_x = null; for (let i = 0; i < this.entites.length; i++) { let entite = this.entites[i]; @@ -250,6 +238,9 @@ export default { min_x = x; } } + // Start from leftmost point, keep moving clockwise + // until reach the start point again. This loop runs O(h) + // times where h is number of points in result or output. let p = l, q; do { // console.log(`do while ${this.id}`, p); @@ -267,29 +258,29 @@ export default { // Search for a point 'q' such that - // orientation(p, q, x) is counterclockwise + // orientation(p, q, x) is clockwise // for all points 'x'. The idea is to keep - // track of last visited most counterclock- - // wise point in q. If any point 'i' is more - // counterclock-wise than q, then update q. + // track of last visited most clockwise + // point in q. If any point 'i' is more + // clockwise than q, then update q. q = (p + 1) % this.entites.length; for (let i = 0; i < this.entites.length; i++) { - let p_x = (this.entites[p].display.ray + 3) * Math.cos(this.entites[p].display.alpha * (Math.PI/180)); - let p_y = (this.entites[p].display.ray + 3) * Math.sin(this.entites[p].display.alpha * (Math.PI/180)); - let i_x = (this.entites[i].display.ray + 3) * Math.cos(this.entites[i].display.alpha * (Math.PI/180)); - let i_y = (this.entites[i].display.ray + 3) * Math.sin(this.entites[i].display.alpha * (Math.PI/180)); - let q_x = (this.entites[q].display.ray + 3) * Math.cos(this.entites[q].display.alpha * (Math.PI/180)); - let q_y = (this.entites[q].display.ray + 3) * Math.sin(this.entites[q].display.alpha * (Math.PI/180)); + let p_x = (this.entites[p].display.ray) * Math.cos(this.entites[p].display.alpha * (Math.PI/180)); + let p_y = (this.entites[p].display.ray) * Math.sin(this.entites[p].display.alpha * (Math.PI/180)); + let i_x = (this.entites[i].display.ray) * Math.cos(this.entites[i].display.alpha * (Math.PI/180)); + let i_y = (this.entites[i].display.ray) * Math.sin(this.entites[i].display.alpha * (Math.PI/180)); + let q_x = (this.entites[q].display.ray) * Math.cos(this.entites[q].display.alpha * (Math.PI/180)); + let q_y = (this.entites[q].display.ray) * Math.sin(this.entites[q].display.alpha * (Math.PI/180)); let val = (i_y - p_y) * (q_x - i_x) - (i_x - p_x) * (q_y - i_y); - // If i is more counterclockwise than current q, then update q + // If i is more clockwise than current q, then update q if (val > 0){ q = i; } } - // Now q is the most counterclockwise with + // Now q is the most clockwise with // respect to p. Set p as q for next iteration, // so that q is added to result 'hull' p = q; @@ -364,16 +355,13 @@ export default { Matter.Composite.add(this.matterEngine.world, this.body); // console.log('concernement body', this.body); - // // listen for animate event dispatched from parent - // this.canvas.addEventListener('animate', this.animate) - // listen for afterUpdate event from Matter.Engine object Matter.Events.on(this.matterEngine, "beforeUpdate", this.onBeforeEngineUpdate); Matter.Events.on(this.matterEngine, "afterUpdate", this.onAfterEngineUpdate); } }, setInitBodyVelocity(){ - let delta = 10; + let delta = 50; Matter.Body.setVelocity(this.body, { x: -delta + Math.random()*delta*2, y: -delta + Math.random()*delta*2 @@ -381,28 +369,29 @@ export default { }, // PAPER OBJECTS initPaperObjects(){ - this.paper_objects = new paper.Group({ + this.paper_main_object = new paper.Group({ pivot: new paper.Point(this.pos), cid: this.id }); - this.paper_objects.addChild(this.setPaperBoussoleBG()); - this.paper_objects.addChild(this.setPaperContour()); - this.paper_objects.addChild(this.setPaperEntites()); + this.paper_main_object.addChild(this.setPaperBoussoleBG()); + this.paper_main_object.addChild(this.setPaperContour()); + this.paper_main_object.addChild(this.setPaperEntites()); + // this.paper_groups.entites = this.setPaperEntites() if (this.concernement.has_puissancedagir) { - this.paper_objects.addChild(this.setPaperPuissanceagirBG()); - this.paper_objects.addChild(this.setPaperPuissanceagirICON()); - this.paper_objects.addChild(this.setPaperPuissanceagirBesoins()); + this.paper_main_object.addChild(this.setPaperPuissanceagirBG()); + this.paper_main_object.addChild(this.setPaperPuissanceagirICON()); + this.paper_main_object.addChild(this.setPaperPuissanceagirBesoins()); } if (this.concernement.has_agissantes) { - this.paper_objects.addChild(this.setPaperAgissantes()); + this.paper_main_object.addChild(this.setPaperAgissantes()); } if (this.concernement.has_doleance) { - this.paper_objects.addChild(this.setPaperDoleanceBG()); - this.paper_objects.addChild(this.setPaperDoleanceICON()); - this.paper_objects.addChild(this.setPaperDoleanceSteps()); + this.paper_main_object.addChild(this.setPaperDoleanceBG()); + this.paper_main_object.addChild(this.setPaperDoleanceICON()); + this.paper_main_object.addChild(this.setPaperDoleanceSteps()); } - console.log(`initPaperObjects ${this.id}`, this.paper_objects); + console.log(`initPaperObjects ${this.id}`, this.paper_main_object); this.initPaperEvents() }, @@ -567,7 +556,8 @@ export default { }, setPaperContour(){ - let getPaddedRoundedSegments = (b,a,c) => { + console.log(`setPaperContour ${this.concernement.id}`); + let getPaddedRoundedSegments = (b,a,c,d) => { const ac = { x: c.x - a.x, y: c.y - a.y } // get ac vecteur const lac = Math.sqrt(Math.pow(ac.x, 2) + Math.pow(ac.y, 2)); // get ac longueur ac const ab = { x: b.x - a.x, y: b.y - a.y } // get ab vecteur @@ -578,7 +568,8 @@ export default { const m = { x: (c.x + n.x)/2, y: (c.y + n.y)/2 } // get nc midle point const ma = { x:a.x - m.x, y: a.y - m.y } // get ma vecteur const lma = Math.sqrt(Math.pow(ma.x, 2)+Math.pow(ma.y, 2)) // get longeur m->a - const vma = { x: ma.x/lma, y: ma.y / lma } // get ma vecteur unitaire + const vma = { x: ma.x/lma, y: ma.y/lma } // get ma vecteur unitaire + console.log(`vma x:${vma.x}, y:${vma.y}`); const pad = 4; // exterior padding // the final padded point const pa = [ @@ -597,12 +588,117 @@ export default { const vnao = { x: vma.y, y: -vma.x } // get the ma normal vector Out const hao = [ vnao.x*hlo, vnao.y*hlo ]; // get the handleOut point + // - / - / - / - / - / - / - / - / - / - / - / - / - / - / - / + if (d) { + let debug = new paper.Group({ + pivot: new paper.Point(this.pos), + name: 'debug' + }); + // B + debug.addChild(new paper.PointText({ + point: [this.pos.x + b.x, this.pos.y + b.y], + content: "b", + fontSize: 10, + justification: 'center', + fillColor: 'red' + })) + // A + debug.addChild(new paper.PointText({ + point: [this.pos.x + a.x, this.pos.y + a.y], + content: "a", + fontSize: 10, + justification: 'center', + fillColor: 'red' + })) + // C + debug.addChild(new paper.PointText({ + point: [this.pos.x + c.x, this.pos.y + c.y], + content: "c", + fontSize: 10, + justification: 'center', + fillColor: 'red' + })) + // N + debug.addChild(new paper.PointText({ + point: [this.pos.x + n.x, this.pos.y + n.y], + content: "n", + fontSize: 10, + justification: 'center', + fillColor: 'red' + })) + // M + debug.addChild(new paper.PointText({ + point: [this.pos.x + m.x, this.pos.y + m.y], + content: "m", + fontSize: 10, + justification: 'center', + fillColor: 'red' + })) + // BA + debug.addChild(new paper.Path.Line({ + from: [this.pos.x + b.x, this.pos.y + b.y], + to: [this.pos.x + a.x, this.pos.y + a.y], + strokeWidth: 4, + strokeColor: 'green', + // dashArray: [5,5] + })) + // CA + debug.addChild(new paper.Path.Line({ + from: [this.pos.x + c.x, this.pos.y + c.y], + to: [this.pos.x + a.x, this.pos.y + a.y], + strokeWidth: 4, + strokeColor: 'green', + // dashArray: [5,5] + })) + // NA + debug.addChild(new paper.Path.Line({ + from: [this.pos.x + n.x, this.pos.y + n.y], + to: [this.pos.x + a.x, this.pos.y + a.y], + strokeWidth: 2, + strokeColor: 'blue', + // dashArray: [5,5] + })) + // NC + debug.addChild(new paper.Path.Line({ + from: [this.pos.x + n.x, this.pos.y + n.y], + to: [this.pos.x + c.x, this.pos.y + c.y], + strokeWidth: 2, + strokeColor: 'orange', + // dashArray: [5,5] + })) + // // MA + // debug.addChild(new paper.Path.Line({ + // from: [this.pos.x + m.x, this.pos.y + m.y], + // to: [this.pos.x + a.x, this.pos.y + a.y], + // strokeWidth: 1, + // strokeColor: 'red', + // // dashArray: [5,5] + // })) + // // NC + // debug.addChild(new paper.Path.Line({ + // from: [this.pos.x + n.x, this.pos.y + n.y], + // to: [this.pos.x + c.x, this.pos.y + c.y], + // strokeWidth: 1, + // strokeColor: 'green', + // dashArray: [5,5] + // })) + this.paper_main_object.addChild(debug) + + } + // - / - / - / - / - / - / - / - / - / - / - / - / - / - / - / + // return new paper.Segment({ + // point: [ + // this.pos.x+(a.x)*this.scale, + // this.pos.y+(a.y)*this.scale + // ] + // }) return new paper.Segment({ point: pa, handleIn: hai, handleOut: hao }) + } const first_point = getPaddedRoundedSegments( this.salientPoints[this.salientPoints.length-1].pos, @@ -615,7 +711,7 @@ export default { segments.push(getPaddedRoundedSegments( this.salientPoints[j-1].pos, this.salientPoints[j].pos, - this.salientPoints[j+1].pos, + this.salientPoints[j+1].pos )) } const last_point = getPaddedRoundedSegments( @@ -627,7 +723,6 @@ export default { segments.push(first_point) - const contrs = new paper.Path({ name: 'contours', segments: segments, @@ -639,9 +734,6 @@ export default { cid: this.id }); - // contrs.segments[0].selected = true; - // contrs.segments[1].selected = true; - return contrs; }, setPaperEntites(){ @@ -1497,10 +1589,125 @@ export default { return g; }, + // PAPER VISIBILITY + handlePaperVisibility(){ + // contours focused + if (!this.isFocused()){ + this.paper_main_object.children['contours'].fillColor = "rgba(255,255,255,0.1)"; + }else{ + this.paper_main_object.children['contours'].fillColor = "rgba(255,255,255,0.4)"; + if (this.is_hover) { + this.paper_main_object.children['contours'].strokeColor = "#01ffe2"; + this.paper_main_object.children['contours'].strokeWidth = 2; + }else{ + this.paper_main_object.children['contours'].strokeColor = "#fff"; + this.paper_main_object.children['contours'].strokeWidth = 1; + } + } + + // contours visibility + if (!this.is_opened + || (this.is_opened && this.map_mode !== "puissancedagir" && this.map_mode !== "doleancer")) { + this.paper_main_object.children['contours'].visible = true; + } else { + this.paper_main_object.children['contours'].visible = false; + } + + // backgrounds + if (this.is_opened) { + // hide all bgs + this.paper_main_object.children.boussole_bg.visible = false; + if (this.concernement.has_puissancedagir) { + this.paper_main_object.children.puissanceagir_bg.visible = false; + } + if (this.concernement.has_doleance) { + this.paper_main_object.children.doleance_bg.visible = false; + } + // choose wich one to show, if one + switch (this.map_mode) { + case 'terraindevie': + this.paper_main_object.children.boussole_bg.visible = true; + break; + case 'puissancedagir': + if (this.concernement.has_puissancedagir) { + this.paper_main_object.children.puissanceagir_bg.visible = true; + } + break; + case 'doleancer': + if (this.concernement.has_doleance) { + this.paper_main_object.children.doleance_bg.visible = true; + } + break; + } + }else{ + this.paper_main_object.children.boussole_bg.visible = false; + if (this.concernement.has_puissancedagir) { + this.paper_main_object.children.puissanceagir_bg.visible = false; + } + if (this.concernement.has_doleance) { + this.paper_main_object.children.doleance_bg.visible = false; + } + } + + // entites + if (this.is_opened + && this.map_mode !== 'puissancedagir' + && this.map_mode !== 'doleancer' + && this.map_mode !== 'action' ) { + this.paper_main_object.children.entites.visible = true; + } else { + this.paper_main_object.children.entites.visible = false; + } + + + // puissance d'agir + if (this.concernement.has_puissancedagir) { + if (this.map_mode === "puissancedagir") { + if (!this.is_opened) { + this.paper_main_object.children.puissanceagir_icon.visible = true; // if not opened and has_puissancedagir draw the puissance d'agir icone + this.paper_main_object.children.puissanceagir_besoins.visible = false; + } else { + this.paper_main_object.children.puissanceagir_icon.visible = false; + this.paper_main_object.children.puissanceagir_besoins.visible = true; + // this.drawBesoins(); + } + } else { + this.paper_main_object.children.puissanceagir_icon.visible = false; + this.paper_main_object.children.puissanceagir_besoins.visible = false; + } + } + + // agissantes + // console.log('this.concernement.has_agissantes', this.concernement.has_agissantes); + if (this.concernement.has_agissantes) { + if (this.map_mode === "action") { + this.paper_main_object.children.agissantes.visible = true; + } else { + this.paper_main_object.children.agissantes.visible = false; + } + } + + // doleance + if (this.concernement.has_doleance) { + if (this.map_mode === "doleancer") { + if (!this.is_opened) { + this.paper_main_object.children.doleance_icon.visible = true; + this.paper_main_object.children.doleance_steps.visible = false; + } else { + this.paper_main_object.children.doleance_icon.visible = false; + this.paper_main_object.children.doleance_steps.visible = true; + } + } else { + this.paper_main_object.children.doleance_icon.visible = false; + this.paper_main_object.children.doleance_steps.visible = false; + } + } + + }, // PAPER EVENTS initPaperEvents(){ - this.paper_objects.onMouseEnter = function(event){ + this.paper_main_object.onMouseEnter = function(event){ if (!this.opened_concernement && this.isFocused()) { // only if no concernement is opened and is this focused this.setHoverElmt({ type: 'concernement', @@ -1510,14 +1717,14 @@ export default { } }.bind(this); - this.paper_objects.onMouseLeave = function(event){ + this.paper_main_object.onMouseLeave = function(event){ if (!this.opened_concernement && this.isFocused()) { // only if no concernement is opened this.resetHoverElmt(); document.body.style.cursor = "auto"; } }.bind(this); - this.paper_objects.onMouseMove = function(event){ + this.paper_main_object.onMouseMove = function(event){ // console.log(`onmousemove ${this.id}`); // TODO besoins & actions & doleances if (this.is_opened) { @@ -1539,7 +1746,7 @@ export default { break; } - let result = this.paper_objects.children[paper_group_tohit].hitTest(event.point); + let result = this.paper_main_object.children[paper_group_tohit].hitTest(event.point); // console.log('move result', result); if (result && result.item.item_id) { // console.log('move has result', result); @@ -1567,7 +1774,7 @@ export default { } }.bind(this); - this.paper_objects.onClick = function(event){ + this.paper_main_object.onClick = function(event){ console.log('paper concernement onClick'); if (!this.is_opened) { if (!this.opened_concernement) { @@ -1600,7 +1807,7 @@ export default { break; } if (op.pg) { - let result = this.paper_objects.children[op.pg].hitTest(event.point); + let result = this.paper_main_object.children[op.pg].hitTest(event.point); // console.log('click result', result); if (result) { // we have clicked on an entite @@ -1637,7 +1844,7 @@ export default { } if (open) { // paper bring to front - this.paper_objects.bringToFront(); + this.paper_main_object.bringToFront(); // calcul opened size regarding window size // let ch = this.canvas.height; let s = this.canvas.height / (this.ray*2.8) @@ -1655,10 +1862,10 @@ export default { // https://github.com/liabru/matter-js/issues/986#issuecomment-812488873 // revert to the original size (by reverting the previous scale) Matter.Body.scale(this.body, 1 / this.scale, 1 / this.scale) - this.paper_objects.scale(1 / this.scale); + this.paper_main_object.scale(1 / this.scale); // then scale again to new scale Matter.Body.scale(this.body, obj.s, obj.s) - this.paper_objects.scale(obj.s); + this.paper_main_object.scale(obj.s); // record new scale this.prev_scale = this.scale; @@ -1693,10 +1900,10 @@ export default { // https://github.com/liabru/matter-js/issues/986#issuecomment-812488873 // revert to the original size (by reverting the previous scale) Matter.Body.scale(this.body, 1 / this.scale, 1 / this.scale) - this.paper_objects.scale(1 / this.scale); + this.paper_main_object.scale(1 / this.scale); // then scale again to new scale Matter.Body.scale(this.body, obj.s, obj.s) - this.paper_objects.scale(obj.s); + this.paper_main_object.scale(obj.s); // record new scale this.prev_scale = this.scale; @@ -1729,7 +1936,6 @@ export default { } } - // reset all matter rotation forces otherwise items will spin when colide Matter.Body.setAngle(this.body, 0); Matter.Body.setAngularSpeed(this.body, 0); @@ -1867,126 +2073,11 @@ export default { // this.setInitBodyVelocity(); // } - this.paper_objects.position = this.pos = this.body.position; + this.paper_main_object.position = this.pos = this.body.position; // this.draw() this.handlePaperVisibility() }, - // PAPER VISIBILITY - handlePaperVisibility(){ - // contours focused - if (!this.isFocused()){ - this.paper_objects.children['contours'].fillColor = "rgba(255,255,255,0.1)"; - }else{ - this.paper_objects.children['contours'].fillColor = "rgba(255,255,255,0.4)"; - if (this.is_hover) { - this.paper_objects.children['contours'].strokeColor = "#01ffe2"; - this.paper_objects.children['contours'].strokeWidth = 2; - }else{ - this.paper_objects.children['contours'].strokeColor = "#fff"; - this.paper_objects.children['contours'].strokeWidth = 1; - } - } - - // contours visibility - if (!this.is_opened - || (this.is_opened && this.map_mode !== "puissancedagir" && this.map_mode !== "doleancer")) { - this.paper_objects.children['contours'].visible = true; - } else { - this.paper_objects.children['contours'].visible = false; - } - - // backgrounds - if (this.is_opened) { - // hide all bgs - this.paper_objects.children.boussole_bg.visible = false; - if (this.concernement.has_puissancedagir) { - this.paper_objects.children.puissanceagir_bg.visible = false; - } - if (this.concernement.has_doleance) { - this.paper_objects.children.doleance_bg.visible = false; - } - // choose wich one to show, if one - switch (this.map_mode) { - case 'terraindevie': - this.paper_objects.children.boussole_bg.visible = true; - break; - case 'puissancedagir': - if (this.concernement.has_puissancedagir) { - this.paper_objects.children.puissanceagir_bg.visible = true; - } - break; - case 'doleancer': - if (this.concernement.has_doleance) { - this.paper_objects.children.doleance_bg.visible = true; - } - break; - } - }else{ - this.paper_objects.children.boussole_bg.visible = false; - if (this.concernement.has_puissancedagir) { - this.paper_objects.children.puissanceagir_bg.visible = false; - } - if (this.concernement.has_doleance) { - this.paper_objects.children.doleance_bg.visible = false; - } - } - - // entites - if (this.is_opened - && this.map_mode !== 'puissancedagir' - && this.map_mode !== 'doleancer' - && this.map_mode !== 'action' ) { - this.paper_objects.children.entites.visible = true; - } else { - this.paper_objects.children.entites.visible = false; - } - - - // puissance d'agir - if (this.concernement.has_puissancedagir) { - if (this.map_mode === "puissancedagir") { - if (!this.is_opened) { - this.paper_objects.children.puissanceagir_icon.visible = true; // if not opened and has_puissancedagir draw the puissance d'agir icone - this.paper_objects.children.puissanceagir_besoins.visible = false; - } else { - this.paper_objects.children.puissanceagir_icon.visible = false; - this.paper_objects.children.puissanceagir_besoins.visible = true; - // this.drawBesoins(); - } - } else { - this.paper_objects.children.puissanceagir_icon.visible = false; - this.paper_objects.children.puissanceagir_besoins.visible = false; - } - } - - // agissantes - // console.log('this.concernement.has_agissantes', this.concernement.has_agissantes); - if (this.concernement.has_agissantes) { - if (this.map_mode === "action") { - this.paper_objects.children.agissantes.visible = true; - } else { - this.paper_objects.children.agissantes.visible = false; - } - } - - // doleance - if (this.concernement.has_doleance) { - if (this.map_mode === "doleancer") { - if (!this.is_opened) { - this.paper_objects.children.doleance_icon.visible = true; - this.paper_objects.children.doleance_steps.visible = false; - } else { - this.paper_objects.children.doleance_icon.visible = false; - this.paper_objects.children.doleance_steps.visible = true; - } - } else { - this.paper_objects.children.doleance_icon.visible = false; - this.paper_objects.children.doleance_steps.visible = false; - } - } - - }, isFocused(){ return this.map_mode === 'terraindevie' || (this.map_mode === 'action' && this.concernement.has_agissantes)