らせん

提供:kuhalaboWiki
(版間での差分)
移動: 案内, 検索
(再帰的な描画と対数らせん)
(座標の3D回転)
 
(1人の利用者による、間の2版が非表示)
269行: 269行:
 
}
 
}
 
</pre>
 
</pre>
 +
 +
== リンク ==
 +
 +
[[スケーラブルアート論]]
 +
 +
[[Category:授業]]

2022年11月4日 (金) 00:05時点における最新版

自然界のらせん(渦巻き)
  • 巻貝の貝殻
  • 台風
  • 銀河の星の渦
  • ひまわりの種の配列
座標系
3種のらせん
アルキメデスらせん
フェルマーらせん
対数らせん
らせんの描画
float theta = 0;
float STEP = 2 * PI * 0.01; //曲線の精度(2*PI = 360度)を100等分
void setup(){
  size(500, 500);
}
void draw(){
  translate(width / 2, height / 2);  //描画ウィンドウの中心に移動
  line(rad(theta) * cos(theta), rad(theta) * sin(theta),
       rad(theta + STEP) * cos(theta + STEP), rad(theta + STEP) * sin(theta + STEP));
  theta += STEP;
}
float rad(float t){ //動径を定める関数
  float r = 5 * t;  //アルキメデスらせん
  //float r = 20 * sqrt(t); //フェルマーらせん
  // float r = pow(1.1, t); //対数らせん
  return(r);
}
  • PIは円周率で3.14159265…
  • rad() 角度を度数法から弧度法に変換する。参考サイト
  • pow(x,a) べき乗の計算 xのa乗
  • sqrt() は平方根
自己相似な対数らせん
float STEP = 2 * PI * 0.01; //曲線の精度
void setup(){
  size(500, 500);
  colorMode(HSB, 1);
}
void draw(){
  background(1,0,1);
  drawLogSpiral();  //対数らせんを描画
}

void drawLogSpiral(){
  float theta = 0;
  float scalar = pow(10, (float) mouseX / width) * height / 2;
  //マウスのx座標によって1~10倍に拡大する
  translate(width / 2, height / 2);  //描画ウィンドウの中心に移動
  for(int i = 0; i < 2000; i++){
    line(scalar * rad(theta) * cos(theta),
      scalar * rad(theta) * sin(theta),
      scalar * rad(theta + STEP) * cos(theta + STEP),
      scalar * rad(theta + STEP) * sin(theta + STEP));
    theta -= STEP;  //反時計回りに進むほど動径は減少する
  }
}
float rad(float t){ //動径を定める関数
  float r = pow(1.1, t);
  return(r);
}

  • mouseX マウスのX座標

[編集] 再帰的な描画と対数らせん

正方形の中に正方形を再帰的に描く

PVector[] vec;  //PVector型の配列を宣言
float gap = 0.01;  //内接する正方形のずれ
void setup(){
  size(500, 500);
  vec = new PVector[4]; //正方形の4つの頂点をベクトルとして生成
  vec[0] = new PVector(0, 0); //ウィンドウ左上の角
  vec[1] = new PVector(width, 0); //ウィンドウ右上の角
  vec[2] = new PVector(width, height);  //ウィンドウ右下の角
  vec[3] = new PVector(0, height);  //ウィンドウ左下の角
}
void draw(){
  drawSquare(vec);  //4つのベクトルを頂点とする四角形を描画
  vec = getVector(vec); //ベクトルをgapの分だけずらす
}
void drawSquare(PVector[] v){ 
  for(int i = 0; i < 4; i++){
    line(v[i].x, v[i].y, v[(i + 1) % 4].x, v[(i + 1) % 4].y);
    //頂点v[i]と頂点v[i+1]のx座標とy座標の値を取りだし,線分を描く
  }
}
PVector[] getVector(PVector[] vec){
  PVector[] nextVec = new PVector[4];
  for(int i = 0; i < 4; i++){
    PVector dir = PVector.sub(vec[(i + 1) % 4], vec[i]);  //2頂点間の方向ベクトル
    dir.mult(gap);  //ずれの分を方向ベクトルにかける
    nextVec[i] = PVector.add(vec[i], dir); //元の頂点の位置ベクトルをずらして新たなベクトルを作る
  }
  return(nextVec);
}
  •  %は割り算のあまり。9%4=1 (9を4で割るとあまり1)
  • 頂点は0,1,2,3なので、3の次は、3+1=4になるが、4で割った余りを考えると4%4=0となる。あまり(剰余系)を使うと、0,1,2,3,0,1,2,3…の循環を表せる。
  • v[i].xはベクトルv[i]のx座標
  • v[i].yはベクトルv[i]のy座標
  • .add(a,b)はベクトルの足し算
  • .sub(a,b)はベクトルの引き算
  • .mult(a)はベクトルの掛け算
void mouseClicked(){
  background(255);
  gap = random(1) / 2;
  println("gap =", gap);
  vec[0] = new PVector(0, 0);
  vec[1] = new PVector(width, 0);
  vec[2] = new PVector(width, height);
  vec[3] = new PVector(0, height);
}
多角形に拡張する。
  • PVector fromAngle : 指定した角度(ラジアン)の傾きを持つ単位ベクトル(大きさ1)を返す。
PVector[] vec;  //PVector型の配列を宣言
float gap = 0.1;  //内接する正多角形のずれ
int gon = 8;  //正多角形の頂点の数
void setup(){
  size(500, 500);
  vec = new PVector[gon];
  for(int i = 0; i < gon; i++){ //正多角形の頂点の位置ベクトル
    vec[i] = PVector.fromAngle(2 * i * PI / gon);
    vec[i].mult(width / 2);
  }
}
void draw(){
  translate(width / 2, height / 2); //描画ウィンドウの中心に移動
  drawPolygon(vec);
  vec = getVector(vec);
}
void drawPolygon(PVector[] v){
  for(int i = 0; i < gon; i++){
    line(v[i].x, v[i].y, v[(i + 1) % gon].x, v[(i + 1) % gon].y);
  }
}
PVector[] getVector(PVector[] v){
  PVector[] nextVec = new PVector[gon];
  for(int i = 0; i < gon; i++){
    PVector dir = PVector.sub(v[(i + 1) % gon], v[i]);
    dir.mult(gap);
    nextVec[i] = PVector.add(v[i], dir);
  }
  return nextVec;
}
void mouseClicked(){
  gap = random(1) / 2;
  gon = int(random(4, 16));
  background(255);
  vec = new PVector[gon];
  for(int i = 0; i < gon; i++){ //正多角形の頂点の位置ベクトル
    vec[i] = PVector.fromAngle(2 * i * PI / gon);
    vec[i].mult(width / 2);
  }
}

[編集] フェルマーらせん

離散的らせん
  • 回転角
    • 有理数
      • 1/2,1/3,1/5,1/10,1/20,1/40
      • /61
      • / 72
      • / 17
      • / 305
      • / 109
      • / 360
      • 17/55
    • 無理数
      • sqrt(5)
      • 黄金比
      • 円周率


int itr = 0;  //描画の繰り返し回数
float scalar = 5; //拡大倍率
float rotation;
void setup() {
  size(500, 500);
  background(255);  //背景を白くする
  rotation = 17.0 / 55;
//  rotation = sqrt(5);
//  rotation = (1 + sqrt(5)) / 2;
}
void draw() {
  translate(width / 2, height / 2);  //描画ウィンドウの中心に移動
  fill(0);  //点を黒く塗る
  drawFermatSpiral(rotation);  //引数を回転角とするフェルマーらせんの描画
  itr++;
}
void drawFermatSpiral(float rot){
  float theta = 2 * PI * itr * rot; //回転角
  PVector v = PVector.fromAngle(theta);
  v.mult(scalar * sqrt(itr));
  ellipse(v.x, v.y, scalar, scalar); //点を描画
}


複数の離散的らせん

int itr = 0;  //描画の繰り返し回数
float scalar = 5; //拡大倍率
void setup() {
  size(500, 500);
  background(255);
}
void draw() {
  translate(width / 2, height / 2);  //描画ウィンドウの中心に移動

  noStroke();
  fill(255, 0, 0, 127);  //点を赤く塗る
  drawFermatSpiral(4.0 / 17);
  fill(0, 0, 255, 127);  //点を青く塗る
  drawFermatSpiral(17.0 / 72);
  fill(0, 255, 0, 127);  //点を緑に塗る
  drawFermatSpiral(72.0 / 305);
  itr++;
}
void drawFermatSpiral(float rot){
  float theta = 2 * PI * itr * rot; //回転角
  PVector v = PVector.fromAngle(theta);
  v.mult(scalar * sqrt(itr));
  ellipse(v.x, v.y, scalar, scalar); //点を描画
}

[編集] リンク

スケーラブルアート論

個人用ツール
名前空間

変種
操作
案内
ツールボックス