def __init__(self): PlanePage.__init__(self, 'Tangent') n_points = 100 delta = .2 # The curve fragments intervals = [ (-pi, -pi / 2 - delta, n_points), (-pi / 2 + delta, pi / 2 - delta, n_points), (pi / 2 + delta, pi, n_points) ] # because intervals is a list of ranges, Curve3D will be a composite of curves curve = Curve3D(lambda t: Vec3(t, tan(t), 0), intervals, width=2).setBoundingBox((-5, 5), (-5, 5)) # add the curve to this page self.addChild(curve) ## asymptotes self.addChild(Line([(-pi / 2, -5, 0), (-pi / 2, 5, 0)], color=(1, .5, .5))) self.addChild(Line([(pi / 2, -5, 0), (pi / 2, 5, 0)], color=(1, .5, .5))) # curve.attachField will create an arrow starting at the curve and ending in the vector given by derivative tangent_vector = curve.attachField("tangent", lambda t: Vec3(1, 1 / cos(t) ** 2, 0)) # by default the arrow doesn't have a tail tangent_vector.add_tail(radius=0.08) # set up the default animations for this page (just the animation for the tangent_vector object in this case) self.setupAnimations([tangent_vector])
class Plane(BaseObject): """A plane that contains the points: origin, p1, p2 """ def __init__(self, color, origin, p1, p2): BaseObject.__init__(self) self.range = (-1, 1, 10) self.base_plane = BasePlane() self.base_plane.setDiffuseColor(color) self.base_plane.setEmissiveColor(color) self.separator.addChild(self.base_plane.root) # local axis self.localXAxis = Line([], color=(1, 0, 0)) self.localYAxis = Line([], color=(1, 0, 0)) self.separator.addChild(self.localXAxis.root) self.separator.addChild(self.localYAxis.root) # calculate the points self.setPoints(origin, p1, p2) def setPoints(self, origin, vector1, vector2): v1 = (vector1 - origin) v2 = (vector2 - origin) ## the plane generated by {v1, v2} def plane(h, t): return Vec3(origin) + h * v1 + t * v2 self.base_plane.setRange(self.range, plane=plane) ## lines along the generators t_min, t_max, n = self.range self.localXAxis.setPoints([plane(*pt) for pt in [(t_min, 0), (t_max, 0)]]) self.localYAxis.setPoints([plane(*pt) for pt in [(0, t_min), (0, t_max)]])
class Plane(BaseObject): """A plane that contains the points: origin, p1, p2 """ def __init__(self, color, origin, p1, p2): BaseObject.__init__(self) self.range = (-1, 1, 10) self.base_plane = BasePlane() self.base_plane.setDiffuseColor(color) self.base_plane.setEmissiveColor(color) self.separator.addChild(self.base_plane.root) # local axis self.localXAxis = Line([], color=(1, 0, 0)) self.localYAxis = Line([], color=(1, 0, 0)) self.separator.addChild(self.localXAxis.root) self.separator.addChild(self.localYAxis.root) # calculate the points self.setPoints(origin, p1, p2) def setPoints(self, origin, vector1, vector2): v1 = (vector1 - origin) v2 = (vector2 - origin) ## the plane generated by {v1, v2} def plane(h, t): return Vec3(origin) + h * v1 + t * v2 self.base_plane.setRange(self.range, plane=plane) ## lines along the generators t_min, t_max, n = self.range self.localXAxis.setPoints( [plane(*pt) for pt in [(t_min, 0), (t_max, 0)]]) self.localYAxis.setPoints( [plane(*pt) for pt in [(0, t_min), (0, t_max)]])
def test_sum(self): points = [p1, p2, p3, p4] = [(0, 0, 0), (1, 1, 1), (-1, 2, 0), (-1, -1, 1)] line1 = Line([p1, p2]) line2 = Line([p3, p4]) line = line1 + line2 self.assertEqual(len(line), 4) self.assertEqual(tuple(line[0]), p1) self.assertEqual(tuple(line[3]), p4) self.assertEqual(line.numVerticesPerSegment, [2, 2])
def test_Line(self): points = [p1,p2,p3,p4] = [(0,0,0),(1,1,1),(-1,2,0),(-1,-1,1)] line = Line([p1,p2,p3,p4]) self.assertEqual(tuple(line[0]), p1) self.assertEqual(tuple(line[3]), p4) self.assertEqual(map(tuple,line.points), points) self.assertEqual(len(line), len(points)) line.setPoints([p2,p3]) self.assertEqual(tuple(line[0]), p2) self.assertEqual(tuple(line[1]), p3) self.assertEqual(len(line), 2) self.assertEqual(map(tuple,line.points), [p2,p3])
def test_Line(self): points = [p1, p2, p3, p4] = [(0, 0, 0), (1, 1, 1), (-1, 2, 0), (-1, -1, 1)] line = Line([p1, p2, p3, p4]) self.assertEqual(tuple(line[0]), p1) self.assertEqual(tuple(line[3]), p4) self.assertEqual(map(tuple, line.points), points) self.assertEqual(len(line), len(points)) line.setPoints([p2, p3]) self.assertEqual(tuple(line[0]), p2) self.assertEqual(tuple(line[1]), p3) self.assertEqual(len(line), 2) self.assertEqual(map(tuple, line.points), [p2, p3])
def __init__(self): Page.__init__( self, u"Hélice circular reflejada<br><br>(cos s/√2, sen s/√2, -s/√2)" ) self.camera_position = (10, -10, 10) self.showAxis(False) tmin, tmax, npuntos = (-2 * pi, 2 * pi, 200) self.addChild(Cylinder(_1(7, 83, 150), tmax - tmin, 2)) def param1hr(t): return 2 * Vec3(cos(t), sin(t), -t / 3.0) def param2hr(t): return 2 * Vec3(-sin(t), cos(t), -1 / 3.0) def param3hr(t): return 2 * Vec3(-cos(t), -sin(t), 0) espiral = Curve3D(param1hr, (tmin * 1.5, tmax * 1.5, npuntos), color=_1(240, 10, 120)) def param1hc_der(t): return 2 * Vec3(cos(t), sin(t), t / 3.0) espiral_der = Curve3D(param1hc_der, (tmin * 1.5, tmax * 1.5, npuntos), color=_1(20, 240, 240)) tangente = espiral.attachField( "tangente", param2hr).setLengthFactor(1).setWidthFactor(.6) tangente.setRadius(0.06) tangente.setDiffuseColor(_1(20, 240, 20)) normal = espiral.attachField( "normal", param3hr).setLengthFactor(1).setWidthFactor(.6) normal.setRadius(0.06) normal.setDiffuseColor(_1(240, 120, 20)) self.addChild(espiral) self.addChild(espiral_der) plano_xy_par = lambda u, v: Vec3(u, v, 0) plano_xy = ParametricPlot3D(plano_xy_par, (-4, 4, 20), (-4, 4, 20)) plano_xy.setDiffuseColor(_1(200, 200, 200)) plano_xy.setTransparencyType( SoTransparencyType.SORTED_OBJECT_SORTED_TRIANGLE_BLEND) plano_xy.setTransparency(0.85) self.addChild(plano_xy) self.addChild(Line([(-4, 0, 0), (4, 0, 0)], color=(0.8, 0.8, 0.5))) self.addChild(Line([(0, -4, 0), (0, 4, 0)], color=(0.8, 0.8, 0.5))) self.setupAnimations( [AnimationGroup([tangente, normal], (10000, 0, len(espiral) - 1))])
def __init__(self, color, origin, p1, p2): BaseObject.__init__(self) self.range = (-1, 1, 10) self.base_plane = BasePlane() self.base_plane.setDiffuseColor(color) self.base_plane.setEmissiveColor(color) self.separator.addChild(self.base_plane.root) # local axis self.localXAxis = Line([], color=(1, 0, 0)) self.localYAxis = Line([], color=(1, 0, 0)) self.separator.addChild(self.localXAxis.root) self.separator.addChild(self.localYAxis.root) # calculate the points self.setPoints(origin, p1, p2)
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 en el paraboloide hiperbólico con una singularidad<br><br>(x,y) → (0, 1, -k/x<sup>2</sup>)" ) par_parab = lambda x, y: Vec3(x, y, x * y) par_tang = lambda x, y: Vec3(0, 1, x) parab = ParametricPlot3D(par_parab, (-1, 1), (-1, 1)) parab.setTransparency(0.4) parab.setTransparencyType( SoTransparencyType.SORTED_OBJECT_SORTED_TRIANGLE_BLEND) parab.setDiffuseColor(_1(68, 28, 119)) self.addChild(parab) def make_curva(c): #return partial(par_parab,c) return lambda x: Vec3(x, c / x, c * 1.01) def make_curva_negy(c): #return partial(par_parab,c) return lambda x: Vec3(x, -c / x, -c * 0.99) def make_tang(c): #return partial(par_tang,c) return lambda x: Vec3(x, -c / (x**2), 0.0) / (sqrt(x**2 + c**2 / (x**4))) def make_tang_negy(c): #return partial(par_tang,c) return lambda x: Vec3(x, c / (x**2), 0.0) / (sqrt(x**2 + c**2 / (x**4))) tangentes = [] for c in range(1, 10): ## 0 < ct < 1 ct = c / 10.0 curva = Curve3D(make_curva(ct), (ct, 1.0, 50), width=1.5) curva.attachField( "tangente", make_tang(ct)).setLengthFactor(.4).setWidthFactor(.1) curva.fields['tangente'].show() tangentes.append(curva.fields['tangente']) self.addChild(curva) curva = Curve3D(make_curva_negy(ct), (ct, 1.0, 50), width=1.5) curva.attachField( "tangente_negy", make_tang_negy(ct)).setLengthFactor(.4).setWidthFactor(.1) curva.fields['tangente_negy'].show() tangentes.append(curva.fields['tangente_negy']) self.addChild(curva) #ct = -1.0 + c/10.0 curva = Curve3D(make_curva(ct), (-ct, -1.0, 50), width=1.5) curva.attachField( "tangente2", make_tang(-ct)).setLengthFactor(.4).setWidthFactor(.1) curva.fields['tangente2'].show() tangentes.append(curva.fields['tangente2']) self.addChild(curva) curva = Curve3D(make_curva_negy(ct), (-ct, -1.0, 50), width=1.5) curva.attachField( "tangente_negy2", make_tang_negy(-ct)).setLengthFactor(.4).setWidthFactor(.1) curva.fields['tangente_negy2'].show() tangentes.append(curva.fields['tangente_negy2']) self.addChild(curva) def animaTangentes(n): for tang in tangentes: tang.animateArrow(n) a1 = Animation(animaTangentes, (5000, 0, 49)) self.setupAnimations([a1]) self.addChild( Line([(-1, 0, 0.01), (1, 0, 0.01)], color=(1, 1, 1)).setWidth(1.5)) self.addChild( Line([(0, -1, 0.01), (0, 1, 0.01)], color=(1, 1, 1)).setWidth(1.5))
def test_Segments(self): [p1,p2,p3,p4] = [(0,0,0),(1,1,1),(-1,2,0),(-1,-1,1)] line = Line([p1,p2,p3,p4]).setNumVerticesPerSegment([2,2]) self.assertEqual(tuple(line[0]),p1) self.assertEqual(tuple(line[3]),p4) self.assertEqual(line.getNumVerticesPerSegment(),[2,2])
def test_Segments(self): [p1, p2, p3, p4] = [(0, 0, 0), (1, 1, 1), (-1, 2, 0), (-1, -1, 1)] line = Line([p1, p2, p3, p4]).setNumVerticesPerSegment([2, 2]) self.assertEqual(tuple(line[0]), p1) self.assertEqual(tuple(line[3]), p4) self.assertEqual(line.getNumVerticesPerSegment(), [2, 2])
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])