refactored getJarvisEnvelopeConvexe getPaddedRoundedSegments & setPaperContour

displaying proximites concernement contours around the entite ref point
This commit is contained in:
Bachir Soussi Chiadmi 2023-10-25 11:56:55 +02:00
parent ecc838abbb
commit 8aa8403f76
4 changed files with 253 additions and 63 deletions

View File

@ -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){

View File

@ -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>

View File

@ -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

View File

@ -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>