はじめに
Processingで1ピクセル描画するのにstrokeとpointを使う際の、色の問題について解決方法をいくつか紹介します。
環境
Processing 4
MacOSX
Win11
問題点 「色が想定と違う」
以下のように、点を描画すると、想定した白色にならない。
255になって欲しいが、181になる。なぜ?
background(0);
stroke(255);
point(50,50);
print(red(get(50,50)));
181.0
解決方法1「noSmoothを使う」
ベタ塗りのみ有効。
半透明(RGBA)を使う場合はおかしくなる。
background(0);
noSmooth();
stroke(255);
point(50,50);
解決方法2「点描画モードを変更する」
https://processing.org/reference/point_.html
strokeCap(PROJECT)で、円ではなく、正方形になる。
background(0);
strokeCap(PROJECT);
stroke(255);
point(50,50);
解決方法3「set()を使う」
background(0);
set(50,50,#FFFFFFFF);
もしくは
background(0);
set(50,50,color(255));
解決方法4「square()を使う」
background(0);
fill(255);
noStroke();
square(50, 50, 1);
解決方法5「pixels[]」を使う
読みにいが最速。
background(0);
loadPixels();
pixels[50+50*width] = color(255);
updatePixels();
描画速度を比較する
No1
size(1920, 1080);
background(0);
noSmooth();
int t = millis();
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
stroke(x, y, 255);
point(x, y);
}
}
print(millis()-t);
No5
size(1920, 1080);
background(0);
int t = millis();
loadPixels();
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
pixels[x+y*width] = color(x,y,255);
}
}
updatePixels();
print(millis()-t);
方法 | 時間 |
---|---|
noSmooth | 690ms |
strokeCap | 300ms |
set | 40ms |
square | 420ms |
pixels[] | 30ms |
考察
太さ100の点を描画する。
strokeWeight(100);
background(0);
stroke(255);
point(50,50);
100 * 100の黒背景に、半径50の円が描かれる。
面積を考えて、
50 * 50 * PI : 100 * 100
= PI : 4
= 64 * PI : 256
= 201 : 256
ここで、181が登場すると嬉しいのだが、201となった。
さらに、以下のような点の太さを変更しながら、描画色を確認するプログラムを実行する。
for (float f=0.9; f<1.4; f+=0.025) {
strokeWeight(f);
background(0);
stroke(255);
point(50, 50);
println(f,red(get(50, 50)));
}
0.9 146.0
0.92499995 155.0
0.9499999 163.0
0.9749999 172.0
0.9999999 181.0
1.0249999 189.0
1.0499998 198.0
1.0749998 205.0
1.0999998 212.0
1.1249998 219.0
1.1499997 226.0
1.1749997 232.0
1.1999997 237.0
1.2249997 243.0
1.2499996 247.0
1.2749996 249.0
1.2999996 251.0
1.3249996 252.0
1.3499995 254.0
1.3749995 255.0
1.3999995 255.0
ここでは、1.375以上であれば、白色になることがわかるが、頭の中の想定では√2=1.414であってほしかった。
試しに以下のように半ピクセルずらしてみたけど、何も変わらなかった。
background(0);
stroke(255);
point(50.5,50.5);
print(red(get(50,50)));