Rétro-B+: Polyèdres comme "à la main"

Description

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

Codes Sources

A voir également

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.