jueves, 24 de abril de 2008

flecha 3d con opciones

(* Estimados integrantes de MaTECmática http://matecmatica.blogspot.com/ *)

(* En la reunión de este jueves 24 de abril, les mostré a los que asistieron como ponerle “opciones” a programas hechos en Mathematica *)
(* como ejemplo modificamos el programa de la flecha3d para que, opcionalmente, el usuario pueda especificar que tan grande debe ser
la cabeza de la flecha y que tan gorda debe ser la flecha *)
(* A continuación el nuevo código que permite esas dos opciones: *)

(* Primero: Estas definiciones sólo son para que flecha3d tenga la misma sintaxis que el comando Arrow de Mathematica.
Observen el uso de los tres guiones bajos después de opciones, esos tres guiones indican que ese argumento es opcional *)

flecha3d[{x1_, y1_, z1_}, {dx_, dy_, dz_},opciones___] :=
flecha3d[{{x1, y1, z1}, {x1 + dx, y1 + dy, z1 + dz}},opciones];

flecha3d[{x1_, y1_, z1_}, d_,opciones___] :=
flecha3d[{{x1, y1, z1}, {x1 + d, y1 + d, z1 + d}},opciones];

(* Segundo: Proteger los nombres “cabeza” y “grosor” para que el usuario final No pueda modificarlos por accidente *)

Protect[cabeza, grosor];

(*Tercero: Especificar los valores “default” de cabeza y grosor *)

Options[flecha3d] = {cabeza -> 0.2, grosor -> 0.01};

(*Cuarto: El programa, modificado para usar las opciones que de el usuario, y si el usuario No especifica alguna de las opciones,
entonces se utiliza su valor “default”, que está guardado en Options[flecha3d]*)

flecha3d[{{x1_, y1_, z1_}, {x2_, y2_, z2_}}, opciones___] :=
Module[{vector, magnitud, normal, vectornormal, cruz, vectorbinormal, micabeza, migrosor},
micabeza = cabeza /. {opciones} /. Options[flecha3d];
migrosor = grosor /. {opciones} /. Options[flecha3d];
vector = {x2 - x1, y2 - y1, z2 - z1};
magnitud = Norm[vector];
normal = {0, z1 - z2, y2 - y1};
vectornormal = magnitud*normal/Norm[normal];
cruz = Cross[vector, vectornormal];
vectorbinormal = magnitud*cruz/Norm[cruz];
{Cylinder[{{x1, y1, z1}, {x1, y1, z1} + (1 - micabeza)*vector}, migrosor* magnitud],
Polygon[{{x1, y1, z1} + (1 - micabeza)* vector +
0.1 vectornormal, {x1, y1, z1} +
(1 - micabeza)* vector - 0.1 vectornormal, {x2, y2, z2}}],
Polygon[{{x1, y1, z1} + (1 - micabeza)*vector +
0.1 vectorbinormal, {x1, y1, z1} +
(1 - micabeza)* vector - 0.1 vectorbinormal, {x2, y2, z2}}]}];

(* Quinto: Ejemplos*)
(* Primero una flecha donde el usuario No especifica grosor Ni tamaño de cabeza.
Recuerden No ponerle punto y coma al siguiente comando para poder ver la gráfica*)

Graphics3D[
flecha3d[{{1.5, 0, 1}, {-2, -2, 2}}]
]

(*Ahora un ejemplo donde el usuario especifica el tamaño de la cabeza*)

Graphics3D[
flecha3d[{{1.5, 0, 1}, {-2, -2, 2}}, cabeza -> 0.5]
]

(*Ahora un ejemplo donde el usuario especifica el tamaño de la cabeza y el grosor*)

Graphics3D[
flecha3d[{{1.5, 0, 1}, {-2, -2, 2}}, grosor -> 0.05, cabeza -> 0.5]
]

(*Nos podemos divertir con un Manipulate: *)

Manipulate[
Graphics3D[
flecha3d[{{1.5, 0, 1}, {-2, -2, 2}}, grosor -> g, cabeza -> c]
],
{g,0.01,0.05},{c,0.1,0.5}]

(*¡Saludos!*)

No hay comentarios: