test-2013-07-03

3951 days ago by comphy

@interact def gfan_browse(p1 = input_box('x^3+y^2',type = str, label='polynomial 1: '), p2 = input_box('y^3+z^2',type = str, label='polynomial 2: '), p3 = input_box('z^3+x^2',type = str, label='polynomial 3: ')): R.<x,y,z> = PolynomialRing(QQ,3) i1 = ideal(R(p1),R(p2),R(p3)) gf1 = i1.groebner_fan() testr = gf1.render() html('Groebner fan of the ideal generated by: ' + str(p1) + ', ' + str(p2) + ', ' + str(p3)) show(testr, axes = False, figsize=[8,8*(3^(.5))/2]) 
       
polynomial 1:  
polynomial 2:  
polynomial 3:  

Click to the left again to hide and once more to show the dynamic interactive window

def proj4_to_3(gfanobj, poly4): fpoints = poly4.vertices() tpoints = [gfanobj._embed_tetra(q) for q in fpoints] adj_data = poly4.vertex_adjacencies() edges = [] for adj in adj_data: for vert in adj[1]: if vert > adj[0]:def proj4_to_3(gfanobj, poly4): fpoints = poly4.vertices() tpoints = [gfanobj._embed_tetra(q) for q in fpoints] adj_data = poly4.vertex_adjacencies() edges = [] for adj in adj_data: for vert in adj[1]: if vert > adj[0]: edges.append([tpoints[adj[0]],tpoints[vert]]) return edges, tpoints from sage.plot.plot3d.index_face_set import IndexFaceSet edges.append([tpoints[adj[0]],tpoints[vert]]) return edges, tpoints from sage.plot.plot3d.index_face_set import IndexFaceSet def render_solid(poly, color = 'blue', opacity = .5): tri_faces = poly.triangulated_facial_incidences() from sage.plot.plot3d.index_face_set import IndexFaceSet return IndexFaceSet([q[1] for q in tri_faces], poly.vertices(), enclosed = True, color = color, opacity = opacity) def render3d(a_gf, color_fan = True, verbose = False, highlights = 'all'): g_cones = [q.groebner_cone() for q in a_gf.reduced_groebner_bases()] g_cones_facets = [q.facets() for q in g_cones] g_cones_ieqs = [a_gf._cone_to_ieq(q) for q in g_cones_facets] # Now the cones are intersected with a plane: cone_info = [ieq_to_vert(q,linearities=[[1,-1,-1,-1,-1]]) for q in g_cones_ieqs] if verbose: for x in cone_info: print x.ieqs() + [[1,1,0,0,0],[1,0,1,0,0],[1,0,0,1,0],[1,0,0,0,1]] print x.linearities() print "" cone_info = [Polyhedron(ieqs = x.ieqs() + [[1,1,0,0,0],[1,0,1,0,0],[1,0,0,1,0],[1,0,0,0,1]], linearities = x.linearities()) for x in cone_info] if color_fan == True: #using fixed color scheme color_list = [] our_vars = list(a_gf.ring().gens()) degs = [[max(q.degree(avar) for q in b) for avar in our_vars] for b in a_gf.reduced_groebner_bases()] maxdegs = [max(float(q[i]) for q in degs) for i in range(len(our_vars))] color_list = [[b[0]/maxdegs[0],b[1]/maxdegs[1],(b[2]+b[3])/(maxdegs[2]+maxdegs[3])] for b in degs] color_list = [tuple(c[i]/max(c) for i in range(3)) for c in color_list] faces = [] if highlights == 'all': highlights = range(len(cone_info)) all_lines = [] i = 0 for cone_data in cone_info: # cone_data is a Polyhedron. try: pdata = proj4_to_3(a_gf,cone_data) cone_lines = pdata[0] cone_verts = pdata[1] if color_fan == True: if i in highlights: faces.append(render_solid(Polyhedron(vertices = cone_verts), color = color_list[i])) i = i + 1 except: print cone_data._rays raise RuntimeError for a_line in cone_lines: all_lines.append(a_line) if faces == []: faceadds = Graphics() else: faceadds = sum(faces) return sum([line3d(a_line) for a_line in all_lines]) + faceadds R4.<w,x,y,z> = PolynomialRing(QQ,4) temp_id = R4.ideal([w^3-x^2, x^3-y^21, y^3-w^2, z - x^2]) temp_gf4 = temp_id.groebner_fan() temp_gf4_rbs = temp_gf4.reduced_groebner_bases() gbdict = dict([['w^3-x^2, x^3-y^2, y^3-w^2, z - x^2',(temp_gf4,temp_gf4_rbs)]]) @interact def Groebner_fan_browser(bsel = slider(0,100,.1,0,label='Individual basis selection', display_value = False), ideal_gens = input_box(default = 'w^3-x^2, x^3-y^2, y^3-w^2, z - x^2', type = str, label = "Ideal generators"), showall = checkbox(True, "Show me them all"), showbases = checkbox(False, "Show highlighted basis")): html('<h3>Groebner fan 3D browser</h3> Enter 4 polynomials in the variables w,x,y,z<BR> <em>This may take forever if you are overambitious</em>') R4.<w,x,y,z> = PolynomialRing(QQ,4) if ideal_gens not in gbdict: id_gens = R4.ideal(list(ideal_gens.split(','))) print id_gens gf4 = id_gens.groebner_fan() gf4rbs = gf4.reduced_groebner_bases() gbdict[ideal_gens] = (gf4,gf4rbs) else: gf4 = gbdict[ideal_gens][0] gf4rbs = gbdict[ideal_gens][1] bnumbers = len(gf4rbs) b_select = [int(bsel*bnumbers/100.0)] if showall: b_select = range(bnumbers) if showbases: for b in b_select: show(gf4rbs[b]) show(render3d(gf4, highlights = b_select), frame = False) 
       
Traceback (most recent call last): for vert in adj[1]: File "", line 1, in <module> File "/tmp/tmpyNavqM/___code___.py", line 10 if vert > adj[_sage_const_0 ]:def proj4_to_3(gfanobj, poly4): ^ SyntaxError: invalid syntax
Traceback (most recent call last):            for vert in adj[1]:
  File "", line 1, in <module>
    
  File "/tmp/tmpyNavqM/___code___.py", line 10
    if vert > adj[_sage_const_0 ]:def proj4_to_3(gfanobj, poly4):
                                    ^
SyntaxError: invalid syntax
from sage.interfaces.phc import phc zringA.<z0,z1,z2,z3,z4,z5,a,b> = PolynomialRing(QQ,8) cyclic6 = [z0 + z1 + z2 + z3 + z4 + z5+a, z0*z1 + z1*z2 + z2*z3 + z3*z4 + z4*z5 + z5*z0, z0*z1*z2 + z1*z2*z3 + z2*z3*z4 + z3*z4*z5 + z4*z5*z0 + z5*z0*z1, z0*z1*z2*z3 + z1*z2*z3*z4 + z2*z3*z4*z5 + z3*z4*z5*z0 + z4*z5*z0*z1 + z5*z0*z1*z2, z0*z1*z2*z3*z4 + z1*z2*z3*z4*z5 + z2*z3*z4*z5*z0 + z3*z4*z5*z0*z1 + z4*z5*z0*z1*z2 + z5*z0*z1*z2*z3, z0*z1*z2*z3*z4*z5 - b] zring.<z0,z1,z2,z3,z4,z5> = PolynomialRing(QQ,6) z1 = [zring(x.subs({a:1/10, b:1/10})) for x in cyclic6] s1 = phc.blackbox(z1,zring) s1sas = s1.save_as_start(start_filename = DATA + 's1phc') cstate = [open(DATA + 's1phc').read()] def def_cyclic(ain, bin): eqs = [zring(x.subs({a:ain, b:bin})) for x in cyclic6] return eqs slines2d = [] mpts = [] @interact def tbp_tracker(show_eqs = checkbox(False),a = slider(-1,1,1/100,1/100), b = slider(-1,1,1/100,1/100), h_c_skew = slider(0,.1,.001,0.0, label='Homotopy skew'), scale = slider([2.0^x for x in srange(.1,4,.025)],default = 2^1.6)): z_pt = phc._path_track_file(start_filename_or_string = cstate[-1], polys = def_cyclic(a,b), input_ring = zring, c_skew = h_c_skew) cstate.append(open(z_pt).read()) z_pp = phc._parse_path_file(z_pt) hue_v = len(cstate)/(len(cstate)+1) znames = ['z0','z1','z2','z3','z4','z5'] for a_sol in z_pp: for z in znames: mpts.append(point([a_sol[0][z].real(), a_sol[0][z].imag()], hue=hue_v,pointsize=3)) mpts.append(point([a_sol[-1][z].real(), a_sol[-1][z].imag()], hue=hue_v,pointsize=3)) for a_sol in z_pp: zlines = [[] for q in znames] for data in a_sol: for i in range(len(znames)): zn = znames[i] zlines[i].append([data[zn].real(), data[zn].imag()]) for zl in zlines: slines2d.append(line(zl, thickness = .5)) show(sum(slines2d)+sum(mpts), figsize = [5,5], xmin = -scale, xmax=scale, ymin=-scale,ymax=scale, axes = false) if show_eqs: pols = def_cyclic(a,b) for i in range(len(pols)): show(pols[i]) 
       
sh: 1: phc: not found Traceback (most recent call last): + z5*z0*z1*z2, File "", line 1, in <module> File "/tmp/tmp_PGtAB/___code___.py", line 15, in <module> s1 = phc.blackbox(z1,zring) File "/usr/lib/sagemath/local/lib/python2.7/site-packages/sage/interfaces/phc\ .py", line 878, in blackbox print os.system('which phc') + ' PHC needs to be installed and in your path' TypeError: unsupported operand type(s) for +: 'int' and 'str'
sh: 1: phc: not found
Traceback (most recent call last):     + z5*z0*z1*z2,
  File "", line 1, in <module>
    
  File "/tmp/tmp_PGtAB/___code___.py", line 15, in <module>
    s1 = phc.blackbox(z1,zring)
  File "/usr/lib/sagemath/local/lib/python2.7/site-packages/sage/interfaces/phc.py", line 878, in blackbox
    print os.system('which phc') + '  PHC needs to be installed and in your path'
TypeError: unsupported operand type(s) for +: 'int' and 'str'
npi = RDF(pi) from math import cos,sin def rot(t): return matrix([[cos(t),sin(t)],[-sin(t),cos(t)]]) def pursuit(n,x0,y0,lamb,steps = 100, threshold = .01): paths = [[[x0,y0]]] for i in range(1,n): rx,ry = list(rot(2*npi*i/n)*vector([x0,y0])) paths.append([[rx,ry]]) oldpath = [x[-1] for x in paths] for q in range(steps): diffs = [[oldpath[(j+1)%n][0]-oldpath[j][0],oldpath[(j+1)%n][1]-oldpath[j][1]] for j in range(n)] npath = [[oldpath[j][0]+lamb*diffs[j][0],oldpath[j][1]+lamb*diffs[j][1]] for j in range(n)] for j in range(n): paths[j].append(npath[j]) oldpath = npath return paths html('<h3>Curves of Pursuit</h3>') @interact def curves_of_pursuit(n = slider([2..20],default = 5, label="# of points"),steps = slider([floor(1.4^i) for i in range(2,18)],default = 10, label="# of steps"), stepsize = slider(srange(.01,1,.01),default = .2, label="stepsize"), colorize = selector(['BW','Line color', 'Filled'],default = 'BW')): outpaths = pursuit(n,0,1,stepsize, steps = steps) mcolor = (0,0,0) outer = line([q[0] for q in outpaths]+[outpaths[0][0]], rgbcolor = mcolor) polys = Graphics() if colorize=='Line color': colors = [hue(j/steps,1,1) for j in range(len(outpaths[0]))] elif colorize == 'BW': colors = [(0,0,0) for j in range(len(outpaths[0]))] else: colors = [hue(j/steps,1,1) for j in range(len(outpaths[0]))] polys = sum([polygon([outpaths[(i+1)%n][j+1],outpaths[(i+1)%n][j], outpaths[i][j+1]], rgbcolor = colors[j]) for i in range(n) for j in range(len(outpaths[0])-1)]) #polys = polys[0] colors = [(0,0,0) for j in range(len(outpaths[0]))] nested = sum([line([q[j] for q in outpaths]+[outpaths[0][j]], rgbcolor = colors[j]) for j in range(len(outpaths[0]))]) lpaths = [line(x, rgbcolor = mcolor) for x in outpaths] show(sum(lpaths)+nested+polys, axes = False, figsize = [5,5], xmin = -1, xmax = 1, ymin = -1, ymax =1) 
       

Curves of Pursuit

# of points 
# of steps 
stepsize 
colorize 

Click to the left again to hide and once more to show the dynamic interactive window

var('u,v') plots = ['Two Interlinked Tori', 'Star of David', 'Double Heart', 'Heart', 'Green bowtie', "Boy's Surface", "Maeder's Owl", 'Cross cap'] plots.sort() @interact def _(example=selector(plots, buttons=True, nrows=2), tachyon=("Raytrace", False), frame = ('Frame', False), opacity=(1,(0.1,1))): url = '' if example == 'Two Interlinked Tori': f1 = (4+(3+cos(v))*sin(u), 4+(3+cos(v))*cos(u), 4+sin(v)) f2 = (8+(3+cos(v))*cos(u), 3+sin(v), 4+(3+cos(v))*sin(u)) p1 = parametric_plot3d(f1, (u,0,2*pi), (v,0,2*pi), color="red", opacity=opacity) p2 = parametric_plot3d(f2, (u,0,2*pi), (v,0,2*pi), color="blue",opacity=opacity) P = p1 + p2 elif example == 'Star of David': f_x = cos(u)*cos(v)*(abs(cos(3*v/4))^500 + abs(sin(3*v/4))^500)^(-1/260)*(abs(cos(4*u/4))^200 + abs(sin(4*u/4))^200)^(-1/200) f_y = cos(u)*sin(v)*(abs(cos(3*v/4))^500 + abs(sin(3*v/4))^500)^(-1/260)*(abs(cos(4*u/4))^200 + abs(sin(4*u/4))^200)^(-1/200) f_z = sin(u)*(abs(cos(4*u/4))^200 + abs(sin(4*u/4))^200)^(-1/200) P = parametric_plot3d([f_x, f_y, f_z], (u, -pi, pi), (v, 0, 2*pi),opacity=opacity) elif example == 'Double Heart': f_x = ( abs(v) - abs(u) - abs(tanh((1/sqrt(2))*u)/(1/sqrt(2))) + abs(tanh((1/sqrt(2))*v)/(1/sqrt(2))) )*sin(v) f_y = ( abs(v) - abs(u) - abs(tanh((1/sqrt(2))*u)/(1/sqrt(2))) - abs(tanh((1/sqrt(2))*v)/(1/sqrt(2))) )*cos(v) f_z = sin(u)*(abs(cos(4*u/4))^1 + abs(sin(4*u/4))^1)^(-1/1) P = parametric_plot3d([f_x, f_y, f_z], (u, 0, pi), (v, -pi, pi),opacity=opacity) elif example == 'Heart': f_x = cos(u)*(4*sqrt(1-v^2)*sin(abs(u))^abs(u)) f_y = sin(u) *(4*sqrt(1-v^2)*sin(abs(u))^abs(u)) f_z = v P = parametric_plot3d([f_x, f_y, f_z], (u, -pi, pi), (v, -1, 1), frame=False, color="red",opacity=opacity) elif example == 'Green bowtie': f_x = sin(u) / (sqrt(2) + sin(v)) f_y = sin(u) / (sqrt(2) + cos(v)) f_z = cos(u) / (1 + sqrt(2)) P = parametric_plot3d([f_x, f_y, f_z], (u, -pi, pi), (v, -pi, pi), frame=False, color="green",opacity=opacity) elif example == "Boy's Surface": url = "http://en.wikipedia.org/wiki/Boy's_surface" fx = 2/3* (cos(u)* cos(2*v) + sqrt(2)* sin(u)* cos(v))* cos(u) / (sqrt(2) - sin(2*u)* sin(3*v)) fy = 2/3* (cos(u)* sin(2*v) - sqrt(2)* sin(u)* sin(v))* cos(u) / (sqrt(2) - sin(2*u)* sin(3*v)) fz = sqrt(2)* cos(u)* cos(u) / (sqrt(2) - sin(2*u)* sin(3*v)) P = parametric_plot3d([fx, fy, fz], (u, -2*pi, 2*pi), (v, 0, pi), plot_points = [90,90], frame=False, color="orange",opacity=opacity) elif example == "Maeder's Owl": fx = v *cos(u) - 0.5* v^2 * cos(2* u) fy = -v *sin(u) - 0.5* v^2 * sin(2* u) fz = 4 *v^1.5 * cos(3 *u / 2) / 3 P = parametric_plot3d([fx, fy, fz], (u, -2*pi, 2*pi), (v, 0, 1),plot_points = [90,90], frame=False, color="purple",opacity=opacity) elif example =='Cross cap': url = 'http://en.wikipedia.org/wiki/Cross-cap' fx = (1+cos(v))*cos(u) fy = (1+cos(v))*sin(u) fz = -tanh((2/3)*(u-pi))*sin(v) P = parametric_plot3d([fx, fy, fz], (u, 0, 2*pi), (v, 0, 2*pi), frame=False, color="red",opacity=opacity) else: print "Bug selecting plot?" return html('<h2>%s</h2>'%example) if url: html('<h3><a target="_new" href="%s">%s</a></h3>'%(url,url)) show(P, viewer='tachyon' if tachyon else 'jmol', frame=frame) 
       
example 
Raytrace 
Frame 
opacity 

Click to the left again to hide and once more to show the dynamic interactive window

C = cube(color=['red', 'green', 'blue'], aspect_ratio=[1,1,1], viewer='tachyon') + sphere((1,0,0),0.2) @interact def example(theta=(0,2*pi), phi=(0,2*pi), zoom=(1,(1,4))): show(C.rotate((0,0,1), theta).rotate((0,1,0),phi), zoom=zoom) 
       
theta 
phi 
zoom 

Click to the left again to hide and once more to show the dynamic interactive window

var('x,y') @interact def example(clr=Color('orange'), f=4*x*exp(-x^2-y^2), xrange='(-2, 2)', yrange='(-2,2)', zrot=(0,pi), xrot=(0,pi), zoom=(1,(1/2,3)), square_aspect=('Square Frame', False), tachyon=('Ray Tracer', True)): xmin, xmax = sage_eval(xrange); ymin, ymax = sage_eval(yrange) P = plot3d(f, (x, xmin, xmax), (y, ymin, ymax), color=clr) html('<h1>Plot of $f(x,y) = %s$</h1>'%latex(f)) aspect_ratio = [1,1,1] if square_aspect else [1,1,1/2] show(P.rotate((0,0,1), -zrot).rotate((1,0,0),xrot), viewer='tachyon' if tachyon else 'jmol', figsize=6, zoom=zoom, frame=False, frame_aspect_ratio=aspect_ratio) 
       
clr 
xrange 
yrange 
zrot 
xrot 
zoom 
Square Frame 
Ray Tracer 

Click to the left again to hide and once more to show the dynamic interactive window

var('s,t') g(s) = ((0.57496*sqrt(121 - 16.0*s^2))/sqrt(10.+ s)) def P(color, rng): return parametric_plot3d((cos(t)*g(s), sin(t)*g(s), s), (s,rng[0],rng[1]), (t,0,2*pi), plot_points = [150,150], rgbcolor=color, frame = False, opacity = 1) colorlist = ['red','blue','red','blue'] @interact def _(band_number = selector(range(1,5)), current_color = Color('red'), auto_update=False): html('<h1 align=center>Egg Painter</h1>') colorlist[band_number-1] = current_color egg = sum([P(colorlist[i],[-2.75+5.5*(i/4),-2.75+5.5*(i+1)/4]) for i in range(4)]) show(egg) 
       
band_number 
current_color 

Click to the left again to hide and once more to show the dynamic interactive window

@interact def color_experimenter(expression=input_box('', 'Expression', str), color=Color('red')): if expression: try: plot(SR(expression), rgbcolor=color).show() except TypeError: print "There's a problem with your expression." 
       
Expression 
color 

Click to the left again to hide and once more to show the dynamic interactive window

def error_msg(msg): print '<html><p style="font-family:Arial, sans-serif;color:#000"><span style="color:red;font-weight:bold">Error</span>: %s</p></html>' % msg @interact def interactive_2d_plotter(expression=input_box('sin(x)', 'Expression', str), x_range=range_slider(-10,10,1,(0,10), label='X Range'), square=checkbox(True, 'Square'), axes=checkbox(False, 'Show Axes')): if expression: try: expression = SR(expression) # turn string into a Sage expression except TypeError: print error_msg('This is not an expression.') return try: xmin, xmax = x_range if square or not axes: print "var('%s')\nplot(%s).show(%s%s%s)" % (expression.variables()[0], repr(expression), 'aspect_ratio=1' if square else '', ', ' if square and not axes else '', 'axes=False' if not axes else '') if square: plot(expression, xmin, xmax).show(aspect_ratio=1, axes=axes) else: plot(expression, xmin, xmax).show(axes=axes) else: print "var('%s')\nplot(%s)" % (expression.variables()[0], repr(expression)) plot(expression, xmin, xmax).show(axes=axes) except ValueError: print error_msg('This expression has more than one variable.') return except TypeError: print error_msg("This expression contains an unknown function.") return 
       
Expression 
X Range 
Square 
Show Axes 

Click to the left again to hide and once more to show the dynamic interactive window

# Simple example demonstrating how to interact with matplotlib directly. # Comment plt.clf() to get the plots overlay in each update. # Gokhan Sever & Harald Schilly (2010-01-24) from scipy import stats import numpy as np import matplotlib.pyplot as plt @interact def plot_norm(loc=(0,(0,10)), scale=(1,(1,10))): rv = stats.norm(loc, scale) x = np.linspace(-10,10,1000) plt.plot(x,rv.pdf(x)) plt.grid(True) plt.savefig('plt.png') plt.clf() 
       
loc 
scale 

Click to the left again to hide and once more to show the dynamic interactive window

#---------------------------# # Javier Pérez Lázaro # # Logroño (Spain) # # javier.perezl@unirioja.es # #---------------------------# #introduction html('<h1><center>Spirograph</center></h1>') text1='Spirograph is a tool for drawing hypotrochoids and epitrochoids.' text2='Assume that a A is a point attached to a circle. A can be attached to the boundary of the circle or to any exterior or interior place. If the circle rolls around the outside of a fixed circle, the curve traced by the point A is called an epitrochoid. In case the circle rolls around the inside of a fixed circle, the curve is an hypotrochoid.' text3='If the quotient between the radii of the circles is a rational number, then the curves are periodic.' #the code @interact def fun( tex1=text_control(text1), tex2=text_control(text2), tex3=text_control(text3), h=('Select:',list(['epitrochoid','hypotrochoid'])), tex4=text_control('Radius of the circle. Should be a rational number with shape p/q.'), b=input_box(default=7/30,label='radius'), tex5=text_control("Rate between the distance of the point to the circle's center and the radius."), rate=input_box(default=1), u=selector(['Plot the curve. Slider of % below enabled.', 'Build an animation of the plot with the number of frames specified below.'],label='Choose:'), per=slider(0,100,1,default=100,label='graph %'), frames=100, cir_bool=checkbox(True, "Show circles?"), auto_update=false): draw=True if h=='hypotrochoid' and (b>=1 or b<=0): print "In a hypotrochoid, radius must be between 0 and 1." draw=False if h=='epitrochoid' and b<=0: print "In a epitrochoid, radius must be positive" draw=False if draw==True: if h=='hypotrochoid': b=-b var('t') cx=(1+b)*cos(t*b/(1+b)) cy=(1+b)*sin(t*b/(1+b)) px=cx-b*rate*cos(t) py=cy-b*rate*sin(t) axeM=1+max([0,b+abs(b)*rate]) if u=='Plot the curve. Slider of % below enabled.': tMax=pi*denominator(b/(b+1))*per/50 L=parametric_plot((px,py),(t,0,max([0.001,tMax])),plot_points=10*rate*tMax) if cir_bool: p=point((px(t=tMax),py(t=tMax)),pointsize=30,color='blue') c=point((cx(t=tMax),cy(t=tMax)),pointsize=30,color='red') cir=circle((cx(t=tMax),cy(t=tMax)),b,color='red') lin=line([(cx(t=tMax),cy(t=tMax)),(px(t=tMax),py(t=tMax))]) L+=circle((0,0),1)+cir+lin+p+c show(L,aspect_ratio=1,xmin=-axeM,xmax=axeM,ymin=-axeM,ymax=axeM) if u=='Build an animation of the plot with the number of frames specified below.': tMax=2*pi*denominator(b/(b+1)) step=tMax/(frames-1) curva=Graphics() v=[] for a in srange(step,tMax,step): curva+=parametric_plot((px,py),(t,a-step,a)) L=curva if cir_bool: cx_a=cx(t=a) cy_a=cy(t=a) px_a=cx_a-b*rate*cos(a) py_a=cy_a-b*rate*sin(a) p=point((px_a,py_a),pointsize=30,color='blue') c=point((cx_a,cy_a),pointsize=30,color='red') cir=circle((cx_a,cy_a),b,color='red') lin=line([(cx_a,cy_a),(px_a,py_a)]) L+=circle((0,0),1)+cir+lin+c+p v.append(L) animate(v,xmin=-axeM,xmax=axeM,ymin=-axeM,ymax=axeM,aspect_ratio=1).show() 
       

Spirograph

Spirograph is a tool for drawing hypotrochoids and epitrochoids.
Assume that a A is a point attached to a circle. A can be attached to the boundary of the circle or to any exterior or interior place. If the circle rolls around the outside of a fixed circle, the curve traced by the point A is called an epitrochoid. In case the circle rolls around the inside of a fixed circle, the curve is an hypotrochoid.
If the quotient between the radii of the circles is a rational number, then the curves are periodic.
Select: 
Radius of the circle. Should be a rational number with shape p/q.
radius 
Rate between the distance of the point to the circle's center and the radius.
rate 
Choose: 
graph % 
frames 
Show circles? 

Click to the left again to hide and once more to show the dynamic interactive window