replica_No_CopyPaste_symbolic_companion_CICM11_marzo_2011

427 days ago by mabanades

 
       
%hide html('<script type="text/javascript">var xmlTexto = "nada"; function showXML(){xmlTexto = document.applets[0].getXML(); document.getElementById("XMLArea").innerHTML = xmlTexto;}</script>') 
       
%hide #http://www.dustindiaz.com/add-and-remove-html-elements-dynamically-with-javascript/ #html('<script type="text/javascript">function addElement() {var ni = document.getElementById("myDiv");var numi = document.getElementById("theValue");var num = (document.getElementById("theValue").value -1)+ 2; numi.value = num;var newdiv = document.createElement("div");var divIdName = "my"+num+"Div"; newdiv.setAttribute("id",divIdName); newdiv.innerHTML = "hola?"; ni.appendChild(newdiv);}</script>') 
       

A Symbolic Companion for GeoGebra.

Automatic determination of geometric loci.

March 2011

Construct or upload (File -> Open) a geometric locus set in the following GeoGebra applet. Sage will be used to (symbolically) compute its equation.

The allowed GeoGebra elements (currently) are: free points, Midpoint(point-point), Point(on Circle), Segment(point-point), Line(point-point, point-line -meaning a parallel), OrthogonalLine, Circle(center-radius, center-point, center-radius_as_segment), Intersect(object-object) and Locus.

Press the Show GGBXML button to obtain the XML description of your locus set in the text area.


Click evaluate. If you do not see evaluate, click %hide and shift+enter. Once the text field is generated, paste in it the the XML description copied from in the text area above

%hide import sgmllib class MyParser(sgmllib.SGMLParser): "A simple parser class." def parse(self, s): "Parse the given string 's'." self.feed(s) self.close() def __init__(self, verbose=0): "Initialise an object, passing 'verbose' to the superclass." sgmllib.SGMLParser.__init__(self, verbose) self.hyperlinks = [] def start_a(self, attributes): "Process a hyperlink and its 'attributes'." for name, value in attributes: if name == "href": self.hyperlinks.append(value) def get_hyperlinks(self): "Return the list of hyperlinks." return self.hyperlinks import urllib, sgmllib # Get something to work with. f = urllib.urlopen('http://alpha.sagenb.org/home/pub/95') s = f.read() # Try and process the page. # The class should have been defined first, remember. myparser = MyParser() myparser.parse(s) # Get the hyperlinks. #print s ##print myparser.get_hyperlinks() 
       
s.__contains__('hola?') 
       
True
True
%hide automatic_names(True) @interact def read_xml(XML_from_construction='Replace this text with the XML desciption in the text area above'): global texto texto=XML_from_construction 
       

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

Click evaluate. If you do not see evaluate, click %hide and shift+enter. This cell carries out the main computation. Scroll down (if needed), take a look to the code, and goto to the next cell.

%hide from xml.etree import ElementTree as ET texto = (texto.replace('\n','')).replace('\t','') ggb = ET.XML(texto) """Since the construction XML element lies on different parts in GeoGebra 3.2 and GeoGebra 4.0, we read it as appropriate and set its value in cons""" if ggb.items()[0][1]=='3.2': cons=ggb[3] else: cons=ggb[5] #next we process the GeoGebra locus construction BoVar=[x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x90, x91, x92, x93, x94, x95, x96, x97, x98, x99];BoVar.reverse() Todo={} def FreePoint(pnt,absc,orde): """Adds the point $pnt$ with coordinates $(absc,orde)$ to the geometric construction.""" Todo.update({pnt:{'coords':(absc,orde),'parents':Set([]),'type':'FreePoint','hist':['FreePoint',pnt,absc,orde],'eq':Set([])}}) def BoundedPoint(pnt, absc, orde): Todo.update({pnt:{'coords':(absc,orde),'type':'BoundedPoint'}}) def is_point(p): return ((p in Todo.keys()) and (Todo[p]['type']=='FreePoint' or Todo[p]['type']=='BoundedPoint')) def x(obj): if is_point(obj): return Todo[obj]['coords'][0] def y(obj): if is_point(obj): return Todo[obj]['coords'][1] """ anc is a global variable used in the function ancestors. It must be set to nil before evaluating the function""" anc=[] def ancestors(n): """Returns a set consisting of $n$ and all its ancestors, if $n$ is a construction object. It returns the empty set in other case.""" global anc res=anc if n in Todo.keys(): res.append(n) t=list(Todo[n]['parents']) res.extend(t) for i in t: ancestors(i) return Set(res) def Line(n,p,q): """Constructs the line $n$ that goes through the points $p$ and $q$.""" vdir=(x(q) - x(p), y(q) - y(p)) eq=Set([(absc - x(p))*(y(q) - y(p)) - (orde - y(p))*(x(q) - x(p))]) pare=Set([p,q]) Todo.update({n:{'vdir':vdir,'eq':eq, 'parents':pare,'type':'Line','hist':['Line',n,p,q]}}) def Segment(n,p,q): """Constructs the line $n$ that goes through the points $p$ and $q$. Defined for GeoGebra compatibility.""" vdir=(x(q) - x(p), y(q) - y(p)) eq=Set([(absc - x(p))*(y(q) - y(p)) - (orde - y(p))*(x(q) - x(p))]) pare=Set([p,q]) Todo.update({n:{'vdir':vdir,'eq':eq, 'parents':pare,'type':'Line','hist':['Segment',n,p,q]}}) def Circle(n,c,p,*q): """Constructs the circle $n$ with center the point $c$ and radius (squared!) $p^2$ if $p$ is a number. If $p$ is a point, $n$is the circle with center $c$ and passing through the point $p$. If there is a fourth argument, the point $q$, then so must be $p$ and the circle has center $c$ and radius (squared) the distance between $p$ and $q$""" pare=[c] if is_point(p): pare.append(p) if len(q)==1: radius2=(x(p)-x(q[0]))^2+(y(p)-y(q[0]))^2 pare.append(q[0]) else: radius2=(x(p)-x(c))^2+(y(p)-y(c))^2 else: radius2=p^2 eq=Set([(absc - x(c))^2 + (orde - y(c))^2 - radius2]) Todo.update({n:{'center':c,'radius2':radius2,'eq':eq, 'parents':Set(pare),'type':'Line','hist':['Circle',n,c,p,q]}}) def MidPoint(n,p,q): """Constructs the midpoint $n$ of points $p$ and $q$.""" if n in Todo.keys(): eq=Todo[n]['eq'] parents=Todo[n]['parents'] temp=Todo[n]['coords'] else: eq=Set([]) parents=Set([]) temp=(BoVar.pop(),BoVar.pop()) eq=eq.union(Set([temp[0]-1/2*(x(p)+x(q)),temp[1]-1/2*(y(p)+y(q))])) parents=parents.union(Set([p,q])) Todo.update({n:{'coords':temp,'type':'BoundedPoint','eq':eq,'parents':parents,'hist':['MidPoint',n,p,q]}}) def PointOnObject(n,o): """Constructs a point $n$ lying on object $o$.""" if n in Todo.keys(): eq=Todo[n]['eq'] temp=Todo[n]['coords'] parents=Todo[n]['parents'] else: eq=Set([]) parents=Set([]) temp=(BoVar.pop(),BoVar.pop()) flag_subs=False for i in list(Todo[o]['eq']): if (absc in list(i.variables()) or orde in list(i.variables())): flag_subs=True eq=eq.union(Set([i.subs(absc=temp[0],orde=temp[1])])) parents=parents.union(Set([o])) if flag_subs: Todo.update({n:{'coords':temp,'parents':parents,'eq':eq,'type':'BoundedPoint','hist':['PointOnObject',n,o]}}) def ParallelLine(n,p,l): """Constructs the line $n$ parallel to the line $l$ passing through $p$.""" vdir=Todo[l]['vdir'] eq=Set([(absc - x(p))*vdir[1] - (orde - y(p))*vdir[0]]) pare=Set([p,l]) Todo.update({n:{'vdir':vdir,'eq':eq, 'parents':pare,'type':'Line','hist':['ParallelLine',n,p,l]}}) def PerpendicularLine(n,p,l): """Constructs the line $n$ perpendicular to the line $l$ passing through $p$.""" vdir=Todo[l]['vdir'] eq=Set([(absc - x(p))*vdir[0] + (orde - y(p))*vdir[1]]) vdir=(-vdir[1],vdir[0]) pare=Set([p,l]) Todo.update({n:{'vdir':vdir,'eq':eq, 'parents':pare,'type':'Line','hist':['PerpendicularLine',n,p,l]}}) def IntersectionObjectObject(n,o1,o2): """Constructs a point $n$ as intersection of objects $o1$ and $o2$.""" PointOnObject(n,o1) PointOnObject(n,o2) def Locus(n,t,*m): """Constructs the locus $n$ with tracer $t$. The third argument, if it exists, $m$, is the mover. If it does not exist, the locus is an implicit one.""" if len(m)==1: mover=str(m[0]) implicit=False else: implicit=True mover='' if implicit: parents=Set([t]) else: parents=Set([t,mover]) vbl='';vblist=[] anc=[];anc_de_t=ancestors(t) anc=[];anc_de_m=ancestors_de_m=ancestors(mover) anc_set=anc_de_t.union(anc_de_m) for i in anc_set: if Todo[i]['type']=='BoundedPoint': vbl=vbl+','+str(x(i)) vblist.append(x(i)) vbl=vbl+','+str(y(i)) vblist.append(y(i)) vbl=vbl.replace(',','',1) vblist.remove(x(t));vblist.remove(y(t)) Eqs=[] for i in anc_set: if Todo[i]['type']=='BoundedPoint': for j in list(Todo[i]['eq']): Eqs.append(j) S = PolynomialRing(QQ, vbl) S.inject_variables() I=Eqs*S H=I.elimination_ideal(eval(str(vblist))) res=H.gens() """res=map(factor,H.gens())""" eq=[] a,b=str(x(t)),str(y(t)) for i in res: i=str(i) i=i.replace('^','**') i=i.replace(a,'absc') i=i.replace(b,'orde') i=eval(i) eq.append(i) T=PolynomialRing(QQ,[absc,orde]) T.inject_variables() J=eq*T di=J.dimension() print 'dimension=',di if di==1: type='Line' eq=Set(eq) elif di==0: type='BoundedPoint' temp=(BoVar.pop(),BoVar.pop()) eqq=[] for i in eq: eqq.append(i.subs({absc:temp[0],orde:temp[1]})) eq=Set(eqq) elif di==2: type='Plane' eq=Set([0]) else: type='Nil' eq=Set([1]) hist=['Locus',n,t] if not implicit: hist.append(mover) diccio=[('implicit',implicit),('tracer',t),('mover',mover),('parents',parents),('eq',eq),('type',type),('hist',hist)] if type=='BoundedPoint': diccio.append(('coords',temp)) Todo.update({n:dict(diccio)}) def eval_cons(cons): for i in cons: b=i.items() if i.tag=='element' and b[0][1]=='point' and not (b[1][1] in Todo.keys()): dic=dict(i.find('coords').items()) coord_x=sage_eval(dic['x']);coord_y=sage_eval(dic['y']) coord_x=coord_x.simplest_rational();coord_y=coord_y.simplest_rational() FreePoint(str(b[1][1]),coord_x,coord_y) elif i.tag=='command': if b[0][1]=='Circle': dic_in=dict(i.find('input').items()) dic_out=dict(i.find('output').items()) """Circle cases: center-radius, center-point,center-radius_as_segment""" if dic_in['a1'].find('Segment[') <> -1: seg=dic_in['a1'] p=seg.split(',')[0];p=p.replace('Segment[','') q=seg.split(',')[1];q=q.replace(']','');q=q.replace(' ','') Circle(dic_out['a0'],dic_in['a0'],p,q) elif dic_in['a1'][0].isalpha(): Circle(dic_out['a0'],dic_in['a0'],dic_in['a1']) else: rad=sage_eval(dic_in['a1']);rad=rad.simplest_rational() Circle(dic_out['a0'],dic_in['a0'],rad) elif b[0][1]=='Segment': """The second ggb Segment definition is not implemented here""" dic_in=dict(i.find('input').items()) dic_out=dict(i.find('output').items()) Segment(dic_out['a0'],dic_in['a0'],dic_in['a1']) elif b[0][1]=='Line': """2 cases: line(point,point) and line(point,line), meaning a parallel ...""" dic_in=dict(i.find('input').items()) dic_out=dict(i.find('output').items()) if is_point(dic_in['a1']): Line(dic_out['a0'],dic_in['a0'],dic_in['a1']) else: ParallelLine(dic_out['a0'],dic_in['a0'],dic_in['a1']) elif b[0][1]=='Midpoint': """midpoint of two given points""" dic_in=dict(i.find('input').items()) dic_out=dict(i.find('output').items()) MidPoint(dic_out['a0'],dic_in['a0'],dic_in['a1']) elif b[0][1]=='OrthogonalLine': """perpendicular line through a given point to a given line""" dic_in=dict(i.find('input').items()) dic_out=dict(i.find('output').items()) PerpendicularLine(dic_out['a0'],dic_in['a0'],dic_in['a1']) elif b[0][1]=='Point': """Point on Circle""" dic_in=dict(i.find('input').items()) dic_out=dict(i.find('output').items()) PointOnObject(dic_out['a0'],dic_in['a0']) elif b[0][1]=='Intersect': """computes the intersection of any pair of linear objects""" dic_in=dict(i.find('input').items()) dic_out=dict(i.find('output').items()) IntersectionObjectObject(dic_out['a0'],dic_in['a0'],dic_in['a1']) elif b[0][1]=='Locus': """computes an explicit locus""" dic_in=dict(i.find('input').items()) dic_out=dict(i.find('output').items()) Locus(dic_out['a0'],dic_in['a0'],dic_in['a1']) def get_eq_internal(n): e=list(Todo[n]['eq']) for i in e: if Set(map(str,i.variables())).union(Set(['absc','orde']))!=Set(['absc','orde']): return 'The object is parametrically defined' if len(e)==1: res=[] for i in e[0].factor_list(): res.append(i[0]) return res elif len(e)==0: return 'The object has no equations' else: res=[] for j in e: restemp=[] for i in j.factor_list(): restemp.append(i[0]) res.append(restemp) return res def get_eq(n): e=list(Todo[n]['eq']) for i in e: if Set(map(str,i.variables())).union(Set(['absc','orde']))!=Set(['absc','orde']): return 'The object is parametrically defined' if len(e)==1: res=[] for i in e[0].factor_list(): res.append(i[0].subs({absc:X,orde:Y})) return res elif len(e)==0: return 'The object has no equations' else: res=[] for j in e: restemp=[] for i in j.factor_list(): restemp.append(i[0].subs({absc:X,orde:Y})) res.append(restemp) return res def box_dim2d(e): """Returns adequate box dimensions for plotting the 2d-geometric object described by $e$, if $e$ is compact. Usa .roots(ring=RR) sobre los polinomios univariables para calcular las raices""" e1,e2=diff(e,absc),diff(e,orde) S = PolynomialRing(QQ, [absc,orde]) S.inject_variables() I=[e,e2]*S H=I.elimination_ideal([orde]) if H.is_principal() and not H.is_one() and not H.is_zero(): eq=gens(H)[0].subs({absc:X,orde:Y}) if eq==0: m0,M1,px=0,0,0 else: raices=eq.roots(ring=RR,multiplicities=False) if raices==[]: return False M1,m0=max(raices),min(raices) px=(M1-m0)/10 if px==0: px=.5 else: return False I=[e,e1]*S H=I.elimination_ideal([absc]) if H.is_principal() and not H.is_one() and not H.is_zero(): eq=gens(H)[0].subs({absc:X,orde:Y}) if eq==0: m2,M3,py=0,0,0 else: raices=eq.roots(ring=RR,multiplicities=False) if raices==[]: return False M3,m2=max(raices),min(raices) py=(M3-m2)/10 if py==0: py=.5 else: return False """px and py extend the drawing box""" return [m0-px,M1+px,m2-py,M3+py] def get_plot(l): l=get_eq_internal(l) if l==[]: return 'There is nothing to plot' else: a=Graphics() for i in l: i=expand(i) dim=box_dim2d(i) if not (dim==False): a=a+implicit_plot(i,(absc,dim[0],dim[1]),(orde,dim[2],dim[3]),aspect_ratio=1) else: a=a+implicit_plot(i,(absc,dims[0],dims[1]),(orde,dims[2],dims[3]),aspect_ratio=1) return a def get_plot_window(l): l=get_eq_internal(l) if l==[]: return 'There is nothing to plot' else: a=Graphics() for i in l: i=expand(i) dim=box_dim2d(i) a=a+implicit_plot(i,(absc,dims[0],dims[1]),(orde,dims[2],dims[3]),aspect_ratio=1) return a eval_cons(cons) 
       
Defining x5, x6, x1, x2
Defining absc, orde
dimension= 1
Defining x5, x6, x1, x2
Defining absc, orde
dimension= 1