def __init__(self): Page.__init__(self, u"Elipsoide<br><br>x<sup>2</sup>/a<sup>2</sup> + y<sup>2</sup>/b<sup>2</sup> + z<sup>2</sup>/c<sup>2</sup> = 1") param = lambda u,v: (cos(u)*cos(v), 1.5*cos(v)*sin(u), 2*sin(v)) elipsoide = ParametricPlot3D(param, (-pi, pi), (-pi/2,pi/2)) col = _1(84,129,121) elipsoide.setAmbientColor(col).setDiffuseColor(col).setSpecularColor(col) par1 = lambda u,v: Vec3(-sin(u)*cos(v), 1.5*cos(u)*cos(v), 0) par2 = lambda u,v: Vec3(-cos(u)*sin(v), -1.5*sin(u)*sin(v), 2*cos(v)) tp = TangentPlane2(param,par1,par2,(0,0),_1(252,250,225)) self.addChild(elipsoide) self.addChild(tp) Slider(rangep=('u', -pi,pi,0,20),func=tp.setU, duration=8000, parent=self) Slider(rangep=('v', -pi/2,pi/2,0,20),func=tp.setV, duration=8000, parent=self)
def __init__(self): Page.__init__(self, u"Cilindro<br><br>x<sup>2</sup>/a<sup>2</sup> + y<sup>2</sup>/b<sup>2</sup> = 1") param = lambda u,t: Vec3(cos(u),sin(u),t) cilindro = ParametricPlot3D(param, (0, 2*pi), (-1,1)) col = _1(177,89,77) cilindro.setAmbientColor(col).setDiffuseColor(col).setSpecularColor(col) def par1(u,t): return Vec3(-sin(u),cos(u),0) def par2(u,t): return Vec3(0,0,1) tp = TangentPlane2(param,par1,par2,(0,0),_1(252,250,225)) tp.localOriginSphere.hide() tp.localYAxis.setColor(col).setWidth(2).show() Slider(rangep=('u', 0,2*pi,0,20),func=tp.setU, duration=8000, parent=self) Slider(rangep=('t', -1,1,0,20),func=tp.setV, duration=4000, parent=self) self.addChild(cilindro) self.addChild(tp)
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)
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)
def addParameter(self, rangep=('w', 0, 1, 0), qlabel=None): """ @param rangep: (name, vmin, vmax, vini) | (name, vmin, vmax) """ if len(rangep) == 3: rangep += rangep[1:2] sliderNpoints = 20 rangep += (sliderNpoints,) ## ============================ slider = Slider(rangep=rangep, func=self.updateAll) self.addWidget(slider) self.parameters[slider.name] = slider ## ============================ if qlabel is not None: if not (type(qlabel) == list or type(qlabel) == tuple): qlabel = [qlabel] slider.qlabel = qlabel for lab in qlabel: conecta(slider, QtCore.SIGNAL("labelChanged(float)"), lab.setParamValue) ## ============================ return slider
def addParameter(self, rangep=('w', 0, 1, 0), qlabel=None): """ @param rangep: (name, vmin, vmax, vini) | (name, vmin, vmax) """ if len(rangep) == 3: rangep += rangep[1:2] sliderNpoints = 20 rangep += (sliderNpoints, ) ## ============================ slider = Slider(rangep=rangep, func=self.updateAll) self.addWidget(slider) self.parameters[slider.name] = slider ## ============================ if qlabel is not None: if not (type(qlabel) == list or type(qlabel) == tuple): qlabel = [qlabel] slider.qlabel = qlabel for lab in qlabel: conecta(slider, QtCore.SIGNAL("labelChanged(float)"), lab.setParamValue) ## ============================ return slider
def __init__(self): Page.__init__(self, u"Campo de Morse sobre el toro") def coreTorusAt(p): dyz = sqrt(p[1]**2 + p[2]**2) return Vec3(0.0, a * p[1] / dyz, a * p[2] / dyz) def unitNormalToTorusAt(p): core = coreTorusAt(p) p_core = p - core dp_core = p_core.length() return p_core / dp_core def projAtTorus(p): core = coreTorusAt(p) p_core = p - core factor = 1.01 * b / p_core.length( ) #un poco más de 1 para que se vea mejor... return core + factor * p_core def valMorseFieldAt(p): n = unitNormalToTorusAt(p) gdotn = -g * n[2] return Vec3(gdotn * n[0], gdotn * n[1], g + gdotn * n[2]) def nextPoint(p, dt): return projAtTorus(p + dt * valMorseFieldAt(p)) class CurveVectorField: def __init__(self, c): self.curve = c def basePoint(self, t): return self.curve[int(t)] def endPoint(self, t): return self.curve[int(t)] + valMorseFieldAt(self.curve[int(t)]) curves = [] vectorial_fields_curves = [] vectorial_fields_curves_bk = [] dtheta = 2.0 * pi / 20.0 for nrot in range(0, 20): points_down_curve = [] points_up_curve = [] q = Vec3(b * cos(nrot * dtheta), a + b * sin(nrot * dtheta), 0.0) # calculo empezando enmedio del toro for n in range(0, 100): p = projAtTorus(q) v = valMorseFieldAt(p) if v.length() < 0.01: break points_down_curve.append(p) points_up_curve.append(Vec3(p[0], p[1], -p[2])) q = nextPoint(p, 0.05) points_down_curve.reverse() # recorrer de arriba a enmedio points_down_curve.pop( ) # quitar los puntos de enmedio, repetidos en las listas points_down_curve.extend(points_up_curve) # unir listas points_down_curve.reverse() curve = Line(points_down_curve, width=2.5) curves.append(curve) cvf = CurveVectorField(curve) vectorial_fields_curves_bk.append(cvf) arrow = AnimatedArrow(cvf.basePoint, cvf.endPoint) arrow.setDiffuseColor(_1(220, 40, 20)) arrow.setWidthFactor(0.25) arrow.add_tail(0.025) vectorial_fields_curves.append(arrow) # la otra mitad del toro... reflejando por el eje Z points_reflected_curve = [] for p in points_down_curve: points_reflected_curve.append(Vec3(-p[0], -p[1], p[2])) curveR = Line(points_reflected_curve, width=2.5) curves.append(curveR) cvf = CurveVectorField(curveR) vectorial_fields_curves_bk.append(cvf) arrow = AnimatedArrow(cvf.basePoint, cvf.endPoint) arrow.setDiffuseColor(_1(220, 40, 20)) arrow.setWidthFactor(0.25) arrow.add_tail(0.025) vectorial_fields_curves.append(arrow) # paralelos hasta arriba points_curve1 = [] q = Vec3(0.25, 0.0, a + b) for n in range(0, 100): p = projAtTorus(q) v = valMorseFieldAt(p) if v.length() < 0.01: break points_curve1.append(p) q = nextPoint(p, 0.05) curve1 = Line(points_curve1, width=2.5) curves.append(curve1) cvf = CurveVectorField(curve1) vectorial_fields_curves_bk.append(cvf) arrow = AnimatedArrow(cvf.basePoint, cvf.endPoint) arrow.setDiffuseColor(_1(220, 40, 20)) arrow.setWidthFactor(0.25) arrow.add_tail(0.025) vectorial_fields_curves.append(arrow) points_curve2 = [] q = Vec3(-0.25, 0.0, a + b) for n in range(0, 100): p = projAtTorus(q) v = valMorseFieldAt(p) if v.length() < 0.01: break points_curve2.append(p) q = nextPoint(p, 0.05) curve2 = Line(points_curve2, width=2.5) curves.append(curve2) cvf = CurveVectorField(curve2) vectorial_fields_curves_bk.append(cvf) arrow = AnimatedArrow(cvf.basePoint, cvf.endPoint) arrow.setDiffuseColor(_1(220, 40, 20)) arrow.setWidthFactor(0.25) arrow.add_tail(0.025) vectorial_fields_curves.append(arrow) self.addChildren(curves) self.addChildren(vectorial_fields_curves) def setSyncParam(t): for i in range(0, len(vectorial_fields_curves)): curve = curves[i] if t < len(curve.getPoints()): vec_field = vectorial_fields_curves[i] #vec_field.animateArrow(int(t)) vec_field.animateArrow(t) Slider(rangep=('t', 0, 198, 1, 199), func=setSyncParam, duration=16000, parent=self) # T(u,v) def toroParam1(u, v): return (b * sin(u), (a + b * cos(u)) * cos(v), (a + b * cos(u)) * sin(v)) def toroParam(u, v): return Vec3(b * sin(u), (a + b * cos(u)) * cos(v), (a + b * cos(u)) * sin(v)) paratoro = ParametricPlot3D(toroParam1, (0, 2 * pi, 150), (0, 2 * pi, 100)) paratoro.setTransparency(0.25) paratoro.setTransparencyType( SoTransparencyType.SORTED_OBJECT_SORTED_TRIANGLE_BLEND) paratoro.setDiffuseColor(_1(68, 28, 119)) self.addChild(paratoro) critic1 = Sphere(center=Vec3(0, 0, a + b), radius=0.075, color=_1(240, 10, 20)) critic2 = Sphere(center=Vec3(0, 0, a - b), radius=0.075, color=_1(240, 10, 20)) critic3 = Sphere(center=Vec3(0, 0, -a + b), radius=0.075, color=_1(240, 10, 20)) critic4 = Sphere(center=Vec3(0, 0, -a - b), radius=0.075, color=_1(240, 10, 20)) self.addChild(critic1) self.addChild(critic2) self.addChild(critic3) self.addChild(critic4)
def __init__(self): Page.__init__( self, u"Construcción de un vector del campo de Morse sobre el toro") def coreTorusAt(p): dyz = sqrt(p[1]**2 + p[2]**2) return Vec3(0.0, a * p[1] / dyz, a * p[2] / dyz) def unitNormalToTorusAt(p): core = coreTorusAt(p) p_core = p - core dp_core = p_core.length() return p_core / dp_core def projAtTorus(p): core = coreTorusAt(p) p_core = p - core factor = 1.005 * b / p_core.length( ) #un poco más de 1 para que se vea mejor... return core + factor * p_core def valMorseFieldAt(p): n = unitNormalToTorusAt(p) gdotn = -g * n[2] return Vec3(gdotn * n[0], gdotn * n[1], g + gdotn * n[2]) def nextPoint(p, dt): return projAtTorus(p + dt * valMorseFieldAt(p)) class CurveVectorField: def __init__(self, c): self.curve = c def basePoint(self, t): return self.curve[int(t)] def endPoint(self, t): return self.curve[int(t)] + valMorseFieldAt(self.curve[int(t)]) class CurveNormalField: def __init__(self, c): self.curve = c def basePoint(self, t): return self.curve[int(t)] def endPoint(self, t): return self.curve[int(t)] + unitNormalToTorusAt( self.curve[int(t)]) class CurveGravityField: def __init__(self, c): self.curve = c def basePoint(self, t): return self.curve[int(t)] def endPoint(self, t): return self.curve[int(t)] + Vec3(0, 0, g) curves = [] vectorial_fields_curves = [] vectorial_fields_curves_bk = [] dtheta = pi / 10.0 nrot = -4 points_down_curve = [] points_up_curve = [] q = Vec3(b * cos(nrot * dtheta), a + b * sin(nrot * dtheta), 0.0) # calculo empezando enmedio del toro for n in range(0, 100): p = projAtTorus(q) v = valMorseFieldAt(p) if v.length() < 0.01: break points_down_curve.append(p) points_up_curve.append(Vec3(p[0], p[1], -p[2])) q = nextPoint(p, 0.05) #Tangent Plane p = projAtTorus(q) p[2] = -p[2] v = valMorseFieldAt(p) u = v.cross(unitNormalToTorusAt(p)) tangent_plane = Plane(_1(200, 200, 200), p, v + p, u + p) points_down_curve.reverse() # recorrer de arriba a enmedio points_down_curve.pop( ) # quitar los puntos de enmedio, repetidos en las listas points_down_curve.extend(points_up_curve) # unir listas points_down_curve.reverse() curve = Line(points_down_curve, width=2.5) curves.append(curve) cvf = CurveVectorField(curve) vectorial_fields_curves_bk.append(cvf) arrow = AnimatedArrow(cvf.basePoint, cvf.endPoint) arrow.setDiffuseColor(_1(220, 40, 200)) arrow.setWidthFactor(0.48) arrow.add_tail(0.025) vectorial_fields_curves.append(arrow) cnf = CurveNormalField(curve) vectorial_fields_curves_bk.append(cnf) arrown = AnimatedArrow(cnf.basePoint, cnf.endPoint) arrown.setDiffuseColor(_1(220, 240, 20)) arrown.setWidthFactor(0.4) #arrown.add_tail( 0.025 ) vectorial_fields_curves.append(arrown) cgf = CurveGravityField(curve) vectorial_fields_curves_bk.append(cgf) arrowg = AnimatedArrow(cgf.basePoint, cgf.endPoint) arrowg.setDiffuseColor(_1(10, 240, 20)) arrowg.setWidthFactor(0.4) #arrowg.add_tail( 0.025 ) vectorial_fields_curves.append(arrowg) self.addChildren(curves) self.addChildren(vectorial_fields_curves) self.addChild(tangent_plane) def setSyncParam(t): for i in range(0, len(vectorial_fields_curves)): #curve = curves[i] if t < len(curves[0].getPoints()): vec_field = vectorial_fields_curves[i] vec_field.animateArrow(t) q = (curves[0])[int(t)] p = projAtTorus(q) v = valMorseFieldAt(p) u = v.cross(unitNormalToTorusAt(p)) tangent_plane.setPoints(p, v + p, u + p) Slider(rangep=('t', 0, 198, 1, 199), func=setSyncParam, duration=8000, parent=self) # T(u,v) def toroParam1(u, v): return (b * sin(u), (a + b * cos(u)) * cos(v), (a + b * cos(u)) * sin(v)) def toroParam(u, v): return Vec3(b * sin(u), (a + b * cos(u)) * cos(v), (a + b * cos(u)) * sin(v)) paratoro = ParametricPlot3D(toroParam1, (0, 2 * pi, 150), (0, 2 * pi, 100)) paratoro.setTransparency(0.25) paratoro.setTransparencyType( SoTransparencyType.SORTED_OBJECT_SORTED_TRIANGLE_BLEND) paratoro.setTransparencyType(SoTransparencyType.SCREEN_DOOR) paratoro.setDiffuseColor(_1(68, 28, 119)) self.addChild(paratoro)
def __init__(self): Page.__init__(self, u"Campo de Morse sobre el toro") a = 2.0 b = 1.0 g = -1.25 # T(u,v) def toroParam1(u, v): return (b * sin(u), (a + b * cos(u)) * cos(v), (a + b * cos(u)) * sin(v)) def toroNormal(u, v): coef = b * (a + b * cos(u)) return Vec3(coef * sin(u), coef * cos(u) * cos(v), coef * cos(u) * sin(v)) def toroMorse(u, v): #coef = -b * ( a + b * cos(u) ) coef2 = -g * cos(u) * sin(v) return Vec3(coef2 * sin(u), coef2 * cos(u) * cos(v), g + coef2 * cos(u) * sin(v)) paratoro = ParametricPlot3D(toroParam1, (0, 2 * pi, 150), (0, 2 * pi, 100)) paratoro.setTransparency(0.25) paratoro.setTransparencyType( SoTransparencyType.SORTED_OBJECT_SORTED_TRIANGLE_BLEND) paratoro.setDiffuseColor(_1(68, 28, 119)) self.addChild(paratoro) def make_curva(c): return lambda t: toroParam1(c, t) def make_curva2(c): return lambda t: toroParam1(c, -t) def make_tang(c): return lambda t: toroMorse(c, t) def make_tang2(c): return lambda t: toroMorse(c, -t) tangentes = [] tangentes2 = [] ncurves = 12 for c in range(0, ncurves + 1): ## -1 < ct < 1 ct = c / float(ncurves) * 2 * pi #curva = Curve3D(make_curva(ct),(-pi/2,pi/2,100), width=0.5) curva = Curve3D(make_curva(ct), (pi / 2, 3 * pi / 2, 100), width=0.5) curva.attachField( "tangente", make_tang(ct)).setLengthFactor(1).setWidthFactor(.5) curva.fields['tangente'].show() tangentes.append(curva.fields['tangente']) ### ct2 = c / float(ncurves) * 2 * pi #curva2 = Curve3D(make_curva2(ct2),(pi/2,3*pi/2,100), width=0.5) curva2 = Curve3D(make_curva2(ct2), (-pi / 2, pi / 2, 100), width=0.5) curva2.attachField( "tangente", make_tang2(ct2)).setLengthFactor(1).setWidthFactor(.5) curva2.fields['tangente'].show() tangentes2.append(curva2.fields['tangente']) self.addChild(curva) self.addChild(curva2) def animaTangentes(n): for tang in tangentes + tangentes2: tang.animateArrow(int(n)) a1 = Animation(animaTangentes, (6000, 0, 99), times=1) self.setupAnimations([a1]) Slider(rangep=('u', 0, 99, 0, 100), func=animaTangentes, parent=self)
def __init__(self): """x^2 - y^2 - z = 0""" Page.__init__(self, u"Paraboloide hiperbólico<br><br>x<sup>2</sup>/a<sup>2</sup> - y<sup>2</sup>/b<sup>2</sup> = z") z = 1.5 def fn(x, y): return x ** 2 - y ** 2 + z def polar(function): def polar_fn(r, t): x = r * cos(t) y = r * sin(t) return x, y, function(x, y) return polar_fn paraboloid = ParametricPlot3D(polar(fn), (.001, 1, 20), (0, 2 * pi, 60)) paraboloid. \ setAmbientColor(_1(145, 61, 74)). \ setDiffuseColor(_1(127, 119, 20)). \ setSpecularColor(_1(145, 61, 74)) base_plane = BasePlane() base_plane.setHeight(0) base_plane.setRange((-2, 2, 7)) ## the hiperbolic paraboloid in parametric form def fn_par(x,y): return Vec3(x, y, x ** 2 - y ** 2 + z) ## its derivatives def fn_x(x,y): return Vec3(1, 0, 2 * x) def fn_y(x,y): return Vec3(0, 1, -2 * y) tangent_plane = TangentPlane2(fn_par, fn_x, fn_y, (0, 0), _1(252, 250, 225)) tangent_plane.setRange((-1.2, 1.2, 7)) self.addChild(paraboloid) self.addChild(base_plane) self.addChild(tangent_plane) def spiral(t): c = t / (2 * pi) t2 = t * 2 return c * cos(t2), c * sin(t2) animate_points = 200 def animate_plane(n): tangent_plane.setLocalOrigin(spiral(2 * pi * n / float(animate_points))) def animate_plane_2(t): tangent_plane.setLocalOrigin(spiral(t)) a1 = Animation(animate_plane, (10000, 0, animate_points)) Slider(('t', 0, 2 * pi, 0, animate_points), animate_plane_2, duration=10000, parent=self) self.setupAnimations([a1])
def __init__(self, parent=None): Page.__init__(self, u"Paralelos y círculos máximos de la esfera") self.showAxis(False) pmin = 0 pmax = 2 * pi r2 = 3. l = -1 def puntos2(t): return Vec3(-cos(t), -sin(t), 0) def make_circulo(t): return partial(par_esfera, t) par_esfera = lambda t, f: Vec3( sin(t) * cos(f), sin(t) * sin(f), cos(t)) par_circulo = lambda f: Vec3(sin(t) * cos(f), sin(t) * sin(f), cos(t)) par_circulo_der = lambda f: Vec3(-cos(f) * sin(t), -sin(t) * sin(f), 0) par_circulo_maximo = make_circulo(pi / 2) esf = ParametricPlot3D(par_esfera, (0, pi, 100), (0, 2 * pi, 120)) esf.setTransparencyType( SoTransparencyType.SORTED_OBJECT_SORTED_TRIANGLE_BLEND) esf.setTransparency(0.3).setDiffuseColor(_1(68, 28, 119)).setSpecularColor( _1(99, 136, 63)) VisibleCheckBox("esfera", esf, True, parent=self) self.addChild(esf) cm = Curve3D(par_circulo_maximo, (pmin, pmax, 200), color=_1(255, 255, 255)) self.addChild(cm) aceleracion_cm = cm.attachField( "aceleracion", puntos2).show().setLengthFactor(.98).setWidthFactor(.3) tini = 1.0472 par_circulo.func_globals['t'] = tini par = Curve3D(par_circulo, (pmin, pmax, 200), color=_1(255, 221, 0)) self.addChild(par) aceleracion_par = par.attachField( "aceleracion", par_circulo_der).show().setLengthFactor(1).setWidthFactor(.3) circle_2 = SimpleSphere(Vec3(0, 0, cos(tini)), radius=.02) circle_2_tr = circle_2.getByName("Translation") self.addChild(circle_2) self.addChild(SimpleSphere(Vec3(0, 0, 0), radius=.02)) ## los meridianos sep = SoSeparator() mer = Curve3D(lambda t: (0, .99 * cos(t), .99 * sin(t)), (pmin, pmax, 100), color=_1(18, 78, 169)) for i in range(24): sep.addChild(rot(2 * pi / 24)) sep.addChild(mer.root) self.addChild(sep) # the sphere rotation axis self.addChild(Line([(0, 0, -1.2), (0, 0, 1.2)], width=2)) def test(t): par_circulo.func_globals['t'] = t par.updatePoints() circle_2_tr.translation = (0, 0, cos(t)) Slider(('t', 0.1, pi - .1, tini, 100), test, duration=4000, parent=self) self.setupAnimations([aceleracion_cm, aceleracion_par])