Bläddra i källkod

refactored getJarvisEnvelopeConvexe getPaddedRoundedSegments & setPaperContour
displaying proximites concernement contours around the entite ref point

bach 1 år sedan
förälder
incheckning
8aa8403f76

+ 243 - 48
src/components/ConcernementMapItem.vue

@@ -58,6 +58,7 @@ export default {
   computed: {
     ...mapState(ConcernementsStore,['map_mode',
                                     'concernementsByID',
+                                    'allEntitesById',
                                     'allSuperpositions_byid',
                                     'allMapItems_byid',
                                     'opened_concernement',
@@ -96,7 +97,7 @@ export default {
       // 
       this.parseEntityPointsValues()
       // this.getSalientPoints()
-      this.getJarvisEnvelopeConvexe()
+      this.sailentEntites = this.concernement.sailentEntites = this.getJarvisEnvelopeConvexe()
 
       // define init position of the item
       this.pos = this.getRandomPos();
@@ -305,7 +306,7 @@ export default {
       // console.log(`this.salientPoints ${this.concernement.id}`, this.salientPoints);
     },
     getJarvisEnvelopeConvexe(){
-      this.salientPoints = [];
+      let sailentEntites = [];
       let entites = this.concernement.revisions_byid[this.concernement.active_revision].entites;
       // console.log(`getJarvisEnvelopeConvexe ${this.id}`, this.entites.length);
       // https://www.geeksforgeeks.org/convex-hull-using-jarvis-algorithm-or-wrapping/
@@ -327,16 +328,20 @@ export default {
         // console.log(`do while ${this.id}`, p);
         // Add current point to result
         let entite = entites[p];
-        let farest = {
-          alpha: entite.display.alpha,
-          ray: entite.display.ray,
-          pos: {
-            x: (entite.display.ray) * Math.cos(entite.display.alpha * (Math.PI/180)),
-            y: (entite.display.ray) * Math.sin(entite.display.alpha * (Math.PI/180))
-          }
-        };
-        this.salientPoints.push(farest);
-
+        // let farest = {
+        //   alpha: entite.display.alpha,
+        //   ray: entite.display.ray,
+        //   pos: {
+        //     x: (entite.display.ray) * Math.cos(entite.display.alpha * (Math.PI/180)),
+        //     y: (entite.display.ray) * Math.sin(entite.display.alpha * (Math.PI/180))
+        //   }
+        // };
+        // this.salientPoints.push(farest);
+        // sailentEntites.push({
+        //   alpha: entite.display.alpha,
+        //   ray: entite.display.ray
+        // });
+        sailentEntites.push(entite);
 
         // Search for a point 'q' such that 
         // orientation(p, q, x) is clockwise 
@@ -367,6 +372,7 @@ export default {
         p = q;
       } while (p != l);
 
+      return sailentEntites;
     },
     getRandomPos(){
       let pad = 200;
@@ -518,7 +524,7 @@ export default {
         pivot: new paper.Point(this.pos),
         name: `main_${this.id}`,
         cid: this.cid,
-        superposition_id: this.mapitem.superposition_ids[0] // TODO what to do with multiples superpositions ids
+        superposition_id: this.mapitem.superposition_ids[0]
       });
 
       // fadein intro
@@ -533,6 +539,10 @@ export default {
         this.paper_main_object.addChild(this.setPaperEntitesSuperposees());
       }
 
+      if (this.concernement.has_proximites) {
+        this.paper_main_object.addChild(this.setPaperEntitesProximite());
+      }
+
       // if (this.concernement.has_puissancedagir) {
       //   this.addNewPaperSymbolInstance('puissanceagir_icon', false, 0.7);
       // }
@@ -556,6 +566,10 @@ export default {
         case 'superposition':
           this.addNewPaperSymbolInstance('boussole_bg', true);
           break;
+        case 'proximite':
+          this.addNewPaperSymbolInstance('boussole_bg', true);
+          this.paper_main_object.addChild(this.setPaperEntitesProximiteReferences());
+          break;
         case 'puissancedagir':
           this.addNewPaperSymbolInstance('puissanceagir_bg', true);
           this.paper_main_object.addChild(this.setPaperPuissanceagirBesoins());
@@ -616,9 +630,9 @@ export default {
         this.paper_main_object.children[name].bringToFront();
       }
     },
-    setPaperContour(){
+    getPaddedRoundedSegments(points, scale){
       // console.log(`setPaperContour ${this.concernement.id}`);
-      let getPaddedRoundedSegments = (b,a,c,d) => {
+      let getSegmentProps = (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
@@ -633,13 +647,17 @@ export default {
         // console.log(`vma x:${vma.x}, y:${vma.y}`);
         const pad = 4; // exterior padding
         // the final padded point
+        // const pa  = [
+        //   this.pos.x+(a.x+vma.x*pad)*this.scale,
+        //   this.pos.y+(a.y+vma.y*pad)*this.scale
+        // ]
         const pa  = [
-          this.pos.x+(a.x+vma.x*pad)*this.scale,
-          this.pos.y+(a.y+vma.y*pad)*this.scale
+          a.x+vma.x*pad,
+          a.y+vma.y*pad
         ]
-        
+
         // handles
-        const delta = 0.05 * this.scale;
+        const delta = 0.05 * scale;
         // handle IN
         const hli   = Math.abs(lab)*delta;            // handle longeur
         const vnai  = { x: -vma.y, y: vma.x }     // get the ma normal unit vector IN
@@ -649,39 +667,59 @@ 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
 
-        return new paper.Segment({
+        return {
           point: pa,
           handleIn: hai,
           handleOut: hao
-        })
-        
+        }
       }
-      const first_point = getPaddedRoundedSegments(
-        this.salientPoints[this.salientPoints.length-1].pos,
-        this.salientPoints[0].pos,
-        this.salientPoints[1].pos
+      const first_point = getSegmentProps(
+        points[points.length-1],
+        points[0],
+        points[1]
       );
       let segments = [first_point]; 
-      for (let j = 1; j < this.salientPoints.length-1; j++) {
-        // segments.push([this.pos.x+this.salientPoints[j].pos.x*this.scale*gap, this.pos.y+this.salientPoints[j].pos.y*this.scale*gap])
-          segments.push(getPaddedRoundedSegments(
-            this.salientPoints[j-1].pos,
-            this.salientPoints[j].pos,
-            this.salientPoints[j+1].pos
+      for (let j = 1; j < points.length-1; j++) {
+          segments.push(getSegmentProps(
+            points[j-1],
+            points[j],
+            points[j+1]
           ))
       }
-      const last_point = getPaddedRoundedSegments(
-        this.salientPoints[this.salientPoints.length-2].pos,
-        this.salientPoints[this.salientPoints.length-1].pos,
-        this.salientPoints[0].pos
+      const last_point = getSegmentProps(
+        points[points.length-2],
+        points[points.length-1],
+        points[0]
       );
       segments.push(last_point)
       segments.push(first_point)
-      
 
+      return segments;
+    },
+    setPaperContour(){
+      // convert sailent entites to x,y points
+      let points = [];
+      this.sailentEntites.forEach(entite => {
+        points.push({
+          x: (entite.display.ray) * Math.cos(entite.display.alpha * (Math.PI/180)),
+          y: (entite.display.ray) * Math.sin(entite.display.alpha * (Math.PI/180))
+        })
+      })
+      // convert points to rouded and padded segments props
+      let segments = this.getPaddedRoundedSegments(points, this.scale)
+      // create "real" Paper Segments from previous segments props
+      let paper_segments = [];
+      segments.forEach(seg => {
+        paper_segments.push(new paper.Segment({
+          point: [this.pos.x+seg.point[0]*this.scale, this.pos.y+seg.point[1]*this.scale],
+          handleIn: seg.handleIn,
+          handleout: seg.handleOut
+        }))
+      });
+      // create the paper path with previous segments
       const contrs = new paper.Path({
         name: 'contours',
-        segments: segments,
+        segments: paper_segments,
         fillColor: 'rgba(255,255,255,0.4)',
         // selected: true,
         strokeColor: '#fff',
@@ -689,7 +727,7 @@ export default {
         pivot: new paper.Point(this.pos),
         cid: this.cid
       });
-
+      // return the paper path
       return contrs;
     },
     setPaperEntites(){
@@ -759,6 +797,143 @@ export default {
       }
       return g;
     },
+    setPaperEntitesProximite(){
+      let g = new paper.Group({
+        pivot: new paper.Point(this.pos),
+        name: 'entites_proximites'
+      });
+      for (let i = 0; i < this.concernement.revisions_byid[this.concernement.active_revision].entites.length; i++) {
+        let entite = this.concernement.revisions_byid[this.concernement.active_revision].entites[i];
+        if (entite.entite // check if we have an entite object with all the contents
+            && entite.entite.proximite.length ) // check if entite id is in the list builded above
+          {
+          // console.log(`entite ${entite.entite.id}`, entite, entite.entite.superposition);
+          // use paper symbol
+          let instance = new paper.SymbolItem(this.paper_symbol_definitions['entite']);
+          instance.name = 'entite';
+          instance.position = new paper.Point([this.pos.x + entite.display.pos.x * this.scale, this.pos.y + entite.display.pos.y * this.scale]);
+          // instance.scale(this.scale);
+          instance.scale(3);
+          instance.fillColor = '#000';
+          instance.item_id = entite.entite.id;
+          instance.item_type = 'entite_proximite';
+          instance.is_symbol_instance = true;
+          g.addChild(instance)
+        }
+      }
+      return g;
+    },
+    setPaperEntitesProximiteReferences(){
+      let g = new paper.Group({
+        pivot: new paper.Point(this.pos),
+        name: 'entites_proximites_references'
+      });
+      // loop through all concernement's entites
+      // keeping only those who have proximite
+      for (let i = 0; i < this.concernement.revisions_byid[this.concernement.active_revision].entites.length; i++) {
+        let entite = this.concernement.revisions_byid[this.concernement.active_revision].entites[i];
+        if (entite.entite // check if we have an entite object with all the contents
+            && entite.entite.proximite.length ) // check if entite id is in the list builded above
+          {
+          // console.log(`PROXIMITE entite ${entite.entite.id}`, entite, entite.entite.proximite);
+          // create the main entite paper point object
+          let entite_pos = {
+            x: this.pos.x + entite.display.pos.x * this.scale,
+            y: this.pos.y + entite.display.pos.y * this.scale
+          }
+          // use paper symbol
+          let instance = new paper.SymbolItem(this.paper_symbol_definitions['entite']);
+          instance.name = 'entite';
+          instance.position = new paper.Point([entite_pos.x, entite_pos.y]);
+          // instance.scale(this.scale);
+          instance.scale(this.scale);
+          instance.fillColor = '#000';
+          instance.item_id = entite.entite.id;
+          instance.item_type = 'entite_proximite';
+          instance.is_symbol_instance = true;
+          g.addChild(instance)
+
+          // create the proximite reference of the main entite
+          // a paper group wich contains the ref entite point and the ref concernement's contour
+          let ref_g = new paper.Group({
+            pivot: new paper.Point(this.pos),
+            name: 'ref_entite_proximite'
+          });
+
+          let beta = 360 / entite.entite.proximite.length;
+          let ray = 5;
+          let e=0;
+          entite.entite.proximite.forEach(entite_ref => {
+            console.log(`${entite_ref.id}, ${entite_ref.title}`, this.allEntitesById[entite_ref.id]);
+            
+            // create the entite ref paper point
+            let ref_instance = new paper.SymbolItem(this.paper_symbol_definitions['entite']);
+            ref_instance.name = 'entite_ref';
+
+            // x: (entite.display.ray) * Math.cos(entite.display.alpha * (Math.PI/180)),
+            // y: (entite.display.ray) * Math.sin(entite.display.alpha * (Math.PI/180))
+
+            let entite_ref_pos = {
+              x: entite_pos.x + ray * Math.cos((beta*e) * (Math.PI/180)),
+              y: entite_pos.y + ray * Math.sin((beta*e) * (Math.PI/180)),
+            }
+
+            ref_instance.position = new paper.Point(entite_ref_pos);
+            // ref_instance.scale(this.scale);
+            ref_instance.scale(this.scale*0.75);
+            ref_instance.fillColor = '#000';
+            ref_instance.item_id = entite_ref.id;
+            ref_instance.item_type = 'entite_proximite_reference';
+            ref_instance.is_symbol_instance = true;
+            ref_g.addChild(ref_instance)
+
+
+            let ref_cid = this.allEntitesById[entite_ref.id].cid;
+            console.log('PROXIMITE ref concernement jarvis_envelope_convexe', this.concernementsByID[ref_cid].sailentEntites);
+            let ref_concernement = this.concernementsByID[ref_cid];
+            
+            let points = [];
+            ref_concernement.sailentEntites.forEach(ent => {
+              points.push({
+                x: (ent.display.ray) * Math.cos(ent.display.alpha * (Math.PI/180)),
+                y: (ent.display.ray) * Math.sin(ent.display.alpha * (Math.PI/180))
+              })
+            })
+            // define the right scale
+            let scale = 0.05;
+            // convert points to rouded and padded segments props
+            let segments = this.getPaddedRoundedSegments(points, scale)
+            // create "real" Paper Segments from previous segments props
+            let paper_segments = [];
+            segments.forEach(seg => {
+              paper_segments.push(new paper.Segment({
+                point: [entite_ref_pos.x+seg.point[0]*scale, entite_ref_pos.y+seg.point[1]*scale],
+                handleIn: seg.handleIn,
+                handleout: seg.handleOut
+              }))
+            });
+            // create the paper path with previous segments
+            const contrs = new paper.Path({
+              name: 'contours',
+              segments: paper_segments,
+              fillColor: 'rgba(255,255,255,0.4)',
+              // selected: true,
+              strokeColor: '#fff',
+              strokeWidth: 1,
+              pivot: new paper.Point(this.pos),
+              cid: this.cid
+            });
+            ref_g.addChild(contrs);
+
+
+            e++;
+          });
+          g.addChild(ref_g);
+        }
+      }
+      return g;
+      
+    },
     setPaperAgissantes(){
       console.log('setPaperAgissantes');
       let g = new paper.Group({
@@ -1184,10 +1359,16 @@ export default {
       // superposition
       // scale down superposed entites on open
       let entites_superposes = this.paper_main_object.children['entites_superposes'];
-      // console.log('entites_superposes.children', entites_superposes.children);
       if(entites_superposes){
         for(let paper_item of entites_superposes.children) {
-          // paper_item.definition = this.paper_symbol_definitions.entite_hover;
+          paper_item.scale(0.25)
+        }
+      }
+      // proximite
+      // scale down proximite entites on open
+      let entites_proximites = this.paper_main_object.children['entites_proximites'];
+      if(entites_proximites){
+        for(let paper_item of entites_proximites.children) {
           paper_item.scale(0.25)
         }
       }
@@ -1197,10 +1378,16 @@ export default {
       // superposition
       // scale up superposed entites on open
       let entites_superposes = this.paper_main_object.children['entites_superposes'];
-      // console.log('entites_superposes.children', entites_superposes.children);
       if(entites_superposes){
         for(let paper_item of entites_superposes.children) {
-          // paper_item.definition = this.paper_symbol_definitions.entite_hover;
+          paper_item.scale(4)
+        }
+      }
+      // proximites
+      // scale up proximites entites on open
+      let entites_proximites = this.paper_main_object.children['entites_proximites'];
+      if(entites_proximites){
+        for(let paper_item of entites_proximites.children) {
           paper_item.scale(4)
         }
       }
@@ -1242,6 +1429,13 @@ export default {
       }
 
       // proximite
+      if (this.concernement.has_proximites) {
+        if (this.map_mode === "proximite") {
+          this.paper_main_object.children.entites_proximites.visible = true;
+        }else{
+          this.paper_main_object.children.entites_proximites.visible = false;
+        }
+      }
 
       // superposition
       if (this.concernement.has_superpositions) {
@@ -1490,13 +1684,14 @@ export default {
             console.log(`Open me ${this.id}`);
             // push route (keep the hash for map_mode)
             // wait for routing to be finished before opening the mapItem
+            let query = {mapitemid: this.id};
+            if (this.map_mode === "superposition") {
+              query.superposition_id = this.mapitem.superposition_ids[0];
+            }
             await this.$router.push({
               name: 'concernement',
               params: {cid: parseInt(this.cid)},
-              query: {
-                mapitemid: this.id,
-                superposition_id: this.mapitem.superposition_ids[0]
-              },
+              query: query,
               hash: `#${this.map_mode}`
             });
             // open/close all concernements
@@ -1692,7 +1887,7 @@ export default {
           Matter.Events.off(this.matterEngine, "afterUpdate", this.onAfterEngineUpdate);
           Matter.Events.on(this.matterEngine, "afterUpdate", this.onAfterEngineUpdate);
       } else {
-        // closing
+        // CLOSING
         this.is_closing = true;
 
         if(this.constraint){

+ 8 - 14
src/components/MapConcernements.vue

@@ -316,7 +316,7 @@ export default {
 
       // cercles
       for (let i = 1; i < 9; i++) {
-        let sw = i === 4 || i === 8 ? 0.5 : 0.25; // width
+        let sw = i === 4 || i === 8 ? 0.25 : 0.1; // width
         let da = i === 4 || i === 8 ? null : [5,5]; // dash array
         if (!da) { // draw only 2 main non-dashed circles
           children.push(new paper.Path.Circle({
@@ -335,14 +335,14 @@ export default {
         from: [pos.x, pos.y - ray],
         to: [pos.x, pos.y + ray],
         strokeColor: '#fff',
-        strokeWidth: 0.5
+        strokeWidth: 0.25
       }));
       // horizontal
       children.push(new paper.Path.Line({
         from: [pos.x - ray, pos.y],
         to: [pos.x + ray, pos.y],
         strokeColor: '#fff',
-        strokeWidth: 0.5
+        strokeWidth: 0.25
       }))
       
       // fleches
@@ -353,7 +353,7 @@ export default {
           [pos.x, pos.y - ray],
           [pos.x + 8, pos.y - ray + 8],
         ],
-        strokeWidth: 0.5,
+        strokeWidth: 0.25,
         strokeColor: '#fff',
       }));
       // milieu
@@ -363,7 +363,7 @@ export default {
         [pos.x, pos.y],
         [pos.x + 8, pos.y + 8],
         ],
-        strokeWidth: 0.5,
+        strokeWidth: 0.25,
         strokeColor: '#fff',
       }));
 
@@ -1138,14 +1138,8 @@ export default {
           // console.log('concernementB', concernementB);
 
           // console.log('superposition', superposition_id, superposition);
-          let mapitemA_id, mapitemB_id;
-          // if (i === 1) {
-          //   mapitemA_id = superposition[0].cid
-          //   mapitemB_id = superposition[1].cid
-          // } else {
-            mapitemA_id = `${superposition[0].cid}___${superposition_id}` 
-            mapitemB_id = `${superposition[1].cid}___${superposition_id}` 
-          // }  
+          let mapitemA_id = `${superposition[0].cid}___${superposition_id}` 
+          let mapitemB_id = `${superposition[1].cid}___${superposition_id}` 
           
           
           // get the concernement matter bodies with id
@@ -1318,7 +1312,7 @@ export default {
       <li>
         <a 
           title="proximite" href="#proximite" @click="setMapMode('proximite')"
-          :class="{ disabled: opened_concernement && !opened_concernement.has_proximite, active: map_mode === 'proximité'}"
+          :class="{ disabled: opened_concernement && !opened_concernement.has_proximites, active: map_mode === 'proximite'}"
         >
           <span class="icon proximite"/> <span class="label"> proximité</span>
         </a>

+ 1 - 0
src/stores/concernements.js

@@ -84,6 +84,7 @@ export const ConcernementsStore = defineStore({
                   }
                   // record a flat list of all entités of all concernement for map-popup
                   this.allEntitesById[entite.entite.id] = entite;
+                  this.allEntitesById[entite.entite.id].cid = concernement.id;
                   // concernement.entites.push(entite); // fill the entites array with visible entite only
 
                   // PROXIMITES

+ 1 - 1
src/views/Concernement.vue

@@ -169,7 +169,7 @@ export default {
 
 <template>
   <section v-if="opened_concernement" class="concernement">
-    <TerrainDeVie v-if="map_mode === 'terraindevie' || map_mode === 'action'|| map_mode === 'superposition'" :cid="main_cid_eid.cid" :eid="main_cid_eid.eid"/>
+    <TerrainDeVie v-if="map_mode === 'terraindevie' || map_mode === 'action' || map_mode === 'superposition' || map_mode === 'proximite'" :cid="main_cid_eid.cid" :eid="main_cid_eid.eid"/>
     <PuissanceAgir v-if="map_mode === 'puissancedagir'" :cid="cid"/>
     <Doleancer v-if="map_mode === 'doleancer'" :cid="cid"/>
   </section>