def __init__(self, A, B, options): A, B = (CC(A), CC(B)) if A.imag()<0: raise ValueError("%s is not a valid point in the UHP model"%(A)) if B.imag()<0: raise ValueError("%s is not a valid point in the UHP model"%(B)) self.path = [] self._hyperbolic_arc(A, B, True); BezierPath.__init__(self, self.path, options) self.A, self.B = (A, B)
def __init__(self, A, B, options): A, B = (CC(A), CC(B)) if A.imag() < 0: raise ValueError("%s is not a valid point in the UHP model" % (A)) if B.imag() < 0: raise ValueError("%s is not a valid point in the UHP model" % (B)) self.path = [] self._hyperbolic_arc(A, B, True) BezierPath.__init__(self, self.path, options) self.A, self.B = (A, B)
def __init__(self, A, B, C, options): """ Initialize HyperbolicTriangle: Examples:: sage: from sage.plot.hyperbolic_triangle import HyperbolicTriangle sage: print HyperbolicTriangle(0, 1/2, I, {}) Hyperbolic triangle (0.000000000000000, 0.500000000000000, 1.00000000000000*I) """ A, B, C = (CC(A), CC(B), CC(C)) self.path = [] sides = options.pop('sides', [1, 2, 3]) verbose = options.pop('verbose', 0) sides.sort() if sides == [1]: if verbose > 0: print "Drawing A - B!" self._hyperbolic_arc(A, B, True) elif sides == [2]: if verbose > 0: print "Drawing B - C!" self._hyperbolic_arc(B, C, True) elif sides == [3]: if verbose > 0: print "Drawing C - A!" self._hyperbolic_arc(C, A, True) elif sides == [1, 2]: if verbose > 0: print "Drawing A - B! & B - C!" self._hyperbolic_arc(A, B, True) self._hyperbolic_arc(B, C, False) elif sides == [1, 3]: if verbose > 0: print "Drawing C - A! & A - B" self._hyperbolic_arc(C, A, True) self._hyperbolic_arc(A, B, False) elif sides == [2, 3]: if verbose > 0: print "Drawing B - C! & C - A" self._hyperbolic_arc(B, C, True) self._hyperbolic_arc(C, A, False) else: self._hyperbolic_arc(A, B, True) self._hyperbolic_arc(B, C, False) self._hyperbolic_arc(C, A, False) BezierPath.__init__(self, self.path, options) self.A, self.B, self.C = (A, B, C) self._pts = [A, B, C]
def __init__(self, A, B, C, options): """ Initialize HyperbolicTriangle: Examples:: sage: from sage.plot.hyperbolic_triangle import HyperbolicTriangle sage: print HyperbolicTriangle(0, 1/2, I, {}) Hyperbolic triangle (0.000000000000000, 0.500000000000000, 1.00000000000000*I) """ A, B, C = (CC(A), CC(B), CC(C)) self.path = [] sides = options.pop('sides',[1,2,3]) verbose=options.pop('verbose',0) sides.sort() if sides == [1]: if verbose>0: print "Drawing A - B!" self._hyperbolic_arc(A, B, True); elif sides == [2]: if verbose>0: print "Drawing B - C!" self._hyperbolic_arc(B, C, True); elif sides == [3]: if verbose>0: print "Drawing C - A!" self._hyperbolic_arc(C, A, True); elif sides == [1,2]: if verbose>0: print "Drawing A - B! & B - C!" self._hyperbolic_arc(A, B, True); self._hyperbolic_arc(B, C, False); elif sides == [1,3]: if verbose>0: print "Drawing C - A! & A - B" self._hyperbolic_arc(C, A,True) self._hyperbolic_arc(A, B, False) elif sides == [2,3]: if verbose>0: print "Drawing B - C! & C - A" self._hyperbolic_arc(B, C,True) self._hyperbolic_arc(C, A, False) else: self._hyperbolic_arc(A, B,True) self._hyperbolic_arc(B, C,False) self._hyperbolic_arc(C, A, False) BezierPath.__init__(self, self.path, options) self.A, self.B, self.C = (A, B, C) self._pts = [A,B,C]
def __init__(self, A, B, C, options): """ Initialize HyperbolicTriangle: Examples:: sage: from sage.plot.hyperbolic_triangle import HyperbolicTriangle sage: print HyperbolicTriangle(0, 1/2, I, {}) Hyperbolic triangle (0.000000000000000, 0.500000000000000, 1.00000000000000*I) """ A, B, C = (CC(A), CC(B), CC(C)) self.path = [] self._hyperbolic_arc(A, B, True) self._hyperbolic_arc(B, C) self._hyperbolic_arc(C, A) BezierPath.__init__(self, self.path, options) self.A, self.B, self.C = (A, B, C)
def __init__(self, A, B, C, options): """ Initialize HyperbolicTriangle: Examples:: sage: from sage.plot.hyperbolic_triangle import HyperbolicTriangle sage: print HyperbolicTriangle(0, 1/2, I, {}) Hyperbolic triangle (0.000000000000000, 0.500000000000000, 1.00000000000000*I) """ A, B, C = (CC(A), CC(B), CC(C)) self.path = [] self._hyperbolic_arc(A, B, True); self._hyperbolic_arc(B, C); self._hyperbolic_arc(C, A); BezierPath.__init__(self, self.path, options) self.A, self.B, self.C = (A, B, C)
def __init__(self, pts, options): """ Initialize HyperbolicPolygon. EXAMPLES:: sage: from sage.plot.hyperbolic_polygon import HyperbolicPolygon sage: print HyperbolicPolygon([0, 1/2, I], {}) Hyperbolic polygon (0.000000000000000, 0.500000000000000, 1.00000000000000*I) """ pts = [CC(_) for _ in pts] self.path = [] self._hyperbolic_arc(pts[0], pts[1], True) for i in range(1, len(pts) - 1): self._hyperbolic_arc(pts[i], pts[i + 1]) self._hyperbolic_arc(pts[-1], pts[0]) BezierPath.__init__(self, self.path, options) self._pts = pts
def __init__(self, pts, options): """ Initialize HyperbolicPolygon. EXAMPLES:: sage: from sage.plot.hyperbolic_polygon import HyperbolicPolygon sage: print(HyperbolicPolygon([0, 1/2, I], {})) Hyperbolic polygon (0.000000000000000, 0.500000000000000, 1.00000000000000*I) """ pts = [CC(_) for _ in pts] self.path = [] self._hyperbolic_arc(pts[0], pts[1], True) for i in range(1, len(pts) - 1): self._hyperbolic_arc(pts[i], pts[i + 1]) self._hyperbolic_arc(pts[-1], pts[0]) BezierPath.__init__(self, self.path, options) self._pts = pts
def bezier_path(self): """ Return ``self`` as a Bezier path. This is needed to concatenate arcs, in order to create hyperbolic polygons. EXAMPLES:: sage: from sage.plot.arc import Arc sage: op = {'alpha':1,'thickness':1,'rgbcolor':'blue','zorder':0, ....: 'linestyle':'--'} sage: Arc(2,3,2.2,2.2,0,2,3,op).bezier_path() Graphics object consisting of 1 graphics primitive sage: a = arc((0,0),2,1,0,(pi/5,pi/2+pi/12), linestyle="--", color="red") sage: b = a[0].bezier_path() sage: b[0] Bezier path from (1.133..., 0.8237...) to (-0.2655..., 0.9911...) """ from sage.plot.bezier_path import BezierPath from sage.plot.graphics import Graphics from matplotlib.path import Path import numpy as np ma = self._matplotlib_arc() def theta_stretch(theta, scale): theta = np.deg2rad(theta) x = np.cos(theta) y = np.sin(theta) return np.rad2deg(np.arctan2(scale * y, x)) theta1 = theta_stretch(ma.theta1, ma.width / ma.height) theta2 = theta_stretch(ma.theta2, ma.width / ma.height) pa = ma pa._path = Path.arc(theta1, theta2) transform = pa.get_transform().get_matrix() cA, cC, cE = transform[0] cB, cD, cF = transform[1] points = [] for u in pa._path.vertices: x, y = list(u) points += [(cA * x + cC * y + cE, cB * x + cD * y + cF)] cutlist = [points[0:4]] N = 4 while N < len(points): cutlist += [points[N:N + 3]] N += 3 g = Graphics() opt = self.options() opt['fill'] = False g.add_primitive(BezierPath(cutlist, opt)) return g
def bezier_path(self): """ Return ``self`` as a Bezier path. This is needed to concatenate arcs, in order to create hyperbolic polygons. EXAMPLES:: sage: from sage.plot.arc import Arc sage: op = {'alpha':1,'thickness':1,'rgbcolor':'blue','zorder':0, ....: 'linestyle':'--'} sage: Arc(2,3,2.2,2.2,0,2,3,op).bezier_path() Graphics object consisting of 1 graphics primitive sage: a = arc((0,0),2,1,0,(pi/5,pi/2+pi/12), linestyle="--", color="red") sage: b = a[0].bezier_path() sage: b[0] Bezier path from (1.618..., 0.5877...) to (-0.5176..., 0.9659...) """ from sage.plot.bezier_path import BezierPath from sage.plot.graphics import Graphics ma = self._matplotlib_arc() transform = ma.get_transform().get_matrix() cA, cC, cE = transform[0] cB, cD, cF = transform[1] points = [] for u in ma._path.vertices: x, y = list(u) points += [(cA * x + cC * y + cE, cB * x + cD * y + cF)] cutlist = [points[0:4]] N = 4 while N < len(points): cutlist += [points[N:N + 3]] N += 3 g = Graphics() opt = self.options() opt['fill'] = False g.add_primitive(BezierPath(cutlist, opt)) return g
def graphplot(self, **options): options['edge_colors'] = { EDGE_COLOR: self._edges, ARC_COLOR: self._arcs } gp = DiGraph.graphplot(self, **options) for i in range(self.size()): a = gp._plot_components['edges'][i][0] if a.options()['rgbcolor'] == EDGE_COLOR: if isinstance(a, CurveArrow): gp._plot_components['edges'][i][0] = \ BezierPath(a.path, {'alpha': 1, 'fill': False, 'linestyle': 'solid', 'rgbcolor': EDGE_COLOR, 'thickness': 1, 'zorder': 1}) else: gp._plot_components['edges'][i][0] = \ Line([a.xhead, a.xtail], [a.yhead, a.ytail], {'alpha': 1, 'legend_color': None, 'legend_label': None, 'linestyle': 'solid', 'rgbcolor': EDGE_COLOR, 'thickness': 1}) return gp
def __init__(self, A, B, options): A, B = (CC(A), CC(B)) self.path = [] self._hyperbolic_arc(A, B, True) BezierPath.__init__(self, self.path, options) self.A, self.B = (A, B)
def _hyperbolic_arc_d(self, z0, z3, first=False): """ Function to construct Bezier path as an approximation to the hyperbolic arc between the complex numbers z0 and z3 in the hyperbolic plane. """ w0 = self._cayley_transform(z0) w3 = self._cayley_transform(z3) if self._verbose > 0: print "in plane z0,z3=", z0, z3 print "in disc: ", w0, w3 npts = self._npts if z0 == infinity or z0 == CC(infinity): zm = [z3 + CC(0, j + 0.5) for j in range(npts - 2)] wm = [self._cayley_transform(x) for x in zm] pts = [w3] pts.extend(wm) pts.append(w0) opt = self._options opt['fill'] = False self._graphics.add_primitive( BezierPath([[(x.real(), x.imag()) for x in pts]], opt)) return if z3 == infinity or z3 == CC(infinity): zm = [z0 + CC(0, j + 0.5) for j in range(npts - 2)] wm = [self._cayley_transform(x) for x in zm] pts = [w0] pts.extend(wm) pts.append(w3) opt = self._options opt['fill'] = False self._graphics.add_primitive( BezierPath([[(x.real(), x.imag()) for x in pts]], opt)) #self._graphics.add_primitive(Line([w1.real(),w2.real()],[w1.imag(),w2.imag()],self._options)) #self.path.append([(0,w0.imag()),CC(0,y), (0,w3.imag())]) return x0 = z0.real() y0 = z0.imag() x3 = z3.real() y3 = z3.imag() if y0 == 0 and y3 == 0: p = (z0.real() + z3.real()) / 2 r = abs(z0 - p) zm = CC(p, r) self._hyperbolic_arc_d(z0, zm, first) self._hyperbolic_arc_d(zm, z3) return else: if abs(x0 - x3) < 1e-10: ## on the same vertical line xmid = (x0 + x3) * 0.5 h = y3 - y0 zm = [CC(xmid, y0 + t * h / (npts - 1)) for t in range(npts)] else: p = RR((x0 + x3) * (x3 - x0) + (y0 + y3) * (y3 - y0)) / (2 * (x3 - x0)) r = RR((p - x0)**2 + y0**2).sqrt() # radius of the circle in H zm = ((z0 + z3) / 2 - p) / abs( (z0 + z3) / 2 - p ) * r + p # midpoint (at least approximately) of geodesic between z0 and z3 t0 = CC(z0 - p).argument() t3 = CC(z3 - p).argument() if self._verbose > 1: print "x0,x3=", x0, x3 print "t0,t3=", t0, t3 print "r=", r print "opt=", self._options if x0 <= x3: zm = [ p + r * CC(0, (t0 + t * (t3 - t0) / (npts - 1))).exp() for t in range(npts) ] else: zm = [ p + r * CC(0, (t0 + t * (t3 - t0) / (npts - 1))).exp() for t in range(npts) ] #print "zm=",zm #zm.insert(0,z0) #zm.append(z3) pts = [self._cayley_transform(x) for x in zm] opt = self._options opt['fill'] = False #w0 = self._cayley_transform(z0) #w3 = self._cayley_transform(z3) if self._verbose > 2: print "pts=", pts self._graphics.add_primitive( BezierPath([[(x.real(), x.imag()) for x in pts]], opt)) return #print "z0_test=",(p+r*exp(t0*I)) #print "z3_test=",(p+r*exp(t3*I)) #t = (8*zm-4*(z0+z3)).imag()/3/(z3-z0).real() # I have no idea what these points should represent.... #z1 = z0 + t*CC(z0.imag(), (p-z0.real())) #z2 = z3 - t*CC(z3.imag(), (p-z3.real())) wm = [self._cayley_transform(x) for x in zm] pp = self._cayley_transform(CC(p, 0)) w1 = self._cayley_transform(z0) w2 = self._cayley_transform(z3) c = self._cayley_transform(CC( p, 0)) # center of circle on the unit disk. if self._verbose > 2: print "p,r=", p, r print "zm=", zm #print "t=",t #print "tt=",(8*zm-4*(z0+z3)).imag()/3/(z3-z0).real() print "C(c)=", pp print "C(zm)=", wm print "C(z0)=", w1 print "C(z3)=", w2 #print "z2=",z2 r = abs(w1 - c) # radius t0 = CC(w0 - pp).argument() t3 = CC(w3 - pp).argument() t = abs(t0 - t3) if self._verbose > 0: print "adding a:rc ", zm.real(), zm.imag(), r, r, t, t0, t3 self._graphics.add_primitive( Line([w1.real(), w2.real(), wm.real()], [w1.imag(), w2.imag(), wm.imag()], { 'thickness': 2, 'alpha': 1, 'rgbcolor': 'blue', 'legend_label': "" })) self._graphics.add_primitive( Point( [w1.real(), w2.real(), wm.real()], [w1.imag(), w2.imag(), wm.imag()], { 'size': 10, 'alpha': 1, 'faceted': True, 'rgbcolor': 'red', 'legend_label': "" }))
def __init__(self, A, B, options): A, B = (CC(A), CC(B)) self.path = [] self._hyperbolic_arc(A, B, True); BezierPath.__init__(self, self.path, options) self.A, self.B = (A, B)
# In[29]: arrow((0, 0), (1, 1)) # In[30]: arrow((0, 0, 1), (1, 1, 1)) # In[32]: from sage.plot.bezier_path import BezierPath # In[33]: BezierPath([[(0, 0), (0.5, 0.5), (1, 0)], [(0.5, 1), (0, 0)]], {'linestyle': 'dashed'}) # In[41]: bezier_path([[(0, 0), (.5, .5), (1, 0)], [(.5, 1), (0, 0)]], linestyle="dashed") # In[45]: b = bezier_path([[(0, 0), (.5, .5), (1, 0)], [(.5, 1), (0, 0)]], linestyle="dashed") d = b.get_minmax_data() d['xmin'] # In[46]: