-
Notifications
You must be signed in to change notification settings - Fork 2
/
Superficies4.py
171 lines (141 loc) · 5.92 KB
/
Superficies4.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# -*- coding: utf-8 -*-
from PyQt4 import QtGui
from pivy.coin import *
from math import *
from superficie.nodes import BasePlane, Curve3D
from superficie.nodes.arrow import Arrow
from superficie.book import Chapter, Page
from superficie.plots import ParametricPlot3D, Plot3D, RevolutionPlot3D
from superficie.widgets import Slider
from superficie.util import _1, connect, Vec3, main
from superficie.animations import Animation
class Helicoide(Page):
u"""
En este cuadro generamos una sección de una helicoide como superficie
reglada y luego pegamos los dos segmentos rectilíneos de los bordes
obteniendo una cateoide. Las medidas y la curvatura gaussiana no se
alteran en ningún estado del proceso, son superficies localmente
isométricas, aunque una es reglada pero no es una superficie de
revolución, cualidad que sí tiene la segunda.
<p>
Superficies:
<ul>
<li>Helicoide: <b>(v cos u, v sen u, au)</b> con <b>0≤u≤2π, v∈ℜ</b></li>
<li>Catenoide: <b>(a cosh v cos u, a cosh v sen u, av)</b> con <b>0≤u≤2π, v∈ℜ</b></li>
</ul>
"""
def __init__(self):
super(Helicoide, self).__init__(u"Isometría local entre una helicoide y una catenoide")
self.camera_position = (8.2, 8.2, 8.2)
self.camera_viewAll = False
def param(u, v, t):
x = cos(t) * sinh(v) * sin(u) + sin(t) * cosh(v) * cos(u)
y = -cos(t) * sinh(v) * cos(u) + sin(t) * cosh(v) * sin(u)
z = u * cos(t) + v * sin(t)
return x,y,z
helic1 = ParametricPlot3D(param, (-pi, pi, 60), (-2, 2))
ht = helic1.getParameter('t')
ht.timeline.setDuration(3000)
ht.updateRange((0,pi/2,0))
helic1.setVerticesPerColumn(2)
helic1.setAmbientColor(_1(202, 78, 70))
helic1.setDiffuseColor(_1(202, 78, 70))
helic1.setSpecularColor(_1(202, 78, 70))
s = Slider(
rangep=('z', 2, 60, 2, 59),
func=helic1.setVerticesPerColumn,
duration=3000,
parent=self
)
self.addChild(helic1)
params = [s,ht]
## no queremos los controles
for p in params:
p.hide()
anims = [p.asAnimation() for p in params]
self.setupAnimations(anims)
class Catenoide(Page):
u"""
Como lo muestra la interacción, la catenoide es la superficie de
revolución generada por la catenaria; cuando se corta a lo largo de una
de ellas puede llevarse, con sólo convertir en rectas los meridianos,
en parte de una helicoide.
<p>
Superficies:
<ul>
<li>Helicoide: <b>(v cos u, v sen u, au)</b> con <b>0≤u≤2π, v∈ℜ</b></li>
<li>Catenoide: <b>(a cosh v cos u, a cosh v sen u, av)</b> con <b>0≤u≤2π, v∈ℜ</b></li> </ul>
"""
def __init__(self):
super(Catenoide,self).__init__(u"Cortamos una catenoide para obtener parte de una helicoide")
self.camera_position = (8.2, 8.2, 8.2)
self.camera_viewAll = False
def param(u, v, t):
t2 = pi/2 - t
x = cos(t2) * sinh(v) * sin(u) + sin(t2) * cosh(v) * cos(u)
y = -cos(t2) * sinh(v) * cos(u) + sin(t2) * cosh(v) * sin(u)
z = u * cos(t2) + v * sin(t2)
return x,y,z
cat = ParametricPlot3D(param, (-pi, pi, 60), (-2, 2))
ht = cat.getParameter('t')
ht.timeline.setDuration(3000)
ht.updateRange((0,pi/2,0))
cat.setVerticesPerColumn(2)
cat.setAmbientColor(_1(4, 73, 143))
cat.setDiffuseColor(_1(4, 73, 143))
cat.setSpecularColor(_1(4, 73, 143))
s = Slider(
rangep=('z', 2, 60, 2, 59),
func=cat.setVerticesPerColumn,
duration=3000,
parent=self
)
self.addChild(cat)
params = [s,ht]
## no queremos los controles
for p in params:
p.hide()
anims = [p.asAnimation() for p in params]
self.setupAnimations(anims)
class Mobius(Page):
u"""
Una superficie es <b>orientable</b> si puede subdividirse en
“triángulos” que la cubren sin traslaparse y cortándose sólo en vértices
o en aristas completas, y todos estos “triángulos” tienen la misma orientación.
Entonces es posible recorrer cualquier curva
cerrada en la superficie con un vector normal que al terminar tiene la
posición original.
<p>
Pero en el círculo central de una Banda de Möbius, obtenida al pegar
los bordes de una tira después de dar media vuelta a uno de ellos,
un vector normal termina su recorrido en sentido opuesto como lo
muestra la interacción.
"""
def __init__(self):
super(Mobius,self).__init__(u"No orientabilidad de la Banda de Möbius")
# self.camera_position = (3.0, 2.8, 2.8)
def par(u,v):
return cos(u) + v*cos(u/2)*cos(u), sin(u) + v*cos(u/2)*sin(u), v*sin(u/2)
mobius = ParametricPlot3D(par, (-pi, pi, 60), (-.5, .5, 14))
mobius.setTransparency(0.5)
def curva(t): return par(t,0)
def puntos(u): return Vec3(cos(u)*sin(u/2.0), sin(u/2.0)*sin(u),-cos(u/2.0))
cm = Curve3D(curva, (-pi, pi, 200), color=_1(255, 255, 255), width=3)
aceleracion_cm = cm.attachField("aceleracion", puntos).setLengthFactor(1).setWidthFactor(.5)
aceleracion_cm.animation.setDuration(12000)
self.addChild(mobius)
self.addChild(cm)
self.addChild( Arrow( (-1,0,0), (0,0,0), 0.02 ) )
self.setupAnimations([aceleracion_cm])
class Superficies4(Chapter):
def __init__(self):
super(Superficies4,self).__init__(u"Isometría y orientación de superficies")
figuras = [
Helicoide,
Catenoide,
Mobius,
]
for f in figuras:
self.addPage(f())
if __name__ == "__main__":
visor = main(Superficies4)