Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

""" 

Arcs in hyperbolic geometry 

 

AUTHORS: 

 

- Hartmut Monien (2011 - 08) 

""" 

#***************************************************************************** 

# Copyright (C) 2011 Hartmut Monien <monien@th.physik.uni-bonn.de>, 

# 2015 Stefan Kraemer <skraemer@th.physik.uni-bonn.de> 

# 2016 Javier Honrubia <jhonrubia6@uned.es> 

# 

# Distributed under the terms of the GNU General Public License (GPL) 

# 

# This code is distributed in the hope that it will be useful, 

# but WITHOUT ANY WARRANTY; without even the implied warranty of 

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 

# General Public License for more details. 

# 

# The full text of the GPL is available at: 

# 

# http://www.gnu.org/licenses/ 

#***************************************************************************** 

from __future__ import print_function 

 

from sage.plot.bezier_path import BezierPath 

from sage.plot.colors import to_mpl_color 

from sage.plot.misc import options, rename_keyword 

from sage.rings.all import CC 

 

class HyperbolicArc(BezierPath): 

""" 

Primitive class for hyberbolic arc type. See ``hyperbolic_arc?`` for 

information about plotting a hyperbolic arc in the complex plane. 

 

INPUT: 

 

- ``a, b`` - coordinates of the hyperbolic arc in the complex plane 

- ``options`` - dict of valid plot options to pass to constructor 

 

EXAMPLES: 

 

Note that constructions should use ``hyperbolic_arc``:: 

 

sage: from sage.plot.hyperbolic_arc import HyperbolicArc 

 

sage: print(HyperbolicArc(0, 1/2+I*sqrt(3)/2, {})) 

Hyperbolic arc (0.000000000000000, 0.500000000000000 + 0.866025403784439*I) 

""" 

 

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 _repr_(self): 

""" 

String representation of HyperbolicArc. 

 

TESTS:: 

 

sage: from sage.plot.hyperbolic_arc import HyperbolicArc 

sage: HyperbolicArc(0, 1/2+I*sqrt(3)/2, {})._repr_() 

'Hyperbolic arc (0.000000000000000, 0.500000000000000 + 0.866025403784439*I)' 

""" 

 

return "Hyperbolic arc (%s, %s)" % (self.A, self.B) 

 

def _hyperbolic_arc(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. 

""" 

z0, z3 = (CC(z0), CC(z3)) 

p = (abs(z0)*abs(z0)-abs(z3)*abs(z3))/(z0-z3).real()/2 

r = abs(z0-p) 

 

if abs(z3-z0)/r < 0.1: 

self.path.append([(z0.real(),z0.imag()), (z3.real(),z3.imag())]) 

return 

 

if z0.imag() == 0 and z3.imag() == 0: 

p = (z0.real()+z3.real())/2 

zm = CC(p, r) 

self._hyperbolic_arc(z0, zm, first) 

self._hyperbolic_arc(zm, z3) 

return 

else: 

zm = ((z0+z3)/2-p)/abs((z0+z3)/2-p)*r+p 

t = (8*zm-4*(z0+z3)).imag()/3/(z3-z0).real() 

z1 = z0 + t*CC(z0.imag(), (p-z0.real())) 

z2 = z3 - t*CC(z3.imag(), (p-z3.real())) 

if first: 

self.path.append([(z0.real(), z0.imag()), 

(z1.real(), z1.imag()), 

(z2.real(), z2.imag()), 

(z3.real(), z3.imag())]); 

first = False 

else: 

self.path.append([(z1.real(), z1.imag()), 

(z2.real(), z2.imag()), 

(z3.real(), z3.imag())]); 

 

@rename_keyword(color='rgbcolor') 

@options(alpha=1, fill=False, thickness=1, rgbcolor="blue", zorder=2, linestyle='solid') 

def hyperbolic_arc(a, b, **options): 

""" 

Plot an arc from a to b in hyperbolic geometry in the complex upper 

half plane. 

 

INPUT: 

 

- ``a, b`` - complex numbers in the upper half complex plane 

connected bye the arc 

 

OPTIONS: 

 

- ``alpha`` - default: 1 

 

- ``thickness`` - default: 1 

 

- ``rgbcolor`` - default: 'blue' 

 

- ``linestyle`` - (default: ``'solid'``) The style of the line, which is one 

of ``'dashed'``, ``'dotted'``, ``'solid'``, ``'dashdot'``, or ``'--'``, 

``':'``, ``'-'``, ``'-.'``, respectively. 

 

Examples: 

 

Show a hyperbolic arc from 0 to 1:: 

 

sage: hyperbolic_arc(0, 1) 

Graphics object consisting of 1 graphics primitive 

 

Show a hyperbolic arc from 1/2 to `i` with a red thick line:: 

 

sage: hyperbolic_arc(1/2, I, color='red', thickness=2) 

Graphics object consisting of 1 graphics primitive 

 

Show a hyperbolic arc form `i` to `2 i` with dashed line:: 

 

sage: hyperbolic_arc(I, 2*I, linestyle='dashed') 

Graphics object consisting of 1 graphics primitive 

sage: hyperbolic_arc(I, 2*I, linestyle='--') 

Graphics object consisting of 1 graphics primitive 

""" 

from sage.plot.all import Graphics 

g = Graphics() 

g._set_extra_kwds(g._extract_kwds_for_show(options)) 

g.add_primitive(HyperbolicArc(a, b, options)) 

g.set_aspect_ratio(1) 

return g