剧情提要:
阿伟看到了一本比较有趣的书,是关于《计算几何》的,2008年由北清派出版。很好奇
它里面讲了些什么,就来看看啦。
正剧开始:
星历2016年09月23日 11:58:19, 银河系厄尔斯星球中华帝国江南行省。
阿伟看到了一本比较有趣的书,是关于《计算几何》的,2008年由北清派出版。很好奇
它里面讲了些什么,就来看看啦。
正剧开始:
星历2016年09月23日 11:58:19, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[计算几何]]。
两个多边形求交集,比如下图:
最初很容易想到通过顶点在另一个多边形里的位置来判断。
<span style="font-size:18px;">#
class Polygon():
#格式:path = [[-6, 9], [8, -7], [8, 3], [-6, 9]]
def __init__(self, path):
if (path[-1] != path[0]):
path.append(path[0]);
self.path = path;
#顶点数量
self.vertNum = len(self.path)-1;
self.vertex = [];
self.edge = [];
self.vertexCalc();
self.edgeCalc();
def vertexCalc(self):
for i in range(self.vertNum):
self.vertex.append(Point(self.path[i]));
def getVertex(self):
return self.vertex;
def edgeCalc(self):
for i in range(self.vertNum):
self.edge.append(SegLine(self.path[i], self.path[i+1]));
def getEdge(self):
return self.edge;
#传入的是[x, y]格式的对象
def pointInPolygon(self, point):
#测试点左右两边截多边形的各边,得到的交点数都为奇数,说明测试点在多边形内
#反之在外面
oddNodes = False;
#点在多边形的边上
if (Point(point) in self.vertex):
return 0;
x, y = point[0], point[1];
j = self.vertNum - 1;
for i in range(self.vertNum):
p1 = self.vertex[i].value();
p2 = self.vertex[j].value();
px1, py1 = p1[0], p1[1];
px2, py2 = p2[0], p2[1];
if (((py1 < y and py2 >= y) or (py2 < y and py1 >= y)) and \
(px1 <= x or px2 <= x)):
if ((px1+(y-py1)/(py2-py1)*(px2-px1)) < x):
oddNodes = not oddNodes;
j = i;
if (oddNodes == False):
#点不在多边形内
return -1;
else:
#点在多边形内
return 1;
#两个多边形的交集区域
def intersection(self, other):
vlist_1 = self.vertex;
vlist_2 = other.vertex;
commonVert = set();
for i in range(len(vlist_1)):
#点在多边形外部是-1, 在边上是0, 在内部是1
if other.pointInPolygon(vlist_1[i].value()) != -1:
commonVert.add(vlist_1[i]);
for i in range(len(vlist_2)):
if self.pointInPolygon(vlist_2[i].value()) != -1:
commonVert.add(vlist_2[i]);
commonVert = list(commonVert);
for i in range(len(commonVert)):
commonVert[i] = commonVert[i].value();
#返回顶点序列
return commonVert;
#把给定的坐标点阵列数组[x, y],...按照距离它们的中心点的角度进行排列
#是为了把无序排列的闭合曲线上的点进行有序排列,后续可再经过连线形成
#可填充的闭合曲线
def angularSort(self, array):
len0 = len(array);
len1 = len(array[0]);
if (len0 <= 0 or len1 != 2):
return array;
xTotal = yTotal = xCenter = yCenter = 0;
for i in range(len0):
xTotal += array[i][0];
yTotal += array[i][1];
xCenter = xTotal/len0;
yCenter = yTotal/len0;
x = y = xdiff = ydiff = 0;
arrayB = [];
for i in range(len0):
x = array[i][0];
y = array[i][1];
xdiff = x - xCenter;
ydiff = y - yCenter;
if (abs(xdiff) < 1e-4):
if (ydiff > 0):
arrayB.append([x, y, math.pi/2]);
else:
arrayB.append([x, y, math.pi/2*3]);
elif (xdiff >= 0 and ydiff > 0):
#第一象限
arrayB.append([x, y, math.atan(abs(ydiff/xdiff))]);
elif (xdiff < 0 and ydiff >= 0):
#第二象限
arrayB.append([x, y, math.pi-math.atan(abs(ydiff/xdiff))]);
elif (xdiff <= 0 and ydiff < 0):
#第三象限
arrayB.append([x, y, math.pi+math.atan(abs(ydiff/xdiff))]);
else:
#第四象限
arrayB.append([x, y, math.pi*2-math.atan(abs(ydiff/xdiff))]);
arrayB = sorted(arrayB, key = lambda a:(a[2], (a[0]-xCenter)**2+(a[1]-yCenter)**2));
retArray = [];
for i in range(len(arrayB)):
retArray.append(arrayB[i][:-1]);
return retArray;
>>>
20
[]
[[4, -1], [3.56, -0.67], [6, -3]]
[[4, -1], [3.6, -0.6], [3.56, -0.67]]
[]
[]
[]
[[4, -1], [3.6, -0.6]]
[[4, -1], [3.6, -0.6]]
[[4, -1], [3.6, -0.6]]
[[4, -1], [1.5, 1.5], [3.6, -0.6]]
[[4, -1], [1.5, 1.5], [3.6, -0.6]]
[[4, -1], [1.5, 1.5], [3.6, -0.6]]
[[4, -1]]
[[4, -1], [3.08, -1.38], [3.33, -1.67], [3.56, -0.67]]
[[4, -1], [3.56, -0.67], [1.33, 1]]
[[3.56, -0.67], [1.5, 1.5], [3.6, -0.6]]
[[4, -1], [1.33, 1], [3.56, -0.67]]
[[1.33, 1], [3.56, -0.67]]
[]
[[3.56, -0.67]]
20
[[], [[4, -1], [3.56, -0.67], [6, -3]], [[4, -1], [3.6, -0.6], [3.56, -0.67]], [], [], [], [[4, -1], [3.6, -0.6]], [[4, -1], [3.6, -0.6]], [[4, -1], [3.6, -0.6]], [[4, -1], [1.5, 1.5], [3.6, -0.6]], [[4, -1], [1.5, 1.5], [3.6, -0.6]], [[4, -1], [1.5, 1.5], [3.6, -0.6]], [[4, -1]], [[4, -1], [3.08, -1.38], [3.33, -1.67], [3.56, -0.67]], [[4, -1], [3.56, -0.67], [1.33, 1]], [[3.56, -0.67], [1.5, 1.5], [3.6, -0.6]], [[4, -1], [1.33, 1], [3.56, -0.67]], [[1.33, 1], [3.56, -0.67]], [], [[3.56, -0.67]]]
---
[[], [[4, -1], [3.56, -0.67], [6, -3]], [[3.6, -0.6], [3.56, -0.67], [4, -1]], [], [], [], [[4, -1], [3.6, -0.6]], [[4, -1], [3.6, -0.6]], [[4, -1], [3.6, -0.6]], [[1.5, 1.5], [3.6, -0.6], [4, -1]], [[1.5, 1.5], [3.6, -0.6], [4, -1]], [[1.5, 1.5], [3.6, -0.6], [4, -1]], [[4, -1]], [[4, -1], [3.56, -0.67], [3.08, -1.38], [3.33, -1.67]], [[1.33, 1], [4, -1], [3.56, -0.67]], [[1.5, 1.5], [3.56, -0.67], [3.6, -0.6]], [[1.33, 1], [4, -1], [3.56, -0.67]], [[1.33, 1], [3.56, -0.67]], [], [[3.56, -0.67]]]
>>>
def tmp15():
#两组路径
path1 = a6=[[[2, -3], [3.33, -1.67], [5.09, -3.68], [2, -6], [1.2, -6.6], [-0.86, -5.57], [-0.4, -4.2], [1, 0], [2, -3]], [[2, -3], [3.33, -1.67], [5.09, -3.68], [5.56, -3.33], [6, -3], [4, -1], [3.56, -0.67], [3.08, -1.38], [2, -3]], [[2, -3], [3.33, -1.67], [5.09, -3.68], [5.56, -3.33], [4, -1], [3.6, -0.6], [3.56, -0.67], [3.08, -1.38], [2, -3]], [[2, -3], [3.33, -1.67], [3.08, -1.38], [1.24, 0.72], [1.33, 1], [0.44, 1.67], [0.46, 1.62], [1, 0], [2, -3]], [[2, -3], [3.33, -1.67], [3.08, -1.38], [3.56, -0.67], [1.33, 1], [1.24, 0.72], [0.46, 1.62], [1, 0], [2, -3]], [[2, -3], [3.33, -1.67], [3.08, -1.38], [3.56, -0.67], [1.33, 1], [0.44, 1.67], [0.46, 1.62], [1, 0], [2, -3]], [[2, -3], [3.33, -1.67], [4, -1], [3.6, -0.6], [3.56, -0.67], [3.08, -1.38], [1.24, 0.72], [1, 0], [2, -3]], [[2, -3], [3.33, -1.67], [4, -1], [3.6, -0.6], [3.56, -0.67], [1.33, 1], [1.24, 0.72], [1, 0], [2, -3]], [[2, -3], [3.33, -1.67], [4, -1], [3.6, -0.6], [3.56, -0.67], [1.33, 1], [1.24, 0.72], [3.08, -1.38], [2, -3]], [[2, -3], [3.33, -1.67], [4, -1], [3.6, -0.6], [1.5, 1.5], [1.33, 1], [1.24, 0.72], [1, 0], [2, -3]], [[2, -3], [3.33, -1.6