[从头学数学] 第282节 [计算几何] 相邻边和相邻点
来源:互联网 发布:每次人口普查的数据 编辑:程序博客网 时间:2024/05/18 14:26
剧情提要:
阿伟看到了一本比较有趣的书,是关于《计算几何》的,2008年由北清派出版。很好奇
它里面讲了些什么,就来看看啦。
正剧开始:
星历2016年09月28日 15:47:30, 银河系厄尔斯星球中华帝国江南行省。
本节到此结束,欲知后事如何,请看下回分解。
阿伟看到了一本比较有趣的书,是关于《计算几何》的,2008年由北清派出版。很好奇
它里面讲了些什么,就来看看啦。
正剧开始:
星历2016年09月28日 15:47:30, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[计算几何]]。
# 点和边的位置关系
<span style="font-size:18px;">#>>> 点在线段[[2.4, 5.4], [6, 9]]的Nevermind边扫描线与线段交点: []点在线段[[0.8, 3.8], [2.4, 5.4]]的Right边扫描线与线段交点: [1.47, 4.47]点在线段[[1.33, 3], [0.8, 3.8]]的Nevermind边扫描线与线段交点: []点在线段[[1.33, 3], [2, 3]]的Nevermind边扫描线与线段交点: []点在线段[[2, 3], [6, 3]]的Nevermind边扫描线与线段交点: []点在线段[[6, 3], [6, 3.86]]的Nevermind边扫描线与线段交点: []点在线段[[6, 3.86], [3.33, 5]]的Left边扫描线与线段交点: [4.57, 4.47]点在线段[[3.33, 5], [6, 9]]的Nevermind边扫描线与线段交点: []>>> 点在线段[[2.4, 5.4], [6, 9]]的Left边扫描线与线段交点: [2.49, 5.49]点在线段[[2.4, 5.4], [-6, 9]]的Left边扫描线与线段交点: [2.19, 5.49]点在线段[[-0.37, 2.56], [-6, 9]]的Right边扫描线与线段交点: [-2.93, 5.49]点在线段[[-0.37, 2.56], [0, 3]]的Nevermind边扫描线与线段交点: []点在线段[[0, 3], [1.33, 3]]的Nevermind边扫描线与线段交点: []点在线段[[1.33, 3], [2, 3]]的Nevermind边扫描线与线段交点: []点在线段[[2, 3], [3.33, 5]]的Nevermind边扫描线与线段交点: []点在线段[[3.33, 5], [6, 9]]的Left边扫描线与线段交点: [3.66, 5.49]#三个点的叉积def crossProduct(P1, P2, P3): x1, y1, x2, y2, x3, y3 = P1[0], P1[1], P2[0], P2[1], P3[0], P3[1]; # # 1 1 1 # x_1 x_2 x_3 # y_1 y_2 y_3 # #逆时针结果为正,顺时针为负 return round((x1*y2-x2*y1)-(x1*y3-x3*y1)+(x2*y3-x3*y2), 3);#判断点在边的左边还是右边def judgePointAgainstEdgePosition(seg, point): #传入SegLine类型和Point类型,这样方便比较 #SegLine是以y优先x其次由小大大排序的,终端点按排序规则大于起始端点 pValue = point.value(); sValue = seg.value(); x0, y0, x1, y1, x2, y2 = pValue[0], pValue[1], sValue[0][0], sValue[0][1],\ sValue[1][0], sValue[1][1]; #点的y值要在线段两个端点的y值中间,可以等于 if (y0 >= y1 and y0 <= y2): cross = crossProduct(pValue, sValue[0], sValue[1]); if (cross > 0): #点在线段的左边 if (y1 < y0): return 'Left'; elif (cross < 0): #点在线段的右边 if (y2 > y0): return 'Right'; return 'Nevermind';#获取扫描线与线段的交点#y方向的扫描线为平行于x轴且y值为某一定值的直线def calcScanLineCrosspoint(seg, point): #传入SegLine类型和Point类型,这样方便比较 #SegLine是以y优先x其次由小大大排序的,终端点按排序规则大于起始端点 pValue = point.value(); sValue = seg.value(); x0, y0, x1, y1, x2, y2 = pValue[0], pValue[1], sValue[0][0], sValue[0][1],\ sValue[1][0], sValue[1][1]; #点的y值要在线段两个端点的y值中间,可以等于 if (y0 >= y1 and y0 <= y2): if y0 == y1: return sValue[0]; elif y0 == y2: return sValue[1]; else: x = x1 + (y0 - y1)/(y2 - y1)*(x2-x1); return [round(x, 2), y0]; 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); center = [[3.45, 4.47], [4.86, 5.51], [2.36, 4.5], [2.63, 4.92], [4.0, 5.0], [3.97, 5.51], [6.01, 2.42], [6.33, 2.21], [-0.28, 5.49], [4.29, 3.73], [6.17, 1.92], [6.07, 1.58], [6.08, 1.89], [6.53, 1.61], [6.39, 1.6], [6.68, 0.49], [6.95, 0.31], [6.92, 0.09], [6.71, 0.27], [6.62, 0.38]]; #第几条线段作为测试 n = 8; len_path_0 = len(path[n]); pCenter_0 = center[n]; for i in range(len_path_0-1): seg = SegLine(path[n][i], path[n][i+1]); p = Point(pCenter_0) print('点在线段{0}的{1}边'.format(str(seg), judgePointAgainstEdgePosition(seg, p))); print('扫描线与线段交点:', calcScanLineCrosspoint(seg, p));#</span>
#找某点的左、右邻居边
<span style="font-size:18px;">#>>> [SegLine([-0.37, 2.56], [-6, 9]), [-2.93, 5.49]][SegLine([2.4, 5.4], [-6, 9]), [2.19, 5.49]] #找某点的左邻居边,也就是路径中处于给定点的左边,并且在y扫描线上最接近的那条边 def findLeftNearestEdge(self, point): edge = None; scanPoint = None; len_ = len(self.path); for i in range(len_): seg = SegLine(self.path[i].value(), self.path[(i+1)%len_].value()); #点在边的右侧 if (judgePointAgainstEdgePosition(seg, point) == 'Right'): if (edge == None): edge = seg; scanPoint = calcScanLineCrosspoint(seg, point); else: a = calcScanLineCrosspoint(seg, point); #取扫描线的交点的x值 if a[0] > scanPoint[0]: edge = seg; scanPoint = a; return [edge, scanPoint]; #找某点的右邻居边,也就是路径中处于给定点的右边,并且在y扫描线上最接近的那条边 def findRightNearestEdge(self, point): edge = None; scanPoint = None; len_ = len(self.path); for i in range(len_): seg = SegLine(self.path[i].value(), self.path[(i+1)%len_].value()); #点在边的左侧 if (judgePointAgainstEdgePosition(seg, point) == 'Left'): if (edge == None): edge = seg; scanPoint = calcScanLineCrosspoint(seg, point); else: a = calcScanLineCrosspoint(seg, point); #取扫描线的交点的x值 if a[0] < scanPoint[0]: edge = seg; scanPoint = a; return [edge, scanPoint];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); center = [[3.45, 4.47], [4.86, 5.51], [2.36, 4.5], [2.63, 4.92], [4.0, 5.0], [3.97, 5.51], [6.01, 2.42], [6.33, 2.21], [-0.28, 5.49], [4.29, 3.73], [6.17, 1.92], [6.07, 1.58], [6.08, 1.89], [6.53, 1.61], [6.39, 1.6], [6.68, 0.49], [6.95, 0.31], [6.92, 0.09], [6.71, 0.27], [6.62, 0.38]]; #第几条线段作为测试 n = 8; len_path_0 = len(path[n]); pCenter_0 = Point(center[n]); a = Path(path[n]); print(a.findLeftNearestEdge(pCenter_0)); print(a.findRightNearestEdge(pCenter_0));#</span>
#找某点的上、下相邻点
<span style="font-size:18px;">#>>> [SegLine([-0.37, 2.56], [-6, 9]), [-2.93, 5.49]][SegLine([2.4, 5.4], [-6, 9]), [2.19, 5.49]][-6, 9][2.4, 5.4]>>> #找某点的上兄弟点,这个点的y坐标大于给定点, #并且处于该点的左、右邻居边之间。 #如果没有这种点,返回左、右邻居边的上顶点中y值比较小的那一个点。 def findUpBrother(self, point): #point是Point类型 rEdge = self.findRightNearestEdge(point); lEdge = self.findLeftNearestEdge(point); rSeg, lSeg = rEdge[0], lEdge[0]; upBrother = None; if (rSeg != None and lSeg != None): len_ = len(self.path); for i in range(len_): a = self.path[i].value(); b = point.value(); if (a[1] > b[1]): if (judgePointAgainstEdgePosition(rSeg, self.path[i]) == 'Left' and\ judgePointAgainstEdgePosition(lSeg, self.path[i]) == 'Right'): if upBrother == None: upBrother = self.path[i]; else: if (upBrother < self.path[i]): upBrother = self.path[i]; if upBrother == None: upBrother = min(Point(lSeg.value()[1]), Point(rSeg.value()[1])); return upBrother; #找某点的下兄弟点,这个点的y坐标小于给定点, #并且处于该点的左、右邻居边之间。 #如果没有这种点,返回左、右邻居边的下顶点中y值比较大的那一个点。 def findDownBrother(self, point): #point是Point类型 rEdge = self.findRightNearestEdge(point); lEdge = self.findLeftNearestEdge(point); rSeg, lSeg = rEdge[0], lEdge[0]; downBrother = None; if (rSeg != None and lSeg != None): len_ = len(self.path); for i in range(len_): a = self.path[i].value(); b = point.value(); if (a[1] < b[1]): if (judgePointAgainstEdgePosition(rSeg, self.path[i]) == 'Left' and\ judgePointAgainstEdgePosition(lSeg, self.path[i]) == 'Right'): if downBrother == None: downBrother = self.path[i]; else: if (downBrother < self.path[i]): downBrother = self.path[i]; if downBrother == None: downBrother = max(Point(lSeg.value()[0]), Point(rSeg.value()[0])); return downBrother; 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); center = [[3.45, 4.47], [4.86, 5.51], [2.36, 4.5], [2.63, 4.92], [4.0, 5.0], [3.97, 5.51], [6.01, 2.42], [6.33, 2.21], [-0.28, 5.49], [4.29, 3.73], [6.17, 1.92], [6.07, 1.58], [6.08, 1.89], [6.53, 1.61], [6.39, 1.6], [6.68, 0.49], [6.95, 0.31], [6.92, 0.09], [6.71, 0.27], [6.62, 0.38]]; #第几条线段作为测试 n = 8; len_path_0 = len(path[n]); pCenter_0 = Point(center[n]); a = Path(path[n]); print(a.findLeftNearestEdge(pCenter_0)); print(a.findRightNearestEdge(pCenter_0)); print(a.findUpBrother(pCenter_0)); print(a.findDownBrother(pCenter_0));#</span>
本节到此结束,欲知后事如何,请看下回分解。
0 0
- [从头学数学] 第282节 [计算几何] 相邻边和相邻点
- [从头学数学] 第264节 [计算几何] 点和线段
- [从头学数学] 第269节 [计算几何] 点在多边形内
- [从头学数学] 第240节 计算几何 整装待发
- [从头学数学] 第263节 [计算几何] 线段生成
- [从头学数学] 第267节 [计算几何] 路径规划
- [从头学数学] 第268节 [计算几何] 环形路径
- [从头学数学] 第271节 [计算几何] 凸包
- [从头学数学] 第274节 [计算几何] 顶点树
- [从头学数学] 第279节 [计算几何] 重心
- [从头学数学] 第280节 [计算几何] 路径合并
- [从头学数学] 第281节 [计算几何] 路径分解
- [从头学数学] 第285节 [计算几何] 区域划分
- [从头学数学] 第278节 [计算几何] 多边形周长和面积
- [从头学数学] 第241节 计算几何 导言 凸包的例子
- [从头学数学] 第265节 [计算几何] 多线段求交点(扫描线法)
- [从头学数学] 第266节 [计算几何] 多线段求交点
- [从头学数学] 第270节 [计算几何] 例题数据生成
- 小娴的男友小旭不幸患了一种怪病,这种怪病吞噬了他的大部分记忆,同时让他突然间不会书写符合正确语序的英文。神奇的是,虽然他写出的句子看上去杂乱无章,不过经过仔细分析可以发现,如果把单词的顺序倒过来,语法
- shell编程之BASH_BUILTINS
- untiy 3d ShaderLab_第9章_1_平面阴影(三) 点光源对平面的投影
- 华为oj之计算字符个数
- play框架自定义插件plugin拦截器
- [从头学数学] 第282节 [计算几何] 相邻边和相邻点
- UIViewController添加UICollectionView控件顶端出现留白的解决办法
- Min-height 最小高度兼容ie6
- 第55课: 在线广告点击流处理代码的分析和实现
- Android--RxJava之并发处理(SerializedSubject)
- 剑指offer--面试题47:不用加减乘除做加法
- mysql条件查询
- 在iOS10中使用stringWithUTF8String时字符串部分显示错误,转换失败导致string为空,程序崩溃
- UVA 10214