我一直在研究Diamond-square算法,我遇到了this website,它向我指出了Notch的Minicraft的源代码,并对算法进行了转换。由Notch。
在大多数情况下,我理解算法,但我可以了解这两个函数中的特定表达式:
private double sample(int x, int y) {
return values[ (x & (w - 1)) + (y & (h - 1)) * w ];
}
private void setSample(int x, int y, double value) {
values[ (x & (w - 1)) + (y & (h - 1)) * w ] = value;
}
我理解x + y * w
,但不理解(x & (w - 1)) + (y & (h - 1)) * w
,除了声明它可以解决这个问题之外,文章并没有解释这一点。
我在python中进行编码,但我不认为Java的按位&
和python之间存在任何差异,所以我摆弄了它有点但我仍然无法得到它。我做的其中一件事是一个模拟不同x
和y
值的循环,并将它们提供给该计算:
import random
w = h = 257 # 2^8 + 1
for i in xrange(10):
x = int(random.uniform(0, 1) *255)
y = int(random.uniform(0, 1) *255)
print x, y, '|', (x & (w-1)) + (y & (h-1)) *w
# I used a less readable right-aligning version of the above to display the output:
# print str( x ).rjust(3), str( y ).rjust(3), '|', str( (x & (w-1)) + (y & (h-1)) * w ).rjust(3)
输出:
112 213 | 0
181 117 | 0
1 105 | 0
216 223 | 0
170 185 | 0
158 32 | 0
124 225 | 0
62 153 | 0
90 147 | 0
196 69 | 0
除非我在这里做了一些根本错误的事情,否则它总是给我零,除非x
和/或y
等于w-1
,在这种情况下:
256 15 | 256
21 256 | 65792
256 256 | 66048
在实际算法中,x
和y
的值似乎总是(如果我理解的话)介于0
和halfStep
之间,halfStep = stepSize/2
},stepSize = featureSise
似乎(在Minicraft的代码中)总是硬编码为16
或32
。因此,根据我目前的理解,表达总是会评估为0
。
所以我很困惑。我不知道这是如何有用的,或者它在实践中是如何起作用的......我知道它有效,但它似乎是巫术......
我理解按位&
是如何工作的,但这似乎没有帮助。
答案 0 :(得分:1)
w
和h
必须是2的幂(并分别表示x
和y
的本地边界。
然后,w-1
和h-1
是一系列序列。每个信息位一个,可能分别低于w
和h
(仍然是>= 0
)。
当您现在评估按位和(&
)时,例如x & (w-1)
,这实际上会产生x % w
,其中%
是python中的模运算,x >= 0
。
因此,x
如果x
被映射到w > x >= 0
,否则x
被截断(将更高位置零),从而满足w > x >= 0
。
这同样适用于y
和h
。
因此,这些逻辑操作只不过是在位级别上评估 mod 。
对于您的代码:设置w=h=256
,一切都应该解决。