Gráficos 3D

 

Figueroa, GMora, W..

  Inicio  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18 

 

Ejes3D y Arrow3D

Para graficar flechas 3D, vamos a usar una pequeña modificación del paquete Arrow3D de Harry Calkins

Vamos a crear una sencilla función Flecha3D[] la cual pondremos en una celda que luego vamos a ejecutar.

Esta función dibuja un cono al final de un segmento que va de pt1 a pt2, el tamaño del cono es un porcentaje de la longitud del segmento. Como el cono se construye con triángulos, se debe indicar el número de triángulos 'nlds'

El código de la función Flecha3D[] es

 


Flecha3D[pt1_, pt2_, nlds_, porc_, color_] := (

      {aa, bb, cc} =pt2-pt1;
      (*construcción de una base ortonormal pata la cabeza de la flecha*)

      nrm1 = {0, 1, 0};
      nrm2 = {1, 0, 0};

      Which[
        aa == 0 && bb == 0, nrm1 = {0, 1, 0}; nrm2 = {1, 0, 0},
        aa == 0 && cc == 0, nrm1 = {1, 0, 0}; nrm2 = {0, 0, 1},
        bb == 0 && cc == 0, nrm1 = {0, 0, 1}; nrm2 = {0, 1, 0},
        aa == 0,
        nrm1 = {1, 0, 0};
        nrm2 = Cross[nrm1, {0, bb, cc}/Norm[{bb, cc}]], bb == 0,
        nrm1 = {0, 1, 0};
        nrm2 = Cross[nrm1, {aa, 0, cc}/Norm[{aa, cc}]], cc == 0,
        nrm1 = {0, 0, 1};
        nrm2 = Cross[nrm1, {aa, bb, 0}/Norm[{aa, bb}]], True,
        nrm1 = {-(((bb + cc)*Abs[aa])/(aa*Sqrt[2*aa^2 + (bb + cc)^2])),
            Abs[aa]/Sqrt[2*aa^2 + (bb + cc)^2],
            Abs[aa]/Sqrt[2*aa^2 + (bb + cc)^2]};
        nrm2 = {((bb - cc)*Abs[aa])/Sqrt[2*aa^4 + (bb + cc)^2*(bb^2 + cc^2) +
                  aa^2*(3*bb^2 + 2*bb*cc + 3*cc^2)], -(((aa^2 + cc*(bb + cc))*
                  Abs[aa])/(aa*Sqrt[2*aa^4 + (bb + cc)^2*(bb^2 + cc^2) +
                  aa^2*(3*bb^2 + 2*bb*cc + 3*cc^2)])), ((aa^2 +
                  bb*(bb + cc))*Abs[aa])/(aa*Sqrt[2*aa^4 + (bb + cc)^2*(bb^2 + cc^2) +
                  aa^2*(3*bb^2 + 2*bb*cc + 3*cc^2)])}
        ];

      (* la cabeza es un porcentaje 'hdsz' del segmento pt1 - pt2 *)

      hdsz  = porc;
      hdrad = Sqrt[((pt2 - (hdsz pt1 + (1 - hdsz)pt2)).(pt2 - (hdsz pt1 +
             (1 -hdsz)pt2)))]/5;

      circ1[ttt_] := hdrad  nrm1 Cos[ttt] +
                     hdrad  nrm2 Sin[ttt] + (hdsz pt1 + (1 - hdsz)pt2);
      circ2[ttt_] := (hdvec = pt2 + hdsz[[1]] (pt1 - pt2)/Norm[(pt1 - pt2)];
      hdrad nrm1 Cos[ttt] + hdrad nrm2 Sin[ttt] + hdvec);

      (* dx es número de lados del cono, Pi/nlds da 2nlds lados*)
      dx = Pi/nlds;

      pts = Partition[N[Table[circ1[t], {t, 0, 2 Pi, dx}]], 2, 1];

      (*Solo fin de Flecha*)
      arrowpolys =Map[{EdgeForm[], SurfaceColor[color],
                       Polygon[Flatten[{#, {pt2}}, 1]]} &, pts];

      Return[arrowpolys];);


Una vez que tenemos una función para graficar flechas 3D, podemos crear una función sencilla para los ejes 3D.

 


tira[str_] = StyleForm[str, FontSize -> 14];

Ejes3D[xmin_, xmax_, ymin_, ymax_, zmin_, zmax_] := {

      (*Flechas*)
      Flecha3D[{xmin, 0, 0}, {xmax, 0, 0}, 3, 0.08, GrayLevel[0]],
      Flecha3D[{0, ymin, 0}, {0, ymax, 0}, 3, 0.09, GrayLevel[0]],
      Flecha3D[{0, 0, zmin}, {0, 0, zmax}, 3, 0.09, GrayLevel[0]],
      (*Ejes*)
      GrayLevel[0],
      Line[{{xmin, 0, 0}, {xmax, 0, 0}, {0, 0, 0}, {0, ymin, 0}, {0, ymax,
            0}, {0, 0, 0}, {0, 0, zmin}, {0, 0, zmax}}],

      Text[tira["X"], {xmax, -0.3, 0}],
      Text[tira["Y"], {-0.3, ymax, 0.1}],
      Text[tira["Z"], {0, -0.2, zmax}],

      (* numeros *)
      Table[Text[tira[i], {i, -0.3, 0.1}], {i, 1, xmax - 1}],
      Table[Text[tira[i], {-0.3, i, 0.1}], {i, 1, ymax - 1}],
      Table[Text[tira[i], {-0.3, 0.1, i}], {i, 1, zmax - 1}],

      (* rayitas *)
      Table[Line[{{-0.1, i, 0}, {0, i, 0}}], {i, ymax - 1}],
       Table[Line[{{i, -0.1, 0}, {i, 0, 0}}], {i, xmax - 1}],
       Table[Line[{{0, -0.1, i}, {0, 0, i}}], {i, zmin, zmax - 1}]
      };


 


EJEMPLO

Como ejemplo, vamos a graficar un sistema de ejes y dos vectores. Usamos la función ve[pto1, pto2] para graficar el segmento de pto1 a pto2 como un vector.

Figura 7.
 
 

El código es

 


color=RGBColor[0, 0.50, 0];
ve[{a1_, a2_, a3_}, {b1_, b2_, b3_}] = {
                    RGBColor[0.50, 0, 1],
                        (*Grosor de la linea*)
                    AbsoluteThickness[2],
                        (*Linea de pto1 a pto2*)
                    Line[{{a1, a2, a3}, {b1, b2, b3}}],
                        (*cabeza de la flecha*)
                    Flecha3D[{a1, a2, a3}, {b1, b2, b3}, 3, 0.4,color]
                                        };

P = {0, 0, 0}; Q = {1, 0, -2}; R = {2, 0, 2};

g = Graphics3D[{
                Ejes3D[-1, 3, -1, 3, -1, 3],
                ve[P, Q],
                ve[P, R]
              }, Boxed -> False,
                 AmbientLight -> RGBColor[1, 1, 0],
                 ViewPoint -> {2.426, 2.190, 0.878}];
Show[g];



 

Nota:  Una versión de flecha 3D más sencilla, implementada por Tom Wickham-Jones, se muestra en el código siguiente

 


Options[Arrow3D] = {HeadLength -> 0.3, HeadNormal -> {0, 0, 1},HeadWidth -> 0.5};

Arrow3D[a_,b_,opts___]:=
    Module[{abLength=N[Sqrt[(b-a).(b-a)]],abUnit,headPerp,headPerpLength,
             headLength,headNormal, headWidth},

        {headLength,
        headNormal,
        headWidth}={HeadLength,HeadNormal,HeadWidth}/.{opts}/.Options[Arrow3D];


        abUnit=(b-a)/abLength;
        headPerp=Cross[abUnit,N[headNormal]];
        headPerp=headPerp/Sqrt[N[headPerp.headPerp]];
        {Line[{a,b-abUnit*headLength}],
        Polygon[{b,b-abUnit*headLength+headPerp*headWidth/2*headLength,
            b-abUnit*headLength,
            b-abUnit*headLength-headPerp*headWidth/2*headLength}]}];




Veamos un ejemplo

 


g = Graphics3D[{
                  Ejes3D[-1, 3, -1, 3, -1, 3],
                  Arrow3D[P, Q],
                  Arrow3D[P, R],
                  Arrow3D[{0, 0, 0}, {1, 1, 1}]
              }, Boxed -> False,
              ViewPoint -> {2.426, 2.190, 0.878}] //Show



 
Figura 8.


 


Revista digital Matemática, Educación e Internet.
Derechos Reservados