好,所以我需要自己的像素操作功能。 在互联网上找到类似ths之类的东西,做了些改动,我的问题是,为什么这么懒? 我需要一个更大的项目,此功能似乎是个问题。我该怎么做才能改善它? 这是必要的代码:
class kolo {
int x;
int y;
kolo(int _x, int _y) {
x=_x;
y=_y;
}
void rysuj() {
fill(255, 0, 0);
circle(x, y, 60);
}
}
ArrayList tab, punkty;
kolo p1=new kolo(100, 400);
kolo p2=new kolo(230, 400);
kolo p3=new kolo(360, 400);
kolo p4=new kolo(490, 400);
boolean drawing=true;
int N=20;
void setup() {
size(800, 800);
tab = new ArrayList<kolo>(4);
punkty=new ArrayList<PVector>(N);
tab.add(p1);
tab.add(p2);
tab.add(p3);
tab.add(p4);
}
void draw() {
background(0);
p1.rysuj();
p2.rysuj();
p3.rysuj();
p4.rysuj();
stroke(100, 100, 100);
line(p1.x, p1.y, p2.x, p2.y);
line(p2.x, p2.y, p3.x, p3.y);
line(p3.x, p3.y, p4.x, p4.y);
for(int i=0; i<50; i++){
putPixel(200, i+50, 255,255,255);
}
}
int teller() {
if (dist(mouseX, mouseY, p1.x, p1.y) < 60) return 1;
if (dist(mouseX, mouseY, p2.x, p2.y) < 60) return 2;
if (dist(mouseX, mouseY, p3.x, p3.y) < 60) return 3;
if (dist(mouseX, mouseY, p4.x, p4.y) < 60) return 4;
else return 0;
}
void mouseDragged() {
if (teller()==1) {
p1.x=mouseX;
p1.y=mouseY;
redraw();
}
if (teller()==2) {
p2.x=mouseX;
p2.y=mouseY;
redraw();
}
if (teller()==3) {
p3.x=mouseX;
p3.y=mouseY;
redraw();
}
if (teller()==4) {
p4.x=mouseX;
p4.y=mouseY;
redraw();
}
}
void putPixel(int x, int y, int r, int g, int b) {
loadPixels();
drawing=true;
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
int loc = x + y * width;
if (loc<width*height)
//print(loc);
pixels[loc] = color(r, g, b);
loc=0;
}
}
updatePixels();
}
如果您自己尝试一下,您会发现用这些像素绘制的细线落后于整个草图,如果没有平滑的移动这些球。
答案 0 :(得分:3)
在您的情况下,putPixel
函数效率极低。
它会循环遍历并更新草图中的所有所有像素,而每次调用时只需设置一个单个像素即可。它的作用与set()相同,只是缠绕时间更长且效率较低。
使用它的方式也效率低下:
for(int i=0; i<50; i++){
putPixel(200, i+50, 255,255,255);
}
这将绘制一条50像素高的线,与line(200,50,200,100);
完整列表:
class kolo {
int x;
int y;
kolo(int _x, int _y) {
x=_x;
y=_y;
}
void rysuj() {
fill(255, 0, 0);
ellipse(x, y, 60,60);
}
}
ArrayList tab, punkty;
kolo p1=new kolo(100, 400);
kolo p2=new kolo(230, 400);
kolo p3=new kolo(360, 400);
kolo p4=new kolo(490, 400);
boolean drawing=true;
int N=20;
void setup() {
size(800, 800);
tab = new ArrayList<kolo>(4);
punkty=new ArrayList<PVector>(N);
tab.add(p1);
tab.add(p2);
tab.add(p3);
tab.add(p4);
}
void draw() {
background(0);
p1.rysuj();
p2.rysuj();
p3.rysuj();
p4.rysuj();
stroke(100, 100, 100);
line(p1.x, p1.y, p2.x, p2.y);
line(p2.x, p2.y, p3.x, p3.y);
line(p3.x, p3.y, p4.x, p4.y);
line(200,50,200,100);
//for(int i=0; i<50; i++){
// putPixel(200, i+50, 255,255,255);
//}
surface.setTitle((int)frameRate + "fps");
}
int teller() {
if (dist(mouseX, mouseY, p1.x, p1.y) < 60) return 1;
if (dist(mouseX, mouseY, p2.x, p2.y) < 60) return 2;
if (dist(mouseX, mouseY, p3.x, p3.y) < 60) return 3;
if (dist(mouseX, mouseY, p4.x, p4.y) < 60) return 4;
else return 0;
}
void mouseDragged() {
if (teller()==1) {
p1.x=mouseX;
p1.y=mouseY;
redraw();
}
if (teller()==2) {
p2.x=mouseX;
p2.y=mouseY;
redraw();
}
if (teller()==3) {
p3.x=mouseX;
p3.y=mouseY;
redraw();
}
if (teller()==4) {
p4.x=mouseX;
p4.y=mouseY;
redraw();
}
}
void putPixel(int x, int y, int r, int g, int b) {
loadPixels();
drawing=true;
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
int loc = x + y * width;
if (loc<width*height)
//print(loc);
pixels[loc] = color(r, g, b);
loc=0;
}
}
updatePixels();
}
当前,您的代码主要使用绘图功能(例如line()
,ellipse()
等),而不是大量的像素操作。
如果您确实想操纵像素,则可以。
重要的是要知道set()
设置了一个像素,但更新了整个图像。
处理像素的更有效方法是访问pixels\[\]
,分批处理许多像素,最后使用updatePixels()
更新整个图像一次
您需要将pixels[]
的x,y位置(2D数组索引)转换为单个1D索引。您的代码已经包含以下内容:x + y * width
set()
示例:
import java.util.Arrays;
PImage canvas;
void setup(){
size(300,300);
canvas = createImage(width,height,RGB);
}
void draw(){
manipulatePixels();
// render pixels
image(canvas,0,0);
}
void manipulatePixels(){
//clear frame
Arrays.fill(canvas.pixels,0);
//draw something
float scalar = sin(frameCount * 0.1);
slowCircle(canvas,mouseX,mouseY,(int)map(scalar,-1.0,1.0,10,30),color(map(scalar,-1.0,1.0,64,255)));
}
void slowCircle(PImage canvas,int x,int y,int radius,color fill){
for(int py = y - radius; py < y + radius; py++){
for(int px = x - radius; px < x + radius; px++){
if(dist(x,y,px,py) < radius){
canvas.set(px,py,fill);
}
}
}
}
pixels[]
示例:
import java.util.Arrays;
PImage canvas;
void setup(){
size(300,300);
canvas = createImage(width,height,RGB);
}
void draw(){
manipulatePixels();
// render pixels
image(canvas,0,0);
}
void manipulatePixels(){
//clear frame
Arrays.fill(canvas.pixels,0);
//draw something
float scalar = sin(frameCount * 0.1);
//slowEllipse(canvas,mouseX,mouseY,(int)map(scalar,-1.0,1.0,10,30),color(map(scalar,-1.0,1.0,64,255)));
fastCircle(canvas,mouseX,mouseY,(int)map(scalar,-1.0,1.0,10,30),color(map(scalar,-1.0,1.0,64,255)));
// update all Pixels in one go
canvas.updatePixels();
}
void slowCircle(PImage canvas,int x,int y,int radius,color fill){
for(int py = y - radius; py < y + radius; py++){
for(int px = x - radius; px < x + radius; px++){
if(dist(x,y,px,py) < radius){
canvas.set(px,py,fill);
}
}
}
}
void fastCircle(PImage canvas,int x,int y,int radius,color fill){
int radiusSquared = radius * radius;
int halfRadius = radius / 2;
int halfRadiusSquared = halfRadius * halfRadius;
int numPixels = canvas.pixels.length;
//for each pixel in the ellipse bounding box
for(int i = 0 ; i < radiusSquared; i++){
int cx = (x - halfRadius) + (i % radius);
int cy = (y - halfRadius) + (i / radius);
// calculate the index within the full image
int pixelIndex = (cx + cy * canvas.width);
// constrain pixel index to array size bounds
if(pixelIndex < 0) pixelIndex = 0;
if(pixelIndex >= numPixels) pixelIndex = numPixels-1;
// calculate the difference between circle centre and current pixel coordinates
int dx = cx-x;
int dy = cy-y;
// calculate distance squared
int distanceSquared = (dx*dx) + (dy*dy);
// compare if the pixel is inside the circle using squared distance (a bit faster since it avoids sqrt())
if(distanceSquared < halfRadiusSquared){
//fill circle pixels
canvas.pixels[pixelIndex] = fill;
}
}
}
值得注意的是,您可以使用PGraphics轻松地将形状光栅化为像素。
您可以看到一个有趣的PGraphics
示例here
下一步要去哪里?如果您喜欢玩pixels[]
,并且想创建一个效果很棒的效果,而该效果可能会在CPU上运行缓慢,那么您可以考虑移到GPU上,Processing通过PShader支持它:您需要的片段着色器部分。您可以看到将基于pixels[]
的CPU代码移植到GPU片段着色器here