当前位置:网站首页>多边形等分
多边形等分
2022-08-05 05:16:00 【staHuri】
多边形等分思路
前提条件
- 封闭面,不可以有空洞
解题思路
- 封闭面中随机构造点
- 利用 k-means 分组(在此方法中设置分组数量 簇数)
- 计算每一个簇的质心
- 利用质心绘制 voronoi 泰森多边形
- 利用封闭面切割泰森多边形
注
本文中判断点是否在面中利用了 这篇文章
实现
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import shapefile as shp
import matplotlib.pyplot as plt
import random
import numpy as np
from sklearn.cluster import KMeans
from scipy.spatial import Voronoi, voronoi_plot_2d
def isPoiWithinPoly(poi, poly):
""" 判断是否在面内 :param poi: [x,y] :param poly: [ [ [x1,y1],[x2,y2],[] ] ] :return: boolean """
sinsc = 0
for epoly in poly:
for i in range(len(epoly) - 1):
s_poi = epoly[i]
e_poi = epoly[i + 1]
if isRayIntersectsSegment(poi, s_poi, e_poi):
sinsc += 1
return True if sinsc % 2 == 1 else False
def isRayIntersectsSegment(poi, s_poi, e_poi):
if s_poi[1] == e_poi[1]:
return False
if s_poi[1] > poi[1] and e_poi[1] > poi[1]:
return False
if s_poi[1] < poi[1] and e_poi[1] < poi[1]:
return False
if s_poi[1] == poi[1] and e_poi[1] > poi[1]:
return False
if e_poi[1] == poi[1] and s_poi[1] > poi[1]:
return False
if s_poi[0] < poi[0] and e_poi[1] < poi[1]:
return False
xseg = e_poi[0] - (e_poi[0] - s_poi[0]) * (e_poi[1] - poi[1]) / (e_poi[1] - s_poi[1]) # 求交
if xseg < poi[0]:
return False
return True
# 开始
sf = shp.Reader("浙江省.shp")
plt.figure()
x = None
y = None
# 将SHP中的图形展示到Plots中
for shape in sf.shapeRecords():
for i in range(len(shape.shape.parts)):
i_start = shape.shape.parts[i]
if i == len(shape.shape.parts) - 1:
i_end = len(shape.shape.points)
else:
i_end = shape.shape.parts[i + 1]
x = [i[0] for i in shape.shape.points[i_start:i_end]]
y = [i[1] for i in shape.shape.points[i_start:i_end]]
plt.plot(x, y)
# 获取当前面的最大最小XY
minX = min(x)
maxX = max(x)
minY = min(y)
maxY = max(y)
# 随机生成一定数量的散点 在这个平面内
# step 总共要多少个点
step = 10000
# count 记录当前点数量
count = 1
point_random = []
for i in range(10000):
rx = random.uniform(minX, maxX)
ry = random.uniform(minY, maxY)
if isPoiWithinPoly([rx, ry], [list(zip(x, y))]) and count < step:
count += 1
point_random.append([rx, ry])
# plt.scatter(rx, ry, s=20, c='aqua', alpha=0.5)
print("当前共有", count, "点")
print("随机点", point_random)
# kmean 簇族 分组量
group_size = 10
clf = KMeans(n_clusters=group_size)
cluster_group = clf.fit_predict(point_random)
# 遍历构造新的随机点 + 分组 [x,y,group_id]
point_kmean = []
# 设置颜色集合
cnames = ['black', 'blue', 'red', 'khaki', 'aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige',
'bisque', 'blanchedalmond', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate',
'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray',
'darkgreen', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred',
'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategray', 'darkturquoise', 'darkviolet', 'deeppink',
'deepskyblue', 'dimgray', 'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro',
'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'honeydew', 'hotpink', 'indianred',
'indigo', 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue',
'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgreen', 'lightgray', 'lightpink', 'lightsalmon',
'lightseagreen', 'lightskyblue', 'lightslategray', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen',
'linen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple',
'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred',
'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive', 'olivedrab',
'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'palevioletred', 'papayawhip', 'peachpuff',
'peru', 'pink', 'plum', 'powderblue', 'purple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon',
'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', 'slategray', 'snow',
'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'white',
'whitesmoke', 'yellow', 'yellowgreen']
for point, gp_id in zip(point_random, cluster_group):
point_kmean.append([point, gp_id])
# 放到 plt 中展示
plt.scatter(point[0], point[1], s=5, c=cnames[gp_id], alpha=1)
# 通过 kmean 质心绘制泰森多边形
cluster_center = clf.cluster_centers_
print("质心")
print(cluster_center)
for i in cluster_center:
plt.scatter(i[0], i[1], s=25, c='green', alpha=1)
# 泰森多边形加载到plot上
points = np.array(cluster_center)
vor = Voronoi(points)
voronoi_plot_2d(vor)
for region in vor.regions:
if not -1 in region:
polygon = [vor.vertices[i] for i in region]
plt.fill(*zip(*polygon))
plt.show()

边栏推荐
- Kubernetes常备技能
- spingboot 容器项目完成CICD部署
- Thread handler句柄 IntentServvice handlerThread
- 【shell编程】第二章:条件测试语句
- 【论文精读】Rich Feature Hierarchies for Accurate Object Detection and Semantic Segmentation(R-CNN)
- 2021电赛资源及经验总结
- 【Pytorch学习笔记】8.训练类别不均衡数据时,如何使用WeightedRandomSampler(权重采样器)
- 吞吐?带宽?傻傻分不清楚
- OSPF网络类型
- [Pytorch study notes] 9. How to evaluate the classification results of the classifier - using confusion matrix, F1-score, ROC curve, PR curve, etc. (taking Softmax binary classification as an example)
猜你喜欢

WCH系列芯片CoreMark跑分

【Kaggle项目实战记录】一个图片分类项目的步骤和思路分享——以树叶分类为例(用Pytorch)

IDEA 配置连接数据库报错 Server returns invalid timezone. Need to set ‘serverTimezone‘ property.

CVPR2020 - 自校准卷积

【shell编程】第三章:函数

MaskDistill-不需要标注数据的语义分割

伪RTOS-ProroThread在CH573芯片上的移植

Tensorflow踩坑笔记,记录各种报错和解决方法

MSRA提出学习实例和分布式视觉表示的极端掩蔽模型ExtreMA

九、响应处理——内容协商底层原理
随机推荐
服务网格istio 1.12.x安装
IJCAI 2022|边界引导的伪装目标检测模型BGNet
基于STM32F407的一个温度传感器报警系统(用的是DS18B20温度传感器,4针0.96寸OLED显示屏,并且附带日期显示)
SQL(1) - Add, delete, modify and search
SSL 证书签发详细攻略
MySQL
网管日记:故障网络交换机快速替换方法
【ts】typescript高阶:模版字面量类型
[Intensive reading of the paper] R-CNN's Bounding box regression problem is detailed
Tensorflow踩坑笔记,记录各种报错和解决方法
【Shell编程】第一章:子串
单变量线性回归
CH32V307 LwIP移植使用
华科提出首个用于伪装实例分割的一阶段框架OSFormer
初识机器学习
用GAN的方法来进行图片匹配!休斯顿大学提出用于文本图像匹配的对抗表示学习,消除模态差异!
PoE视频监控解决方案
[Database and SQL study notes] 8. Views in SQL
【shell编程】第二章:条件测试语句
Mysql-连接https域名的Mysql数据源踩的坑