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
|
#!/usr/bin/env python
"""
ffgeom.py
Copyright (C) 2005 Aaron Cyril Spike, aaron@ekips.org
This file is part of FretFind 2-D.
FretFind 2-D is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FretFind 2-D 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.
You should have received a copy of the GNU General Public License
along with FretFind 2-D; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
import math
try:
NaN = float('NaN')
except ValueError:
PosInf = 1e300000
NaN = PosInf/PosInf
class Point:
precision = 5
def __init__(self, x, y):
self.__coordinates = {'x' : float(x), 'y' : float(y)}
def __getitem__(self, key):
return self.__coordinates[key]
def __setitem__(self, key, value):
self.__coordinates[key] = float(value)
def __repr__(self):
return '(%s, %s)' % (round(self['x'],self.precision),round(self['y'],self.precision))
def copy(self):
return Point(self['x'],self['y'])
def translate(self, x, y):
self['x'] += x
self['y'] += y
def move(self, x, y):
self['x'] = float(x)
self['y'] = float(y)
class Segment:
def __init__(self, e0, e1):
self.__endpoints = [e0, e1]
def __getitem__(self, key):
return self.__endpoints[key]
def __setitem__(self, key, value):
self.__endpoints[key] = value
def __repr__(self):
return repr(self.__endpoints)
def copy(self):
return Segment(self[0],self[1])
def translate(self, x, y):
self[0].translate(x,y)
self[1].translate(x,y)
def move(self,e0,e1):
self[0] = e0
self[1] = e1
def delta_x(self):
return self[1]['x'] - self[0]['x']
def delta_y(self):
return self[1]['y'] - self[0]['y']
#alias functions
run = delta_x
rise = delta_y
def slope(self):
if self.delta_x() != 0:
return self.delta_x() / self.delta_y()
return NaN
def intercept(self):
if self.delta_x() != 0:
return self[1]['y'] - (self[0]['x'] * self.slope())
return NaN
def distanceToPoint(self, p):
len = self.length()
if len == 0: return NaN
return math.fabs(((self[1]['x'] - self[0]['x']) * (self[0]['y'] - p['y'])) - \
((self[0]['x'] - p['x']) * (self[1]['y'] - self[0]['y']))) / len
def angle(self):
return math.pi * (math.atan2(self.delta_y(), self.delta_x())) / 180
def length(self):
return math.sqrt((self.delta_x() ** 2) + (self.delta_y() ** 2))
def pointAtLength(self, len):
if self.length() == 0: return Point(NaN, NaN)
ratio = len / self.length()
x = self[0]['x'] + (ratio * self.delta_x())
y = self[0]['y'] + (ratio * self.delta_y())
return Point(x, y)
def pointAtRatio(self, ratio):
if self.length() == 0: return Point(NaN, NaN)
x = self[0]['x'] + (ratio * self.delta_x())
y = self[0]['y'] + (ratio * self.delta_y())
return Point(x, y)
def createParallel(self, p):
return Segment(Point(p['x'] + self.delta_x(), p['y'] + self.delta_y()), p)
def intersect(self, s):
return intersectSegments(self, s)
def intersectSegments(s1, s2):
x1 = s1[0]['x']
x2 = s1[1]['x']
x3 = s2[0]['x']
x4 = s2[1]['x']
y1 = s1[0]['y']
y2 = s1[1]['y']
y3 = s2[0]['y']
y4 = s2[1]['y']
denom = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1))
num1 = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3))
num2 = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3))
num = num1
if denom != 0:
x = x1 + ((num / denom) * (x2 - x1))
y = y1 + ((num / denom) * (y2 - y1))
return Point(x, y)
return Point(NaN, NaN)
|