Esempio n. 1
0
 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)
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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)
Esempio n. 5
0
 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
Esempio n. 6
0
 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
Esempio n. 7
0
    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)
Esempio n. 8
0
    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)
Esempio n. 9
0
    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)
Esempio n. 10
0
    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])
Esempio n. 11
0
    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])