Processingで発光表現を試してみた

# Processingを使って発光表現を試してみる

この記事ではProcessingを使って、発光表現を利用した作品例を紹介します。

# 手法

[Processingで発光表現](http://p5aholic.hatenablog.com/entry/2015/12/10/000000)という記事のコードを利用させていただき、これをクラスにしてアレンジしました。

若干のインタラクティブ性を持たせるために、マウスを動かすと球が大きくなるように書いています。

ソースコードも載せておきます。

```
PImage img;
float t=0;
float amp;
float r=120;
float min_radius = 120;
float max_radius = 200;

pixel_circle[] c=new pixel_circle[6];

void setup(){
  fullScreen(P3D);
  frameRate(45); 
  hint(DISABLE_DEPTH_TEST);
  blendMode(ADD);
  imageMode(CENTER);
  for(int num=0;num<6;num++){
    img=createLight(random(0.6,0.9),random(0.3,0.5),random(0.6,0.8));
    c[num]=new pixel_circle(r,img);
  }
}

void draw(){
  background(15,20,50);
  translate(width/2,height/2,0);
  rotateX(frameCount*0.01);
  rotateY(frameCount*0.01);
  rotateZ(frameCount*0.01);
  translate(-width/4*amp,0,0);
  
  amp=cos(radians(t))*cos(radians(t));
  change_color(c,amp);
  r = change_radius(c,r);
  
  c[0].display();
  translate(width/2*amp,0,0);
  c[1].display();
  translate(-width/4*amp,width/4*amp,0);
  c[2].display();
  translate(0,-width/2*amp,0);
  c[3].display();
  translate(0,width/4*amp,-width/4*amp);
  c[4].display();
  translate(0,0,width/2*amp);
  c[5].display();
  
  t++;
}

void change_color(pixel_circle[] c,float amp){
  if(amp<0.002){
    for(int num=0;num<6;num++){
    c[num].change_color();
    }
  }
}

float change_radius(pixel_circle[] c,float r){
  if(dist(mouseX,mouseY,pmouseX,pmouseY)>0){
    r+=2;
    if(r>max_radius){
      r=max_radius;
    }
  }
  else{
    r-=2;
    if(r<min_radius){
      r=min_radius;
    }
  }
  for(int num=0;num<6;num++){
    c[num].change_radius(r);
  }
  return r;
}
    

PImage createLight(float rPower,float gPower,float bPower){
  int side=150;
  float center=side/2.0;
  
  PImage img=createImage(side,side,RGB);
  
  for(int y=0;y<side;y++){
    for(int x=0;x<side;x++){
      float distance=(sq(center-x)+sq(center-y))/50.0;
      int r=int((255*rPower)/distance);
      int g=int((255*gPower)/distance);
      int b=int((255*bPower)/distance);
      img.pixels[x+y*side]=color(r,g,b);
    }
  }
  return img;
}


class pixel_circle{
  float radius;
  float x,y,z;
  float velocity=0;
  
  PImage img1;
  
  pixel_circle(float radius1,PImage img2){
    radius=radius1;
    img1=img2;
  }
  
  void display(){
    float lastX=0,lastY=0,lastZ=0;
    float s=0,t=0;
  
    rotateX(frameCount*0.01);
    rotateY(frameCount*0.01);
    while(s<=180){
      float radianS=radians(s)%(2*PI);
      float radianT=radians(t)%(2*PI);
      float x=radius*sin(radianS)*cos(radianT);
      float y=radius*sin(radianS)*sin(radianT);
      float z=radius*cos(radianS);
    
      stroke(128);
      if(lastX!=0){
        strokeWeight(0.2);
        line(x,y,z,lastX,lastY,lastZ);
      }
    
      pushMatrix();
      translate(x,y,z);
      rotateY(-frameCount*0.01);
      rotateX(-frameCount*0.01);

      image(img1,0,0);
      popMatrix();
    
      lastX=x;
      lastY=y;
      lastZ=z;
   
      s++;
      t+=velocity;
    }
    rotateY(-frameCount*0.01);
    rotateX(-frameCount*0.01); 
    velocity+=0.04;
  }
  
  void change_color(){
    img1=createLight(random(0.5,0.8),random(0.5,0.8),random(0.5,0.8));
  }
  
  void change_radius(float r1){
    radius=r1;
  } 
}
```

# 結果

![結果](https://media.giphy.com/media/26zzfVZAYaJZ9q9Py/giphy.gif)

[追記] [他の作品](http://qiita.com/mikittt/items/776e6f2a114866386b54)もあげました！