Série d'articles graphiques "Rétro".
Bonjour,
Voici un autre affichage d'objets 3D dessinés au trait.
L'image "CubeAlaMain.jpg" montre comment on dessine souvent un cube lorsqu'on ne dispose que d'un crayon et d'un bout de papier ou que d'une craie et d'un tableau noir.
Essayons de simuler cette manière de dessiner.
AlaMainZut
La notion de "profondeur" par rapport à l'écran (this.W) est utilisée pour trier les arrêtes pour ensuite les dessiner de la plus éloignée à la plus proche.
Chaque trait est précédé d'une "ligne" plus épaisse (de couleur du fond) qui efface tout ce qui est sous l'arrête concernée.
function PlatonTrait(n,R) { // Rayon sphère englobante (bounding sphere)
// ... codage différent de Rétro-B: Les solides de Platon au trait
// ... (voir 'PlatonTrait.js')
}
PlatonTrait.prototype.Proj=function(p) { // Dans 'Proj.js'
this.U=[]; this.V=[]; W=this.W=[]; // W global pour tri (sort)
for (var k=0,K=this.S.length; k<K; ++k) { // cordonnées projetées selon p
var s=this.S[k],w=p.d+p.yx*s[0]+p.yy*s[1]+p.yz*s[2],q=p.d/w;
this.U[k]=q*(p.xx*s[0]+p.xy*s[1]);
this.V[k]=q*(p.zx*s[0]+p.zy*s[1]+p.zz*s[2]);
this.W[k]=w;
} // ▼ tri des arêtes selon la "profondeur" de leur centre (ou milieu)
this.A.sort(function(a,b){return W[b[0]]-W[a[0]]+W[b[1]]-W[a[1]];});
};
PlatonTrait.prototype.Draw=function(ctx,u0,v0,dil) { // Dans 'DrawZut.js
ctx.clearRect(0,0,cnv.width,cnv.height);
for (var m=0,M=this.A.length; m<M; ++m) { // pour chaque arrête
var e=this.A[m],a=e[0],b=e[1];
var ua=u0+dil*this.U[a],va=v0+dil*this.V[a];
var ub=u0+dil*this.U[b],vb=v0+dil*this.V[b];
ctx.beginPath(); ctx.lineWidth='19'; ctx.strokeStyle='#FFFFFF'
ctx.moveTo(ua,va); ctx.lineTo(ub,vb); // effacement
ctx.stroke();
ctx.beginPath(); ctx.lineWidth='5'; ctx.strokeStyle='#000000'
ctx.moveTo(ua,va); ctx.lineTo(ub,vb); // arête
ctx.stroke();
}
};
Le résultat (
DodécaèdreZut.jpg) montre que
l'algorithme n'est pas au point !
Pour essayer la version "zut", adaptez la ligne 8 du fichier Draw.html:
<script type='text/javascript' src='DrawZut.js'></script>
AlaMain
Pour éviter les effacements autour des sommets, raccourcissons les lignes d'effacement:
PlatonTrait.prototype.Draw=function(ctx,u0,v0,dil) {
ctx.clearRect(0,0,cnv.width,cnv.height);
for (var m=0,M=this.A.length; m<M; ++m) { // pour chaque arrête
var e=this.A[m],a=e[0],b=e[1],d;
var ua=u0+dil*this.U[a],ub=u0+dil*this.U[b],du=ub-ua;
var va=v0+dil*this.V[a],vb=v0+dil*this.V[b],dv=vb-va;
d=Math.max(0.001,Math.sqrt(du*du+dv*dv))/19,du/=d,dv/=d;
ctx.beginPath(); ctx.lineWidth='19'; ctx.strokeStyle='#FFFFFF'
ctx.moveTo(ua+du,va+dv); ctx.lineTo(ub-du,vb-dv); // effacement
ctx.stroke();
ctx.beginPath(); ctx.lineWidth='5'; ctx.strokeStyle='#000000'
ctx.moveTo(ua,va); ctx.lineTo(ub,vb); // arête
ctx.stroke();
}
};
Bien sûr, la méthode n'est pas
parfaite, mais, en variant le positionnement de l'objet, on arrive presque toujours à obtenir une image satisfaisante.
Sur internet, je n'ai rien trouvé qui pourrait correspondre à cet algorithme. Connaîtriez-vous quelque chose ?
Liens CodeS-SourceS:
Rétro-B: Les solides de Platon au trait
Bonne lecture ...
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.