-
Notifications
You must be signed in to change notification settings - Fork 0
/
segment.py
150 lines (107 loc) · 4.17 KB
/
segment.py
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
#!/usr/bin/env python
class segment(object):
"""A class for segments of lines in the complex plane.
EXAMPLES:
>>> segment(complex(0,0),complex(0,1))
0j ---> 1j
"""
def __init__(self,u,v):
t = type(complex(0,0))
if type(u) != t or type(v) != t:
raise ValueError, "Arguments must be complex numbers."
self.u = u
self.v = v
def __repr__(self):
return '%s ---> %s' %(self.u, self.v)
def __eq__(self, other):
return self.u == other.u and self.v == other.v
def length(self):
"""Returns the length of the segment.
EXAMPLES:
>>> segment(complex(0,0),complex(0,1)).length()
1.0
"""
return abs(self.u - self.v)
def reverse(self):
"""Reverses the direction of a segment.
EXAMPLES:
>>> segment(complex(0,0),complex(0,1)).reverse()
"""
return segment(self.v, self.u)
def intersects(self, other):
"""Returns True if two segments intersect internally.
EXAMPLES:
>>> a = segment(complex(0,-1),complex(0,1))
>>> b = segment(complex(-1,0),complex(1,0))
>>> a.intersects(b)
True
"""
ao = triangle( self.v, other.u, other.v ).clockwise() != \
triangle( self.u, other.u, other.v ).clockwise()
ac = triangle( self.u, self.v, other.v ).clockwise() != \
triangle( self.u, self.v, other.u ).clockwise()
return ao and ac
def intersection(self, other):
"""Returns the intersection of the lines defined by the two segments.
EXAMPLES:
>>> a = segment(complex(0,-1),complex(0,1))
>>> b = segment(complex(-1,0),complex(1,0))
>>> a.intersection(b)
(-0-0j)
"""
den = (self.u.real-self.v.real)*(other.u.imag-other.v.imag)-\
(self.u.imag-self.v.imag)*(other.u.real-other.v.real)
if abs(den) < 0.001:
return ValueError, "Lines are too close to parallel."
x = self.u.real*self.v.imag-self.u.imag*self.v.real
y = other.u.real*other.v.imag-other.u.imag*other.v.real
nx = x*(other.u.real-other.v.real)-y*(self.u.real-self.v.real)
ny = x*(other.u.imag-other.v.imag)-y*(self.u.imag-self.v.imag)
return complex(nx/den, ny/den)
class triangle(object):
"""A class for triangles in the complex plane.
EXAMPLES:
>>> triangle(complex(0,0),complex(0,1), complex(1,0) )
[0j, 1j, (1+0j)]
"""
def __init__(self,u,v,w):
t = type(complex(0,0))
if type(u) != t or type(v) != t or type(w) != t:
raise ValueError, "Arguments must be complex numbers."
self.u = u
self.v = v
self.w = w
def __repr__(self):
return str([self.u, self.v, self.w])
def __eq__(self, other):
return self.u == other.u and self.v == other.v and self.w == other.w
def area(self):
"""Twice the signed area of a triangle in the complex plane.
EXAMPLES:
>>> triangle(complex(0,0),complex(0,1), complex(1,0) ).area()
-1.0
"""
return (self.w.imag-self.u.imag)*(self.v.real-self.u.real)-\
(self.w.real-self.u.real)*(self.v.imag-self.u.imag)
def clockwise(self):
"""Returns True if oriented clockwise
and False if oriented anticlockwise.
EXAMPLES:
>>> triangle(complex(0,0),complex(0,1), complex(1,0) ).clockwise()
False
"""
return self.area < 0
def inside(self,z):
"""Returns True if the point z is inside the triangle self.
EXAMPLES:
>>> triangle(complex(0,0),complex(0,1), complex(1,0) ).inside(complex(2,0))
False
"""
return triangle(self.u, self.v, z).clockwise() \
and triangle(self.v, self.w, z).clockwise() \
and triangle(self.w, self.u, z).clockwise()
# This is to run the tests in the examples.
# http://docs.python.org/library/doctest.html
if __name__ == "__main__":
import doctest
doctest.testmod()