Parametrización para la rotación alrededor de una recta
Consideramos primero el problema de encontrar una matriz de rotación correspondiente a un giro de ángulo alrededor del vector unitario u. Este problema se puede resolver geometricamente
TEOREMA. Dado
y
u unitario entonces
es un giro de v de ángulo alrededor del vector u.
Demostración: ver [2] .
Implementación en MATHEMATICA
La implementación en MATHEMATICA requiere de dos ingredientes, la fórmula de rotación y un procedimiento para aplicar la fórmula a una imagen tridimensional de tipo Graphics3D[ ]. La idea es simple: navegamos en el objeto tridimensional buscando las primitivas con ``Head" Line, Polygon o Point y aplicamos la fórmula de rotación a la lista de puntos de cada primitiva. En el módulo (programa) ortonormalizamos u por si se le olvida al usuario.
Giro alrededor de un vector |
Rotar[objeto_,u_,phi_]:=Module[{A}, A=(#+Sin[phi]*Cross[u/Sqrt[u.u],#]+ 2(Sin[0.5*phi]^2)*Cross[u/Sqrt[u.u],Cross[u/Sqrt[u.u],#]])&; objeto /. {poly : Polygon[_] :> Map[A, poly, {2}], line : Line[_] :> Map[A, line, {2}], point : Point[_] :> Map[A, point, {1}]}]; |
Se puede usar la parametrización dada por el teorema anterior para rotar un
vector alrededor de una recta que no pasa necesariamente por el origen: primero
se traslada la recta hasta que pase por el origen, se hace la rotación y de
nuevo se traslada a la posición original.
TEOREMA. Sea
u un vector unitario. Consideremos la recta
L : Q + t u. Sea
Av una parametrización correspondiente a un giro de ángulo
alrededor del vector unitario
u, entonces
A(v - Q) + Q es una rotación de
v, de ángulo ,
alrededor de la recta L.
Implementación en Mathematica
Procedemos de manera análoga que en la sección anterior
RotarLin[objeto_, Q_, u_, phi_] := Module[{A}, A=((#-Q)+Sin[phi]*Cross[u/Sqrt[u.u],(# - Q)]+ 2(Sin[0.5*phi]^2)*Cross[u/Sqrt[u.u],Cross[u/Sqrt[u.u],(# - Q)]] + Q)&; objeto /. {poly : Polygon[_] :> Map[A, poly, {2}], line : Line[_] :> Map[A, line, {2}], point : Point[_] :> Map[A, point, {1}]}];
En MATHEMATICA, un dodecaedro es una lista
de 12 polígonos {Polygon[{...}],...,Polygon[{...}]}. Cada
comando Polygon[{V1,...,V5}] contiene los 5 vértices de la
cara correspondiente. Para hacer una rotación de una cara del dodecaedro,
fijamos un vértice (digamos V1) y tomamos el punto medio del lado
opuesto al vértice. La recta que une estos puntos será el eje de giro.
Luego usamos el comando RotarLin[] definido anteriormente. El código
de la animación sería el siguiente |
|
<< Graphics`Polyhedra` Clear[d, cara, u, Q]; d = Dodecahedron[]; cara = Graphics3D[{ d[[1]] }]; u = d[[1,1,1]]-(d[[1,1,3]]+d[[1,1,4]])/2; Q = d[[1, 1, 1]]; dode = Graphics3D[{ Drop[d, {1}] }]; RotarLin[ob_,Q_,u_,phi_]:=Module[{A},...]; Do[ Show[{dode, RotarLin[ cara, Q, u, t ]}, PlotRange->{{-1.5,1.5},{-1.5,1.5},{-1.5,1.5}}, AspectRatio -> Automatic, ViewPoint -> {0.031, 0.032, 3.383}, Boxed -> False, Axes -> False] , {t, 0, 2Pi, 0.2}] |
A esta animación se le aplicaron efectos especiales en Microsoft Image Composer, aquí mismo se generó la animación "gif" para el Web con GifAnimator.
Parametrización de un círculo en un plano
El último teorema nos dice también, cómo parametrizar un circunferencia en un plano: consideremos el plano : [(x, y, z) - Oc] . n = 0 y la circunferencia C, sobre el plano , de centro Oc y radio || Oc - P||, P C. Una parametrización de C es AP - Oc + Oc.
Considere el triángulo con vértices
A = (- 1, 1,), B
= (1, 1, - ),
y C = (0, 0,) Para parametrizar la circunferencia, tomamos como centro el incentro Ic; el radio es || Ic - P|| donde P=Proy(A - B)(Ic-B), P es el punto de tangencia del círculo con un lado del tríangulo. Parte del código para desplegar la figura es
|
triangulo=Graphics3D[{...}]; Clear[A]; u=Cross[{-1,1,0},{1,1,-1}]; A[v_,Q_,u_,phi_]:=(v-Q)+Sin[phi]*Cross[u/Sqrt[u.u],(v-Q)]+ 2(Sin[0.5*phi]^2)*Cross[u/Sqrt[u.u],Cross[u/Sqrt[u.u],(v-Q)]]+Q; circunferencia= ParametricPlot3D[Evaluate[A[P,Ic,u,phi] /. phi->t] ,{t,0,2Pi},DisplayFunction->Identity]; Show[{triangulo, circunferencia}, Boxed->False, Axes->False, ViewPoint->{0.405,2.768,1.904}, DisplayFunction->$DisplayFunction];
|