not good but great

プログラミング、アート、映画・本の感想について書きます。

三角関数やノイズを使って円や螺旋を描く

円を描く

f:id:naoyashiga:20140503180331p:plain

for(float ang = 0;ang <= 360;ang += 5){
    float rad = radians(ang);
    x = centx + (radius * cos(rad));
    y = centy + (radius * sin(rad));
    point(x,y);
}

ellipse関数を使えば、すぐに円は描画できます。しかし三角関数を使って、描画した方が応用が効きます。上のコードは一部抜粋したコードです。円周上に点を打っています。

らせんを描く

点で描く

f:id:naoyashiga:20140503181300p:plain

for(float ang = 0;ang <= 360 * 5;ang += 5){
    radius += 0.5;
    float rad = radians(ang);
    x = centx + (radius * cos(rad));
    y = centy + (radius * sin(rad));
    point(x,y);
}

螺旋を描くには半径を増加させて、回転角度を増やせば良いです。

実線で描く

f:id:naoyashiga:20140503182228p:plain

void setup(){
  size(500,500);
  background(255);
  strokeWeight(2);
  smooth();
  
  float radius = 10;
  int centx = width / 2;
  int centy = height / 2;
  
  stroke(20,50,70);
  float x,y;
  float lastx = -999;
  float lasty = -999; 
  
  for(float ang = 0;ang <= 360 * 5;ang += 5){
    radius += 0.5;
    float rad = radians(ang);
    x = centx + (radius * cos(rad));
    y = centy + (radius * sin(rad));
    
    if(lastx > -999){
      line(x,y,lastx,lasty);
    }    
    lastx = x;
    lasty = y;
  }
}

"-999"にしているのは、x,yが定義された後にlastx,lastyを使いためです。if文で「lastx > -999」とすることにより、1回目の描画を避けています。-999にしている意味はsizeで指定した数値と被らないようにしているためです。-999じゃなくて-1000でも別に問題はないと思います。

らせんにノイズを加える

f:id:naoyashiga:20140503183807p:plain

//ノイズに入れる乱数  
float radiusNoise = random(10);

for(float ang = 0;ang <= 360 * 5;ang += 5){
  //乱数増加
  radiusNoise += 0.05;
  //半径にノイズを加える
  radius += noise(radiusNoise) * 20 - 10;
  float rad = radians(ang);
  x = centx + (radius * cos(rad));
  y = centy + (radius * sin(rad));
  
  if(lastx > -999){
    line(x,y,lastx,lasty);
  }
  
  lastx = x;
  lasty = y;
}

前回エントリで出てきたnoiseを使って、らせんをもう少しぐちゃぐちゃしたものにします。
・前回エントリ
randomやnoise(パーリンノイズ)を用いて線を描画する - not good but great

繰り返して描画する

f:id:naoyashiga:20140503185006p:plain
10回ノイズを加えたらせんを描画しました。線の太さは細くしました。

f:id:naoyashiga:20140503185127p:plain
今度は100回繰り返しました。かなり線が多いです。

開始角度、終了角度、増加する角度数を変更

f:id:naoyashiga:20140503185913p:plain

int startAngle = int(random(360));
int endAngle = 360 * 3 + int(random(360 * 3));
int angleStep = 5 + int(random(3));

for(float ang = startAngle;ang <= endAngle;ang += angleStep){
  /*描画処理*/
}

開始角度、終了角度をランダムにしたことで、中心に集まるようになりました。終了角度が大きな値を取らないと、周辺まで螺旋が伸びないのが理由です。

線のスタイルをランダムにする

f:id:naoyashiga:20140503185930p:plain

stroke(random(20),random(50),random(70),random(80));

線の色と透明度をランダムにしました。少しオシャレになったかもしれません笑。

自作のノイズ

f:id:naoyashiga:20140503193026p:plain

void setup(){
  size(500,500);
  background(255);
  strokeWeight(5);
  smooth();
  
  int centx = width / 2;
  int centy = height / 2;
  
  
  float x,y;
  float noiseVal = random(10);
  float radius = 100,rad;
  
  beginShape();
  
  fill(#fe6fb7,80);
  
  int startAngle = 0;
  int endAngle = 360;
  int angleStep = 1;
  
  for(float ang = startAngle;ang <= endAngle;ang += angleStep){
    noiseVal += 0.1;
    radius += customNoise(noiseVal) * 30;
    
    rad = radians(ang);
    x = centx + (radius * cos(rad));
    y = centy + (radius * sin(rad));
    
    curveVertex(x,y);
    
  }
  
  endShape();
}

Shapeを使って、塗りつぶしを行っています。始点と終点が繋がっていないので、線がないところがあります。

float customNoise(float value){
  float retValue = pow(sin(value),3);
  return retValue;
}

sin3乗を使って、半径を変化させて円を描画してみました。色もピンク色にしてみました。

f:id:naoyashiga:20140503194523p:plain

float customNoise(float value){
  float retValue = pow(sin(value),15) + 50 * cos(value);
  return retValue;
}

適当に三角関数をいじってみました。また回転角度も増やしました。色も赤にしてみました。