import $ from 'jquery'
import { j3pAjouteBouton, j3pBoule, j3pDetruit, j3pDiv, j3pElement } from 'src/legacy/core/functions'
import { j3pCreeSegment, j3pCreeSVG, j3pCreeTexte, j3pCreeVecteur, j3pPolygone } from 'src/legacy/core/functionsSvg'
/** @module legacy/outils/3D/3D */
/*
window.objet = {
sommets:[[],[1,-1,-1],[1,1,-1],[-1,1,-1],[-1,-1,-1],[1,-1,1],[1,1,1],[-1,1,1],[-1,-1,1]],
faces:[[4,3,2,1],[1,2,6,5],[2,3,7,6],[3,4,8,7],[4,1,5,8],[5,6,7,8]],
nomsommets:["","A","B","C","D","E","F","G","H"],
objets : [
{nom:"O",type:"point",coord:[0,0,0]}
]
*/
function _3D (idconteneur, objet) {
this.idconteneur = idconteneur
if (objet.dim === undefined) {
this.dim = { larg: 300, haut: 300 }
} else {
this.dim = objet.dim
this.dim.larg = (objet.dim.larg) ? objet.dim.larg : 300
this.dim.haut = objet.dim.haut ? objet.dim.haut : 300
}
// Alex :
this.faces_cachees = objet.faces_cachees
this.sommets = objet.sommets
this.faces = objet.faces
if (objet.repere === undefined) objet.repere = [1, 2, 4, 5]
this.repere = objet.repere
this.nomsommets = []
// si nomsommets undefined les sommets sont nommés automatiquement "somk" (mais étiquettes non affichées)
if (objet.nomsommets) {
this.nomsommets.push('')
for (let k = 1; k < this.sommets.length; k++) {
this.nomsommets.push((objet.nomsommets[k] === '') ? 'som' + k : objet.nomsommets[k])
}
} else {
this.nomsommets = ['']
for (let k = 1; k < this.sommets.length; k++) this.nomsommets.push('som' + k)
}
this.sommetsvisibles = []
if (objet.sommetsvisibles) {
for (let k = 1; k < this.sommets.length; k++) this.sommetsvisibles[k] = objet.sommetsvisibles[k]
} else {
for (let k = 1; k < this.sommets.length; k++) this.sommetsvisibles[k] = false
}
if (objet.mef) {
if ((objet.mef.couleursommets === undefined) && (objet.mef.couleurfaces === undefined)) {
this.mef = { couleursommets: { defaut: 'F00' }, couleurfaces: { defaut: '#895632' } }
} else if ((objet.mef.couleursommets) && (objet.mef.couleurfaces === undefined)) {
this.mef = { couleursommets: objet.mef.couleursommets, couleurfaces: { defaut: '#895632' } }
} else if ((objet.mef.couleursommets === undefined) && (objet.mef.couleurfaces)) {
this.mef = { couleursommets: { defaut: 'F00' }, couleurfaces: objet.mef.couleursommets }
} else {
this.mef = objet.mef
}
this.mef.typerotation = (objet.mef.typerotation) ? objet.mef.typerotation : 'Oz'
} else {
this.mef = { typerotation: 'Oz', couleursommets: { defaut: 'F00' }, couleurfaces: { defaut: '#92BBD8' } }
}
this.objets = (objet.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++) {
if (this.objets[k].visible === undefined) this.objets[k].visible = true
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 = (this.dim.zoom) ? this.dim.zoom : (Math.max(this.dim.larg / 3, this.dim.haut / 3)) / Math.sqrt(sup)
// environ 50 dans le cas du cube
const conteneur = j3pElement(this.idconteneur)
this.rotation = { Ox: 0, Oy: 0, Oz: 0 }
this.arotation = { Ox: 0, Oy: 0, Oz: 0 }
this.rotation.type = this.mef.typerotation
this.centreX = this.dim.larg / 2
this.centreY = this.dim.haut / 2
this.SVGfaces = []
this.sommets2D = []
this.construit()
this.mode = 'rien' // "rotation"
const that = this
conteneur.tabIndex = '1'
$('#' + this.conteneur).keypress(function (event) {
if (event.keyCode !== 38 && event.keyCode !== 40) return
switch (event.keyCode) {
case 38:
that.zoom -= 0.5
break
case 40:
that.zoom += 0.5
break
}
that.construit()
})
conteneur.addEventListener('mousemove',
function (evt) {
if (that.mode === 'rien') return
const { left, top } = this.getBoundingClientRect()
const courantX = event.clientX - left
const courantY = event.clientY - top
if (that.rotation.type === 'Oz') {
that.rotation.Oz = that.arotation.Oz + Math.ceil((courantX - that.ancienX))
} else {
that.rotation.Ox = that.arotation.Ox + Math.ceil((courantX - that.ancienX))
}
that.rotation.Oy = that.arotation.Oy + Math.ceil((courantY - that.ancienY))
that.construit()
that.ancienX = courantX
that.ancienY = courantY
that.arotation.Ox = that.rotation.Ox
that.arotation.Oy = that.rotation.Oy
that.arotation.Oz = that.rotation.Oz
}
)
conteneur.addEventListener('mousedown',
function (evt) {
that.mode = 'rotation'
const { left, top } = this.getBoundingClientRect()
that.ancienX = event.clientX - left
that.ancienY = event.clientY - top
}
)
conteneur.addEventListener('mouseup',
function (evt) {
that.mode = 'rien'
}
)
j3pDiv(idconteneur, { id: this.idconteneur + 'divboutonbascule', contenu: '', coord: [0, 310] })
j3pAjouteBouton(this.idconteneur + 'divboutonbascule', this.idconteneur + 'boutonbascule', 'MepBoutonsDG', 'Rotation ' + this.rotation.type)
j3pElement(this.idconteneur + 'boutonbascule').addEventListener('click',
function (evt) {
if (evt.target.value === 'Rotation (Oz)') {
evt.target.value = 'Rotation (Ox)'
that.rotation.type = 'Ox'
} else if (evt.target.value === 'Rotation (Oy)') {
evt.target.value = 'Rotation (Oz)'
that.rotation.type = 'Oz'
} else {
evt.target.value = 'Rotation (Oy)'
that.rotation.type = 'Oy'
}
}
)
}
_3D.prototype.anime = function (rotX, rotY, rotZ, lenteur) {
// lenteur = 0 ==> instantané
if (Number(lenteur) === 0) {
this.rotation.Ox = rotX
this.rotation.Oy = rotY
this.rotation.Oz = rotZ
this.construit()
return
}
const nbmvt = 50
const tabX = []
const tabY = []
const tabZ = []
tabX[0] = this.rotation.Ox
tabY[0] = this.rotation.Oy
tabZ[0] = this.rotation.Oz
for (let k = 1; k <= nbmvt; k++) {
tabX[k] = tabX[0] + k * (rotX - tabX[0]) / nbmvt
tabY[k] = tabY[0] + k * (rotY - tabY[0]) / nbmvt
tabZ[k] = tabZ[0] + k * (rotZ - tabZ[0]) / nbmvt
}
this.objetanimation = { boucle: false, nbiter: nbmvt, itercourante: 1, tabX, tabY, tabZ }
const that = this
const loopTimerId = setInterval(function () {
that.rotation.Ox = tabX[that.objetanimation.itercourante]
that.rotation.Oy = tabY[that.objetanimation.itercourante]
that.rotation.Oz = tabZ[that.objetanimation.itercourante]
that.construit(that.rotation.Ox, that.rotation.Oy, that.rotation.Oz)
that.objetanimation.itercourante++
if (that.objetanimation.itercourante > that.objetanimation.nbiter) {
clearInterval(loopTimerId)
}
}, lenteur)
}
// tab : coord 3D
// retourne les coord de tab dans le repere designe par this.repere
_3D.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 passage = [
[this.repere2[0][0], this.repere2[1][0], this.repere2[2][0]],
[this.repere2[0][1], this.repere2[1][1], this.repere2[2][1]],
[this.repere2[0][2], this.repere2[1][2], this.repere2[2][2]]
]
let vecOI = [I[0] - O[0], I[1] - O[1], I[2] - O[2]]
let vecOJ = [J[0] - O[0], J[1] - O[1], J[2] - O[2]]
let vecOK = [K[0] - O[0], K[1] - O[1], K[2] - O[2]]
let vecOM = [tab[0] - O[0], tab[1] - O[1], tab[2] - O[2]]
vecOI = j3pProduitMatVec(passage, vecOI)
vecOJ = j3pProduitMatVec(passage, vecOJ)
vecOK = j3pProduitMatVec(passage, vecOK)
vecOM = j3pProduitMatVec(passage, vecOM)
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)
}
_3D.prototype.estDansParallelepipedeRepere = function (tab) {
const res = this.coordDansRepere(tab)
// console.log(res)
// console.log((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))
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))
}
_3D.prototype.to2D = function (tab) {
// car vision suivant Oi
return [tab[1] * this.zoom + this.centreX, -tab[2] * this.zoom + this.centreY]
}
// En degrés
_3D.prototype.rotationVecteur = function (vec, Ox, Oy, Oz) {
let tempo1 = j3pRotation('Ox', Ox, vec)
tempo1 = j3pRotation('Oy', Oy, tempo1)
tempo1 = j3pRotation('Oz', Oz, tempo1)
return tempo1
}
_3D.prototype.construit = function () {
if (this.svg) j3pDetruit(this.idconteneur + 'figure')
this.svg = j3pCreeSVG(this.idconteneur, {
id: this.idconteneur + 'figure',
width: this.dim.larg,
height: this.dim.haut
})
const newsommets = []
this.repere2 = [
this.rotationVecteur([1, 0, 0], this.rotation.Ox, this.rotation.Oy, this.rotation.Oz),
this.rotationVecteur([0, 1, 0], this.rotation.Ox, this.rotation.Oy, this.rotation.Oz),
this.rotationVecteur([0, 0, 1], this.rotation.Ox, this.rotation.Oy, this.rotation.Oz)
]
const passage = [
[this.repere2[0][0], this.repere2[1][0], this.repere2[2][0]],
[this.repere2[0][1], this.repere2[1][1], this.repere2[2][1]],
[this.repere2[0][2], this.repere2[1][2], this.repere2[2][2]]
]
// Les coordonnées des points sont relatives à repere2
// Pour l’affichage, il faut déterminer les coordonnées des points dans le repere [1,0,0];[0,1,0];[0,0,1]
for (let k = 0; k < this.sommets.length; k++) {
newsommets.push(j3pProduitMatVec(passage, this.sommets[k]))
}
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]
for (let u = 0; u < f.length; u++) {
const v = (u === f.length - 1) ? 0 : u + 1
if (pv <= 0 && this.faces_cachees !== false) {
j3pCreeSegment(this.svg, {
id: this.idconteneur + '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'
})
} else {
j3pCreeSegment(this.svg, {
id: this.idconteneur + '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
})
}
}
if (pv > 0 || !this.faces_cachees) {
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]])]
const couleurface = (this.mef.couleurfaces['f' + k]) ? this.mef.couleurfaces['f' + k] : this.mef.couleurfaces.defaut
j3pPolygone(this.svg, {
id: this.idconteneur + 'face' + k,
tab,
couleur: couleurface,
couleurRemplissage: couleurface,
opaciteRemplissage: opacite
})
}
}
for (let k = 1; k < this.nomsommets.length; k++) {
const nom = this.nomsommets[k]
this.objets[this.numeroObjet(nom)].coord = this.sommets[k]
if ((nom !== 'som' + k) && this.sommetsvisibles[k]) {
const coord = j3pProduitMatVec(passage, this.sommets[k])
const coord2D = this.to2D(coord)
const couleursommet = (this.mef.couleursommets[nom]) ? this.mef.couleursommets[nom] : this.mef.couleursommets.defaut
j3pCreeTexte(this.svg, {
id: 'nomsommet' + nom,
texte: nom,
x: coord2D[0],
y: coord2D[1] - 2,
couleur: couleursommet,
italique: true,
taille: 12
})
}
}
// 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]
const nom = this.objets[k].nom
if (o.type !== 'point') {
if (this.objets[k].pointilles === undefined) this.objets[k].pointilles = false
if (this.objets[k].couleur === undefined) this.objets[k].couleur = '#333'
}
switch (o.type) {
case 'point':
if (o.estsommet === undefined) {
if (o.couleur === undefined) o.couleur = 'rouge'
const couleur = o.couleur
let couleurtexte = ''
switch (o.couleur) {
case 'rouge':
couleurtexte = '#CC0000'
break
case 'bleu':
couleurtexte = '#0000CC'
break
case 'vert':
couleurtexte = '#008800'
break
}
const tempo = j3pProduitMatVec(passage, o.coord)
const coord2D = this.to2D(tempo)
if (this.objets[k].visible) {
j3pBoule(this.svg, {
couleur,
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] + 6,
y: coord2D[1] - 5,
couleur: couleurtexte,
italique: true,
taille: 12
})
}
this.objets[k].coord2 = tempo
} else {
this.objets[k].coord2 = j3pProduitMatVec(passage, o.coord)
}
break
case 'segment':
// console.log('this.objets[this.numeroObjet(o.ext1)].coord2='+this.objets[this.numeroObjet(o.ext1)].coord2)
{
const coordext1 = this.objets[this.numeroObjet(o.ext1)].coord2
const coordext2 = this.objets[this.numeroObjet(o.ext2)].coord2
const coord2D1 = this.to2D(coordext1)
const coord2D2 = this.to2D(coordext2)
if (this.objets[k].visible) {
if (this.objets[k].pointilles) {
j3pCreeSegment(this.svg, {
id: this.idconteneur + 'segment' + nom,
x1: coord2D1[0],
y1: coord2D1[1],
x2: coord2D2[0],
y2: coord2D2[1],
couleur: this.objets[k].couleur,
epaisseur: 3,
opacite: 1,
pointilles: '6,6'
})
} else {
j3pCreeSegment(this.svg, {
id: this.idconteneur + 'segment' + nom,
x1: coord2D1[0],
y1: coord2D1[1],
x2: coord2D2[0],
y2: coord2D2[1],
couleur: this.objets[k].couleur,
epaisseur: 3,
opacite: 1
})
}
}
}
break
case 'droite':
{
const coordext1 = this.objets[this.numeroObjet(o.ext1)].coord2
const coordext2 = this.objets[this.numeroObjet(o.ext2)].coord2
const t = 100
const debutDroite = [coordext1[0] - t * (coordext2[0] - coordext1[0]), coordext1[1] - t * (coordext2[1] - coordext1[1]), coordext1[2] - t * (coordext2[2] - coordext1[2])]
const finDroite = [coordext1[0] + t * (coordext2[0] - coordext1[0]), coordext1[1] + t * (coordext2[1] - coordext1[1]), coordext1[2] + t * (coordext2[2] - coordext1[2])]
const coord2D1 = this.to2D(debutDroite)
const coord2D2 = this.to2D(finDroite)
if (this.objets[k].visible) {
if (this.objets[k].pointilles) {
j3pCreeSegment(this.svg, {
id: this.idconteneur + 'segment' + nom,
x1: coord2D1[0],
y1: coord2D1[1],
x2: coord2D2[0],
y2: coord2D2[1],
couleur: this.objets[k].couleur,
epaisseur: 3,
opacite: 1,
pointilles: '6,6'
})
} else {
j3pCreeSegment(this.svg, {
id: this.idconteneur + 'segment' + nom,
x1: coord2D1[0],
y1: coord2D1[1],
x2: coord2D2[0],
y2: coord2D2[1],
couleur: this.objets[k].couleur,
epaisseur: 3,
opacite: 1
})
}
}
}
break
case 'demi-droite':
{
const coordext1 = this.objets[this.numeroObjet(o.ext1)].coord2
const coordext2 = this.objets[this.numeroObjet(o.ext2)].coord2
const t = 100
const debutDroite = [coordext1[0], coordext1[1], coordext1[2]]
const finDroite = [coordext1[0] + t * (coordext2[0] - coordext1[0]), coordext1[1] + t * (coordext2[1] - coordext1[1]), coordext1[2] + t * (coordext2[2] - coordext1[2])]
const coord2D1 = this.to2D(debutDroite)
const coord2D2 = this.to2D(finDroite)
if (this.objets[k].visible) {
if (this.objets[k].pointilles) {
j3pCreeSegment(this.svg, {
id: this.idconteneur + 'segment' + nom,
x1: coord2D1[0],
y1: coord2D1[1],
x2: coord2D2[0],
y2: coord2D2[1],
couleur: this.objets[k].couleur,
epaisseur: 3,
opacite: 1,
pointilles: '6,6'
})
} else {
j3pCreeSegment(this.svg, {
id: this.idconteneur + 'segment' + nom,
x1: coord2D1[0],
y1: coord2D1[1],
x2: coord2D2[0],
y2: coord2D2[1],
couleur: this.objets[k].couleur,
epaisseur: 3,
opacite: 1
})
}
}
}
break
case 'plan':
{
const coordext1 = this.objets[this.numeroObjet(o.ext1)].coord2
const coordext2 = this.objets[this.numeroObjet(o.ext2)].coord2
const t = 100
const debutDroite = [coordext1[0] - t * (coordext2[0] - coordext1[0]), coordext1[1] - t * (coordext2[1] - coordext1[1]), coordext1[2] - t * (coordext2[2] - coordext1[2])]
const finDroite = [coordext1[0] + t * (coordext2[0] - coordext1[0]), coordext1[1] + t * (coordext2[1] - coordext1[1]), coordext1[2] + t * (coordext2[2] - coordext1[2])]
const coord2D1 = this.to2D(debutDroite)
const coord2D2 = this.to2D(finDroite)
if (this.objets[k].visible) {
if (this.objets[k].pointilles) {
j3pCreeSegment(this.svg, {
id: this.idconteneur + 'segment' + nom,
x1: coord2D1[0],
y1: coord2D1[1],
x2: coord2D2[0],
y2: coord2D2[1],
couleur: this.objets[k].couleur,
epaisseur: 3,
opacite: 1,
pointilles: '6,6'
})
} else {
j3pCreeSegment(this.svg, {
id: this.idconteneur + 'segment' + nom,
x1: coord2D1[0],
y1: coord2D1[1],
x2: coord2D2[0],
y2: coord2D2[1],
couleur: this.objets[k].couleur,
epaisseur: 3,
opacite: 1
})
}
}
}
break
case 'vecteur':
{
const coordext1 = this.objets[this.numeroObjet(o.ext1)].coord2
const coordext2 = this.objets[this.numeroObjet(o.ext2)].coord2
const coord2D1 = this.to2D(coordext1)
const coord2D2 = this.to2D(coordext2)
if (this.objets[k].visible) {
if (this.objets[k].pointilles) {
j3pCreeVecteur(this.svg, {
numero: 0,
id: this.idconteneur + 'vecteur' + nom,
x1: coord2D1[0],
y1: coord2D1[1],
x2: coord2D2[0],
y2: coord2D2[1],
couleur: this.objets[k].couleur,
epaisseur: 3,
opacite: 1,
pointilles: '6,6'
})
} else {
j3pCreeVecteur(this.svg, {
numero: 0,
id: this.idconteneur + 'vecteur' + nom,
x1: coord2D1[0],
y1: coord2D1[1],
x2: coord2D2[0],
y2: coord2D2[1],
couleur: this.objets[k].couleur,
epaisseur: 3,
opacite: 1
})
}
}
}
break
}
}
}
_3D.prototype.ajoute = function (listeObjets) {
for (let k = 0; k < listeObjets.length; k++) {
if (typeof listeObjets[k].visible === 'undefined') {
listeObjets[k].visible = true
}
this.objets.push(listeObjets[k])
}
this.construit()
}
_3D.prototype.tourne = function (coord) {
let tempo = j3pRotation('Ox', this.rotation.Ox, coord)
tempo = j3pRotation('Oy', this.rotation.Oy, tempo)
tempo = j3pRotation('Oz', this.rotation.Oz, tempo)
return tempo
}
_3D.prototype.numeroObjet = function (nom) {
for (let k = 0; k < this.objets.length; k++) {
if (this.objets[k].nom === nom) return k
}
return -1
}
/*
nomsommets:["","A","","C","D","E","F","G","H"],
sommetsvisibles:["",true,false,false,false,false,false,false,false]
*/
_3D.prototype.visible = function (nomObjet) {
if (this.nomsommets.indexOf(nomObjet) !== -1) {
this.sommetsvisibles[this.nomsommets.indexOf(nomObjet)] = true
this.construit()
return
}
const numero = this.numeroObjet(nomObjet)
if (!this.objets[numero].visible) {
this.objets[numero].visible = true
this.construit()
}
}
_3D.prototype.invisible = function (nomObjet) {
if (this.nomsommets.indexOf(nomObjet) !== -1) {
this.sommetsvisibles[this.nomsommets.indexOf(nomObjet)] = false
this.construit()
return
}
const numero = this.numeroObjet(nomObjet)
if (this.objets[numero].visible) {
this.objets[numero].visible = false
this.construit()
}
}
/*
*
* Rotation /t ch du point tab et d’angle angle
*/
export function j3pRotation (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
}
/**
* Retourne le produit vectoriel de deux vecteurs
* (utilisé seulement dans 3D.js et Solide.js (ce dernier n’étant jamais chargé)
* @param {number[]} v1
* @param {number[]} v2
* @return {number}
*/
export function j3pVectoriel (v1, v2) {
const res = []
res[0] = v1[1] * v2[2] - v1[2] * v2[1]
res[1] = v1[2] * v2[0] - v1[0] * v2[2]
res[2] = v1[0] * v2[1] - v1[1] * v2[0]
return res
}
export function j3pScalaire3D (u, v) {
return u[0] * v[0] + u[1] * v[1] + u[2] * v[2]
}
export function j3pVectNorme3D (u) {
const norme = Math.sqrt(u[0] * u[0] + u[1] * u[1] + u[2] * u[2])
return ([u[0] / norme, u[1] / norme, u[2] / norme])
}
export function j3pNorme3D (u) {
return Math.sqrt(u[0] * u[0] + u[1] * u[1] + u[2] * u[2])
}
// mat = [[a11,a12,a13],[a21,a22,a23],[a31,a32,a33]]
export function j3pInverseMatrice (m) {
const cofac00 = m[1][1] * m[2][2] - m[1][2] * m[2][1]
const cofac01 = -(m[1][0] * m[2][2] - m[1][2] * m[2][0])
const cofac02 = m[1][0] * m[2][1] - m[1][1] * m[2][0]
const cofac10 = -(m[0][1] * m[2][2] - m[0][2] * m[2][1])
const cofac11 = m[0][0] * m[2][2] - m[0][2] * m[2][0]
const cofac12 = -(m[0][0] * m[2][1] - m[2][0] * m[0][1])
const cofac20 = m[0][1] * m[1][2] - m[0][2] * m[1][1]
const cofac21 = -(m[0][0] * m[1][2] - m[1][0] * m[0][2])
const cofac22 = m[0][0] * m[1][1] - m[0][1] * m[1][0]
const detm = m[0][0] * cofac00 + m[0][1] * cofac01 + m[0][2] * cofac02
return [[cofac00 / detm, cofac10 / detm, cofac20 / detm], [cofac01 / detm, cofac11 / detm, cofac21 / detm], [cofac02 / detm, cofac12 / detm, cofac22 / detm]]
}
export function j3pProduitMatVec (m, tab) {
return [m[0][0] * tab[0] + m[0][1] * tab[1] + m[0][2] * tab[2], m[1][0] * tab[0] + m[1][1] * tab[1] + m[1][2] * tab[2], m[2][0] * tab[0] + m[2][1] * tab[1] + m[2][2] * tab[2]]
}
export default _3D