[从头学数学] 第272节 [计算几何] 从线段集连通区域

来源:互联网 发布:sql server 2005 64位 编辑:程序博客网 时间:2024/05/18 14:14
剧情提要:
阿伟看到了一本比较有趣的书,是关于《计算几何》的,2008年由北清派出版。很好奇
它里面讲了些什么,就来看看啦。


正剧开始:
星历2016年09月23日 11:58:19, 银河系厄尔斯星球中华帝国江南行省。

[工程师阿伟]正在和[机器小伟]一起研究[计算几何]]。




给定一个线段集,怎样获得它们所形成的区域呢?



如果这个线段集像上图这样规整,每个顶点恰好都连接有两条线段,皆大欢喜。


<span style="font-size:18px;">#>>> 6[Point([8, -7]), Point([5.67, -3.5]), Point([6, -3]), Point([6, 3]), Point([6, 3.86]), Point([8, 3]), Point([8, -7])]---[[8, -7], [5.67, -3.5], [6, -3], [6, 3], [6, 3.86], [8, 3], [8, -7]]>>> #处理每个顶点最多连接两条线段的#线段集的路径连接问题。def connectSeg(seg):    #seg = [SegLine([8, -7], [8, 3]), SegLine([8, -7], [5.67, -3.5]), SegLine([6, -3], [6, 3]), SegLine([5.67, -3.5], [6, -3]), SegLine([8, 3], [6, 3.86]), SegLine([6, 3], [6, 3.86])];    #去除重复线段    seg = list(set(seg));    len_seg = len(seg);        d = dict();      path = [];    #构造顶点集    vertex = set();    for i in range(len_seg):        seg_ = seg[i].value();        vertex.add(Point(seg_[0]));        vertex.add(Point(seg_[1]));    print('顶点数:', len(vertex));    #这里的排序相当重要,一定要从所有顶点中最小的那个开始找    vertex = sorted(list(vertex));    len_vert = len(vertex);    #构造边集字典    for i in range(len_vert):        d[vertex[i]] = [];    for i in range(len_seg):        seg_ = seg[i].value();        d[Point(seg_[0])].append(Point(seg_[1]));        d[Point(seg_[1])].append(Point(seg_[0]));    #选择起始点    start = curVert = vertex[0];    path.append(curVert);        while len_vert > 0:        #从字典中移除相应线段的记录        if (len(d[curVert]) == 0):            break;        choice = d[curVert].pop(0);        d[choice].remove(curVert);        #处理下一个点        curVert = choice;        if (curVert in vertex):            vertex.remove(curVert);            path.append(curVert);            len_vert = len(vertex);        else:            path.append(curVert);            break;    for i in range(len(path)):        path[i] = path[i].value();    print('连通:', path);    return path;#</span>

但是还有可能有以下情况:








最后这张图很明显的暴露了算法中的问题。


这些都是来自于多边形求交的实际问题,或许每种算法都有它的各自的应用场景。

比如这两个多边形共用的边是算它们的交集呢,还是不算,这会影响到很多后续问题。


<span style="font-size:18px;">//if (1) {var r = 20;              config.setSector(1,1,1,1);                config.graphPaper2D(0, 0, r);              config.axis2D(0, 0, 250, 1.2);   //坐标轴设定                var scaleX = 2*r, scaleY = 2*r;                  var spaceX = 2, spaceY = 2;                   var xS = -10, xE = 10;                  var yS = -10, yE = 10;                  config.axisSpacing(xS, xE, spaceX, scaleX, 'X');                    config.axisSpacing(yS, yE, spaceY, scaleY, 'Y');                                        var transform = new Transform();    //顶点var a = [];for (var i = 0; i < $vertex.length; i++) {a.push($vertex[i][0]);}//显示变换                if (a.length > 0) {                    a = transform.scale(transform.translate(a, 0, 0), scaleX/spaceX, scaleY/spaceY);}var lable = [];for (var i = 0; i < 100; i++) {lable.push(i.toFixed(0));}/*//边集var b = [];for (var i = 0; i < $seg.length; i++) {b.push([a[$seg[i][0]], a[$seg[i][1]]]);}var edges = b.length;for (var i = 0; i < edges; i++) {shape.multiLineDraw([].concat(b[i]), 'red');}*/var colorArray = ['red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'purple', ];var seg = [];var nSeg = $divideSeg.length;plot.setLineWidth(2);for (var i = 0; i < nSeg; i++) {seg = transform.scale(transform.translate($divideSeg[i], 0, 0), scaleX/spaceX, scaleY/spaceY);shape.multiLineDraw([].concat(seg), 'pink');}var nPath = $inter.length;i = xGlobal;//路径var path1 = transform.scale(transform.translate($path1[i%nPath], 0, 0), scaleX/spaceX, scaleY/spaceY);plot.setLineWidth(15);shape.multiLineDraw([].concat(path1), colorArray[4]);var path2 = transform.scale(transform.translate($path2[i%nPath], 0, 0), scaleX/spaceX, scaleY/spaceY);plot.setLineWidth(10);shape.multiLineDraw([].concat(path2), colorArray[3]);var interPoints = $inter[i%nPath].length;if (interPoints > 0) {var interpath = transform.scale(transform.translate($inter[i%nPath], 0, 0), scaleX/spaceX, scaleY/spaceY);if (interPoints >= 2) {plot.setLineWidth(4);shape.multiLineDraw([].concat(interpath), colorArray[0]);}else {shape.pointDraw([].concat(interpath), 'red');}}//主要顶点shape.pointDraw([].concat(a), 'blue', 1, 1, lable);}//</span>

<span style="font-size:18px;">//$vertex = [[[-10, -9], 0], [[-2, -9], 1], [[2, -9], 2], [[2, -7], 3], [[8, -7], 4], [[-2, -5], 5], [[2, -3], 6], [[6, -3], 7], [[4, -1], 8], [[4, 1], 9], [[0, 3], 10], [[2, 3], 11], [[6, 3], 12], [[8, 3], 13], [[-4, 5], 14], [[0, 5], 15], [[-6, 9], 16], [[6, 9], 17]];$seg = [[10, 11, 2.0], [15, 16, 7.211], [2, 5, 5.657], [1, 13, 15.62], [4, 8, 7.211], [7, 15, 10.0], [0, 3, 12.166], [6, 11, 6.0], [9, 17, 8.246], [12, 14, 10.198]];$divideSeg = [[[-10, -9], [-0.51, 2.38]], [[-0.51, 2.38], [-0.37, 2.56]], [[-0.37, 2.56], [0, 3]], [[-2, -9], [1.2, -6.6]], [[1.2, -6.6], [2, -6]], [[2, -6], [5.09, -3.68]], [[5.09, -3.68], [5.56, -3.33]], [[5.56, -3.33], [6, -3]], [[-2, -9], [-1.38, -5.31]], [[-1.38, -5.31], [-1.27, -4.64]], [[-1.27, -4.64], [-0.15, 2.11]], [[-0.15, 2.11], [-0.12, 2.28]], [[-0.12, 2.28], [0, 3]], [[-2, -9], [-0.86, -5.57]], [[-0.86, -5.57], [-0.4, -4.2]], [[-0.4, -4.2], [1, 0]], [[1, 0], [1.24, 0.72]], [[1.24, 0.72], [1.33, 1]], [[1.33, 1], [1.5, 1.5]], [[1.5, 1.5], [1.78, 2.33]], [[1.78, 2.33], [2, 3]], [[2, -9], [5.35, -3.97]], [[5.35, -3.97], [5.67, -3.5]], [[5.67, -3.5], [6, -3]], [[2, -7], [1.2, -6.6]], [[1.2, -6.6], [-0.86, -5.57]], [[-0.86, -5.57], [-1.38, -5.31]], [[-1.38, -5.31], [-2, -5]], [[2, -7], [2, -6]], [[2, -6], [2, -3]], [[8, -7], [6, -3]], [[6, -3], [4.5, 0]], [[4.5, 0], [4.29, 0.43]], [[4.29, 0.43], [4, 1]], [[8, -7], [8, 3]], [[8, -7], [5.67, -3.5]], [[5.67, -3.5], [5.56, -3.33]], [[5.56, -3.33], [4, -1]], [[4, -1], [3.67, -0.5]], [[3.67, -0.5], [1.78, 2.33]], [[1.78, 2.33], [1.33, 3]], [[1.33, 3], [0.8, 3.8]], [[0.8, 3.8], [0, 5]], [[8, -7], [5.35, -3.97]], [[5.35, -3.97], [5.09, -3.68]], [[5.09, -3.68], [3.33, -1.67]], [[3.33, -1.67], [3.08, -1.38]], [[3.08, -1.38], [1.24, 0.72]], [[1.24, 0.72], [0.46, 1.62]], [[0.46, 1.62], [0.36, 1.73]], [[0.36, 1.73], [-0.12, 2.28]], [[-0.12, 2.28], [-0.37, 2.56]], [[-0.37, 2.56], [-6, 9]], [[-2, -5], [-1.27, -4.64]], [[-1.27, -4.64], [-0.4, -4.2]], [[-0.4, -4.2], [2, -3]], [[2, -3], [3.33, -1.67]], [[3.33, -1.67], [4, -1]], [[2, -3], [1, 0]], [[1, 0], [0.46, 1.62]], [[0.46, 1.62], [0.44, 1.67]], [[0.44, 1.67], [0, 3]], [[2, -3], [3.08, -1.38]], [[3.08, -1.38], [3.56, -0.67]], [[3.56, -0.67], [3.6, -0.6]], [[3.6, -0.6], [3.67, -0.5]], [[3.67, -0.5], [4.29, 0.43]], [[4.29, 0.43], [6, 3]], [[6, -3], [4, -1]], [[4, -1], [3.6, -0.6]], [[3.6, -0.6], [1.5, 1.5]], [[1.5, 1.5], [0, 3]], [[6, -3], [6, 3]], [[4, -1], [4.5, 0]], [[4.5, 0], [6, 3]], [[4, -1], [3.56, -0.67]], [[3.56, -0.67], [1.33, 1]], [[1.33, 1], [0.44, 1.67]], [[0.44, 1.67], [0.36, 1.73]], [[0.36, 1.73], [-0.15, 2.11]], [[-0.15, 2.11], [-0.51, 2.38]], [[-0.51, 2.38], [-4, 5]], [[4, -1], [3.67, -0.5]], [[3.67, -0.5], [1.78, 2.33]], [[1.78, 2.33], [1.33, 3]], [[1.33, 3], [0.8, 3.8]], [[0.8, 3.8], [0, 5]], [[0, 3], [1.33, 3]], [[1.33, 3], [2, 3]], [[2, 3], [6, 3]], [[0, 3], [0.8, 3.8]], [[0.8, 3.8], [2.4, 5.4]], [[2.4, 5.4], [6, 9]], [[2, 3], [3.33, 5]], [[3.33, 5], [6, 9]], [[6, 3], [6, 3.86]], [[6, 3.86], [6, 9]], [[8, 3], [6, 3.86]], [[6, 3.86], [3.33, 5]], [[3.33, 5], [2.4, 5.4]], [[2.4, 5.4], [-6, 9]], [[8, 3], [6, 9]]]/*$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]]]*/$path1 =[[[6, -3], [8, -7], [5.35, -3.97], [5.09, -3.68], [5.56, -3.33], [4, -1], [4.5, 0], [6, 3], [6, -3]], [[6, -3], [8, -7], [5.35, -3.97], [5.09, -3.68], [3.33, -1.67], [3.08, -1.38], [3.56, -0.67], [4, -1], [6, -3]], [[6, -3], [8, -7], [5.35, -3.97], [5.09, -3.68], [3.33, -1.67], [4, -1], [4.5, 0], [6, 3], [6, -3]], [[6, -3], [4.5, 0], [4.29, 0.43], [3.67, -0.5], [1.78, 2.33], [1.5, 1.5], [3.6, -0.6], [4, -1], [6, -3]], [[6, -3], [4.5, 0], [4.29, 0.43], [3.67, -0.5], [1.78, 2.33], [1.33, 3], [2, 3], [6, 3], [6, -3]], [[6, -3], [4.5, 0], [4.29, 0.43], [6, 3], [2, 3], [1.78, 2.33], [3.67, -0.5], [4, -1], [6, -3]], [[6, -3], [4.5, 0], [4, -1], [3.67, -0.5], [1.78, 2.33], [1.33, 3], [2, 3], [6, 3], [6, -3]], [[6, -3], [4.5, 0], [4, -1], [3.6, -0.6], [3.67, -0.5], [1.78, 2.33], [2, 3], [6, 3], [6, -3]], [[6, -3], [4.5, 0], [4, -1], [3.6, -0.6], [1.5, 1.5], [1.78, 2.33], [2, 3], [6, 3], [6, -3]], [[6, -3], [4.5, 0], [4, -1], [3.56, -0.67], [3.6, -0.6], [3.67, -0.5], [4.29, 0.43], [6, 3], [6, -3]], [[6, -3], [4, -1], [5.56, -3.33], [5.67, -3.5], [8, -7], [8, 3], [6, 3.86], [6, 3], [6, -3]], [[6, -3], [4, -1], [3.67, -0.5], [1.78, 2.33], [2, 3], [3.33, 5], [6, 3.86], [6, 3], [6, -3]], [[6, -3], [4, -1], [3.67, -0.5], [3.6, -0.6], [1.5, 1.5], [1.78, 2.33], [2, 3], [6, 3], [6, -3]], [[6, -3], [4, -1], [3.6, -0.6], [3.67, -0.5], [1.78, 2.33], [1.33, 3], [2, 3], [6, 3], [6, -3]], [[6, -3], [4, -1], [3.6, -0.6], [1.5, 1.5], [1.78, 2.33], [3.67, -0.5], [4.29, 0.43], [6, 3], [6, -3]], [[6, -3], [4, -1], [3.6, -0.6], [1.5, 1.5], [1.78, 2.33], [1.33, 3], [2, 3], [6, 3], [6, -3]], [[6, -3], [4, -1], [3.6, -0.6], [1.5, 1.5], [0, 3], [1.33, 3], [2, 3], [6, 3], [6, -3]], [[6, -3], [4, -1], [3.56, -0.67], [3.6, -0.6], [3.67, -0.5], [1.78, 2.33], [2, 3], [6, 3], [6, -3]], [[6, -3], [4, -1], [3.56, -0.67], [3.6, -0.6], [1.5, 1.5], [1.78, 2.33], [2, 3], [6, 3], [6, -3]], [[6, -3], [4, -1], [3.56, -0.67], [1.33, 1], [1.5, 1.5], [1.78, 2.33], [2, 3], [6, 3], [6, -3]]]$path2 = [[[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]]]//交集$inter = [[], [], [], [], [[1.33, 3], [2, 3], [6, 3]], [], [[6, -3], [6, 3], [2, 3]], [[6, -3], [6, 3]], [], [[3.67, -0.5], [4.29, 0.43], [6, 3]], [[8, -7], [5.67, -3.5], [6, -3], [6, 3], [6, 3.86], [8, 3], [8, -7]], [[6, -3], [6, 3], [2, 3], [3.33, 5], [6, 3.86], [6, 3]], [[6, -3], [4.5, 0], [6, 3], [2, 3]], [[6, -3], [6, 3]], [[6, -3], [4.5, 0], [6, 3], [6, -3]], [[6, -3], [4.5, 0], [4.29, 0.43], [6, 3], [6, -3]], [[6, -3], [6, 3]], [[6, -3], [6, 3]], [[6, -3], [4.5, 0], [6, 3], [6, -3]], [[6, -3], [4, -1], [4.5, 0], [6, 3], [6, -3]]]//</span>

本节到此结束,欲知后事如何,请看下回分解。



0 0
原创粉丝点击