color distribution plot
[imago.git] / geometry.py
1 """Imago geometry module"""
2
3 from math import sin, cos, atan, pi
4
5 class V(object):
6     def __init__(self, x, y):
7         self.x = x
8         self.y = y
9     
10     def __add__(self, other):
11         return V(self.x + other.x, self.y + other.y)
12
13     def __sub__(self, other):
14         return V(self.x - other.x, self.y - other.y)
15
16     def __rmul__(self, other):
17         return V(other * self.x, other * self.y)
18
19     def __len__(self):
20         return 2
21
22     def __getitem__(self, key):
23         if key == 0:
24             return self.x
25         elif key == 1:
26             return self.y
27         elif type(key) != int:
28             raise TypeError("V indices must be integers") 
29         else:
30             raise KeyError("V index ({}) out of range".format(key))
31
32     def __iter__(self):
33         yield self.x
34         yield self.y
35
36     @property
37     def normal(self):
38         return V(-self.y, self.x)
39
40 def projection(p, l, v):
41     return V(*intersection(line(p, p + v.normal), line(*l)))
42
43 def l2ad((a, b), size):
44     """Represent line as (angle, distance).
45     
46     Take a line (represented by two points) and image size.
47     Return the line represented by its angle and distance
48     from the center of the image.
49
50     """
51     if (a[0] - b[0]) == 0:
52         angle = pi / 2
53     else:
54         q = float(a[1] - b[1]) / (a[0] - b[0])
55         angle = atan(q)
56
57     if angle < 0:
58         angle += pi
59     if angle > pi:
60         angle -= pi
61
62     distance = (((a[0] - (size[0] / 2)) * sin(angle)) + 
63                 ((a[1] - (size[1] / 2)) * - cos(angle)))
64     return (angle, distance)
65
66 def line(x, y):
67     """Return parametric representation of line."""
68     a = x[1] - y[1]
69     b = y[0] - x[0]
70     c = a * y[0] + b * y[1]
71     return (a, b, c)
72
73 def intersection(p, q):
74     """Return intersection of two lines."""
75     det = p[0] * q[1] - p[1] * q[0]
76     if det == 0:
77         return None
78     return (int(round(float(q[1] * p[2] - p[1] * q[2]) / det)), 
79             int(round(float(p[0] * q[2] - q[0] * p[2]) / det)))