def _geodesic_between_two_points_d(x1,y1,x2,y2,z0=I): r""" Geodesic path between two points represented in the unit disc by the map w = (z-I)/(z+I) INPUTS: - ''(x1,y1)'' -- starting point (0<y1<=infinity) - ''(x2,y2)'' -- ending point (0<y2<=infinity) - ''z0'' -- (default I) the point in the upper corresponding to the point 0 in the disc. I.e. the transform is w -> (z-I)/(z+I) OUTPUT: - ''ca'' -- a polygonal approximation of a circular arc centered at c and radius r, starting at t0 and ending at t1 EXAMPLES:: sage: l=_geodesic_between_two_points_d(0.1,0.2,0.0,0.5) """ pi=RR.pi() from sage.plot.plot import line from sage.functions.trig import (cos,sin) # First compute the points if(y1<0 or y2<0 ): raise ValueError,"Need points in the upper half-plane! Got y1=%s, y2=%s" %(y1,y2) if(y1==infinity): P1=CC(1 ) else: P1=CC((x1+I*y1-z0)/(x1+I*y1-z0.conjugate())) if(y2==infinity): P2=CC(1 ) else: P2=CC((x2+I*y2-z0)/(x2+I*y2-z0.conjugate())) # First find the endpoints of the completed geodesic in D if(x1==x2): a=CC((x1-z0)/(x1-z0.conjugate())) b=CC(1 ) else: c=RR(y1**2 -y2**2 +x1**2 -x2**2 )/RR(2 *(x1-x2)) r=RR(sqrt(y1**2 +(x1-c)**2 )) a=c-r b=c+r a=CC((a-z0)/(a-z0.conjugate())) b=CC((b-z0)/(b-z0.conjugate())) if( abs(a+b) < 1E-10 ): # On a diagonal return line([[P1.real(),P1.imag()],[P2.real(),P2.imag()]]) th_a=a.argument() th_b=b.argument() # Compute the center of the circle in the disc model if( min(abs(b-1 ),abs(b+1 ))< 1E-10 and min(abs(a-1 ),abs(a+1 ))>1E-10 ): c=b+I*(1 -b*cos(th_a))/sin(th_a) elif( min(abs(b-1 ),abs(b+1 ))> 1E-10 and min(abs(a-1 ),abs(a+1 ))<1E-10 ): c=a+I*(1 -a*cos(th_b))/RR(sin(th_b)) else: cx=(sin(th_b)-sin(th_a))/sin(th_b-th_a) c=cx+I*(1 -cx*cos(th_b))/RR(sin(th_b)) # First find the endpoints of the completed geodesic r=abs(c-a) t1=CC(P1-c).argument() t2=CC(P2-c).argument() #print "t1,t2=",t1,t2 return _circ_arc(t1,t2,c,r)
def _geodesic_between_two_points_d(x1, y1, x2, y2, z0=I): r""" Geodesic path between two points represented in the unit disc by the map w = (z-I)/(z+I) INPUTS: - ''(x1,y1)'' -- starting point (0<y1<=infinity) - ''(x2,y2)'' -- ending point (0<y2<=infinity) - ''z0'' -- (default I) the point in the upper corresponding to the point 0 in the disc. I.e. the transform is w -> (z-I)/(z+I) OUTPUT: - ''ca'' -- a polygonal approximation of a circular arc centered at c and radius r, starting at t0 and ending at t1 EXAMPLES:: sage: l=_geodesic_between_two_points_d(0.1,0.2,0.0,0.5) """ pi = RR.pi() from sage.plot.plot import line from sage.functions.trig import (cos, sin) # First compute the points if (y1 < 0 or y2 < 0): raise ValueError, "Need points in the upper half-plane! Got y1=%s, y2=%s" % ( y1, y2) if (y1 == infinity): P1 = CC(1) else: P1 = CC((x1 + I * y1 - z0) / (x1 + I * y1 - z0.conjugate())) if (y2 == infinity): P2 = CC(1) else: P2 = CC((x2 + I * y2 - z0) / (x2 + I * y2 - z0.conjugate())) # First find the endpoints of the completed geodesic in D if (x1 == x2): a = CC((x1 - z0) / (x1 - z0.conjugate())) b = CC(1) else: c = RR(y1**2 - y2**2 + x1**2 - x2**2) / RR(2 * (x1 - x2)) r = RR(sqrt(y1**2 + (x1 - c)**2)) a = c - r b = c + r a = CC((a - z0) / (a - z0.conjugate())) b = CC((b - z0) / (b - z0.conjugate())) if (abs(a + b) < 1E-10): # On a diagonal return line([[P1.real(), P1.imag()], [P2.real(), P2.imag()]]) th_a = a.argument() th_b = b.argument() # Compute the center of the circle in the disc model if (min(abs(b - 1), abs(b + 1)) < 1E-10 and min(abs(a - 1), abs(a + 1)) > 1E-10): c = b + I * (1 - b * cos(th_a)) / sin(th_a) elif (min(abs(b - 1), abs(b + 1)) > 1E-10 and min(abs(a - 1), abs(a + 1)) < 1E-10): c = a + I * (1 - a * cos(th_b)) / RR(sin(th_b)) else: cx = (sin(th_b) - sin(th_a)) / sin(th_b - th_a) c = cx + I * (1 - cx * cos(th_b)) / RR(sin(th_b)) # First find the endpoints of the completed geodesic r = abs(c - a) t1 = CC(P1 - c).argument() t2 = CC(P2 - c).argument() #print "t1,t2=",t1,t2 return _circ_arc(t1, t2, c, r)