【发布时间】:2020-11-17 06:44:12
【问题描述】:
我正在尝试将两个数组的迭代转换为组合数组大小的 4 倍,以制作图像,
example input => [[1][0]]
expected output=> [[255][255][255][255][0][0][0][255]]
((height*width+index)*4) (我尝试过使用和不使用 *4)是我理解为将其转换为 ImageData().data 的 rgba 的公式;
我只写最新的一行,将对 ImageData.data 进行切片/连接/切片,这样我每次绘制只写一行。
预期的视觉效果 是二维元胞自动机规则的可视化,一次绘制 1 条线。
实际情况: 奇怪的电路弯曲-y,脉动模式。
draw(){
if(this.height<this.lineNum){ //lineNum is the current y draw line
this.image.data = this.image.data.slice(this.width*4).join(this.image.data.slice(0,this.width*4)); //cut the begining, put it at the end, then write over it so it moves
}
this.nodes.forEach((node,x)=>{
const state = node.lastState();
const index = (((Math.min(this.lineNum,this.height))*x + (node.index))*4);
this.image.data[index+0]=state?255:0;
this.image.data[index+1]=state?255:0;
this.image.data[index+2]=state?255:0;
this.image.data[index+3]=255;
})
this.ctx.putImageData(this.image ,0,0);
}
这是完整的代码,但我确信我的这个公式有错误。
上面的sn-p来自第61行的draw函数。
https://codepen.io/altruios/pen/QWEoYXz?editors=1010
编辑
const index = (((Math.min(node.state.length-1,this.height))*this.width + (node.index))*4);
产生更“稳定”但仍然不正确的东西。
所以我认为这个公式可能是正确的,并且有一些状态更新逻辑没有正确发生。
【问题讨论】:
-
x是您的节点在列表中的索引,我怀疑这是您想要的。您可能希望将当前行索引乘以画布的宽度(可能是this.width?)此外,使用const arr = new Uint32Array( this.image.data.buffer );,您可以将4个分配替换为单个arr[ index ] = state ? 0xFFFFFFFF : 0xFF000000;,其中index不需要* 4乘法。 -
x 和 node.index 是相同的值。我想这就是我想要的,它代表画布的x轴,不是吗?我会尝试在每个并条框分配新的数组。
-
如果你有row_index和column_index,扁平化索引是
(row_index * image_width) + column_index。 -
不,TypedArrays 只是对 ArrayBuffer 的视图。因此,当我们执行
new Uint32Array( this.image.data.buffer )并修改该数组时,ArrayBuffer 会被修改,因此this.image.dataUint8ClampedArray 视图也反映了该更改。 -
嗯...它确实改变了 ImageData 的缓冲区。但是,此 ImageData 不再链接到画布的缓冲区,因此它不会改变画布上绘制的内容。
标签: javascript matrix canvas cellular-automata imagedata