高分辨率处理输出 [英] High-Resolution Processing Output

查看:91
本文介绍了高分辨率处理输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻求有关编程语言/环境处理的帮助.

我对Processing非常陌生,我正在openprocessing.org上尝试某人的一段代码.我非常喜欢这段代码提供的视觉效果,并且我想进一步使用它.不幸的是,输出分辨率很低.因此,我正在寻找可以帮助我解决以下问题的人员:a)增加生成的形状的大小或分辨率,以及b)将所有内容另存为pdf文件.

您可以在此处找到运行中的原始代码: https://www.openprocessing.org/sketch/377730

这是代码:

import java.util.Arrays;
float[][] z, v, a;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  size(512, 512);
  colorMode(RGB, 2);
  z = new float[width][height];
  v = new float[width][height];
  a = new float[width][height];
  loadPixels();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void draw() {
  for (int x = 1; x < width-1; x++) {
    for (int y = 1; y < height-1; y++) {
      a[x][y] = (v[x-1][y] + v[x+1][y] + v[x][y-1] + v[x][y+1])/4 - v[x][y];
    }
  }
  for (int x = 1; x < width-1; x++) {
    for (int y = 1; y < height-1; y++) {
      v[x][y] += a[x][y];
      z[x][y] += v[x][y];
      pixels[width*y+x] = color(sin(z[x][y]) + 1, cos(z[x][y]), 1);
    }
  }
  updatePixels();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void move() {
  if (mouseX > -1    &&    mouseX < width    &&    mouseY > -1    &&    mouseY < height) {
    v[mouseX][mouseY] = randomGaussian() * TAU;
  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void mouseClicked() { move(); }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void mouseDragged() { move(); }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void keyPressed() {
  noLoop();
  for (int x = 0; x < width; x++)    Arrays.fill(z[x], 0);
  for (int x = 0; x < width; x++)    Arrays.fill(v[x], 0);
  loop();
}

到目前为止,我已经尝试过将一种高分辨率的方法发布到Processing-Forum上,但是这种方法对我来说并不奏效,至少在我正在使用的上述代码的上下文中没有.这是论坛中的代码,演示了一个用户以高分辨率保存处理"输出的输出的方式:

int dim = 5000;
int dimScreen = dim/10;
color c1 = #AFA786;
color c2 = #000000;

void setup() { size(dimScreen,dimScreen); }
void draw()  { exampleSketch(); }

void exampleSketch() {
  for (int y=0; y<=height; y++) {
    stroke(lerpColor(c1,c2,float(y)/height));
    line(0,y,width,y);
  }
  stroke(#FFFFFF);
  fill(#BBBBBB);
  ellipse(width/2, height/2, width/2, height/2);
  line(0, 0, width, height);
}

void keyPressed() {
  if (key ==' ') {
    g = createGraphics(dim,dim,JAVA2D);
    this.height = dim;
    this.width = dim;
    g.beginDraw();
    exampleSketch();
    g.endDraw();
    save("result.png");
    println("screenshot saved");
    this.height = dimScreen;
    this.width = dimScreen;
  }
}

我将非常感谢任何精通Processing和Java来帮助我的人.非常感谢,祝您有个美好的夜晚.

这是我尝试将第二个代码实现到第一个代码中的尝试:

import processing.pdf.*;
import java.util.Arrays;
float[][] z, v, a;

int dim = 900;
int dimScreen = dim/10;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  size(900, 900);
  smooth(8);
  colorMode(RGB, 2);
  z = new float[width][height];
  v = new float[width][height];
  a = new float[width][height];
  loadPixels();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void draw()  { exampleSketch(); }


void exampleSketch() {

  for (int x = 1; x < width-1; x++) {
    for (int y = 1; y < height-1; y++) {
      a[x][y] = (v[x-1][y] + v[x+1][y] + v[x][y-1] + v[x][y+1])/4 - v[x][y];
    }
  }
  for (int x = 1; x < width-1; x++) {
    for (int y = 1; y < height-1; y++) {
      v[x][y] += a[x][y];
      z[x][y] += v[x][y];
      pixels[width*y+x] = color(sin(z[x][y]) + 1, cos(z[x][y]), 1);
    }
  }
  updatePixels();


}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void move() {
  if (mouseX > -1    &&    mouseX < width    &&    mouseY > -1    &&    mouseY < height) {
    v[mouseX][mouseY] = randomGaussian() * TAU;

  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void mouseClicked() { move(); }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void mouseDragged() { move(); }


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void keyPressed() {
  if (key ==' ') {
    g = createGraphics(dim,dim,JAVA2D);
    this.height = dim;
    this.width = dim;
    g.beginDraw();
    exampleSketch();
    g.endDraw();
    save("result2.png");
    println("screenshot saved");
    this.height = 900;
    this.width = 900;
  }
}

两个屏幕快照,比较了实施白色背景的乔治解决方案前后的视觉效果:

解决方案

除了Kevin的回答,您还可以使用 JVisualVM 查看大部分CPU时间都花在了哪里.在不同时间对CPU进行采样和配置后,令人惊讶的是,大多数时间大部分时间是在计算RGB值:

最好从优化时占用大部分CPU的功能开始.

这是草绘的一个版本,使用默认的0-255 RGB范围并计算内联的RGB值(将A,R,G,B字节放在一起):

import processing.pdf.*;
import java.util.Arrays;
float[][] z, v, a;

int dim = 900;
int dimScreen = dim/10;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  size(900, 900);
  smooth(8);
  //colorMode(RGB, 2);
  z = new float[width][height];
  v = new float[width][height];
  a = new float[width][height];
  loadPixels();

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void draw()  { exampleSketch(); }


void exampleSketch() {

  int r,g,b = 255;
  for (int x = 1; x < width-1; x++) {
    for (int y = 1; y < height-1; y++) {
      a[x][y] = (v[x-1][y] + v[x+1][y] + v[x][y-1] + v[x][y+1]) * .25 - v[x][y];
    //}
  //}
//  //for (int x = 1; x < width-1; x++) {
    //for (int y = 1; y < height-1; y++) {
      v[x][y] += a[x][y];
      z[x][y] += v[x][y];
      r = ((int)((sin(z[x][y]) + 1) * 128) << 16);
      g = ((int)((cos(z[x][y]) * 128)) << 8);
      pixels[width*y+x] = 0xff000000 | r | g | b;
    }
  }
  updatePixels();
  fill(0);
  text((int)frameRate+"fps",15,15);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void move() {
  if (mouseX > -1    &&    mouseX < width    &&    mouseY > -1    &&    mouseY < height) {
    v[mouseX][mouseY] = randomGaussian() * TAU;

  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void mouseClicked() { move(); }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void mouseDragged() { move(); }


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int screenshotCount=1;
void keyPressed() {
  if (key ==' ') {
    save("result"+nf(screenshotCount,4)+".png");
    println("screenshot saved");
  }
}

//http://stackoverflow.com/questions/40350644/high-resolution-processing-output

更新: 这是一个经过修改的函数,可以映射这些值以使背景为白色:

void exampleSketch() {
  float rv,gv;
  int r,g,b = 255;
  for (int x = 1; x < width-1; x++) {
    for (int y = 1; y < height-1; y++) {
      //compute accumulated value of neighbour cells(left+right+top+bottom), average (/4 or * .25) then subtract the current cell from v
      a[x][y] = (v[x-1][y] + v[x+1][y] + v[x][y-1] + v[x][y+1]) * .25 - v[x][y];
      //increment current v cell by the current accumulated cell
      v[x][y] += a[x][y];
      //increment current z (final/result) cell by the updated v cell
      z[x][y] += v[x][y];
      //in short z[x][y] += v[x][y] + ((v[-1][0] + v[+1][0] + v[0][-1] + v[0][+1]) / 4 - v[x][y])
      //scale sin(z) and cos(z) results to 0-255: sin/cos returns -1.0 to 1.0 then 1.0 is added -> 0.0 to 2.0 , then 128 is multiplied = 0-255
      rv = (sin(z[x][y]) + 1.0) * 128;
      gv = (cos(z[x][y]) + 1.0) * 128;
      //contrain to 0-255
      if(rv < 0)   rv = 0;
      if(rv > 255) rv = 255;
      if(gv < 0)   gv = 0;
      if(gv > 255) gv = 255;
      //cast to int and shift
      r = ((int)(rv) << 16);
      g = ((int)(gv) << 8);
      //alpha (0xff000000) cobined with r , g, b 
      int argb = 0xff000000 | r | g | b;
      pixels[width*y+x] = argb;
    }
  }
  updatePixels();
  fill(0);
  text((int)frameRate+"fps",15,15);
}

这里我可以保存:

更新2 : 这是一个计算透明度值而不是白色的版本:

import processing.pdf.*;
import java.util.Arrays;
float[][] z, v, a;

int dim = 900;
int dimScreen = dim/10;

PImage canvas;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  size(900, 900);
  smooth(8);
  //colorMode(RGB, 2);
  z = new float[width][height];
  v = new float[width][height];
  a = new float[width][height];
  loadPixels();


  canvas = createImage(width,height,ARGB);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void draw()  { exampleSketch(); }


void exampleSketch() {
  float rs,gc,rv,gv;
  int r,g,b = 255;
  for (int x = 1; x < width-1; x++) {
    for (int y = 1; y < height-1; y++) {
      //compute accumulated value of neighbour cells(left+right+top+bottom), average (/4 or * .25) then subtract the current cell from v
      a[x][y] = (v[x-1][y] + v[x+1][y] + v[x][y-1] + v[x][y+1]) * .25 - v[x][y];
      //increment current v cell by the current accumulated cell
      v[x][y] += a[x][y];
      //increment current z (final/result) cell by the updated v cell
      z[x][y] += v[x][y];
      //in short z[x][y] += v[x][y] + ((v[-1][0] + v[+1][0] + v[0][-1] + v[0][+1]) / 4 - v[x][y])
      //scale sin(z) and cos(z) results to 0-255
      rs = sin(z[x][y]) + 1.0;
      gc = cos(z[x][y]) + 1.0;
      rv = rs * 128;
      gv = gc * 128;
      //contrain to 0-255
      if(rv < 0)   rv = 0;
      if(rv > 255) rv = 255;
      if(gv < 0)   gv = 0;
      if(gv > 255) gv = 255;
      //cast to int and shift
      r = ((int)(rv) << 16);
      g = ((int)(gv) << 8);
      //average sin/cos results = use the sin/cos results used for red/green channels, scale them by half (128) brightness and add them up
      //then subtract that from the max (255) to invert the alpha(transparency) value
      int alpha = 255-(int)((rs * 128) + (gc * 128));
      int argb = alpha << 24 | r | g | b;
      canvas.pixels[width*y+x] = argb;
    }
  }
  canvas.updatePixels();
  image(canvas,0,0);
  fill(0);
  text((int)frameRate+"fps",15,15);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void move() {
  if (mouseX > -1    &&    mouseX < width    &&    mouseY > -1    &&    mouseY < height) {
    v[mouseX][mouseY] = randomGaussian() * TAU;

  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void mouseClicked() { move(); }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void mouseDragged() { move(); }


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int screenshotCount=1;
void keyPressed() {
  if (key ==' ') {
    canvas.save("result"+nf(screenshotCount,4)+".png");
    println("screenshot saved");
  }
}

不幸的是,我没有时间详细介绍和提供快速的解决方案,但是我可以提供一些可能会有所帮助的指针:

这看起来像是简化的 BZ或Gray Scott反应扩散模拟:

查看 Daniel Shiffman的视频教程:它将帮助您理解更好的算法并编写更有效的实现.

我想到了另外两种加快速度的硬性方法:

  1. 在GPU上并行执行任务,将算法重写为处理GLSL着色器(PShader) -另外,如果您不介意实现略有不同,可以更容易地调整 Shadertoy反应扩散片段着色器作为PShaders运行(例如这一个)
  2. 在CPU上并行执行任务(请参见 Java多处理 资源-某种干燥材料)

I'm looking for help with the programming language/environment Processing.

I'm fairly new to Processing and I am experimenting with a piece of code from someone over at openprocessing.org. I really like the visual results this code delivers and I would like to further work with it. Unfortunately, the output is very low resolution. Hence I'm looking for someone who might be able to help me figure out how to a) Increase the size or resolution of the shapes generated and b) save everything as a pdf file.

You can find the original code in action here: https://www.openprocessing.org/sketch/377730

This is the code:

import java.util.Arrays;
float[][] z, v, a;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  size(512, 512);
  colorMode(RGB, 2);
  z = new float[width][height];
  v = new float[width][height];
  a = new float[width][height];
  loadPixels();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void draw() {
  for (int x = 1; x < width-1; x++) {
    for (int y = 1; y < height-1; y++) {
      a[x][y] = (v[x-1][y] + v[x+1][y] + v[x][y-1] + v[x][y+1])/4 - v[x][y];
    }
  }
  for (int x = 1; x < width-1; x++) {
    for (int y = 1; y < height-1; y++) {
      v[x][y] += a[x][y];
      z[x][y] += v[x][y];
      pixels[width*y+x] = color(sin(z[x][y]) + 1, cos(z[x][y]), 1);
    }
  }
  updatePixels();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void move() {
  if (mouseX > -1    &&    mouseX < width    &&    mouseY > -1    &&    mouseY < height) {
    v[mouseX][mouseY] = randomGaussian() * TAU;
  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void mouseClicked() { move(); }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void mouseDragged() { move(); }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void keyPressed() {
  noLoop();
  for (int x = 0; x < width; x++)    Arrays.fill(z[x], 0);
  for (int x = 0; x < width; x++)    Arrays.fill(v[x], 0);
  loop();
}

So far I have experimented with a supposed high-resolution method posted to the Processing-Forum, which hasn't worked for me though, at least not in the context of the code above I'm working with. Here's the piece of code from the forum which demonstrates one user's way of saving the output of a Processing output in a high resolution:

int dim = 5000;
int dimScreen = dim/10;
color c1 = #AFA786;
color c2 = #000000;

void setup() { size(dimScreen,dimScreen); }
void draw()  { exampleSketch(); }

void exampleSketch() {
  for (int y=0; y<=height; y++) {
    stroke(lerpColor(c1,c2,float(y)/height));
    line(0,y,width,y);
  }
  stroke(#FFFFFF);
  fill(#BBBBBB);
  ellipse(width/2, height/2, width/2, height/2);
  line(0, 0, width, height);
}

void keyPressed() {
  if (key ==' ') {
    g = createGraphics(dim,dim,JAVA2D);
    this.height = dim;
    this.width = dim;
    g.beginDraw();
    exampleSketch();
    g.endDraw();
    save("result.png");
    println("screenshot saved");
    this.height = dimScreen;
    this.width = dimScreen;
  }
}

I'd be hugely grateful to anyone who's proficient enough with Processing and Java to help me out. Thanks so much and have a good night.

Here is my attempt of implementing the second code into the first one:

import processing.pdf.*;
import java.util.Arrays;
float[][] z, v, a;

int dim = 900;
int dimScreen = dim/10;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  size(900, 900);
  smooth(8);
  colorMode(RGB, 2);
  z = new float[width][height];
  v = new float[width][height];
  a = new float[width][height];
  loadPixels();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void draw()  { exampleSketch(); }


void exampleSketch() {

  for (int x = 1; x < width-1; x++) {
    for (int y = 1; y < height-1; y++) {
      a[x][y] = (v[x-1][y] + v[x+1][y] + v[x][y-1] + v[x][y+1])/4 - v[x][y];
    }
  }
  for (int x = 1; x < width-1; x++) {
    for (int y = 1; y < height-1; y++) {
      v[x][y] += a[x][y];
      z[x][y] += v[x][y];
      pixels[width*y+x] = color(sin(z[x][y]) + 1, cos(z[x][y]), 1);
    }
  }
  updatePixels();


}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void move() {
  if (mouseX > -1    &&    mouseX < width    &&    mouseY > -1    &&    mouseY < height) {
    v[mouseX][mouseY] = randomGaussian() * TAU;

  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void mouseClicked() { move(); }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void mouseDragged() { move(); }


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void keyPressed() {
  if (key ==' ') {
    g = createGraphics(dim,dim,JAVA2D);
    this.height = dim;
    this.width = dim;
    g.beginDraw();
    exampleSketch();
    g.endDraw();
    save("result2.png");
    println("screenshot saved");
    this.height = 900;
    this.width = 900;
  }
}

Edit: Two screenshots comparing the different visual results before and after implementing George's solution for a white background:

解决方案

In addition to Kevin's answer, you can use JVisualVM to see where most of the CPU time is spent on. After sampling and profiling the CPU at different times surprisingly most of the time was computing the RGB values:

It's best to start with the functions taking most of the CPU when optimizing.

Here is a version of the sketch that uses the default 0-255 RGB range and computes the RGB value inlined (putting the A,R,G,B bytes together):

import processing.pdf.*;
import java.util.Arrays;
float[][] z, v, a;

int dim = 900;
int dimScreen = dim/10;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  size(900, 900);
  smooth(8);
  //colorMode(RGB, 2);
  z = new float[width][height];
  v = new float[width][height];
  a = new float[width][height];
  loadPixels();

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void draw()  { exampleSketch(); }


void exampleSketch() {

  int r,g,b = 255;
  for (int x = 1; x < width-1; x++) {
    for (int y = 1; y < height-1; y++) {
      a[x][y] = (v[x-1][y] + v[x+1][y] + v[x][y-1] + v[x][y+1]) * .25 - v[x][y];
    //}
  //}
//  //for (int x = 1; x < width-1; x++) {
    //for (int y = 1; y < height-1; y++) {
      v[x][y] += a[x][y];
      z[x][y] += v[x][y];
      r = ((int)((sin(z[x][y]) + 1) * 128) << 16);
      g = ((int)((cos(z[x][y]) * 128)) << 8);
      pixels[width*y+x] = 0xff000000 | r | g | b;
    }
  }
  updatePixels();
  fill(0);
  text((int)frameRate+"fps",15,15);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void move() {
  if (mouseX > -1    &&    mouseX < width    &&    mouseY > -1    &&    mouseY < height) {
    v[mouseX][mouseY] = randomGaussian() * TAU;

  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void mouseClicked() { move(); }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void mouseDragged() { move(); }


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int screenshotCount=1;
void keyPressed() {
  if (key ==' ') {
    save("result"+nf(screenshotCount,4)+".png");
    println("screenshot saved");
  }
}

//http://stackoverflow.com/questions/40350644/high-resolution-processing-output

Update: Here's an a modified function that maps the values so the background is white:

void exampleSketch() {
  float rv,gv;
  int r,g,b = 255;
  for (int x = 1; x < width-1; x++) {
    for (int y = 1; y < height-1; y++) {
      //compute accumulated value of neighbour cells(left+right+top+bottom), average (/4 or * .25) then subtract the current cell from v
      a[x][y] = (v[x-1][y] + v[x+1][y] + v[x][y-1] + v[x][y+1]) * .25 - v[x][y];
      //increment current v cell by the current accumulated cell
      v[x][y] += a[x][y];
      //increment current z (final/result) cell by the updated v cell
      z[x][y] += v[x][y];
      //in short z[x][y] += v[x][y] + ((v[-1][0] + v[+1][0] + v[0][-1] + v[0][+1]) / 4 - v[x][y])
      //scale sin(z) and cos(z) results to 0-255: sin/cos returns -1.0 to 1.0 then 1.0 is added -> 0.0 to 2.0 , then 128 is multiplied = 0-255
      rv = (sin(z[x][y]) + 1.0) * 128;
      gv = (cos(z[x][y]) + 1.0) * 128;
      //contrain to 0-255
      if(rv < 0)   rv = 0;
      if(rv > 255) rv = 255;
      if(gv < 0)   gv = 0;
      if(gv > 255) gv = 255;
      //cast to int and shift
      r = ((int)(rv) << 16);
      g = ((int)(gv) << 8);
      //alpha (0xff000000) cobined with r , g, b 
      int argb = 0xff000000 | r | g | b;
      pixels[width*y+x] = argb;
    }
  }
  updatePixels();
  fill(0);
  text((int)frameRate+"fps",15,15);
}

Heres what I could save:

Update 2: Here is a version that computes a transparency value instead of white:

import processing.pdf.*;
import java.util.Arrays;
float[][] z, v, a;

int dim = 900;
int dimScreen = dim/10;

PImage canvas;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  size(900, 900);
  smooth(8);
  //colorMode(RGB, 2);
  z = new float[width][height];
  v = new float[width][height];
  a = new float[width][height];
  loadPixels();


  canvas = createImage(width,height,ARGB);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void draw()  { exampleSketch(); }


void exampleSketch() {
  float rs,gc,rv,gv;
  int r,g,b = 255;
  for (int x = 1; x < width-1; x++) {
    for (int y = 1; y < height-1; y++) {
      //compute accumulated value of neighbour cells(left+right+top+bottom), average (/4 or * .25) then subtract the current cell from v
      a[x][y] = (v[x-1][y] + v[x+1][y] + v[x][y-1] + v[x][y+1]) * .25 - v[x][y];
      //increment current v cell by the current accumulated cell
      v[x][y] += a[x][y];
      //increment current z (final/result) cell by the updated v cell
      z[x][y] += v[x][y];
      //in short z[x][y] += v[x][y] + ((v[-1][0] + v[+1][0] + v[0][-1] + v[0][+1]) / 4 - v[x][y])
      //scale sin(z) and cos(z) results to 0-255
      rs = sin(z[x][y]) + 1.0;
      gc = cos(z[x][y]) + 1.0;
      rv = rs * 128;
      gv = gc * 128;
      //contrain to 0-255
      if(rv < 0)   rv = 0;
      if(rv > 255) rv = 255;
      if(gv < 0)   gv = 0;
      if(gv > 255) gv = 255;
      //cast to int and shift
      r = ((int)(rv) << 16);
      g = ((int)(gv) << 8);
      //average sin/cos results = use the sin/cos results used for red/green channels, scale them by half (128) brightness and add them up
      //then subtract that from the max (255) to invert the alpha(transparency) value
      int alpha = 255-(int)((rs * 128) + (gc * 128));
      int argb = alpha << 24 | r | g | b;
      canvas.pixels[width*y+x] = argb;
    }
  }
  canvas.updatePixels();
  image(canvas,0,0);
  fill(0);
  text((int)frameRate+"fps",15,15);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void move() {
  if (mouseX > -1    &&    mouseX < width    &&    mouseY > -1    &&    mouseY < height) {
    v[mouseX][mouseY] = randomGaussian() * TAU;

  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void mouseClicked() { move(); }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void mouseDragged() { move(); }


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int screenshotCount=1;
void keyPressed() {
  if (key ==' ') {
    canvas.save("result"+nf(screenshotCount,4)+".png");
    println("screenshot saved");
  }
}

Unfortunately I don't have the time to get into more detail and provide a fast working solution, but I can provide some pointers that may help:

This looks like a simplified BZ or Grey Scott reaction diffusion simulation:

Check out Daniel Shiffman's video tutorial on it: it will help you understand the algorithm better and write a more efficient implementation.

There are a couple more hardcore methods of speeding this up that come to mind:

  1. Parallelize the task on the GPU, rewriting the algorithm as a Processing GLSL shader (PShader) - additionally, if you don't mind slightly different implementation, it might be easier to tweak Shadertoy reaction diffusion fragment shaders to run as PShaders (e.g. this one or this one)
  2. Parallelize the task on the CPU (see Java Multiprocessing resources - sorta dry material)

这篇关于高分辨率处理输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆