121
121
return ( float(y) / 0xffffffffL ) # reals
123
123
#------ Mersenne Twister -- end
129
Based from Dinu C. Gherman's work,
130
modified for Blender/Mathutils by Campell Barton
132
######################################################################
134
######################################################################
135
from Blender.Mathutils import DotVecs
136
def convexHull(point_list_2d):
137
"""Calculate the convex hull of a set of vectors
138
The vectors can be 3 or 4d but only the Xand Y are used.
139
returns a list of convex hull indicies to the given point list
142
######################################################################
144
######################################################################
147
"""Calc. determinant of a special matrix with three 2D points.
149
The sign, "-" or "+", determines the side, right or left,
150
respectivly, on which the point r lies, when measured against
151
a directed vector from p to q.
153
return (q.x*r.y + p.x*q.y + r.x*p.y) - (q.x*p.y + r.x*q.y + p.x*r.y)
155
def _isRightTurn((p, q, r)):
156
"Do the vectors pq:qr form a right turn, or not?"
157
#assert p[0] != q[0] and q[0] != r[0] and p[0] != r[0]
158
if _myDet(p[0], q[0], r[0]) < 0:
163
# Get a local list copy of the points and sort them lexically.
164
points = [(p, i) for i, p in enumerate(point_list_2d)]
165
points.sort(lambda a,b: cmp((a[0].x, a[0].y), (b[0].x, b[0].y)))
167
# Build upper half of the hull.
168
upper = [points[0], points[1]] # cant remove these.
169
for i in xrange(len(points)-2):
170
upper.append(points[i+2])
171
while len(upper) > 2 and not _isRightTurn(upper[-3:]):
174
# Build lower half of the hull.
176
lower = [points.pop(0), points.pop(1)]
179
while len(lower) > 2 and not _isRightTurn(lower[-3:]):
182
# Concatenate both halfs and return.
183
return [p[1] for ls in (upper, lower) for p in ls]
186
def lineIntersect2D(v1a, v1b, v2a, v2b):
188
Do 2 lines intersect, if so where.
189
If there is an error, the retured X value will be None
190
the y will be an error code- usefull when debugging.
192
the first line is (v1a, v1b)
193
the second is (v2a, v2b)
195
This function accounts for all known cases of 2 lines ;)
200
_x1,_y1= v2a.x, v2a.y
201
_x2,_y2= v2b.x, v2b.y
203
# Bounding box intersection first.
204
if min(x1, x2) > max(_x1, _x2) or \
205
max(x1, x2) < min(_x1, _x2) or \
206
min(y1, y2) > max(_y1, _y2) or \
207
max(y1, y2) < min(_y1, _y2):
208
return None, 100 # Basic Bounds intersection TEST returns false.
210
# are either of the segments points? Check Seg1
211
if abs(x1 - x2) + abs(y1 - y2) <= SMALL_NUM:
214
# are either of the segments points? Check Seg2
215
if abs(_x1 - _x2) + abs(_y1 - _y2) <= SMALL_NUM:
218
# Make sure the HOZ/Vert Line Comes first.
219
if abs(_x1 - _x2) < SMALL_NUM or abs(_y1 - _y2) < SMALL_NUM:
220
x1, x2, y1, y2, _x1, _x2, _y1, _y2 = _x1, _x2, _y1, _y2, x1, x2, y1, y2
222
if abs(x2-x1) < SMALL_NUM: # VERTICLE LINE
223
if abs(_x2-_x1) < SMALL_NUM: # VERTICLE LINE SEG2
224
return None, 111 # 2 verticle lines dont intersect.
226
elif abs(_y2-_y1) < SMALL_NUM:
227
return x1, _y1 # X of vert, Y of hoz. no calculation.
229
yi = ((_y1 / abs(_x1 - _x2)) * abs(_x2 - x1)) + ((_y2 / abs(_x1 - _x2)) * abs(_x1 - x1))
231
if yi > max(y1, y2): # New point above seg1's vert line
233
elif yi < min(y1, y2): # New point below seg1's vert line
236
return x1, yi # Intersecting.
239
if abs(y2-y1) < SMALL_NUM: # HOZ LINE
240
if abs(_y2-_y1) < SMALL_NUM: # HOZ LINE SEG2
241
return None, 121 # 2 hoz lines dont intersect.
243
# Can skip vert line check for seg 2 since its covered above.
244
xi = ((_x1 / abs(_y1 - _y2)) * abs(_y2 - y1)) + ((_x2 / abs(_y1 - _y2)) * abs(_y1 - y1))
245
if xi > max(x1, x2): # New point right of seg1's hoz line
247
elif xi < min(x1, x2): # New point left of seg1's hoz line
250
return xi, y1 # Intersecting.
252
# Accounted for hoz/vert lines. Go on with both anglular.
254
b2 = (_y2-_y1)/(_x2-_x1)
261
xi = - (a1-a2)/(b1-b2)
263
if (x1-xi)*(xi-x2) >= 0 and (_x1-xi)*(xi-_x2) >= 0 and (y1-yi)*(yi-y2) >= 0 and (_y1-yi)*(yi-_y2)>=0: