1 Delaunay三角网
定义:
它是一系列相连的但不重叠的三角形的集合, 而且这些三角形的外接圆不包含这个面域的其他任何点。
性质:
(1)每个德洛内(Delaunay) 三角形的外接圆不包含面内的其他任何点, 称之为德洛内(Delaunay) 三角网的空外接圆性质, 这个特征已经作为创建德洛内(Delaunay) 三角网的一项判别标准;
(2)它的另一个性质最大最小角性质: 每两个相邻的三角形构成的凸四边形的对角线,在相互交换后,六个内角的最小角不再增大。
2 泰森多边形
定义:
泰森多边形是对空间平面的一种剖分,其特点是多边形内的任何位置离该多边形的样点(如居民点)的距离最近,离相邻多边形内样点的距离远,且每个多边形内含且仅包含一个样点。由于泰森多边形在空间剖分上的等分性特征,因此可用于解决最近点、最小封闭圆等问题,以及许多空间分析问题,如邻接、接近度和可达性分析等。
3 实现程序
1 import turtle as p 2 3 4 # # 计算每个TIN三角形三边垂直平分线交点(外心)/ Voronoi多边形的每个顶点 5 def wai_xin(point_dic): 6 end_point = [] 7 cou = len(point_dic) - 1 8 x1 = point_dic[7][0] 9 y1 = point_dic[7][1] 10 for i in range(cou): 11 if i < cou - 1: 12 x2 = point_dic[i+1][0] 13 y2 = point_dic[i+1][1] 14 x3 = point_dic[i+2][0] 15 y3 = point_dic[i+2][1] 16 else: 17 x2 = point_dic[6][0] 18 y2 = point_dic[6][1] 19 x3 = point_dic[1][0] 20 y3 = point_dic[1][1] 21 A1 = 2 * (x2 - x1) 22 B1 = 2 * (y2 - y1) 23 C1 = x2 ** 2 + y2 ** 2 - x1 ** 2 - y1 ** 2 24 A2 = 2 * (x3 - x2) 25 B2 = 2 * (y3 - y2) 26 C2 = x3 ** 2 + y3 ** 2 - x2 ** 2 - y2 ** 2 27 x = int(((C1 * B2) - (C2 * B1)) / ((A1 * B2) - (A2 * B1))) 28 y = int(((A1 * C2) - (A2 * C1)) / ((A1 * B2) - (A2 * B1))) 29 end_point.append([x,y]) 30 return end_point 31 32 33 # # 画图UI界面 34 def paint_TIN_Voronoi(point_dic,wai_xy,point_abc,point_zhong_1,point_zhong_2): 35 # # UI界面显示TIN点、TIN点号、TIN点之间相互连线 36 p.setup(width=0.5, height=0.8) 37 p.pensize(3) 38 p.speed(2) 39 p.pencolor('red') 40 p.hideturtle() 41 # # 显示TIN点、TIN点号 42 for i in range(len(point_dic)): 43 p.penup() 44 p.goto(point_dic[i+1]) 45 p.write('*',font = ('黑体',25)) 46 p.goto(point_dic[i+1][0] - 20,point_dic[i+1][1] - 20) 47 p.write('%s' % point_abc[i+1], font=('黑体',28)) 48 p.pencolor('blue') 49 p.speed(4) 50 score = len(point_dic) 51 for j in range(score): 52 if j < score - 2: 53 # # 纠正不知道什么原因引起的坐标误差,连线绘制TIN三角网 54 p.penup() 55 p.goto(point_dic[j+1][0] + 7,point_dic[j+1][1] + 20) 56 p.pendown() 57 p.goto(point_dic[j+2][0] + 7,point_dic[j+2][1] + 20) 58 else: 59 p.penup() 60 p.goto(point_dic[score-1][0] + 7,point_dic[score-1][1] + 20) 61 p.pendown() 62 p.goto(point_dic[1][0] + 7,point_dic[1][1] + 20) 63 for k in range(score): 64 p.penup() 65 p.goto(point_dic[score][0] + 7,point_dic[score][1] + 20) 66 p.pendown() 67 p.goto(point_dic[k+1][0]+7,point_dic[k+1][1]+20) 68 # # 标记TIN三角形的名称‘M1 -- M6’ 69 for h in range(6): 70 p.speed(2) 71 p.pencolor('green') 72 p.pensize(5) 73 p.penup() 74 p.goto(wai_xy[h][0] + 30,wai_xy[h][1]) 75 p.pendown() 76 p.write('M%s' % (h+1), font=('宋体',24)) 77 78 79 # # UI界面显示Voronoi点、Voronoi点号、Voronoi点之间相互连线 80 p.speed(2) 81 p.pencolor('black') 82 p.pensize(2) 83 # # 显示点、点号 84 for l in range(len(wai_xy)): 85 p.penup() 86 p.goto(wai_xy[l][0],wai_xy[l][1]) 87 p.pendown() 88 p.write('*', font=('黑体',20)) 89 p.penup() 90 p.goto(wai_xy[l][0] - 20, wai_xy[l][1] - 20) 91 p.write('%s' % (l + 1), font=('黑体', 28)) 92 cout = len(wai_xy) 93 p.pencolor('yellow') 94 p.pensize(3) 95 p.speed(3) 96 for m in range(cout): 97 if m < cout -1: 98 p.penup() 99 p.goto(wai_xy[m][0] + 7,wai_xy[m][1] + 20) 100 p.pendown() 101 p.goto(wai_xy[m+1][0] + 7,wai_xy[m+1][1] + 20) 102 else: 103 p.penup() 104 p.goto(wai_xy[cout-1][0] + 7,wai_xy[cout-1][1] + 20) 105 p.pendown() 106 p.goto(wai_xy[0][0] + 7,wai_xy[0][1] + 20) 107 # # 标记泰森多边形名称为‘S_’ 108 p.speed(2) 109 p.penup() 110 p.goto(10,-10) 111 p.pendown() 112 p.pencolor('#4F4F4F') 113 p.pensize(9) 114 p.write('S1',font=('黑体',35)) 115 # # 继续绘制多边形的各点延长线 116 p.pensize(3) 117 for i in range(len(wai_xy)): 118 p.pencolor('yellow') 119 p.penup() 120 p.goto(wai_xy[i][0] + 7,wai_xy[i][1] + 20) 121 p.pendown() 122 p.goto(point_zhong_1[i][0]*1.1,point_zhong_1[i][1]*1.1) 123 p.penup() 124 # # 纠正点号显示位置 125 if i == 0: 126 p.goto(point_zhong_1[i][0] - 45,point_zhong_1[i][1] - 15) 127 p.pendown() 128 p.pencolor('black') 129 p.write(str(i+7),font=('黑体',25)) 130 if i == 1: 131 p.goto(point_zhong_1[i][0] - 15, point_zhong_1[i][1] + 20) 132 p.pendown() 133 p.pencolor('black') 134 p.write(str(i + 7), font=('黑体', 25)) 135 if i == 2: 136 p.goto(point_zhong_1[i][0] + 30, point_zhong_1[i][1] + 20) 137 p.pendown() 138 p.pencolor('black') 139 p.write(str(i + 7), font=('黑体', 25)) 140 if i == 3: 141 p.goto(point_zhong_1[i][0] + 35, point_zhong_1[i][1] - 40) 142 p.pendown() 143 p.pencolor('black') 144 p.write(str(i + 7), font=('黑体', 25)) 145 if i == 4: 146 p.goto(point_zhong_1[i][0], point_zhong_1[i][1] - 60) 147 p.pendown() 148 p.pencolor('black') 149 p.write(str(i + 7), font=('黑体', 25)) 150 if i == 5: 151 p.goto(point_zhong_1[i][0] - 35, point_zhong_1[i][1] - 60) 152 p.pendown() 153 p.pencolor('black') 154 p.write(str(i + 7), font=('黑体', 25)) 155 # # 标识其他泰森多边形名称 156 p.pencolor('#4F4F4F') 157 for i in range(len(point_zhong_2)): 158 p.penup() 159 p.goto(point_zhong_2[i][0] - 10,point_zhong_2[i][1]) 160 p.pendown() 161 p.write('S%s' % str(i+2),font=('黑体',35)) 162 # # 写UI标题 163 p.pencolor('black') 164 p.penup() 165 p.goto(-345,260) 166 p.pendown() 167 p.write('TIN-Voronoi-示意图',font=('微软雅黑',45)) 168 p.penup() 169 170 171 172 p.done() 173 174 175 176 177 if __name__ == '__main__': 178 # # TIN各点坐标 179 point_dic = { 180 1: (-300, -220), 181 2: (-260, 150), 182 3: (120, 210), 183 4: (360, 20), 184 5: (236, -245), 185 6: (0, -305), 186 7:(0,-35), 187 } 188 # # TIN各点编号 189 point_abc = { 190 1: 'A', 191 2: 'B', 192 3: 'C', 193 4: 'D', 194 5: 'E', 195 6: 'F', 196 7: 'G', 197 } 198 # # 中点1坐标 199 point_zhong_1 = [ 200 [-273.0,-15.0], 201 [-63.0,200.0], 202 [247.0,135.0], 203 [305.0,-98.5], 204 [125.0,-255.0], 205 [-143.0,-242.5], 206 ] 207 # # 中点2坐标 208 point_zhong_2 = [ 209 [-168.0, 92.5], 210 [92.0, 167.5], 211 [276.0, 18.25], 212 [215.0, -176.75], 213 [-9.0, -248.75], 214 [-208.0, -128.75], 215 ] 216 wai_xy = wai_xin(point_dic) 217 paint_TIN_Voronoi(point_dic,wai_xy,point_abc,point_zhong_1,point_zhong_2)