2012-12-09 2 views
1

저는 Processing을 처음 사용하고 있으며 전자 이동을 시뮬레이션하고 있습니다. 각 particle에 그라디언트 색상을 추가하려고 할 때까지 모든 것이 잘 보입니다. 프레임 속도가 상당히 떨어집니다.가공 : 그래디언트를 효율적으로 그릴 수 있습니다.

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(); 
} 
+0

잘이 질문은 좋은 유용한 답변을 생성 한 아무튼... –

답변

9

귀하의 질문은 전자의 움직임을 시뮬레이션에 관한 것이 아니라 효율적으로 처리에 그라디언트를 그리기에 대한 자세한 : 여기

내가 지금까지 시도한 것입니다. 예> 기본 사항> 색상> RadialGradient 샘플로 시작했습니다. 샘플 자체는 꽤 느리게 실행됩니다. 아마도 색상 (HSB) 및 그리기 기능을 사용하는 방법과 성능에 대해 집중하지 않기 때문일 것입니다.

당신이 할 수있는 일은 더 편안하게 사용할 수있는 PGraphics 또는 PImage을 사용하여 그라데이션을 캐시하는 것입니다.

또한 PGraphics가 PImage를 확장 것을 주목할 필요가
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; 
} 

따라서 표시 할 수있는 image() 기능 등을 사용하여 :

다음은 픽셀 작업에 사용하지 않는 경우 더 간단 할 수 PGraphics를 사용하여 예입니다 및 기타 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; 
} 

는 물론, 이것은 쉽게 더 많은 전자를 사용할 수 있도록합니다 :

그리고 여기에 같은 캐싱 픽셀을 사용하여 수행 개념입니다. 사실 전자의 움직임에서 오프 주제, 여기) (그릴 사소한 조작을함으로써 재미 테스트는 다음과 같습니다

void draw(){ 
    background(255); 
    translate(width * .5, height * .5); 
    for(int i = 0 ; i < 200 ; i++){ 
    float a = (frameCount * .025 + (i*.1)); 
    image(e,(100+i)*cos(a + i), (50+i)*sin(a + i)); 
    } 
} 

200

void draw(){ 
    background(255); 
    translate(width * .5, height * .5); 
    for(int i = 0 ; i < 1000 ; i++){ 
    float a = (frameCount * .025 + (i*.1)); 
    image(e,(100+(i * .25))*cos(a + i), (50+(i * .25))*sin(a + i)); 
    } 
} 

1000

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)); 
    } 
} 

5K

재미있어!

지금 당신은 실제로 (데모를 변경하는 데 사용할 키 1,2,3,4) 바로 여기에 코드를 실행할 수 있습니다

var e,demo = 2; 
 
function setup(){ 
 
    createCanvas(500,500); 
 
    e = getGradientImg(30,30,0,100,100); 
 
} 
 
function draw(){ 
 
    background(255); 
 
    translate(width * .5, height * .5); 
 
    if(demo == 1){ 
 
    var a = frameCount * .1; 
 
    image(e,100*cos(a), 50*sin(a)); 
 
    } 
 
    if(demo == 2){ 
 
    for(var i = 0 ; i < 200 ; i++){ 
 
     var a = (frameCount * .025 + (i*.1)); 
 
     image(e,(100+i)*cos(a + i), (50+i)*sin(a + i)); 
 
    } 
 
    } 
 
    if(demo == 3){ 
 
    for(var i = 0 ; i < 1000 ; i++){ 
 
     var a = (frameCount * .025 + (i*.1)); 
 
     image(e,(100+(i * .25))*cos(a + i), (50+(i * .25))*sin(a + i)); 
 
    } 
 
    } 
 
    if(demo == 4){ 
 
    scale(.2); 
 
    for(var i = 0 ; i < 5000 ; i++){ 
 
     var a = (frameCount * .025 + (i*.1)); 
 
     image(e,sin(a) * (100+(i * .5))*cos(a + i), (50+(i * .25))*sin(a + i)); 
 
    } 
 
    } 
 
} 
 
function keyReleased(){ 
 
    if(key === '1') demo = 1; 
 
    if(key === '2') demo = 2; 
 
    if(key === '3') demo = 3; 
 
    if(key === '4') demo = 4; 
 
} 
 

 
function getGradientImg(w,h,hue,satMax,brightness){ 
 
    push();//isolate drawing styles such as color Mode 
 
    colorMode(HSB,360,100,100); 
 
    var gradient = createImage(w,h);//create an image with an alpha channel 
 
    var np = w * h;//total number of pixels 
 
    var np4 = np*4; 
 
    var cx = floor(gradient.width * 0.5);//center on x 
 
    var cy = floor(gradient.height * 0.5);//center on y 
 
    gradient.loadPixels(); 
 
    for(var i = 0 ; i < np4; i+=4){//for each pixel 
 
     var id4 = floor(i * .25); 
 
     var x = id4%gradient.width;//compute x from pixel index 
 
     var y = floor(id4/gradient.width);//compute y from pixel index 
 
     var d = dist(x,y,cx,cy);//compute distance from centre to current pixel 
 
     //map the saturation and transparency based on the distance to centre 
 
     gradient.pixels[i] = hue; 
 
     gradient.pixels[i+1] = map(d,0,cx,satMax,0); 
 
     gradient.pixels[i+2] = brightness; 
 
     gradient.pixels[i+3] = map(d,0,cx,255,0); 
 
    } 
 
    gradient.updatePixels();//finally update all the pixels 
 
    pop(); 
 
    return gradient; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.4/p5.min.js"></script>

관련 문제