[从头学数学] 第268节 [计算几何] 环形路径

剧情提要:
阿伟看到了一本比较有趣的书,是关于《计算几何》的,2008年由北清派出版。很好奇
它里面讲了些什么,就来看看啦。


正剧开始:
星历2016年09月21日 10:28:35, 银河系厄尔斯星球中华帝国江南行省。

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


<span style="font-size:18px;">#
>>> 
24
[SegLine([-10, -9], [-2, -9]), SegLine([-10, -9], [2, -9]), SegLine([-10, -9], [8, -7]), SegLine([-10, -9], [2, -3]), SegLine([-10, -9], [2, 3]), SegLine([-10, -9], [-4, 5]), SegLine([-10, -9], [0, 5]), SegLine([-2, -9], [4, 1]), SegLine([2, -9], [-2, -5]), SegLine([2, -9], [-4, 5]), SegLine([2, -9], [0, 5]), SegLine([2, -7], [8, -7]), SegLine([2, -7], [-2, -5]), SegLine([2, -7], [2, -3]), SegLine([2, -7], [6, -3]), SegLine([2, -7], [4, -1]), SegLine([2, -7], [-6, 9]), SegLine([8, -7], [4, 1]), SegLine([8, -7], [-6, 9]), SegLine([8, -7], [6, 9]), SegLine([-2, -5], [2, -3]), SegLine([-2, -5], [4, -1]), SegLine([0, 3], [6, 3]), SegLine([0, 5], [6, 9])]
[[[-10, -9], [-2, -9]], [[-10, -9], [2, -9]], [[-10, -9], [8, -7]], [[-10, -9], [2, -3]], [[-10, -9], [2, 3]], [[-10, -9], [-4, 5]], [[-10, -9], [0, 5]], [[-2, -9], [4, 1]], [[2, -9], [-2, -5]], [[2, -9], [-4, 5]], [[2, -9], [0, 5]], [[2, -7], [8, -7]], [[2, -7], [-2, -5]], [[2, -7], [2, -3]], [[2, -7], [6, -3]], [[2, -7], [4, -1]], [[2, -7], [-6, 9]], [[8, -7], [4, 1]], [[8, -7], [-6, 9]], [[8, -7], [6, 9]], [[-2, -5], [2, -3]], [[-2, -5], [4, -1]], [[0, 3], [6, 3]], [[0, 5], [6, 9]]]

def tmp11():
    #主端点
    mainVert = [[[-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]];

    len_ = len(mainVert);

    segs = [];
    
    for i in range(30):
        idx = [];
        for j in range(2):
            idx.append(random.randint(0, len_-1));
        pStart = mainVert[idx[0]][0];
        pEnd = mainVert[idx[1]][0];
        if (pStart != pEnd):
            segs.append(SegLine(mainVert[idx[0]][0], mainVert[idx[1]][0]));

    segs = sorted(list(set(segs)));

    print(len(segs));

    print(segs);

    result = [];
    for i in range(len(segs)):
        result.append(segs[i].value());

    print(result);

#</span>


首先多生成一些线段




选点1作为测试,看看有多少环形路径


<span style="font-size:18px;">#
>>> 
{Point([2, -7]): [Point([-2, -5]), Point([2, -3])], Point([6, -3]): [Point([-2, -9]), Point([2, -9]), Point([0, 3]), Point([6, 3])], Point([6, 3]): [Point([2, -3]), Point([6, -3]), Point([4, -1]), Point([0, 3]), Point([6, 9])], Point([-10, -9]): [Point([0, 3])], Point([8, -7]): [Point([4, 1]), Point([8, 3]), Point([0, 5]), Point([-6, 9])], Point([8, 3]): [Point([8, -7]), Point([-6, 9]), Point([6, 9])], Point([-2, -9]): [Point([6, -3]), Point([0, 3]), Point([2, 3])], Point([2, -3]): [Point([2, -7]), Point([-2, -5]), Point([4, -1]), Point([0, 3]), Point([6, 3])], Point([2, -9]): [Point([6, -3])], Point([0, 5]): [Point([8, -7]), Point([4, -1])], Point([4, -1]): [Point([2, -3]), Point([6, 3]), Point([-4, 5]), Point([0, 5])], Point([-2, -5]): [Point([2, -7]), Point([2, -3])], Point([0, 3]): [Point([-10, -9]), Point([-2, -9]), Point([2, -3]), Point([6, -3]), Point([6, 3]), Point([6, 9])], Point([-6, 9]): [Point([8, -7]), Point([8, 3])], Point([6, 9]): [Point([0, 3]), Point([2, 3]), Point([6, 3]), Point([8, 3])], Point([-4, 5]): [Point([4, -1])], Point([4, 1]): [Point([8, -7])], Point([2, 3]): [Point([-2, -9]), Point([6, 9])]}
>>> 

def tmp12():
    #主端点
    mainVert = [[[-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]];
    len_vert = len(mainVert);

    #线段
    seg = [[[-10, -9], [0, 3]], [[-2, -9], [6, -3]], [[-2, -9], [0, 3]], [[-2, -9], [2, 3]], [[2, -9], [6, -3]], [[2, -7], [-2, -5]], [[2, -7], [2, -3]], [[8, -7], [4, 1]], [[8, -7], [8, 3]], [[8, -7], [0, 5]], [[8, -7], [-6, 9]], [[-2, -5], [2, -3]], [[2, -3], [4, -1]], [[2, -3], [0, 3]], [[2, -3], [6, 3]], [[6, -3], [0, 3]], [[6, -3], [6, 3]], [[4, -1], [6, 3]], [[4, -1], [-4, 5]], [[4, -1], [0, 5]], [[0, 3], [6, 3]], [[0, 3], [6, 9]], [[2, 3], [6, 9]], [[6, 3], [6, 9]], [[8, 3], [-6, 9]], [[8, 3], [6, 9]]]
    len_seg = len(seg);

    #记录每一个顶点会和哪些其它顶点构成边
    segMap = dict();
    for i in range(len_vert):
        segMap[Point(mainVert[i][0])] = [];

    for i in range(len_seg):
        p1 = Point(seg[i][0]);
        p2 = Point(seg[i][1])
        segMap[p1].append(p2);
        segMap[p2].append(p1);

    print(segMap);

#</span>


解出的部分路径:

<span style="font-size:18px;">#
>>> 
11
[[Point([-2, -9]), Point([6, -3]), Point([0, 3]), Point([-2, -9])], [Point([-2, -9]), Point([6, -3]), Point([6, 3]), Point([0, 3]), Point([-2, -9])], [Point([-2, -9]), Point([0, 3]), Point([6, 9]), Point([2, 3]), Point([-2, -9])], [Point([-2, -9]), Point([6, -3]), Point([0, 3]), Point([6, 9]), Point([2, 3]), Point([-2, -9])], [Point([-2, -9]), Point([6, -3]), Point([6, 3]), Point([2, -3]), Point([0, 3]), Point([-2, -9])], [Point([-2, -9]), Point([6, -3]), Point([6, 3]), Point([6, 9]), Point([0, 3]), Point([-2, -9])], [Point([-2, -9]), Point([6, -3]), Point([6, 3]), Point([6, 9]), Point([2, 3]), Point([-2, -9])], [Point([-2, -9]), Point([0, 3]), Point([6, 3]), Point([6, 9]), Point([2, 3]), Point([-2, -9])], [Point([-2, -9]), Point([6, -3]), Point([0, 3]), Point([6, 3]), Point([6, 9]), Point([2, 3]), Point([-2, -9])], [Point([-2, -9]), Point([6, -3]), Point([6, 3]), Point([4, -1]), Point([2, -3]), Point([0, 3]), Point([-2, -9])], [Point([-2, -9]), Point([0, 3]), Point([2, -3]), Point([6, 3]), Point([6, 9]), Point([2, 3]), Point([-2, -9])]]
>>> 

[[[-2, -9], [6, -3], [0, 3], [-2, -9]], [[-2, -9], [6, -3], [6, 3], [0, 3], [-2, -9]], [[-2, -9], [0, 3], [6, 9], [2, 3], [-2, -9]], [[-2, -9], [6, -3], [0, 3], [6, 9], [2, 3], [-2, -9]], [[-2, -9], [6, -3], [6, 3], [2, -3], [0, 3], [-2, -9]], [[-2, -9], [6, -3], [6, 3], [6, 9], [0, 3], [-2, -9]], [[-2, -9], [6, -3], [6, 3], [6, 9], [2, 3], [-2, -9]], [[-2, -9], [0, 3], [6, 3], [6, 9], [2, 3], [-2, -9]], [[-2, -9], [6, -3], [0, 3], [6, 3], [6, 9], [2, 3], [-2, -9]], [[-2, -9], [6, -3], [6, 3], [4, -1], [2, -3], [0, 3], [-2, -9]], [[-2, -9], [0, 3], [2, -3], [6, 3], [6, 9], [2, 3], [-2, -9]]]

def tmp12():
    debug = 0;
    
    #主端点
    mainVert = [[[-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]];
    len_vert = len(mainVert);

    #线段
    seg = [[[-10, -9], [0, 3]], [[-2, -9], [6, -3]], [[-2, -9], [0, 3]], [[-2, -9], [2, 3]], [[2, -9], [6, -3]], [[2, -7], [-2, -5]], [[2, -7], [2, -3]], [[8, -7], [4, 1]], [[8, -7], [8, 3]], [[8, -7], [0, 5]], [[8, -7], [-6, 9]], [[-2, -5], [2, -3]], [[2, -3], [4, -1]], [[2, -3], [0, 3]], [[2, -3], [6, 3]], [[6, -3], [0, 3]], [[6, -3], [6, 3]], [[4, -1], [6, 3]], [[4, -1], [-4, 5]], [[4, -1], [0, 5]], [[0, 3], [6, 3]], [[0, 3], [6, 9]], [[2, 3], [6, 9]], [[6, 3], [6, 9]], [[8, 3], [-6, 9]], [[8, 3], [6, 9]]]
    len_seg = len(seg);

    #记录每一个顶点会和哪些其它顶点构成边
    segMap = dict();
    for i in range(len_vert):
        segMap[Point(mainVert[i][0])] = [];

    for i in range(len_seg):
        p1 = Point(seg[i][0]);
        p2 = Point(seg[i][1])
        segMap[p1].append(p2);
        segMap[p2].append(p1);

    #print(segMap);

    #每个顶点最多访问一次
    findedPath = [];

    #目标
    index = 1;
    taskVertex = Point(mainVert[index][0]);

    path = [[taskVertex]];
    result = [];
    
    while (path != []):
        a = path[0];
        path = path[1:];

        if (len(a) > 8):
            continue;

        p = segMap[a[-1]];

        for item in p:
            if item == taskVertex:
                if (len(a) > 2):
                    #此句是为了防止路径不断进行相同顶点之间的排列组合
                    b = sorted(a + [item]);
                    if not b in findedPath:
                        result.append(a+[item]);
                        findedPath.append(b);
            elif not item in a:
                path.append(a+[item]);

    if (debug):
        print(len(result));
        print(result);

    for i in range(len(result)):
        for j in range(len(result[i])):
            result[i][j] = result[i][j].value();

    print(result);

#</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.71, -7.45]], [[-0.71, -7.45], [0.29, -7.29]], [[0.29, -7.29], [2, -7]], [[-2, -9], [-0.71, -7.45]], [[-0.71, -7.45], [-0.18, -6.82]], [[-0.18, -6.82], [4.3, -1.44]], [[4.3, -1.44], [4.58, -1.11]], [[4.58, -1.11], [8, 3]], [[2, -9], [0.29, -7.29]], [[0.29, -7.29], [-0.18, -6.82]], [[-0.18, -6.82], [-2, -5]], [[8, -7], [4.3, -1.44]], [[4.3, -1.44], [4, -1]], [[2, -3], [2.0, 2.33]], [[2.0, 2.33], [2, 3]], [[2, 3], [2.0, 3]], [[6, -3], [4.58, -1.11]], [[4.58, -1.11], [2.0, 2.33]], [[2.0, 2.33], [1.5, 3]], [[1.5, 3], [0.71, 4.06]], [[0.71, 4.06], [0, 5]], [[4, 1], [4.57, 3.29]], [[4.57, 3.29], [6, 9]], [[0, 3], [1.5, 3]], [[1.5, 3], [2, 3]], [[2, 3], [2.0, 3]], [[6, 3], [4.57, 3.29]], [[4.57, 3.29], [0.71, 4.06]], [[0.71, 4.06], [-4, 5]], [[0, 5], [-6, 9]]];
*/

$divideSeg = [[[-10, -9], [0, 3]], [[-2, -9], [6, -3]], [[-2, -9], [0, 3]], [[-2, -9], [2, 3]], [[2, -9], [6, -3]], [[2, -7], [-2, -5]], [[2, -7], [2, -3]], [[8, -7], [4, 1]], [[8, -7], [8, 3]], [[8, -7], [0, 5]], [[8, -7], [-6, 9]], [[-2, -5], [2, -3]], [[2, -3], [4, -1]], [[2, -3], [0, 3]], [[2, -3], [6, 3]], [[6, -3], [0, 3]], [[6, -3], [6, 3]], [[4, -1], [6, 3]], [[4, -1], [-4, 5]], [[4, -1], [0, 5]], [[0, 3], [6, 3]], [[0, 3], [6, 9]], [[2, 3], [6, 9]], [[6, 3], [6, 9]], [[8, 3], [-6, 9]], [[8, 3], [6, 9]]]

$path = [[[-2, -9], [6, -3], [0, 3], [-2, -9]], [[-2, -9], [6, -3], [6, 3], [0, 3], [-2, -9]], [[-2, -9], [0, 3], [6, 9], [2, 3], [-2, -9]], [[-2, -9], [6, -3], [0, 3], [6, 9], [2, 3], [-2, -9]], [[-2, -9], [6, -3], [6, 3], [2, -3], [0, 3], [-2, -9]], [[-2, -9], [6, -3], [6, 3], [6, 9], [0, 3], [-2, -9]], [[-2, -9], [6, -3], [6, 3], [6, 9], [2, 3], [-2, -9]], [[-2, -9], [0, 3], [6, 3], [6, 9], [2, 3], [-2, -9]], [[-2, -9], [6, -3], [0, 3], [6, 3], [6, 9], [2, 3], [-2, -9]], [[-2, -9], [6, -3], [6, 3], [4, -1], [2, -3], [0, 3], [-2, -9]], [[-2, -9], [0, 3], [2, -3], [6, 3], [6, 9], [2, 3], [-2, -9]]]

//</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;
		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');
		}
		
		
		nSeg = $path.length;
		plot.setLineWidth(5);
		for (var i = nSeg-1; i >= 0; i-=3) {
			seg = transform.scale(transform.translate($path[i], 0, 0), scaleX/spaceX, scaleY/spaceY);
			plot.setLineWidth(3*i+2);
			shape.multiLineDraw([].concat(seg), colorArray[i%7]);
		}
		
		
		shape.pointDraw([].concat(a), 'blue', 1, 1, lable);
		
		

	}

//</span>



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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值