GALERIE    EN COURS    SCENES    MACROS    GUIDE    A PROPOS


 

Dessiner une vecteur



Le but ici est de dessiner un "vecteur" entre deux points. Le "vecteur" est composé un cylinder{} et d'un cone{}. Le cône a un angle de 30° et la base a un rayon de deux fois le rayon du cylindre. Ces valeurs peuvent bien sût être changées. Ce qui donne une flèche de ce genre :
fleche
On choisi deux points Pt1 et Pt2 de manière aléatoire.

deux points


Première étape : On calcule la distance entre ces deux points. On peut alors construire notre flèche avec cette dimension en utilisant la macro Arrow que nous verrons plus loin. J'ai choisi ici de la construire sur l'axe X. Elle est représentée en jaune dans l'image ci dessous :

fleche


Par simple soustraction de vecteurs on déplace le point Pt1 à l'origine <0, 0, 0> qui devient Pt3. On applique la même chose au point Pt2 qui devient Pt4. C'est en fait une translation:
#declare Pt3 = Pt1 - Pt1; // c'est juste pour la compréhension
#declare Pt4 = Pt2 - Pt1;


fleche


On va maintenant travailler avec le triangle formé avec les points Pt3 et Pt4. Notre flèche n'a toujours pas bougé. On doit calculer l'angle dans le plan horizontal XZ.

triangle


Pas de difficulté majeure pour déterminer cet angle :
#declare AngleH = degrees(atan2(p4.z,p4.x));
On en profile aussi pour calculer l'angle dans le plan vertical qui passe par Pt3 et Pt4.
#declare AngleV = degrees(atan2(p4.y,sqrt(p4.x*p4.x + p4.z*p4.z)));
Les angles sont représentés en cyan dans l'image.

Nous avons tout ce qu'il faut pour "installer" notre flèche entre les deux points du départ Pt1 et Pt2.

final

object {
  Arrow(vDist,0.03)
  rotate AngleV*z
  rotate -AngleH*y
  translate p1	
  pigment { color Yellow }
  }
Attention, l'ordre des transformations est important et ne peut pas être changé ! Vous pouvez essayer et voir ce que ça donne ...

"Arrow" est une macro à laquelle on passe deux paramètres. Len qui est la longueur totale de la flèche, et rad qui est le rayon du cylindre. Vous remarquerez la présence du nombre 15. Demi-angle au sommet du cône que nous avons fixé au début à 30°. Idem dans la définition du cone {}, la base à un rayon de deux fois le rayon du cylinder {}.
#macro Arrow(Len,rad)
  #local arrowLen = 2*rad/tan(radians(15));
  union {
    cylinder { <0, 0, 0>, <Len-arrowLen, 0, 0>, rad }
    cone { <Len-arrowLen, 0, 0>, 2*rad, <Len, 0, 0>, 0 }
    }
#end
Nous pouvons construire la macro qui va tout faire d'un seul coup et à laquelle on passe les trois paramètres suivants : le point de départ, le point d'arrivé et le rayon du cylindre de la flèche.
#macro DrawVector(pt1, pt2, rad)
  // --- Euclidean distance between the two points
  #local dist = p2-p1;
  #local dist = sqrt(dist.x* dist.x + dist.y* dist.y + dist.z* dist.z);
  // --- Translate to origin
  #local p4 = pt2-pt1; 
  // --- "Horizontal" angle between the X axis and the vector in the XZ plane. 
  #local AngleH = degrees(atan2(p4.z,p4.x));
  // --- "Vertical" angle between the XZ plane and the vector. 
  #local AngleV = degrees(atan2(p4.y,sqrt (p4.x*p4.x + p4.z*p4.z) ) );
  // --- Build arrow
  #local arrowLen = 2*rad/tan(radians(15));
  union {
    cylinder { <0,0,0>, <dist-arrowLen, 0, 0>, rad }
    cone { <dist-arrowLen, 0, 0>, 2*rad, <dist, 0, 0>, 0 }
    // --- Transforms
    rotate AngleV*z
    rotate -AngleH*y
    translate pt1
    }
#end








Haut de la page | Sommaire ]