剧情提要:
阿伟看到了一本比较有趣的书,是关于《计算几何》的,2008年由北清派出版。很好奇
它里面讲了些什么,就来看看啦。
正剧开始:
星历2016年09月27日 11:58:38, 银河系厄尔斯星球中华帝国江南行省。
这里的合并算法是有问题的,对于两条可能有多段穿插的路径,或许应该把每段的交汇和分离都记录下来,先放着吧。
阿伟看到了一本比较有趣的书,是关于《计算几何》的,2008年由北清派出版。很好奇
它里面讲了些什么,就来看看啦。
正剧开始:
星历2016年09月27日 11:58:38, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[计算几何]]。
比如下面两条路径,如果它们合并成一个环形的大路径,新路径是什么呢?
<span style="font-size:18px;">#
class Path():
def info(self):
print(self.path);
def __init__(self, path):
if (path[-1] == path[0]):
path = path[:-1];
if (type(path[0]) == Point):
self.path = path;
else:
self.path = [];
for i in range(len(path)):
self.path.append(Point(path[i]));
#判断路径相等
def __eq__(self, other):
if other == None:
return False;
len_1 = len(self.path);
len_2 = len(other.path);
if (len_1 != len_2):
return False;
if (other[0] in self):
idx = self.path.index(other[0]);
for i in range(len_1):
if other[i] != self.path[(idx+i)%len_1]:
return False;
return True;
else:
return False;
def __len__(self):
return len(self.path);
def __iter__(self):
for i in range(len(self)):
yield self.path[i];
def __contains__(self, item):
return item in self.path;
def __getitem__(self, index):
return self.path[index];
#路径上的顶点集
def pointSet(self):
pSet = set();
for i in range(len(self.path)):
pSet.add(self.path[i]);
return pSet;
#两个点序号之间的劣弧路径,是以通过点的数量定优劣弧的,不是根据路径长度。
def minorSubpath(self, idx1, idx2):
idx1, idx2 = min(idx1, idx2), max(idx1, idx2);
len_path = len(self.path);
if (idx2 - idx1) <= len_path//2:
subPath = self.path[idx1:idx2+1];
else:
subPath = self.path[idx2:]+self.path[:idx1+1];
return subPath;
#两个点序号之间的优弧路径,是以通过点的数量定优劣弧的,不是根据路径长度。
def majorSubpath(self, idx1, idx2):
idx1, idx2 = min(idx1, idx2), max(idx1, idx2);
len_path = len(self.path);
if (idx2 - idx1) >= len_path//2:
subPath = self.path[idx1:idx2+1];
else:
subPath = self.path[idx2:]+self.path[:idx1+1];
return subPath;
#连接两段子路径,两段路径必须有相同的起点和终点,这样形成一个环路
def linkPath(self, path1, path2):
result = [];
if path1[0] == path2[0] and path1[-1] == path2[-1]:
path2 == reversed(path2);
result = path1[:-1]+path2[:-1];
elif path1[0] == path2[-1] and path1[-1] == path2[0]:
result = path1[:-1]+path2[:-1];
return result;
#找公共点集在路径中的端点
def findCommonBound(self, interSet):
array = sorted(list(interSet));
print(array);
if (len(array) < 2):
return [];
elif (len(array) == 2):
#一共只有两个交点,它们就是边界
return [array[0], array[1]];
elif (len(array) < len(self.path)):
min_ = max_ = array[0];
print(array[0]);
idx1 = idx2 = self.path.index(min_);
print(idx1);
len_ = len(self.path);
idx1 -= 1;
idx2 += 1;
print(self.path[idx2%len_]);
while self.path[idx1%len_] in array:
min_ = self.path[idx1%len_];
idx1 -= 1;
while self.path[idx2%len_] in array:
max_ = self.path[idx2%len_];
idx2 += 1;
return [min_, max_];
else:
return [self.path[0], self.path[-1]];
#合并两条路径,返回的是值的阵列,不是Path类
def union(self, other):
path1 = self.pointSet();
path2 = other.pointSet();
u = path1.intersection(path2);
len_ = len(u);
indexArray = [];
for item in u:
indexArray.append(self.path.index(item));
minIndex = min(indexArray);
maxIndex = max(indexArray);
for i in range(minIndex, maxIndex):
u.add(self.path[i]);
print('---', u);
#两条路径有多于两个的交点
if (len_ >= 2 and len_ < len(self)):
#交点在两条路径中的序号
a = self.findCommonBound(u);
print(a);
min_, max_ = a[0], a[1];
minIdx_, maxIdx_ = self.path.index(min_), self.path.index(max_);
minIdx_2, maxIdx_2 = other.path.index(min_), other.path.index(max_);
subPath1 = self.majorSubpath(minIdx_, maxIdx_);
subPath2 = other.majorSubpath(minIdx_2, maxIdx_2);
'''
print(subPath1);
print(subPath2);
print('\n');
'''
result = self.linkPath(subPath1, subPath2);
return result;
elif (len_ == len(self)):
return self.path;
else:
return [];
def tmp5():
path = [[[6, 9], [2.4, 5.4], [0.8, 3.8], [1.33, 3], [2, 3], [6, 3], [6, 3.86], [3.33, 5], [6, 9]], [[6, 9], [2.4, 5.4], [0.8, 3.8], [1.33, 3], [2, 3], [3.33, 5], [6, 3.86], [8, 3], [6, 9]], [[6, 9], [2.4, 5.4], [0.8, 3.8], [0, 3], [1.5, 1.5], [1.78, 2.33], [2, 3], [3.33, 5], [6, 9]], [[6, 9], [2.4, 5.4], [0.8, 3.8], [0, 3], [1.33, 3], [1.78, 2.33], [2, 3], [3.33, 5], [6, 9]], [[6, 9], [2.4, 5.4], [0.8, 3.8], [0, 3], [1.33, 3], [2, 3], [6, 3], [6, 3.86], [6, 9]], [[6, 9], [2.4, 5.4], [0.8, 3.8], [0, 3], [1.33, 3], [2, 3], [3.33, 5], [6, 3.86], [6, 9]], [[6, 9], [2.4, 5.4], [3.33, 5], [2, 3], [6, 3], [6, -3], [8, -7], [8, 3], [6, 9]], [[6, 9], [2.4, 5.4], [3.33, 5], [6, 3.86], [6, 3], [6, -3], [8, -7], [8, 3], [6, 9]], [[6, 9], [2.4, 5.4], [-6, 9], [-0.37, 2.56], [0, 3], [1.33, 3], [2, 3], [3.33, 5], [6, 9]], [[6, 9], [3.33, 5], [2, 3], [1.78, 2.33], [3.67, -0.5], [4.29, 0.43], [6, 3], [6, 3.86], [6, 9]], [[6, 9], [3.33, 5], [2, 3], [6, 3], [6, -3], [5.67, -3.5], [8, -7], [8, 3], [6, 9]], [[6, 9], [3.33, 5], [2, 3], [6, 3], [6, -3], [8, -7], [8, 3], [6, 3.86], [6, 9]], [[6, 9], [3.33, 5], [2, 3], [6, 3], [4.5, 0], [6, -3], [8, -7], [8, 3], [6, 9]], [[6, 9], [3.33, 5], [6, 3.86], [6, 3], [6, -3], [5.67, -3.5], [8, -7], [8, 3], [6, 9]], [[6, 9], [3.33, 5], [6, 3.86], [6, 3], [4.5, 0], [6, -3], [8, -7], [8, 3], [6, 9]], [[6, 9], [6, 3.86], [6, 3], [4.29, 0.43], [4.5, 0], [6, -3], [8, -7], [8, 3], [6, 9]], [[6, 9], [6, 3.86], [6, 3], [6, -3], [5.56, -3.33], [5.67, -3.5], [8, -7], [8, 3], [6, 9]], [[6, 9], [6, 3.86], [6, 3], [6, -3], [5.67, -3.5], [5.35, -3.97], [8, -7], [8, 3], [6, 9]], [[6, 9], [6, 3.86], [6, 3], [4.5, 0], [6, -3], [5.67, -3.5], [8, -7], [8, 3], [6, 9]], [[6, 9], [6, 3.86], [6, 3], [4.5, 0], [4, -1], [6, -3], [8, -7], [8, 3], [6, 9]]]
len_path = len(path);
path_0 = path[0];
path_2 = path[2];
path_0_2 = path_0[:-1];
path_0_2 = path_0_2[-3:] + path_0_2[:-3];
#print(Path(path_0) == Path(path_2)); #False;
#print(Path(path_0) == Path(path_0_2)); #True;
a = Path(path_0);
b = Path(path_2);
#a.info();
#b.info();
uab = a.union(b);
#</span>
这里的合并算法是有问题的,对于两条可能有多段穿插的路径,或许应该把每段的交汇和分离都记录下来,先放着吧。
本节到此结束,欲知后事如何,请看下回分解。