简单随机多边形切割方案

news2024/9/30 5:33:49

过程化处理中希望能够对某块区域生成随机多边形,以及再切割成子多边形
各种尝试之后发现一种通过python、turtle、pyclipper实现的简单方案

随机多边形

采用python直接生成随机多边形,算法原理:将360度随机拆分成各个角度,再通过随机半径连接起来

def get_random_poly(num_vertices, bounds):
    radii=[]
    for i in range(num_vertices):
        radii.append(random.uniform(0.5,1.0))
    min_weight=1.0
    max_weight=10.0
    total_weight=0.0
    angle_weights=[]
    for i in range(num_vertices):
        angle_weights.append(random.uniform(min_weight,max_weight))
        total_weight+=angle_weights[-1]
    angles=[]
    for angle_weight in angle_weights:
        angles.append(angle_weight*2*math.pi/total_weight)
    rx=(bounds[1][0]-bounds[0][0])/2
    ry=(bounds[1][1]-bounds[0][1])/2
    cx=bounds[0][0]+rx
    cy=bounds[0][1]+ry
    points=[]
    theta=0.0
    for i in range(num_vertices):
        points.append((
            cx+rx*radii[i]*math.cos(theta),
            cy+ry*radii[i]*math.sin(theta)))
        theta+=angles[i]
    return points

生成用以拆分多边形的矩形

采用中心点、法线矢量的方式生成

def get_perpendicular_rect(c,pn,hl,hw):
    p0=(c[0]+pn[1]*hl,c[1]-pn[0]*hl)
    p1=(c[0]-pn[1]*hl,c[1]+pn[0]*hl)
    rect=[]
    rect.append((p0[0]+pn[0]*hw,p0[1]+pn[1]*hw))
    rect.append((p0[0]-pn[0]*hw,p0[1]-pn[1]*hw))
    rect.append((p1[0]-pn[0]*hw,p1[1]-pn[1]*hw))
    rect.append((p1[0]+pn[0]*hw,p1[1]+pn[1]*hw))
    return rect

拆分多边形

采用pyclipper库实现任意多边形拆分,算法原型是Vatti clipping
这里采用递归的方式分割子多边形,直到面积小于指定值

import turtle
import random
import math
import pyclipper
...
# 计算多边形中心点
def get_poly_center(poly):
    c=[0,0]
    for p in poly:
        c[0]+=p[0]
        c[1]+=p[1]
    c[0]/=len(poly)
    c[1]/=len(poly)
    return c
    
# 计算两点距离的sqrt
def get_distsq(p0,p1):
    d=(p1[0]-p0[0],p1[1]-p0[1])
    return d[0]*d[0]+d[1]*d[1]
    
# 获取多边形中最远的点
def get_furthest_point(poly):
    c=get_poly_center(poly)
    f=poly[0]
    sq=get_distsq(c,f)
    for i in range(1,len(poly)):
        sq2=get_distsq(c,poly[i])
        if sq2>sq:
            sq=sq2
            f=poly[i]
    return c,f

# 计算多边形面积,正负可用来判定多边形矢量方向
def get_poly_area(poly):
    area=0
    v0=poly[0]
    v1=poly[1]
    for i in range(2,len(poly)):
        v2=poly[i]
        area+=(v1[0]-v0[0])*(v2[1]-v0[1])-(v1[1]-v0[1])*(v2[0]-v0[0])
        v1=v2
    return area*0.5

# 递归分割多边形,maxarea为最小不可分割面积
def clip_poly(poly,hl,hw,maxarea):
    ret=[]
    c,f=get_furthest_point(poly)
    d=[f[0]-c[0],f[1]-c[1]]
    l=math.sqrt(d[0]*d[0]+d[1]*d[1])
    d[0]/=l
    d[1]/=l
    pc=pyclipper.Pyclipper()
    pc.AddPath(poly,pyclipper.PT_SUBJECT,True)
    pc.AddPath(get_perpendicular_rect(c,d,hl,hw),pyclipper.PT_CLIP,True)
    for r in pc.Execute(pyclipper.CT_DIFFERENCE,pyclipper.PFT_EVENODD,pyclipper.PFT_EVENODD):
        area=get_poly_area(r)
        if area>=0:
            r.reverse()
        if math.fabs(area)<=maxarea:
            ret.append(r)
        else:
            reg=clip_poly(r,hl,hw,maxarea)
            for r2 in reg:
                ret.append(r2)
    return ret

通过turtle工具将切割效果显示出来

这里要注意turtle坐标中心点位于画布中央,x轴正向朝右,y轴正向朝上

...
# 利用鼠标点击事件可多次查看分割效果
def onmouseclick(x,y):
    radius=100
    poly=get_random_poly(10, ((x-radius,y-radius),(x+radius,y+radius)))
    reg=clip_poly(poly,900,3,300)
    for poly in reg:
        poly.append(poly[0])
        for p in poly:
            turtle.goto(p)
            turtle.down()
        turtle.up()

# python主程序入口
if __name__=='__main__':
    ts=turtle.getscreen()
    ts.onclick(onmouseclick)
    turtle.up()
    # 设置随机种子用以固定每次生成的结果
    random.seed(3)
    onmouseclick(0,0)
    turtle.done()

最终效果

在这里插入图片描述

参考

https://blog.csdn.net/bby1987/article/details/108858785
https://blog.csdn.net/qq_25737169/article/details/113843872
https://blog.csdn.net/ithiker/article/details/127712621

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/128704.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

过年不让放炮,我用Python实现了1000响大地红的特效

同志们&#xff0c;马上&#xff08;后天&#xff09;就要2023年啦&#xff0c;您有没有对象啦哈哈哈 咳咳&#xff0c;搞错了~~再来 新的一年&#xff0c;新的气象&#xff0c;穿上新衣逛街 俗话说得好&#xff0c;这所谓放鞭炮就是来压邪祟&#xff0c;除恶的&#xff0c;…

web前端-javascript-DOM和BOM详解

文章目录DOM 和 BOM1. DOM2. BOM2.1 BOM 简介2.2 分类2.3 语法1) Navigator 当前浏览器2&#xff09;Histry 向前或向后翻页3&#xff09;Location 地址栏的信息DOM 和 BOM 1. DOM 浏览器已经为我们提供了文档节点的对象&#xff0c;这个对象是 window 对象的属性可以在页面中…

2023北京/深圳NPDP产品经理入门到精通班招生简章

NPDP产品经理国际资格认证是国际公认的唯一的新产品开发专业认证&#xff0c;集理论、方法与实践为一体的全方位的知识体系&#xff0c;为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 我们针对互联网时代的个人、互联网企业、与传统企业推出一系列学习。 课程从…

喜上加喜|怿星科技荣获高工智能金球奖两项大奖

12月2日晚&#xff0c;2022第六届高工智能汽车金球奖年度颁奖典礼在上海虹桥正式开幕&#xff0c;来自行业内的100多家头部企业出席了此次盛会。 金球奖是由高工智能汽车组织的聚焦于汽车智能网联产业链的年度颁奖盛典。参选企业覆盖了汽车智能化创新公司、人工智能创新公司、传…

怎样把图片转化成jpeg格式?jpeg格式转换器分享

我们保存照片时发现有时候保存的图片为png格式或webp格式&#xff0c;而上传到其他平台的时候会有jpeg图片格式要求&#xff0c;那么就需要将图片转为jpeg&#xff0c;如何将图片格式转换&#xff08;在线图片格式转换器&#xff08;jpg、png、gif、webp、bmp、tiff&#xff09…

GoF23——工厂模式

✯ 面向对象设计原则 对接口编程而不是对实现编程优先使用对象组合而不是继承介绍说明 工厂模式&#xff08;Factory Pattern&#xff09;属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 在工厂模式中&#xff0c;我们在创建对象时不会对客户端暴露创建逻辑&am…

Java8并行流---并行数据处理与性能

Java8并行流---并行数据处理与性能0.主要内容1.并行流1.1将顺序流转换为并行流附录附录.10.主要内容 主要内容 用并行流并行处理数据 并行流的性能分析 分支/合并框架 使用Spliterator分割流 1.并行流 调用parallelStream方法来把集合转换为并行流。并行流就是一个把内容分成多…

pytorch应用(入门2) 一维线性回归

目录nn.Module&#xff08;模组&#xff09;torch.optim (优化)模型的保存和加载一维线性回归代码如下&#xff1a;均方差损失函数nn.MSELoss()model.parameters()的理解与使用torch.autograd.Variableoptimizer.zero_grad()model.eval的作用深度学习方法——pytorch下GPU与CPU…

如何设计一个好的工业产品?

许多人不知道工业设计的本质是什么?与工业设计相比&#xff0c;其本质是解决消费群体的相关问题&#xff0c;实现消费者的需求&#xff0c;使客户更容易选择。但是如何设计一个好的工业产品呢? 1.更加科学合理地摆脱困境 产品设计必须开拓进取。它应该能够引领时代潮流&#…

基础数学复习(2)——插值

文章目录插值和拟合的区别&#xff08;了解&#xff09;拉格朗日插值&#xff08;必考&#xff09;插值余项说不定会考的证明题拉格朗日插值缺点和适用范围&#xff08;了解&#xff09;牛顿插值&#xff08;必考&#xff09;推导差商的性质&#xff08;会考&#xff09;——通…

Java语法五:锁策略以及CAS

目录 1.常见的锁策略 2&#xff1a;Synchronized原理 2.1&#xff1a;加锁工作工程 2.2:其他的优化操作 2.2.1&#xff1a;锁消除 2.2.2&#xff1a;锁粗化 3.CAS 3.1&#xff1a;实现原子类 3.2&#xff1a;CAS中的ABA问题 3.2.1&#xff1a;什么是ABA问题 3.2.2&am…

【JavaScript】俄罗斯方块简单网页版

文章目录js制作简单网页版俄罗斯方块效果演示设计思路一、HTML网页结构代码二、CSS代码三、JS代码四、代码资源分享js制作简单网页版俄罗斯方块 程序虽然很难写&#xff0c;却很美妙。要想把程序写好&#xff0c;需要写好一定的基础知识&#xff0c;包括编程语言、数据结构与算…

在mac上搭建php的SNMP开发环境

前言 最近需要开发AC的snmp协议&#xff0c;需要开启php的snmp扩展&#xff0c;网上能搜索到的主要还是windows和centos下面的几篇资料。这里主要介绍下mac系统下如何搭建php的snmp开发环境。 第一步&#xff0c;安装php&#xff1a; 首先需要在mac上面安装PHP&#xff0c;这…

重点物联网漏洞利用情况

重点物联网 漏洞利用情况本节我们选取了两个漏洞进行分析。UPnP 相关的漏洞我们将在 4.4.3 进行分析&#xff0c;除去 UPnP 相关漏 洞外&#xff0c;被利用最多的是 Eir D1000 路由器的一个漏洞 [44]&#xff08;CVE-2016-10372&#xff09;&#xff0c;我们将对其进行分析。 …

第006课 - 使用vagrant快速创建linux虚拟机

使用vagrant快速创建linux虚拟机 项目中使用的环境,都是装在linux当中的,我们可以使用linux虚拟机。 https://www.virtualbox.org/ 直接双击进行安装运行。 CPU开启虚拟化 virtualbox安装需要我们的cpu开启虚拟化。 这个需要设置主板。 在开机启动的时候,找到cpu配置:…

什么是金手指,金手指的设计要求有哪些?

金手指&#xff08;connecting finger&#xff09;是电脑硬件如&#xff1a;&#xff08;内存条上与内存插槽之间、显卡与显卡插槽等&#xff09;&#xff0c;所有的信号都是通过金手指进行传送的。金手指由众多金黄色的导电触片组成&#xff0c;因其表面镀金而且导电触片排列如…

阿里云主要产品架构介绍

文章目录前言主要产品云产品访问拓扑ECS架构RDS架构OCS架构SLB架构OSS架构OTS架构ODPS架构SLSSLS的产品视角SLS运维视角OAS结语前言 阿里云产品众多&#xff0c;基本涵盖了从存储到计算到网络的方方面面&#xff0c;当然还包括大数据和人工智能。这些产品&#xff0c;共同组成…

响应式原理 之 vue2 vue3

目录 一、响应式概念 二、响应式函数的实现 watchFn 三、响应式依赖的收集 四、监听对象的变化 1. vue2 2. vue3 五、对象的依赖管理 1. 图解 2. 代码 六、响应式完整代码 一、响应式概念 m有一个初始化的值&#xff0c;有一段代码使用了这个值那么在m有一个新的值时…

热门探讨丨SaaS软件是否正在“毁掉”数字化转型企业?

——当它浮出水面&#xff0c;才能看到水下的错落。 截至2021年末&#xff0c;我国企业的数量达到4842万户&#xff0c;增长1.7倍&#xff0c;其中99%以上都是中小企业。 根据调查&#xff0c;在数字化转型浪潮中&#xff0c;我国有超过70%的企业对数字化转型处于积极态度&am…

网络部署运维实验(pat 端口映射含命令)

♥️作者&#xff1a;小刘在这里 ♥️每天分享云计算网络运维课堂笔记&#xff0c;疫情之下&#xff0c;你我素未谋面&#xff0c;但你一定要平平安安&#xff0c;一 起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的&#xff0c;绽放&#xff0c;…