DOTS计算Voronoi图形生成,根据点自动划分区域生成多边形

news/2024/11/15 17:43:06/文章来源:https://www.cnblogs.com/flamesky/p/18429992

 

 如图,生成Voronoi图形,代码如下。

 

// web* src = https://gist.github.com/andrew-raphael-lukasik/cc9d61edbbb44ecb4956c6cb69363a8e
using UnityEngine;
using Unity.Mathematics;
using Unity.Jobs;
using Unity.Collections;
using Unity.Profiling;[ExecuteInEditMode]
public class VoronoiTextureBurstJobComponent : MonoBehaviour
{[SerializeField][Min(1)] uint _seed = 769;[SerializeField][Range(2,512)] int _width = 300, _height = 300;[SerializeField][Range(1,64)] int _numRandomPoints = 3;Texture2D _texture;NativeList<ushort2> _points;uint lastSeedUsed = 0;void OnValidate (){bool inputChanged = false;if( !_points.IsCreated ){_points = new NativeList<ushort2>( Allocator.Persistent );inputChanged = true;}if( _points.Length!=_numRandomPoints ){_points.Length = _numRandomPoints;inputChanged = true;}if( _texture==null || _texture.width!=_width || _texture.height!=_height ){if( _texture==null ) DestroyItWillYou( _texture );_texture = new Texture2D( _width , _height , TextureFormat.RGBA32 , mipCount:0 , linear:true );inputChanged = true;}if( inputChanged || _seed!=lastSeedUsed ){lastSeedUsed = _seed;var watch = System.Diagnostics.Stopwatch.StartNew();var dep = new FillRandomPointsJob{TextureWidth    = _width ,TextureHeight    = _height ,Seed            = _seed ,Points            = _points ,}.Schedule();NativeArray<RGBA32> textureData = _texture.GetRawTextureData<RGBA32>();new GenerateVoronoiDiagramJob{Points            = _points ,TextureWidth    = _width ,TextureHeight    = _height ,TextureOutput    = textureData ,}.Schedule( textureData.Length , _width , dep ).Complete();_texture.Apply();Debug.Log( $"jobs took {watch.ElapsedMilliseconds} [ms] to complete");}}void OnEnable ()=> OnValidate();void OnDisable (){if( _texture!=null ) DestroyItWillYou(_texture);if( _points.IsCreated ) _points.Dispose();}void OnGUI ()=> GUI.DrawTexture( new Rect(0,0,_width,_height) , _texture );void DestroyItWillYou ( Object obj ){if( Application.isPlaying ) Destroy( obj );else DestroyImmediate( obj );}[Unity.Burst.BurstCompile]struct FillRandomPointsJob : IJob{public int TextureWidth, TextureHeight;public uint Seed;[WriteOnly] public NativeArray<ushort2> Points;void IJob.Execute (){var rnd = new Unity.Mathematics.Random( Seed );int len = Points.Length;for( int i=0 ; i<len ; i++ )Points[i] = new ushort2{ x=(ushort)rnd.NextInt(TextureWidth) , y=(ushort)rnd.NextInt(TextureHeight) };}}[Unity.Burst.BurstCompile]struct GenerateVoronoiDiagramJob : IJobParallelFor{[ReadOnly] public NativeArray<ushort2> Points;public int TextureWidth, TextureHeight;[WriteOnly] public NativeArray<RGBA32> TextureOutput;void IJobParallelFor.Execute ( int jobIndex ){float2 pixelPos = new int2{ x=jobIndex%TextureWidth , y=jobIndex/TextureWidth };float pointDist = float.MaxValue;int pointIndex = -1;for( int i=Points.Length-1 ; i!=-1 ; i-- ){float2 pointPos = new float2{ x=Points[i].x , y=Points[i].y };float dist = math.lengthsq( pointPos - pixelPos );// dist sq// float2 vec =  math.abs( pointPos - pixelPos );// float dist = vec.x + vec.y;// manhattan distanceif( dist<pointDist ){pointDist = dist;pointIndex = i;}if( dist<math.max(math.min(TextureWidth*0.01f,TextureHeight*0.01f),1) ){TextureOutput[jobIndex] = new RGBA32{ r=0 , g=0 , b=0 , a=255 };return;}}RGBA32 colorFromCoord;{ushort2 pointCoord = Points[pointIndex];float2 f = new float2{ x=pointCoord.x , y=pointCoord.y } / ( new float2{ x=TextureWidth , y=TextureHeight } - new float2{ x=1 , y=1 } );byte r = (byte)( 255*f.x );byte g = (byte)( 255*f.y );byte b = (byte)( (r+g)%255 );colorFromCoord = new RGBA32{ r=r , g=g , b=b , a=255 };}TextureOutput[jobIndex] = colorFromCoord;}}struct ushort2 { public ushort x, y; }struct RGBA32 { public byte r, g, b, a; }}

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue2+3基础

。第一个Vue程序 使用script进行Vue全局设置: 指定Vue实例挂载的位置 , Vue和js一样,都需要在script里写 第一步创建vue实例 1.为什么要new vue(),直接调用Vue不行吗?不行,因为如果直接调用Vue()会报如下错误: 2.关于vue构造函数:optionsoptions翻译为多个选项 Vue…

JAVA的字符串这篇讲清楚了

JAVA_String 从概念上讲,JAVA字符串就是Unicode序列。例如"Java\u2122"由5个UNICODE字符J,a,v,a和™组成。Java没有内置和字符串类型,而是试用java标准库中提供的一个预定义类,很自然地叫做了string。 子串substring String subStr = str.substring(beginIndex);这…

任务4:制作二维码

该二维码链接到游戏“植物大战僵尸”,寓教于乐。 提升趣味性和互动性的同时,学生们参与到课堂当中,发挥主体作用,感受到自然界植物的多样性,对土壤的作用有了更深刻的理解。

封装的练习题目1

1.使用面向对象的思想,编写自定义描述狗的信息。设定属性包括:品种,年龄,心 情,名字;方法包括:叫,跑。 要求: 1)设置属性的私有访问权限,通过公有的 get,set 方法实现对属性的访问 2)限定心情只能有“心情好”和“心情不好”两种情况,如果无效输入进行提示, 默认…

五款免费可视化工具全解析:选择你的最佳搭档

1. 山海鲸可视化 介绍: 山海鲸可视化是一款免费的国产可视化报表软件,与许多其他宣传免费的软件不同,山海鲸的报表功能完全免费并且没有任何限制,就连网站管理后台这个功能也是免费的。同时山海鲸可视化还提供了种类丰富的可视化图表、三维模型、模板可供使用,软件采用点击…

408OS_PV操作大题总结

咸鱼今年压了读者写者问题,前几年没考过。死锁的四个条件是:禁止抢占(no preemption):系统资源不能被强制从一个线程中退出。 持有和等待(hold and wait):一个线程在等待时持有并发资源。持有并发资源并还等待其它资源,也就是吃着碗里的望着锅里的。 互斥(mutual exc…

2024.9.24 思维导图与PDF

哈哈哈终于有我也用过的东西啦~Xmind一款打工人用了都说好的软件(#.#) 【知识小课堂1】不同款式的思维导图:【知识小课堂2】PDF转换器! 1、PDF(便携式文档格式),这种文件格式与操作系统平台无关 —— PDF文件不管是在Windows还是别的操作系统中都是通用的。 2、这一特点使它…

如何设计一个伪无埋点的框架?

主要基于无埋点的缺点,来设计一个伪无埋点的框架,使得业务既可以拥有无埋点的特性,又能满足业务的数据分析需求本文同步发布于公众号:移动开发那些事如何设计一个伪无埋点的框架 在前面的文章:Android无埋点技术概览 中提到传统的无埋点有几大缺点:埋点字段有限,没有办法…

吴恩达机器学习课程 笔记4 分类 逻辑回归

逻辑回归 机器学习中的逻辑回归(Logistic Regression)是一种广泛使用的分类算法,尽管它的名字中包含“回归”这个词,但实际上它主要用于解决分类问题,特别是二分类问题。逻辑回归模型可以用来预测某一类事件发生的概率,例如预测用户是否会点击广告、病人是否患有某种疾病…

设计模式之中介模式(三分钟学会一个设计模式)

中介模式(Mediator)又称之为调停模式。mediator [ˈmiːdieɪtə(r)] n. 调停者;斡旋者;解决纷争的人(或机构); 本意就是解决纠纷的中间人它是面向对象六大原则中最少知道原则的一个典型应用。(关于面向对象六大原则,可看前文:https://www.cnblogs.com/jilodream/p/535351…