解决
我正在研究2D程序岛生成器。到目前为止,我已经使用了几种噪声函数和混合来实现所需的岛形状,但目前它们的尺寸仅为300 x 200像素。我想要做的是将图像数据(不是图像)扩展到400,000 x 400,000范围内所需的地图大小。我考虑过简单地将噪声函数更改为较低的频率,从而产生较大的岛屿,但我也将它们与生成的梯度混合在一起,该梯度已经在计算上很重。增加生成的渐变的大小会大大缩短生成时间。
我的岛屿形状/图像:http://4.bp.blogspot.com/-ed7nK7jwcJc/UxYjNMxUF-I/AAAAAAAAASc/sG-BygA4usA/s1600/PopulationMap1.png
岛屿背后的数据是一系列花车,范围从0到1,代表水/海滩/陆地。我所需要的只是将 THAT 数据扩展到我继续生成道路等所需的范围。基本上每个像素都是一个瓦片,我需要宽度约为400k,宽度为300。我意识到输入数据可能太少而无法将其扩展到高,但我仍然想尝试它。
我已经阅读了所有图像过滤和插值方法,但我无法掌握它们中的任何一个。我注意到这个问题已经问Array interpolation但是我无法理解如何让它在大于4x4的网格上工作,但是OP正好描述了我正在寻找的东西。
基本上线性或双三次滤波/缩放浮点值的大网格。我只需要一些示例代码来概述该过程..
如果所有其他方法都失败了,我会将渐变切换为更简单的方法,只生成我希望它开始的大小的整个地图数据。但我真的想尝试扩展它。提前谢谢。
编辑 - 我已经达到了这样的程度,即我所查询的点周围的每个瓦片都有一个加权值对列表。因此,如果我查询5.5,5.5的值,我会得到周围(包括)5,5的瓦片的值和重量。所以我有一个9 {0.9,1.27} {0.3,0.77}等值对的列表,其中第一个是数组中的元素,第二个是它的权重(它与查询点之间的距离的倒数)。现在我正在努力将所有这些加权值对加在一起以达到最终值。我很确定它与某种插值有关但我无法完全掌握它的方法。如果我能够通过这一部分那么我应该对其余部分做得很好。
答案 0 :(得分:0)
我找到了一种适合我的方法。我将尝试在此处解释我的解决方案,以防其他人需要有关此主题的帮助。请注意,这可能不是最佳解决方案,但确实可以完成工作。
我从源数组float[,] sourceArray
开始
还有一个我希望缩放到float[,] targetArray
然后我循环遍历目标数组中的每个tile(数组元素),并获得它的中心与缩放目标的总高度和宽度之间的百分比值。然后我调用一个返回计算值的方法,传入百分比,源数组,源数组的宽度和源数组的高度。
for(float x = 0, x < scaleWidth, x++)
{
for(float y = 0, y < scaleHeight, y++)
{
Vector2 percentage = new Vector2((x+0.5)/scaleWidth, (y+0.5)/scaleHeight);
targetArray[x,y] = GetScaleValueAt(percentage, sourceArray, sourceWidth, sourceHeight);
}
}
我的GetScaleValueAt()
方法返回请求的,正确缩放的值。首先,它根据百分比在源数组中找到相应的位置。它还会找到该位置所在的图块。
public float GetScaleValueAt(float percent, float[,] source, int width, int height)
{
Vector2 location = new Vector2(width * percent.X, height * percent.Y);
Point centerTile = new Point((int)Math.Floor(loc.X), (int)Math.Floor(loc.Y));\
然后我使用另一种方法来获得与中心区域相邻的所有区块(包括中心区块)
List<Point> tiles = GetIncNeighborhood(centerTile.X, centerTile.Y, width, height);
接下来,我遍历此列表并使用WeightedPair
填充第二个列表,该列表只是一个具有两个浮点值的类或结构 - float value, weight
是可访问的。 weight
是根据location
与每个图块之间距离的倒数计算出来的。我还保存了加权值的总和。
List<WeightedPair> weightValues = new List<WeightedPair>();
float weightedTotal = 0;
foreach(Point p in tiles)
{
Vector2 distance = new Vector2();
distance.X = System.Math.Abs(loc.X - p.X);
distance.Y = System.Math.Abs(loc.Y - p.Y);
float inverseDist = 1 / distance.Length();
float value = source[p.X, p.Y];
weightedTotal += invDist;
weightValues.Add(new WeightedPair(value, invDist));
}
最后,我遍历weightValues
列表并通过将每个value
乘以相应的weight/weightedTotal
来计算值。
float finalValue = 0;
foreach(WeightedPair w in weightValues)
{
finalValue += w.value * (w.weight/weightedTotal);
}
return finalValue;
}
结果是一个类似于整体形状和复杂性的较小版本的图像,带有一些轻微的伪像和保真度问题。它不如标准图像处理技术好,但对我来说效果很好。希望这有助于某人。