2015-08-28 31 views
3

我遇到了一个有些烦人的问题,在不知道正确的词汇表的情况下难以解释,但下面的两个图像应该解释我在找什么。在网络中画出点的影响

我有一个连接点的网络。每个点都有一个颜色属性。

Dot Network

网络中的每个点表示,对于没有更好的术语的,由相应的颜色“拥有”的位置。我现在想正常上展示其附近,即颜色“领土”的影响各拥有点有,通过产生一个类似于此:

Colored Dot Network

我看不到一个简单的解决了这一点。我能看到的最可能的解决方案是生成一个平面,将有关每个点的信息传递给适当的着色器,并用它来计算平面的纹理。然而,与这个例子不同的是,不仅有10个点,而且可能在1000-2000之间。

要提出一些更为具体的问题:

1)能着色器处理点(金额超过1000个)?

2)我不确定着色器必须具备哪种算法才能获得正确的结果。遍历所有点并将它们与所有剩余的点进行比较并生成某种权重似乎是不理想的。我的背景是物理学,第一个本能就是产生类似于维格纳 - 塞茨细胞的东西。 (我会提供一个图片链接来解释我的意思,但是看起来我只能用一个新帐户发布2个链接,但是快速的谷歌图片搜索应该有很多好的结果)

3)显而易见的一个问题:我错过了一个微不足道的解决方案吗?

+0

点是否会移动或改变其影响范围?如果不是,则可以更高效地为每个点生成一个相对于其直接相邻点的影响多边形,并根据需要更新每个多边形的颜色。 – rutter

+0

@rutter他们不会相对于彼此移动,他们的关系也不会改变。每个点生成一个多边形不是我以前考虑过的。虽然回想起来,我对Wigner-seitz细胞的第一本能就是这样,所以也许它有优点 –

回答

1

这就是我要做的,创建一个所有点的数组和它们的位置,让我们来谈谈这个问题,就像你将以统一的全屏模式运行它,然后创建一个新的数组来保存所有点的位置,我们希望以像素为单位的世界位置。现在代码如下:

Transform[] dots; 
Vector3[] position; //Vector2 is more appropriate because of 2D space but most of the Unity functions support only Vector3 

void Awake(){ 
    for(int i =0; i < dots.Length; i++) 
     position[i] = Camera.main.WorldToScreenPoint(dots[i].position); 
} 

现在我们在屏幕上有所有点的位置,接下来的事情就是创建实际的纹理。

Texture2D outTex = new Texture2D (Screen.height, Screen.width, TextureFormat.RGB24, false); 

现在我们应该遍历这个纹理上的每个像素,并创建特定的公式来确定该像素应该是什么颜色。

添加Color32类型的另一个数组变量,该变量将为每个点定义颜色(由谁拥有)。

int h = outTex.height; 
int w = outTex.width; 
for (int i = 0; i < h; i++) 
    for (int j = 0; j < w; j++) { 
     //Formula for determining color is right here, here is my suggestion 
     //(the most simplest one), check the color of each dot and based on the distance 
     //between this pixel and dot's position determine how much influence that dot 
     //has on this pixel, here is how it goes 
     float red = 0; 
     float green = 0; 
     float blue = 0; 
     float divider = 0; 
     for(int c = 0; c < dots.Length; c++){ 
      float curDist = Vector3.Distance(dots[c].position, new Vector3(j, i ,0); 
      curDist = 1f/(curDist+1f); 
      red += dotColors[c].r * curDist; 
      green += dotColors[c].g * curDist; 
      blue += dotColors[c].b * curDist; 
      divider++; 
     } 
     outTex.SetPixel (j , i, new Color32(red/divider, green/divider, blue/divider, 255);  
    } 
outTex.Apply(); 

最后一部分会添加一些精灵,它具有整个屏幕的大小并将其应用到它。

所有这些只是给你一个基本的想法,你将如何去解决它,所有这些代码没有经过测试,所以你会prolly发现它的一些错误,但我把这个工作留给你。如果您在这里发现任何问题并发表评论,我会回复,因为您提出了一个有趣的问题,我非常乐意帮助您。这让我想起使用不同颜色的光源渲染白色2D纹理(这是你的点),所以试着在网上找到人们如何编写2D光渲染的脚本,你会prolly找到一些有趣和有用的东西那里。

+0

我已经采取了你的方法并改变了一下,所以不是将颜色混合在一起,而是使用任何颜色点最接近,它确实产生了我正在寻找的确切结果,但是......平均情况下有2000个点,纹理需要相当高的分辨率才能使结果看起来可以接受。即使3k * 3k纹理看起来不太好。有了这些数据,算法足以让我在此期间做饭。我可以缓存结果,但它是保证随时间变化的少数几件事之一 –

+0

您可以向我发送生成的图像或屏幕截图吗?我真的很感兴趣,看看它看起来如何,但我没有时间把它全部设置为现在:)问题为什么需要这么长时间是因为“SetPixel”是非常缓慢和无效的,因为每次你打电话它需要一个大量的内存和删除所有它只是为了设置一个像素的颜色,请尝试使用“SetPixels”http://docs.unity3d.com/ScriptReference/Texture2D.SetPixels.html –

+0

[Here](http:// imgur .com/p8YEpHq)是它目前的样子。我为每个点分配了一个随机颜色来进行测试,但它应该看起来完全符合我需要的方式,一旦每个点具有合适的颜色。我现在给SetPixels一个试试,并比较它与SetPixel相比花费的时间。 –