# Autore: Maurizio Paolini (2005) # Licenza: GPL # # seguono alcune costruzioni basate sullo scripting python # di 'kig' e l'interfaccia 'pykig.py' di Daniele Zambelli # per operare con il modello del semipiano di Poincare' # # Le costruzioni particolari ottenute possono essere utilizzate # per ottenere delle macro # # ROTAZIONE: # la rotazione nel semipiano di Poincare' non e' ottenuta scriptsegment='''def calc( arg1, arg2 ): # Construct the hyperbolic segment (arc) connecting the two points a=arg1.coordinate(); b=arg2.coordinate(); ax=a.x ay=a.y if ay < 0: return InvalidObject() bx=b.x by=b.y if by < 0: return InvalidObject() asq=ax*ax + ay*ay bsq=bx*bx + by*by den = 2*(bx - ax) if den == 0: return Segment(a,b) x = (bsq - asq)/den c = Coordinate(x,0) rsq = asq + x*x - 2*x*ax r = sqrt (rsq) if rsq > 1000*asq: return Segment(a,b) alfa = atan2(ay, ax-x) beta = atan2(by, bx-x) return Arc(c,r,alfa,beta-alfa) ''' def HyperbolicSegment ( a, b ): return PythonScript (scriptsegment, [a, b]) scriptline='''def calc( arg1, arg2 ): # Construct the hyperbolic line (semicircle) through two points a=arg1.coordinate(); b=arg2.coordinate(); ax=a.x ay=a.y if ay < 0: return InvalidObject() bx=b.x by=b.y if by < 0: return InvalidObject() asq=ax*ax + ay*ay bsq=bx*bx + by*by den = 2*(bx - ax) if den == 0: return Ray(Coordinate(ax,0.),b) x = (bsq - asq)/den c = Coordinate(x,0) rsq = asq + x*x - 2*x*ax r = sqrt (rsq) if rsq > 100000*asq: return Ray(Coordinate(ax,0.),b) alfa = atan2(ay, ax-x) beta = atan2(by, bx-x) return Arc(c,r,0.,atan2(0.,-1.)) ''' def HyperbolicLine ( a, b ): return PythonScript (scriptline, [a, b]) scriptcircle='''def calc( arg1, arg2 ): # Construct the hyperbolic circle centered in arg1 through arg2 a=arg1.coordinate(); b=arg2.coordinate(); ax=a.x ay=a.y if ay < 0: return InvalidObject() bx=b.x by=b.y if by <= 0: return InvalidObject() asq=ax*ax + ay*ay bsq=bx*bx + by*by den = 2*(bx - ax) num2 = bsq - asq - den*bx dby2 = num2/by dy = by - dby2/2. d = Coordinate(ax,dy) r2 = sqrt( den*den + dby2*dby2 ) return Circle(d,r2/2.) ''' def HyperbolicCircle ( a, b ): return PythonScript (scriptcircle, [a, b]) scriptlinebyvector='''def calc( arg1, arg2 ): # Construct the hyperbolic line through arg1 and direction arg2 a=arg1.coordinate() dir=arg2.dir() ax=a.x ay=a.y if ay < 0: return InvalidObject() dirx=dir.x diry=dir.y cx=ax + ay*diry/dirx r = sqrt ((cx-ax)*(cx-ax) + ay*ay) c = Coordinate(cx,0.) return Arc(c,r,0.,atan2(0.,-1.)) ''' scriptlineend1='''def calc( arg1 ): # Construct the first endpoint of a line if arg1.inherits( Ray.stype() ): ld = arg1.data() return Point( ld.a ) return Point (arg1.secondEndPoint()) ''' scriptlineend2='''def calc( arg1 ): # Construct the second endpoint of a line if arg1.inherits( Ray.stype() ): return InvalidObject() return Point (arg1.firstEndPoint()) ''' scriptsegmentdir1='''def calc( arg1, arg2 ): # Construct the vector tangent in A to the hyp segment AB # A (arg1) and B (arg2) are the two endpoints a=arg1.coordinate(); b=arg2.coordinate(); ax=a.x ay=a.y if ay < 0: return InvalidObject() bx=b.x by=b.y if by < 0: return InvalidObject() asq=ax*ax + ay*ay bsq=bx*bx + by*by den = 2*(bx - ax) if den == 0: return Segment(a,b) cx = (bsq - asq)/den dirort = Coordinate( ay, cx - ax) dirortnorm = dirort.length() if den < 0: dirortnorm = -dirortnorm return Vector (a, a + dirort/dirortnorm) ''' scriptcirclelineradical='''def calc( arg1, arg2 ): if arg2.inherits( Ray.stype() ): # by now... line = Ray.data() return Line(line) a = arg1.center() ax = a.x ay = a.y #return Point (a) r1sq = arg1.squareRadius() c = arg2.center() cx = c.x r2 = arg2.radius() r2sq = r2*r2 dirx = ax - cx diry = ay if c.y != 0: return InvalidObject() num = r2sq - r1sq dirsq = dirx*dirx + diry*diry lam = num/(2*dirsq) #lam = (ax*ax + ay*ay - cx*cx - r1sq + r2sq)/(2*((ax - cx)*(ax - cx) + ay*ay)) #lam = 0.5 mx = (ax + cx)/2 my = ay/2 dir = Coordinate(dirx, diry) point = Coordinate (mx + lam*dirx, my + lam*diry) dirort = Coordinate (-diry, dirx) return Line (point, point + dirort) #return Point (a) ''' assoluto = Line(Point(-1.,0.,internal=True),Point(1.,0.,internal=True)) # # ROTAZIONE del punto B attorno ad A di angolo "Angle". # basata su una riflessione attorno all'asse verticale per A # seguita da una inversione circolare rispetto ad un cerchio # passante per A e centro sull'asse delle ascisse costruito in # modo che l'angolo che forma in A rispetto all'asse verticale # sia la meta' dell'angolo "Angle". # def HyperbolicRotation (B, A, Angle): reflectionaxis = Orthogonal (assoluto, A, HIDDEN) Breflected = AxialSymmetry (B, reflectionaxis, HIDDEN) projection = LineLineIntersection (reflectionaxis, assoluto, HIDDEN) rotatedprojection = Rotate (projection, A, Angle, HIDDEN) # angleatA = Angle (projection, A, rotatedprojection) # ... non proseguo in questo modo perche' al momento pykig non # permette di costruire la bisettrice pushdown = Vector (A, projection, HIDDEN) pusheddown = Translate (rotatedprojection, pushdown, HIDDEN) ltangent = Line (A, pusheddown, HIDDEN) ortoline = Orthogonal (ltangent, A, HIDDEN) inversioncenter = LineLineIntersection (ortoline, assoluto, HIDDEN) inversioncircle = Circle (inversioncenter, A, HIDDEN) return InvertPoint (Breflected, inversioncircle)