Processing 处理:高效地绘制渐变

Processing 处理:高效地绘制渐变,processing,Processing,我是新手,我一直在研究模拟电子运动。 在我尝试为每个粒子添加渐变色之前,一切都似乎很好。帧速率大幅下降 以下是我到目前为止所做的尝试: float a=0; float s; void setup() { size(500,500); smooth(); frameRate(500); colorMode(HSB,360,100,100); noStroke(); ellipseMode(RADIUS); } void draw() { background(200

我是新手,我一直在研究模拟电子运动。 在我尝试为每个粒子添加渐变色之前,一切都似乎很好。帧速率大幅下降

以下是我到目前为止所做的尝试:

float a=0;
float s;
void setup()
{
  size(500,500);
  smooth();
  frameRate(500);
  colorMode(HSB,360,100,100);
  noStroke();
  ellipseMode(RADIUS);
}

void draw()
{
  background(200,0,100);
  pushMatrix();
  translate(width/2, height/2);
  rotate(radians(-18));
  for ( int r = width ; r >= 0; r = r - 1 )
  {
    s = 500*exp(-r);
    fill(202, s, 100);
    ellipse(100*cos(a), 50*sin(a), r, r);

  }
  a+=0.1;
  popMatrix();
}

你的问题不是关于模拟电子运动,而是关于在处理过程中有效地绘制梯度。我看到您已经从示例>基础>颜色>径向梯度示例开始。请注意,示例本身运行速度非常慢,可能是因为重点关注如何使用颜色(HSB)和绘图功能,而较少关注性能

你能做的就是使用or缓存渐变,你更喜欢使用or

下面是一个使用PGraphics的示例,如果您不习惯使用像素,这可能会更简单:

PImage e;
void setup(){
  size(500,500);
  e = getElectronImg(30,30,0,100,100);//create a cached drawing
}
void draw(){
  background(255);
  translate(width * .5, height * .5);
  float a = frameCount * .1;
  image(e,100*cos(a), 50*sin(a));
}

PImage getElectronImg(int w,int h,int hue,int satMax,int brightness){
  PGraphics electron = createGraphics(w+1,h+1);//create a PGraphics object
  electron.beginDraw();//init drawing using the same Processing drawing functions
    electron.colorMode(HSB,360,100,100);
    electron.background(0,0);//transparent bg
    electron.noStroke();
    int cx = electron.width/2;
    int cy = electron.height/2;
    for (int r = w; r > 0; --r) {
      electron.fill(hue,map(r,0,w,satMax,0),brightness);
      electron.ellipse(cx, cy, r, r);
    }
  electron.endDraw();
  return electron;
}
还值得注意的是,PGraphics扩展了PImage,因此可以使用函数like和其他PImage显示

下面是使用像素实现的相同缓存概念:

PImage e;
void setup(){
  size(500,500);
  e = getElectronImg(30,30,0,100,100);
}
void draw(){
  background(255);
  translate(width * .5, height * .5);
  float a = frameCount * .1;
  image(e,100*cos(a), 50*sin(a));
}

PImage getElectronImg(int w,int h,int hue,int satMax,int brightness){
  pushStyle();//isolate drawing styles such as color Mode
    colorMode(HSB,360,100,100);
    PImage electron = createImage(w,h,ARGB);//create an image with an alpha channel
    int np = w * h;//total number of pixels
    int cx = electron.width/2;//center on x
    int cy = electron.height/2;//center on y
    for(int i = 0 ; i < np; i++){//for each pixel
      int x = i%electron.width;//compute x from pixel index
      int y = (int)(i/electron.width);//compute y from pixel index
      float d = dist(x,y,cx,cy);//compute distance from centre to current pixel
      electron.pixels[i] = color(hue,map(d,0,cx,satMax,0),brightness,map(d,0,cx,255,0));//map the saturation and transparency based on the distance to centre
    } 
    electron.updatePixels();//finally update all the pixels
  popStyle();
  return electron;
}
PImage e;
无效设置(){
尺寸(500500);
e=getElectronImg(30,30,0100);
}
作废提款(){
背景(255);
平移(宽度*.5,高度*.5);
浮点a=帧数*.1;
图像(e,100*cos(a),50*sin(a));
}
PImage GetElectroning(整数w、整数h、整数色调、整数satMax、整数亮度){
pushStyle();//隔离图形样式,例如颜色模式
彩色模式(HSB,360100100);
PImage electron=createImage(w,h,ARGB);//使用alpha通道创建图像
int np=w*h;//像素总数
int cx=electron.width/2;//以x为中心
int cy=electron.height/2;//以y为中心
对于(int i=0;i
当然,这将使使用更多的电子变得容易。 与真实电子运动无关,这里有一些有趣的测试,通过对draw()进行一些小调整:

void draw(){
背景(255);
平移(宽度*.5,高度*.5);
对于(int i=0;i<200;i++){
浮点a=(帧数*.025+(i*.1));
图像(e,(100+i)*cos(a+i),(50+i)*sin(a+i));
}
}

void draw(){
背景(255);
平移(宽度*.5,高度*.5);
对于(int i=0;i<1000;i++){
浮点a=(帧数*.025+(i*.1));
图像(e,(100+(i*.25))*cos(a+i),(50+(i*.25))*sin(a+i));
}
}

void draw(){
背景(255);
平移(宽度*.5,高度*.5);
比例(.25);
对于(int i=0;i<5000;i++){
浮点a=(帧数*.025+(i*.1));
图像(e,sin(a)*(100+(i*.5))*cos(a+i),(50+(i*.25))*sin(a+i));
}
}

玩得开心

现在您可以在这里实际运行代码(使用键1、2、3、4更改演示):

var e,demo=2;
函数设置(){
createCanvas(500500);
e=getGradientImg(30,30,0100);
}
函数绘图(){
背景(255);
平移(宽度*.5,高度*.5);
如果(演示==1){
var a=帧数*.1;
图像(e,100*cos(a),50*sin(a));
}
如果(演示==2){
对于(变量i=0;i<200;i++){
变量a=(帧数*.025+(i*.1));
图像(e,(100+i)*cos(a+i),(50+i)*sin(a+i));
}
}
如果(演示==3){
对于(变量i=0;i<1000;i++){
变量a=(帧数*.025+(i*.1));
图像(e,(100+(i*.25))*cos(a+i),(50+(i*.25))*sin(a+i));
}
}
如果(演示==4){
比例(.2);
对于(变量i=0;i<5000;i++){
变量a=(帧数*.025+(i*.1));
图像(e,sin(a)*(100+(i*.5))*cos(a+i),(50+(i*.25))*sin(a+i));
}
}
}
函数keyReleased(){
如果(键=='1')演示=1;
如果(键=='2')演示=2;
如果(键=='3')演示=3;
如果(键=='4')演示=4;
}
函数getGradientImg(w、h、色调、satMax、亮度){
push();//隔离图形样式,如颜色模式
彩色模式(HSB,360100100);
var gradient=createImage(w,h);//使用alpha通道创建图像
var np=w*h;//像素总数
var np4=np*4;
var cx=地板(渐变宽度*0.5);//在x上居中
var cy=地板(渐变高度*0.5);//在y上居中
gradient.loadPixels();
对于(var i=0;i

你的问题不是模拟电子运动,而是更有效地在处理过程中绘制梯度。我看到您已经从示例>基础>颜色>径向梯度示例开始。请注意,示例本身运行速度非常慢,可能是因为重点关注如何使用颜色(HSB)和绘图功能,而较少关注性能

你能做的就是使用or缓存渐变,你更喜欢使用or

下面是一个使用PGraphics的示例,如果您不习惯使用像素,这可能会更简单:

PImage e;
void setup(){
  size(500,500);
  e = getElectronImg(30,30,0,100,100);//create a cached drawing
}
void draw(){
  background(255);
  translate(width * .5, height * .5);
  float a = frameCount * .1;
  image(e,100*cos(a), 50*sin(a));
}

PImage getElectronImg(int w,int h,int hue,int satMax,int brightness){
  PGraphics electron = createGraphics(w+1,h+1);//create a PGraphics object
  electron.beginDraw();//init drawing using the same Processing drawing functions
    electron.colorMode(HSB,360,100,100);
    electron.background(0,0);//transparent bg
    electron.noStroke();
    int cx = electron.width/2;
    int cy = electron.height/2;
    for (int r = w; r > 0; --r) {
      electron.fill(hue,map(r,0,w,satMax,0),brightness);
      electron.ellipse(cx, cy, r, r);
    }
  electron.endDraw();
  return electron;
}
还值得注意的是,PGraphics扩展了PImage,因此可以使用函数like和其他PImage显示

下面是使用像素实现的相同缓存概念:

PImage e;
void setup(){
  size(500,500);
  e = getElectronImg(30,30,0,100,100);
}
void draw(){
  background(255);
  translate(width * .5, height * .5);
  float a = frameCount * .1;
  image(e,100*cos(a), 50*sin(a));
}

PImage getElectronImg(int w,int h,int hue,int satMax,int brightness){
  pushStyle();//isolate drawing styles such as color Mode
    colorMode(HSB,360,100,100);
    PImage electron = createImage(w,h,ARGB);//create an image with an alpha channel
    int np = w * h;//total number of pixels
    int cx = electron.width/2;//center on x
    int cy = electron.height/2;//center on y
    for(int i = 0 ; i < np; i++){//for each pixel
      int x = i%electron.width;//compute x from pixel index
      int y = (int)(i/electron.width);//compute y from pixel index
      float d = dist(x,y,cx,cy);//compute distance from centre to current pixel
      electron.pixels[i] = color(hue,map(d,0,cx,satMax,0),brightness,map(d,0,cx,255,0));//map the saturation and transparency based on the distance to centre
    } 
    electron.updatePixels();//finally update all the pixels
  popStyle();
  return electron;
}
PImage e;
空硒
void draw(){
  background(255);
  translate(width * .5, height * .5);
  scale(.25);
  for(int i = 0 ; i < 5000 ; i++){
    float a = (frameCount * .025 + (i*.1));
    image(e,sin(a) * (100+(i * .5))*cos(a + i),  (50+(i * .25))*sin(a + i));
  }
}