2014-03-05 63 views
0

解决C#二维数组按比例放大

我工作在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表示水/海滩/土地。我需要的只是将这个数据缩放到我需要的范围内,以便继续生成道路等等。基本上每个像素都是一块瓷砖,我需要宽度从目前的300宽度大约400k宽。我意识到输入数据可能太少,无法将其扩展到很高的水平,但我仍然想尝试。

我已经阅读了所有图像过滤和插值方法,但我无法掌握它们中的任何一个。我注意到这个问题已经问Array interpolation,但我不明白如何让它在大于4x4的网格上工作,但OP描述了我正在寻找的东西。

基本上线性或双三次浮点值的大网格过滤/缩放。我只需要一些示例代码来描述这个过程。

如果一切都失败了,我会将我的渐变切换到一个更简单的方法,并以我希望它开始的大小生成完整的地图数据。但我真的想尝试缩放它。提前致谢。

编辑 - 我已经到了一个点,我有一个加权值对的列表围绕我查询点的每个瓷砖。所以如果我在5.5,5.5的价值查询,我会得到周围(包括)5,5的瓷砖的价值和重量。所以我有一个9 {0.9,1.27} {0.3,0.77}等值对的列表,其中第一个是数组中的元素,第二个是它的权重(它与查询点之间的距离的倒数)。现在我正在努力将所有这些加权值对添加到一起以达到最终值。我很确定它与某种内插有关,但我无法完全理解如何去做。如果我能通过这部分,那么我应该与其他人一样好。

回答

0

我想出了一个适合我的方法。我会尽力在此解释我的解决方案,以防其他人需要此主题的帮助。请注意,这可能不是最好的解决方案,但它确实完成了工作。

我开始与我的源阵列float[,] sourceArray 和更大的阵列,我想我然后依次通过每瓦(数组元素)扩展到float[,] targetArray

在我的目标阵列,并获得百分比值之间它的中心和量表目标的总高度和宽度。然后我调用返回计算值的方法,传递百分比,源数组,源数组的宽度和源数组的高度。

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, weightweight根据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; 
} 

其结果是一个图像类似于整体形状和复杂度较小的版本与一些小的文物和保真度问题。它不如标准图像处理技术,但它对我来说非常合适。希望这可以帮助某人。