Processing – DECODE https://decode.red/blog data decode, decoder or decoded ... design of code Mon, 15 Dec 2025 06:15:00 +0000 ja hourly 1 https://wordpress.org/?v=4.7.29 Ulam Spiral ../../../202012281232/ Mon, 28 Dec 2020 10:23:33 +0000 ../../../?p=1232 素数を螺旋状に並べた自然数の部分にマークして可視化すると、対角線が強調された規則性があるように見える画像をウラムの螺旋と呼ばれます。素数の出現ルールはまだ解明されていないためそのヒントになるのではと期待されています。
先日放送が終了した東野圭吾原作「危険なビーナス」で、殺人事件の動機となる題材として使われいたことをきっかけに、実際にプログラムで描いてみました。(こういうネタを作品にしこむのはさすがです。「恨む」とかけてたり・・)

参考)https://tony-mooori.blogspot.com/2015/10/processing_25.html
上記、無駄のないプログラムでシンプルでしたので、使わせていただきました。

ここではただ描画するだけでなく、下記、素数をとおる半直線(8方向)の関数との重なり具合も見てみました。(赤点)
参考) https://ja.wikipedia.org/wiki/%E3%82%A6%E3%83%A9%E3%83%A0%E3%81%AE%E8%9E%BA%E6%97%8B

またオイラーの素数多項式についても調べてみました。(赤点)
参考)

下記コード。コメントで描画を切り替えています。

import java.util.*;

int[] xy1, xy2;

void setup() {
  size(512, 512);

  xy1 = new int[width*height];
  xy2 = new int[width*height];
  
  Arrays.fill(xy1, 1);
  xy1[0] = xy1[1] = 0;
  for (int i = 2; i < sqrt(xy1.length) ; i++ ) {
    if ( xy1[i] == 1 ) {
      for (int j = 2 * i; j < xy1.length; j += i ) {
        xy1[j] = 0;
      }
    }
  }
  
  Arrays.fill(xy2, 0);
  
  for(int i=0;i<xy2.length;i++){
    for(int j=0;j<xy2.length;j++){
      int u = 4 * j * j - 3 * j + 1;
      //int u = 4 * j * j - 2 * j + 1;
      //int u = 4 * j * j - 1 * j + 1;
      //int u = 4 * j * j - 0 * j + 1;
      //int u = 4 * j * j + 1 * j + 1;
      //int u = 4 * j * j + 2 * j + 1;
      //int u = 4 * j * j + 3 * j + 1;
      //int u = 4 * j * j + 12 * j + 1;
      if(u > xy2.length){
        break;
      }
      if(i == u){
        xy2[i] = 1;
      }
    }
  }
  
  /*
  for(int i=0;i<xy2.length;i++){
    for(int j=0;j<xy2.length;j++){
      int u = j * j + j + 41;
      if(u > xy2.length){
        break;
      }
      if(i == u){
        xy2[i] = 1;
      }
    }
  }
  */
}

void draw() {
  background(0);

  stroke(0, 255, 255);
  fill(0, 255, 0);
  
  translate(width/2, height/2);

  int x = 0;
  int y = 0;

  int dx = 1;
  int dy = 0;
  int n = 1;
  
  for (int i = 1; i < width * height; i++ ) {
    if (xy1[i] == 1){
      if(xy1[i] == xy2[i]){
        stroke(255, 0, 0);
      }
      else{
        stroke(0, 255, 255);
      }
      point(x, y);
    }
    
    if ( n * n + 1 == i ) {
      dy = (n % 2)*2-1;
      dx = 0;
      n++;
    } else if ( n * n - n + 1 == i) {
      dx = (n % 2)*2-1;
      dy = 0;
    }
    x += dx;
    y += dy;
  }
}

規則性がありそうなのに、数式にできないという、本当に素数は不思議です。

]]>
Vector Field ../../../202003141086/ Sat, 14 Mar 2020 02:54:22 +0000 ../../../?p=1086 「大きさ」と「向き」の二つの量をもつベクトル。3Dグラフィックを扱うとき必ず出てきますが、もう少し勉強しようと数学のベクトル解析という分野を学び始めました。
しかし数式ばかりでなかなか学んだ感が得られなかったので、ベクトル場という部分について理解を深めるために、Processingでプログラムを作ってみました。

参考) https://medium.com/@vladisluka/vector-fields-in-processing-779516b15141

上が基本的なベクトル関数

→f = (x, y)
の例。
Cellを作り、Cell単位でベクトルを表現しています。
「大きさ」は長さとしてCellに入る程度に丸めています。また「向き」によって色を変えてます。
こうやってみると「向き」というのは情報量が多いことが実感できます。

int len = 16;

void setup () {
  size(640, 640);
  background(0);
  
  colorMode(HSB, 360);
  
  int cols = floor(width / len);
  int rows = floor(height / len);
 
  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) {
      Cell cell = new Cell(i, j);
      
      pushMatrix();
      strokeWeight(2);
      stroke(degrees(cell.arg)+180, 360, 360);
 
      translate((i + 0.5) * len, (j + 0.5) * len);
      rotate(cell.arg);
      line(cell.mag*2, 0, -cell.mag*2, 0);
      translate(len/2, 0);
  
      float a = radians(150);
      float x1 = 5 * cos(a);
      float y1 = 5 * sin(a);
      
      line(0, 0, x1, y1);  
      line(0, 0, x1, -y1);
        
      popMatrix();    
    }
  }
}
class Cell { 
  float arg;
  float mag;
  Cell (int i, int j) {
    float x = (i + 0.5) * len;
    float y = (j + 0.5) * len;   
    x = map(x, 0, width, -3, 3);
    y = map(y, 0, height, -3, 3);
    
    //float u = x;
    //float v = y;
    
    //float u = x * x;
    //float v = 0.5 * y;
    
    float u = cos(x);
    float v = sin(y);
  
    PVector vec = new PVector(u, v);  
    mag = vec.mag(); 
    arg = vec.heading();
  }
}

→f = (x*x, 0.5*y)

→f = (cos(x), sin(y))

様々なデータの可視化にも有用ですが、コンピータグラフィックを使ったアートにも威力を発揮しそうです。

]]>
3D Bezier ../../../202001301070/ Thu, 30 Jan 2020 13:30:49 +0000 ../../../?p=1070 ベジエ曲線というと、3点以上の点を結んだ線分を等分した点を、さらに結んだ線から作る曲線ですが、コンピュータグラフィックによく使われます。平面上に曲線を描くことが多いですが、ここでは3D空間に描き、それをさまざまな角度から眺めてみたいと思います。

環境: Processing 3.3.7 / macOS High Sierra

import peasy.*;
PeasyCam cam;

PVector[] pt = new PVector[5];
int step = 20;
void setup(){
  size(800, 800, P3D);
  colorMode(HSB, 1);
  cam = new PeasyCam(this, 800);
  pt[0] = new PVector(0, 0, 0);
  pt[1] = new PVector(width, 0, 400);
  pt[2] = new PVector(width, height, 0);
  pt[3] = new PVector(0, height, 400);
  pt[4] = new PVector(0, 0, 800);
}
void draw(){
  background(0);
  for(int i=0;i<=step;i++){  
    PVector[] mp = pt;
    while(mp.length > 1){
      PVector[] vt = new PVector[mp.length-1];
      for (int m=0; m<mp.length-1; m++){
        vt[m] = PVector.sub(mp[m+1],mp[m]);
        vt[m].mult(float(i) / float(step));
        vt[m].add(mp[m]);
      }  
      stroke(float(vt.length) / float(pt.length), 1, 1, 1);
      for (int n=0; n<vt.length-1; n++){
        strokeWeight(1);
        line(vt[n].x, vt[n].y, vt[n].z, vt[n+1].x, vt[n+1].y, vt[n+1].z);
      }
      mp = vt;
    }
  }
}



下記書籍のベジエ曲線のコードを参考にpeasyを使って3D化したものです。peasyは最近よく使うのですが、マウスでぐりぐりしながら簡単に3Dオプジェクトをさまざまな角度から見ることができるので、とても便利です。

「数学から作るジェネラティブアート」(技術評論社)

]]>
3D Turtle Graph ../../../201912271064/ Fri, 27 Dec 2019 06:01:50 +0000 ../../../?p=1064 シンプルな手順で複雑なグラフィックが描画できるタートルグラフ。座標を与えてラインを描画する方法でなく、描く主体に指示をして描画します。この主体をタートルと呼び、2Dではその動きが比較的簡単にイメージできるのですが、3Dとなると上下左右の回転を意識する必要があり、なかなか頭を使います。自分主体の回転なので、角度の考え方は以下の過去記事が参考になります。

../../../20171230780/ 「クォータニオン」

ここでは飛行機などの動きでよく用いられる、ロール、ピッチ、ヨーの考え方で動かしてみました。

参考) https://forum.processing.org/two/discussion/20706/#Comment_104904

ロールは、機体の進行方向を軸にした回転、ピッチは上下(Tilt up,down)、ヨーは左右(Pan)で、ここではロールとヨーだけ使います。

import peasy.*;
PeasyCam camera;

PVector v;
int yaw  = 0;
int roll = 0;

void setup() {
  size(1200, 1200, P3D);
  camera = new PeasyCam(this, 0, 0, 0, 1000);
}

void draw() {
  background(111);
  colorMode(HSB);

  v = new PVector(0, 0, 0);
  yaw = 0;
  roll = 0;
  
  pushMatrix();
  for(int i=0;i<255;i++){
    rollAngle(10);
    stroke(i, 255, 255);
    forward(5);
    yawAngle(90);
    forward(200);
    yawAngle(-90);
    forward(5);
    yawAngle(-90);
    forward(200);
    yawAngle(90);
  }
  popMatrix();
}
void yawAngle (float a) {
  yaw += a;
}
void rollAngle (float a) {
  roll += a;
}
 
void forward(  float len  ) {
 
  float psi = radians(yaw);
  float phi = radians(roll);
 
  PVector prev =  v.copy();
 
  v.x =prev.x+ len * cos(phi) * sin(psi);
  v.y =prev.y+ len * sin(phi) * sin(psi); 
  v.z =prev.z+ len * cos(psi);
 
  line (prev.x, prev.y, prev.z, v.x, v.y, v.z) ;
}

ロールで傾けて、ヨーで向きを変えて、これを繰り返していますが、動きをわかりやすくするためラインの色を赤から順に変化させています。

まずは簡単な例でイメージトレーニングでした。

]]>
Complex Analysis ../../../201911031048/ Sun, 03 Nov 2019 01:28:45 +0000 ../../../?p=1048 素粒子のようなミクロの世界、宇宙のようなマクロの世界など、複素数の不思議な性質が様々な場面で使われています。関連書籍を読んでいて、もしかしたらこの世界の根本的な原理を表現するのに不可欠なものなのではと、もっと勉強したくなりました。その入り口として複素関数による写像がとっつきやすく、見た目も面白いので試してみました。


(https://www.mathcha.io/editor 利用)
複素数平面x,yで表されるzを、演算結果の実数部、虚数部をわけてu,v平面に変換します。
シンプルな複素数の二次関数ですが、これが取りうる値の空間をグラフ表示してみました。

上図(u,v)は下図(x,y)のとりうる領域を変換したものです。

これら、(u,v)の方が実際にはもっと大きくなりますが、座標を調整したあります。
(u,v)のどの部分が(x,y)のどの部分と対応するかわかりやすくするために色を赤から青に変化させてみました。
これを順に見ていくと(u,v)の方には後半の半分しかないことがわかります。これは重複して描画しているからです。(領域が重なる)
もう少しシンプルにするため横線のみの描画をしてみました。

これを変化したのが下です。

下のコードは一番上の画像を出力したものです。
vertexの部分のコメントを切り替えると、変換前後の画像の切り替えができます。いろいろと描画単位を変えてみると理解が深まります。
ところどころコメントがされていますが、線を一本一本アニメーションして描画することにも対応しました。(コードを短くするためこのようにしました。手抜きともいいます^^)

void setup() {
  size(400, 400);
  frameRate(10);
}
int f = -10;
void draw() {
  background(255);
  
  strokeWeight(1);
  stroke(127);
  line(width/2, 0, width/2, height);
  line(0, height/2, width, height/2);

  noFill();
  strokeWeight(2);
  
  pushMatrix();
  translate(width/2, height/2);

  colorMode(HSB);
  
  f = 10;
  int c = 0;
  for(int y=-10;y<=f;y++){
    beginShape();
    stroke( c, 255, 255);
    for(int x=-10;x<=10;x++){
      //vertex(x*10, -y*10);
      int u = x * x - y * y;
      int v = 2 * x * y;
      vertex(u, v);
    }    
    endShape();
    c += 4;
  }
  for(int x=-10;x<=f;x++){
    beginShape();
    stroke( c, 255, 255);
    for(int y=-10;y<=10;y++){
      //vertex(x*10, -y*10);
      int u = x * x - y * y;
      int v = 2 * x * y;
      vertex(u, v);
    }    
    endShape();
    c += 4;
  }
  popMatrix();
  f ++;
  if(f == 10){
 //   f = -10;
  }
}

空間が曲げられる様子が面白いです。シンプルな二次関数でもこれですから、もっといろいろと期待できます。Processingはこういうことにとても便利ですね。(学生時代にあったら・・)

]]>
Scatter Plot 3D ../../../201909071032/ Sat, 07 Sep 2019 05:24:54 +0000 ../../../?p=1032 Excelで3Dの散布図を描画しようとしたら、できないことに気づきました。似たようなことは等高線を使うようですが、ちょっと意図が違うので以前の投稿を参考にProcessingで描画してみました。

Processing 3D

float rotx = -0.04;
float roty = -0.04;

int zz = 1024;
void setup(){  
  size(1024, 1024, P3D);
  noLoop();
}
void setPoint(float x, float y, float z, int r, int g, int b){
    pushMatrix();
    translate(width/2 + x, height/2 + y, zz/2 - z);
    noStroke();
    fill(r,g,b);
    sphere(2);
    popMatrix();
}
void draw(){
  background(0);
  rotateX(rotx);
  rotateY(roty);
  
  for(int i=-50;i<50;i++){
     setPoint(i*10, 0, 0, 255, 0, 0);
  }
  for(int i=-50;i<50;i++){
    setPoint(0, i*10, 0, 0, 255, 0);
  }
  for(int i=-50;i<50;i++){
    setPoint(0, 0, i*10, 0, 0 , 255);
  }
  
  float px = 100;
  float py = -100;
  float pz = -100;
  
  for(int i=0; i<10000 ; i++){
    float rx = random(0, 500);
    float ry = random(-500, 0);
    float rz = random(-500, 0);
    
    if(sqrt((px-rx)*(px-rx)+(py-ry)*(py-ry)+(pz-rz)*(pz-rz)) < 50){
      setPoint(rx, ry, rz, 255, 255, 0);
    }
    else{
      setPoint(rx, ry, rz, 100, 255, 255);
    }   
  }
  setPoint(px, py, pz, 255, 0, 0);   
}


右上手前の事象にランダムな点を描画し、そのうちの赤点px,py,pzからの距離が50のものを黄色で表示しました。

参考にしたプログラムは、ループするのでランダムな点がアニメーションしてしまうため一回のみのループとしました。そのためマウスドラッグによる視点変更ができなくなっています。

過去のコードをすぐ引用できるのでこういうときBlogに記述しておくと便利だなぁ、と今回改めて感じました。

]]>
Quaternion ../../../20171230780/ Sat, 30 Dec 2017 00:57:06 +0000 ../../../?p=780 数学では四元数といわれ、虚数のi,j,kを三つ使い表現されとても難しく感じるものですが、3Dグラフィックスの世界では、3D空間のオブジェクトの回転でなくてはならない考え方です。X,Y,Z軸それぞれで回転するのではなく、あるベクトルを軸としてその周りを回転します。天体望遠鏡を持っている人なら、赤道儀のしくみからイメージしやすいかもしれません。
前回Processingで3D空間のテストをしたつづきで、このクォータニオンのテストをしてみました。

参考: https://github.com/kynd/PQuaternion/blob/master/Quaternion.pde#L8

Processingのクォータニオンのクラスは上のものをそのまま引用させていただきました。

また、マウスドラッグ視点を変えられる便利なライブラリpeasyを使用しました。
http://mrfeinberg.com/peasycam/

import peasy.*;
PeasyCam cam;
int SZ = 600;

void setup(){  
  size(600, 600, P3D);
  cam = new PeasyCam(this, 100);
  cam.setMinimumDistance(50); 
  cam.setMaximumDistance(500);
}
void draw(){
  background(240);
  
  for(int i=0;i<60;i++){
    pushMatrix();
    translate(i*10 - 300, SZ/2 - 300, SZ/2 -300);
    noStroke();
    fill(255,0,0);
    sphere(2);
    popMatrix();
  }
  for(int i=0;i<60;i++){
    pushMatrix();
    translate(SZ/2-300, i*10-300, SZ/2-300);
    noStroke();
    fill(0,255,0);
    sphere(2);
    popMatrix();
  }
  for(int i=0;i<60;i++){
    pushMatrix();
    translate(SZ/2-300, SZ/2-300, i*10-300);
    noStroke();
    fill(0,0,255);
    sphere(2);
    popMatrix();
  }
  
  pushMatrix();
  translate(150, 150, 150);
  noStroke();
  fill(0,255,255);
  sphere(4);
  popMatrix();

  for(int i=0;i<60;i++){
    pushMatrix();
    
    Quaternion q = new Quaternion();
    
    q.setAngleAxis(radians(15), new PVector(1, 0, 0));
    PVector r = new PVector(SZ/2-300, SZ/2-300, i*10-300);
    PVector m = q.mult(r);
    translate(m.x, m.y, m.z);
    noStroke();
    fill(255,0,255);
    sphere(1);
    popMatrix();
  }
}

プログラムは、前回作成したプログラムからZ軸をX軸を中心に15度回転されせたものを上書きしました。(紫の点)

public class Quaternion {
  
public float x, y, z, w;
public Quaternion() {
    x = y = z = 0;
    w = 1;
}
public Quaternion(float _x, float _y, float _z, float _w) {
    x = _x;
    y = _y;
    z = _z;
    w = _w;
}
public Quaternion(float angle, PVector axis) {
    setAngleAxis(angle, axis);
}

public Quaternion get() {
    return new Quaternion(x, y, z, w);
}
public Boolean equal(Quaternion q) {
    return x == q.x && y == q.y && z == q.z && w == q.w;
}
public void set(float _x, float _y, float _z, float _w) {
    x = _x;
    y = _y;
    z = _z;
    w = _w;
}
public void setAngleAxis(float angle, PVector axis) {
    axis.normalize();
    float hcos = cos(angle / 2);
    float hsin = sin(angle / 2);
    w = hcos;
    x = axis.x * hsin;
    y = axis.y * hsin;
    z = axis.z * hsin;
}
public Quaternion conj() {
    Quaternion ret = new Quaternion();
    ret.x = -x;
    ret.y = -y;
    ret.z = -z;
    ret.w = w;
    return ret;
}
public Quaternion mult(float r) {
    Quaternion ret = new Quaternion();
    ret.x = x * r;
    ret.y = y * r;
    ret.z = z * r;
    ret.w = w * w;
    return ret;
}
public Quaternion mult(Quaternion q) {
    Quaternion ret = new Quaternion();
    ret.x = q.w*x + q.x*w + q.y*z - q.z*y;
    ret.y = q.w*y - q.x*z + q.y*w + q.z*x;
    ret.z = q.w*z + q.x*y - q.y*x + q.z*w;
    ret.w = q.w*w - q.x*x - q.y*y - q.z*z;
    return ret;
}
public PVector mult(PVector v) {
  float px = (1 - 2 * y * y - 2 * z * z) * v.x +
             (2 * x * y - 2 * z * w) * v.y +
             (2 * x * z + 2 * y * w) * v.z;
             
  float py = (2 * x * y + 2 * z * w) * v.x +
             (1 - 2 * x * x - 2 * z * z) * v.y +
             (2 * y * z - 2 * x * w) * v.z;
             
  float pz = (2 * x * z - 2 * y * w) * v.x +
             (2 * y * z + 2 * x * w) * v.y +
             (1 - 2 * x * x - 2 * y * y) * v.z;

    return new PVector(px, py, pz);
}
public void normalize(){
  float len = w*w + x*x + y*y + z*z;
  float factor = 1.0f / sqrt(len);
  x *= factor;
  y *= factor;
  z *= factor;
  w *= factor;
}

}

また以前、Unityを試したブログでこのQuaternionがでてくるので、ここでちょっとだけ復習してみました。
「Unity 5 / C#」
http://crossframe.iiv.jp/201611241241/


直方体にして軸もちょっとずらして、回る様子をわかりやすくしました。

]]>
Processing 3D ../../../20171122774/ Wed, 22 Nov 2017 14:25:34 +0000 ../../../?p=774 Processingというと、グラフィックの得意な言語、開発環境ですが、3D空間の描画にも便利です。
ただ2Dの拡張のような3Dであるため、座標の感覚がつかみづらく感じました。そこで空間を把握するため3D座標軸とデータをプロットしてみました。(カメラ使用しない)

float rotx = 0;
float roty = 0;

int d1[] = {-1,-3,-5,-7,-3,-4,-8,-4,-5,0};//R
int d2[] = {3,6,3,2,5,7,4,2,1,2};//G
int d3[] = {4,2,2,4,6,7,5,8,4,3};//B
int d4[] = {-5,-2,-3,-4,-7,-5,-6,-1,-3,-2};//Cyan

void setup(){  
  size(600, 600, P3D);
}
void draw(){
  background(240);
  rotateX(rotx);
  rotateY(roty);
  
  for(int i=0;i<60;i++){
    pushMatrix();
    translate(i*10, height/2, height/2);
    noStroke();
    fill(255,0,0);
    sphere(2);
    popMatrix();
  }
  for(int i=0;i<60;i++){
    pushMatrix();
    translate(width/2, i*10, height/2);
    noStroke();
    fill(0,255,0);
    sphere(2);
    popMatrix();
  }
  for(int i=0;i<60;i++){
    pushMatrix();
    translate(width/2, width/2, i*10);
    noStroke();
    fill(0,0,255);
    sphere(2);
    popMatrix();
  }
  
  for(int i=0;i<10;i++){
    pushMatrix();
    translate(width/2 + i*10, height/2 + d1[i]*10, 300 - 100);
    noStroke();
    fill(255, 100, 100, 70);
    sphere(5);
    popMatrix();
  }
  for(int i=0;i<10;i++){
    pushMatrix();
    translate(width/2 + i*10, height/2 + d2[i]*10, 300 - 0);
    noStroke();
    fill(100, 255, 100, 70);
    sphere(5);
    popMatrix();
  }
  for(int i=0;i<10;i++){
    pushMatrix();
    translate(width/2 + i*10, height/2 + d3[i]*10, 300 + 100);
    noStroke();
    fill(100, 100, 255, 70);
    sphere(5);
    popMatrix();
  }
  for(int i=0;i<10;i++){
    pushMatrix();
    translate(width/2 + (-i)*10, height/2 + d4[i]*10, 300 + 180);
    noStroke();
    fill(100, 255, 255, 70);
    sphere(5);
    popMatrix();
  }
}
void mouseDragged() {
  float rate = 0.01;
  rotx += (mouseY - pmouseY) * rate;
  roty += (pmouseX - mouseX) * rate;
}

起動直後、Z軸上から眺めています。(X軸:赤、Y軸:緑、Z軸:青)

マウスでドラッグして視点を視点を変えるとクリッピングされていた手前のデータ(Cyan)が現れます。

さらに変えて、奥から手前にどの間隔でデータを並んでいるか確認してみます。(奥行き600)

カメラ位置や、ローテートのポイントを、使う目的に合わせて設定する必要があります。
Z軸回転のrotateZ()をためしてみましたが、ちょっとイメージと違う動きをしていて、なかなか難しいです。

]]>
Perlin Noise ../../../20141013213/ Mon, 13 Oct 2014 12:24:51 +0000 ../../../?p=213 Processingというグラフィックアート、デザインでよく使われるプログラム言語&ツールがあります。
データビジュアライゼーションの分野でも、積極的に使われています。
これにはパーリンノイズという、でたらめでもなく、規則的でもなく、自然に見せる乱数を発生する関数(noise())がありますが、前回の1/fノイズの続きで、その性質を調べてみました。

PrintWriter writer = createWriter("noise.csv");
background(0);
size(512, 512);

float n1 = 0;
float n2 = 0;
float n3 = 0;

for(int x = 0 ; x < 512 ; x += 1){
  float p1 = noise(n1);
  float p2 = noise(n2);
  float p3 = noise(n3);

  n1 += 2;
  n2 += 0.1;
  n3 += 0.003;
  
  writer.println(p1 + "," + p2 + "," + p3);
 
  noStroke();
  
  fill(255,0,125);
  ellipse(x, p1 * height, 5, 5);
  fill(0,255,0);
  ellipse(x, p2 * height, 5, 5);
  fill(0,255, 255);
  ellipse(x, p3 * height, 5, 5);
}

writer.flush();
writer.close();

Perlin01
noiseのパラメータn1,n2,n3の増加量で、滑らかさを変えることができます。でたらめ、自然ぽい、その中間、といった意図で、パラメータを調節してみました。
そして3つの乱数列をcsvファイルの出力して、Excelで読み込みます。

Perlin02
座標系が逆なので、Excelに読み込むと上下逆になります。

Perlin03
前回と同様、パワースペクトルをとりました。
1/fにそっているように見えます。

またこのバーリンノイズは、2次元、3次元にも適用できるところが面白いです。

float d = 100;
size(512, 512);
noStroke();
background(0);

loadPixels();
for(int y = 0; y < height; y++){
  for(int x = 0; x < width; x++){
    float g = noise(x / d, y / d) * 255;
    pixels[y * width + x] = color(g);
  }
}
updatePixels();

Perlin04
実行するたびに、変化します。
Perlin05
これを自前だとどうやってつくるのだろう、と興味が広がります。

]]>