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 __all__ = ['poly_info', 'isInsidePoly', 'smallestEnclosingBall',
26 'distanceToPlane']
27
28 from numpy import allclose, dot, zeros
29 from numpy.linalg import norm
30
31 from pycv.cs import arrayd
32 from pycv.ext import cg_poly_info, cg_inside_poly, cg_smallest_enclosing_ball
33
35 """Compute the area of a polygon.
36
37 Input:
38 poly: a numpy array of shape (N,2) representing a polygon
39 Output:
40 (x, y) : centroid location
41 area : area of the polygon
42 direction : direction to differentiate between clockwise and
43 counter-clockwise
44 """
45 info = zeros(3)
46 cg_poly_info(arrayd(poly),info)
47 return info[:2], abs(info[2]), int(info[2] >= 0)
48
50 """
51 Check if point (x,y) is inside a polygon or not.
52
53 Input:
54 x: x location
55 y: y location
56 poly: a numpy array of shape (N,2) representing a polygon
57 Output:
58 1 if (x,y) is inside the polygon, 0 otherwise.
59
60 Reference:
61 W. Randolph Franklin (WRF) at
62 http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
63 """
64 return cg_inside_poly(float(x), float(y), arrayd(poly))
65
67 """Compute a (hyper-)ball of smallest radius enclosing a point set.
68
69 :Parameters:
70 a : array(shape=(N,d), dtype='d')
71 an array of N d-dimensional points
72
73 :Returns:
74 p : array(shape=(d,), dtype='d')
75 center point of the (hyper-)ball
76 r : double
77 its *squared* radius, supposed to be the smallest possible value
78 support_array : array(shape=(M,d), dtype='d')
79 an array of supporting points, M is the number of supporting points
80 accuracy : double
81 relative accuracy of the solution
82 slack : double
83 slack value
84
85 Reference:
86 This is a re-implementation from scratch based on the idea of
87 Bernd Gaertner at http://www.inf.ethz.ch/personal/gaertner
88 by Minh-Tri Pham
89 """
90 a = arrayd(a)
91
92 (N,d) = a.shape
93 outvec = zeros(d+1)
94 supvec = zeros((N,d))
95 statsd = zeros(2,'double')
96
97 nsp = cg_smallest_enclosing_ball(a, N, d, outvec, supvec, statsd)
98
99 return outvec[:d],float(outvec[d]),supvec[:nsp],float(statsd[0]),float(statsd[1])
100
102 """Compute the value(s) proportional to the L2 distance(s) of a point or a
103 set of points to a plane.
104
105 :Parameters:
106 a : array(shape=(*,d), dtype='d')
107 a point or a set of points in a d-dimensional space
108 plane : array(shape=(d+1,), dtype='d')
109 a set of parameters representing the plane
110 i.e. a0*x0 + a1*x1 + ... + a_{d-1}*x_{d-1} + a_d = 0
111
112 :Returns:
113 b : array(shape=(*), dtype ='d')
114 a value or a set of values representing the value(s) proportional
115 to the L2 distance(s)
116 alpha : double
117 a value representing the proportion, divide the value(s) by this
118 number to get the L2 distance(s)
119 """
120 d = plane.size - 1
121
122 ishape = a.shape[:-1]
123 if d != a.shape[-1]:
124 raise IndexError('The shape of the first argument is not correct.')
125
126 pa = plane[:d]
127 x0 = plane[d]
128
129 alpha = norm(pa)
130 if allclose(alpha,0):
131 raise ValueError('The specified (hyper-)plane is singular.')
132
133 b = dot(a.reshape(a.size / d, d), pa) + x0
134 return b.reshape(ishape), alpha
135
136
138 """Compute the L2 distance(s) of a point or a set of points to a plane.
139
140 :Parameters:
141 a : array(shape=(*,d), dtype='d')
142 a point or a set of points in a d-dimensional space
143 plane : array(shape=(d+1,), dtype='d')
144 a set of parameters representing the plane
145 i.e. a0*x0 + a1*x1 + ... + a_{d-1}*x_{d-1} + a_d = 0
146
147 :Returns:
148 b : array(shape=(*), dtype ='d')
149 a value or a set of values representing the L2 distance(s)
150 """
151 b, alpha = _distanceToPlane(a,plane)
152 return b/alpha
153