import $ from 'jquery'
import { j3pBoule, j3pDetruit, j3pElement } from 'src/legacy/core/functions'
import { j3pInverseMatrice, j3pProduitMatVec, j3pRotation, j3pVectoriel } from 'src/legacy/outils/3D/3D'
import { j3pCreeSegment, j3pCreeSVG, j3pCreeTexte, j3pPolygone } from 'src/legacy/core/functionsSvg'
/**
* objet utilisé nulle part, ne fonctionne peut-être pas
* @param idconteneur
* @param objet
* @constructor
*/
function Solide (idconteneur, objet) {
this.idconteneur = idconteneur
// j3pElement(idconteneur).ref= ref
this.sommets = objet.sommets
this.faces = objet.faces
this.repere = objet.repere
// si nomsommets undefined les sommets sont nommés automatiquement "somk" (mais étiquettes non affichées)
if (typeof (objet.nomsommets) === 'undefined') {
this.nomsommets = ['']
for (let k = 1; k < this.sommets.length; k++) {
this.nomsommets.push('som' + k)
}
} else {
this.nomsommets = objet.nomsommets
}
if (typeof (objet.mef) === 'undefined') {
this.mef = { couleursommets: { defaut: 'F00' }, couleurfaces: { defaut: '#895632' } }
} else {
if ((typeof (objet.mef.couleursommets) === 'undefined') && (typeof (objet.mef.couleurfaces) === 'undefined')) {
this.mef = { couleursommets: { defaut: 'F00' }, couleurfaces: { defaut: '#895632' } }
} else if ((typeof (objet.mef.couleursommets) !== 'undefined') && (typeof (objet.mef.couleurfaces) === 'undefined')) {
this.mef = { couleursommets: objet.mef.couleursommets, couleurfaces: { defaut: '#895632' } }
} else if ((typeof (objet.mef.couleursommets) === 'undefined') && (typeof (objet.mef.couleurfaces) !== 'undefined')) {
this.mef = { couleursommets: { defaut: 'F00' }, couleurfaces: objet.mef.couleursommets }
} else {
this.mef = objet.mef
}
}
if (typeof (objet.objets) === 'undefined') {
this.objets = []
} else {
this.objets = objet.objets
}
// remplissage du tableau objets avec les points sommets du solide
const tab = []
for (let k = 1; k < this.sommets.length; k++) {
const o = {}
o.estsommet = true// non construit en tant que point car déjà construit
o.nom = this.nomsommets[k]
o.type = 'point'
o.coord = this.sommets[k]
tab.push(o)
}
for (let k = 0; k < this.objets.length; k++) tab.push(this.objets[k])
this.objets = tab
let d
let sup = 0
for (let k = 1; k < this.sommets.length; k++) {
d = this.sommets[k][0] * this.sommets[k][0] + this.sommets[k][1] * this.sommets[k][1] + this.sommets[k][2] * this.sommets[k][2]
if (d > sup) {
sup = d
}
}
this.zoom = 100 / Math.sqrt(sup)
// environ 50 dans le cas du cube
this.conteneur = this.idconteneur
this.rotation = { Ox: 0, Oy: 0, Oz: 0 }
// this.svg = j3pCreeSVG(this.idconteneur,{id:this.idconteneur+"figure",width:400,height:400})
this.centreX = 150
this.centreY = 150
this.SVGfaces = []
this.sommets2D = []
this.construit()
this.mode = 'rien' // "rotation"
const that = this
j3pElement(this.conteneur).tabIndex = '1'
$('#' + this.conteneur).keypress(function (event) {
if (event.keyCode != 38 && event.keyCode != 40) {
return
}
switch (event.keyCode) {
case 38:
that.zoom -= 2
break
case 40:
that.zoom += 2
break
}
that.construit()
})
j3pElement(this.conteneur).addEventListener('mousemove',
function (event) {
if (that.mode == 'rien') {
return
}
const { x, y } = j3pElement(that.conteneur).getBoundingClientRect()
that.courantX = event.clientX - x
that.courantY = event.clientY - y
that.rotation.Oz = Math.ceil((that.courantX - that.ancienX))
that.rotation.Oy = Math.ceil((that.courantY - that.ancienY))
that.construit()
that.ancienX = that.courantX
that.ancienY = that.courantY
}
)
j3pElement(this.conteneur).addEventListener('mousedown',
function (event) {
that.mode = 'rotation'
const { x, y } = j3pElement(that.conteneur).getBoundingClientRect()
that.ancienX = event.clientX - x
that.ancienY = event.clientY - y
}
)
j3pElement(this.conteneur).addEventListener('mouseup',
function (event) {
that.mode = 'rien'
}
)
}
// tab : coord 3D
// retourne les coord de tab dans le repere designe par this.repere
Solide.prototype.coordDansRepere = function (tab) {
const O = this.objets[this.repere[0] - 1].coord
const I = this.objets[this.repere[1] - 1].coord
const J = this.objets[this.repere[2] - 1].coord
const K = this.objets[this.repere[3] - 1].coord
const vecOI = [I[0] - O[0], I[1] - O[1], I[2] - O[2]]
const vecOJ = [J[0] - O[0], J[1] - O[1], J[2] - O[2]]
const vecOK = [K[0] - O[0], K[1] - O[1], K[2] - O[2]]
const vecOM = [tab[0] - O[0], tab[1] - O[1], tab[2] - O[2]]
const m = [[vecOI[0], vecOJ[0], vecOK[0]], [vecOI[1], vecOJ[1], vecOK[1]], [vecOI[2], vecOJ[2], vecOK[2]]]
const m1 = j3pInverseMatrice(m)
return j3pProduitMatVec(m1, vecOM)
}
Solide.prototype.estDansParallelepipedeRepere = function (tab) {
const res = this.coordDansRepere(tab)
return (res[0] < 1 + 0.05 && res[0] > -0.05) && (res[1] < 1 + 0.05 && res[1] > -0.05) && (res[2] < 1 + 0.05 && res[2] > -0.05)
}
Solide.prototype.to2D = function (tab) {
// car vision suivant Oi
return [tab[1] * this.zoom + this.centreX, -tab[2] * this.zoom + this.centreY]
}
Solide.prototype.construit = function () {
if (typeof (this.svg) !== 'undefined') {
j3pDetruit(this.idconteneur + 'figure')
}
this.svg = j3pCreeSVG(this.idconteneur, { id: this.idconteneur + 'figure', width: 300, height: 300 })
const newsommets = []
let tempo = []
for (let k = 0; k < this.sommets.length; k++) {
tempo = j3pRotation('Ox', this.rotation.Ox, this.sommets[k])
tempo = j3pRotation('Oy', this.rotation.Oy, tempo)
newsommets.push(j3pRotation('Oz', this.rotation.Oz, tempo))
}
for (let k = 0; k < this.faces.length; k++) {
const f = this.faces[k]
const s = newsommets
const vec1 = [s[f[1]][0] - s[f[0]][0], s[f[1]][1] - s[f[0]][1], s[f[1]][2] - s[f[0]][2]]
const vec2 = [s[f[2]][0] - s[f[1]][0], s[f[2]][1] - s[f[1]][1], s[f[2]][2] - s[f[1]][2]]
// console.log(vec1,vec2)
// composante Ox du vecteur normal à la face
// Si négative alors face cachée@
const pv = j3pVectoriel(vec1, vec2)[0]
// console.log('pv :'+k," "+pv)
for (let u = 0; u < f.length; u++) {
const v = (u == f.length - 1) ? 0 : u + 1
if (pv > 0) {
j3pCreeSegment(this.svg, {
id: 'face' + k + '_' + u,
x1: this.to2D(s[f[u]])[0],
y1: this.to2D(s[f[u]])[1],
x2: this.to2D(s[f[v]])[0],
y2: this.to2D(s[f[v]])[1],
couleur: '#000000',
epaisseur: 3,
opacite: 1
})
} else {
j3pCreeSegment(this.svg, {
id: 'face' + k + '_' + u,
x1: this.to2D(s[f[u]])[0],
y1: this.to2D(s[f[u]])[1],
x2: this.to2D(s[f[v]])[0],
y2: this.to2D(s[f[v]])[1],
couleur: '#222222',
epaisseur: 2,
opacite: 1,
pointilles: '2,6'
})
}
}
// console.log("vuecache",f,pv)
if (pv > 0) {
const opacite = 0.5
let tab = []
if (f.length == 4) {
tab = [this.to2D(s[f[0]]), this.to2D(s[f[1]]), this.to2D(s[f[2]]), this.to2D(s[f[3]])]
}
if (f.length == 3) {
tab = [this.to2D(s[f[0]]), this.to2D(s[f[1]]), this.to2D(s[f[2]])]
}
let couleurface = this.mef.couleurfaces.defaut
if (typeof (this.mef.couleurfaces['f' + k]) !== 'undefined') {
couleurface = this.mef.couleurfaces['f' + k]
}
j3pPolygone(this.svg, {
id: 'face' + k,
tab,
couleur: couleurface,
couleurRemplissage: couleurface,
opaciteRemplissage: opacite
})
}
}
let nom
for (let k = 1; k < this.nomsommets.length; k++) {
nom = this.nomsommets[k]
this.objets[this.numeroObjet(nom)].coord = this.sommets[k]
if (nom != 'som' + k) {
const coord = this.sommets[k]
const coord2D = this.to2D(coord)
let couleursommet = this.mef.couleursommets.defaut
if (typeof (this.mef.couleursommets[nom]) !== 'undefined') {
couleursommet = this.mef.couleursommets[nom]
}
j3pCreeTexte(this.svg, {
id: 'nomsommet' + nom,
texte: nom,
x: coord2D[0],
y: coord2D[1],
couleur: couleursommet,
italique: true,
taille: 12
})
}
}
this.sommets = newsommets
// Construction des objets particuliers
/*
objets : [
{nom:"O",type:"point",coord:[0,0,0]},
{nom:"s1",type:"segment",ext1:"O",ext2:"K"}
]
*/
for (let k = 0; k < this.objets.length; k++) {
const o = this.objets[k]
switch (o.type) {
case 'point':
if (typeof (o.estsommet) === 'undefined') {
let tempo = rotation3D('Ox', this.rotation.Ox, o.coord)
tempo = rotation3D('Oy', this.rotation.Oy, tempo)
tempo = rotation3D('Oz', this.rotation.Oz, tempo)
const coord2D = this.to2D(tempo)
// j3pCreePoint(this.svg,{id:this.idconteneur+"point"+o.nom,nom:o.nom,x:coord2D[0],y:coord2D[1],taille:12,couleur:"#00F",taillepolice:14,epaisseur:2,decal:[-5,-5]});
j3pBoule(this.svg, {
couleur: 'rouge',
id: this.idconteneur + 'point' + o.nom,
cx: coord2D[0],
cy: coord2D[1],
diametre: 10
})
j3pCreeTexte(this.svg, {
id: this.idconteneur + 'textepoint' + o.nom + nom,
texte: o.nom,
x: coord2D[0] - 8,
y: coord2D[1] - 7,
couleur: '#F00',
italique: true,
taille: 12
})
this.objets[k].coord = tempo
}
break
case 'segment': {
const coordext1 = this.objets[this.numeroObjet(o.ext1)].coord
const coordext2 = this.objets[this.numeroObjet(o.ext2)].coord
const coord2D1 = this.to2D(coordext1)
const coord2D2 = this.to2D(coordext2)
const bool1 = this.estDansParallelepipedeRepere(coordext1)
const bool2 = this.estDansParallelepipedeRepere(coordext2)
if (bool1 && bool2) {
j3pCreeSegment(this.svg, {
id: this.idconteneur + 'segment' + nom,
x1: coord2D1[0],
y1: coord2D1[1],
x2: coord2D2[0],
y2: coord2D2[1],
couleur: '#00AA44',
epaisseur: 3,
opacite: 1,
pointilles: '4,6'
})
} else {
j3pCreeSegment(this.svg, {
id: this.idconteneur + 'segment' + nom,
x1: coord2D1[0],
y1: coord2D1[1],
x2: coord2D2[0],
y2: coord2D2[1],
couleur: '#00AA44',
epaisseur: 3,
opacite: 1
})
}
break
} // case segment
}
}
}
Solide.prototype.tourne = function (coord) {
let tempo = rotation3D('Ox', this.rotation.Ox, coord)
tempo = rotation3D('Oy', this.rotation.Oy, tempo)
tempo = rotation3D('Oz', this.rotation.Oz, tempo)
return tempo
}
Solide.prototype.numeroObjet = function (nom) {
for (let k = 0; k < this.objets.length; k++) {
if (this.objets[k].nom == nom) {
return k
}
}
return -1
}
/**
* Rotation /t ch du point tab et d’angle angle
* @private
*/
function rotation3D (ch, angle, tab) {
angle = (angle / 180) * Math.PI
const res = []
switch (ch) {
case 'Ox':
res[0] = tab[0]
res[1] = tab[1] * Math.cos(angle) - tab[2] * Math.sin(angle)
res[2] = tab[1] * Math.sin(angle) + tab[2] * Math.cos(angle)
break
case 'Oy':
res[0] = tab[2] * Math.sin(angle) + tab[0] * Math.cos(angle)
res[1] = tab[1]
res[2] = tab[2] * Math.cos(angle) - tab[0] * Math.sin(angle)
break
case 'Oz':
res[0] = tab[0] * Math.cos(angle) - tab[1] * Math.sin(angle)
res[1] = tab[0] * Math.sin(angle) + tab[1] * Math.cos(angle)
res[2] = tab[2]
break
}
return res
}
/* */