作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我开始使用arduinos之类的语言开始进入C的中等深度,并且只想提供一些有关如何使用For循环生成随机噪声的建议。
重要的一点:
void testdrawnoise() {
int j = 0;
for (uint8_t i=0; i<display.width(); i++) {
if (i == display.width()-1) {
j++;
i=0;
}
M = random(0, 2); // Random 0/1
display.drawPixel(i, j, M); // (Width, Height, Pixel on/off)
display.refresh();
}
}
i
达到
display.width()-1
,则向下移动到下一行。像素是亮(黑)还是灭(白)由
M
确定。
最佳答案
首先,循环永远不会结束,并且继续不断地递增j
,因此,在填满屏幕一次之后,您将继续在屏幕高度之外进行循环。尽管您的库does bounds checking,在j
溢出并恢复为零之前,在没有实际做有用工作的情况下肯定不会有效地使用CPU来继续循环。
另外,有符号的溢出在C ++中是未定义的行为,因此从技术上讲,您的立场是不稳定的(我本来以为Arduino总是使用-fwrapv
进行编译,从而保证了有符号整数溢出(aa)的折回)。
鉴于您正在使用的库将整个帧缓冲区保留在内存中并通过refresh
调用将其全部发送,因此在每个像素处重新发送它没有多大意义-尤其是因为帧传输可能是通过这是该循环中最慢的部分。因此,您可以将其移出循环。
将它们放在一起(加上缓存宽度和高度,并使用更简单的random
重载),可以将其更改为:
void testdrawnoise() {
int w = display.width(), h = display.height();
for (int j=0; j<h; ++j) {
for (int i=0; i<w; ++i) {
display.drawPixel(i, j, random(2));
}
}
display.refresh();
}
int
更改为
byte
来获得一些好处,但是请不要相信我)
loop()
函数或无限循环以使其继续生成随机模式。
sharpmem_buffer
的全局变量中。
malloc
时,库将对内存中的相应字节执行一系列布尔运算,以仅设置您要的位,而不会触及其余位。相当愚蠢,因为无论如何您都会随机覆盖其他对象。
void testdrawnoise() {
// access the buffer defined in another .cpp
extern byte *sharpmem_buffer;
byte *ptr = sharpmem_buffer; // pointer to current position
// end position
byte *end = ptr + display.width()*display.height()/8;
for (; ptr!=end; ++ptr) {
// store a full byte of random
*ptr = random(256);
}
display.refresh();
}
drawPixel
时间,它应该比以前的版本至少快8倍(我实际上期望的要多得多,因为不仅循环的核心执行了1/8的迭代,而且它也更简单-除了
refresh()
之外,没有函数调用,没有分支,没有对内存的布尔操作)。
random
返回一个带符号的值,还不清楚它提供的范围是什么。因此,我们必须推出自己的PRNG,以保证提供32个完整的随机位。
random
of the obvious size;我们将直接使用来自Wikipedia的xorshift32,因为我们实际上并不需要改进的“ *”或“ +”版本(我们也不关心较大的同行提供更长的期限)。
struct XorShift32 {
uint32_t state = 0x12345678;
uint32_t next() {
uint32_t x = state;
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
state = x;
return x;
}
};
XorShift32 xorShift;
testdrawnoise()
:
void testdrawnoise() {
int size = display.width()*display.height();
// access the buffer defined in another .cpp
extern byte *sharpmem_buffer;
/*
we can access the framebuffer as if it was an array of 32-bit words;
this is fine, since it was alloc-ed with malloc, which guarantees memory
aligned for the most restrictive built-in type, and the library only
uses it with byte pointers, so there should be no strict aliasing problem
*/
uint32_t *ptr = (uint32_t *)sharpmem_buffer;
/*
notice that the division is an integer division, which truncates; so, we
are filling the framebuffer up the the last multiple of 4 bytes; with
"strange" sizes we may be leaving out up to 3 bytes (see later)
*/
uint32_t *end = ptr + size/32;
for (; ptr!=end; ++ptr) {
// store a full byte of random
*ptr = xorShift.next();
}
// now to fill the possibly missing last three bytes
// pick it up where we left it
byte *final_ptr = (byte *)end;
byte *final_end = sharpmem_buffer + size/8;
// generate 32 random bits; it's ok, we'll need at most 24
uint32_t r = xorShift.next();
for(; final_ptr!=final_end; ++final_ptr) {
// take the lower 8 bits
*final_ptr = r;
// throw away the bits we used, get in the upper ones
r = r>>8;
}
display.refresh();
}
关于c++ - 使用For循环生成随机视觉噪声,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45391453/
我是一名优秀的程序员,十分优秀!