らせん
提供:kuhalaboWiki
(版間での差分)
(→リンク) |
|||
269行: | 269行: | ||
} | } | ||
</pre> | </pre> | ||
+ | |||
+ | ==座標の3D回転== | ||
+ | ;X軸を中心にフェルマーらせんを回転 | ||
+ | * '''rotateX()'''を使う (https://processing.org/reference/rotateX_.html) | ||
+ | * '''size()'''に'''P3D'''を指定 | ||
+ | <pre> | ||
+ | |||
+ | int itr = 0; //描画の繰り返し回数 | ||
+ | float scalar = 5; //拡大倍率 | ||
+ | float rotation; | ||
+ | float r =0; | ||
+ | void setup() { | ||
+ | size(500, 500, P3D); // 3D座標を指定する | ||
+ | background(255); //背景を白くする | ||
+ | rotation = (1 + sqrt(5)) / 2; | ||
+ | } | ||
+ | void draw() { | ||
+ | translate(width / 2, height / 2); //描画ウィンドウの中心に移動 | ||
+ | rotateX(r); | ||
+ | fill(0); //点を黒く塗る | ||
+ | |||
+ | float theta = 2 * PI * itr * rotation; //回転角 | ||
+ | PVector v = PVector.fromAngle(theta); | ||
+ | v.mult(scalar * sqrt(itr)); | ||
+ | ellipse(v.x, v.y, scalar, scalar); //点を描画 | ||
+ | |||
+ | itr++; | ||
+ | r = r + 0.01; | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | ;Y軸を中心にフェルマーらせんを回転 | ||
+ | * '''rotateY()'''を使う (https://processing.org/reference/rotatYX_.html) | ||
+ | * '''size()'''に'''P3D'''を指定 | ||
+ | <pre> | ||
+ | |||
+ | int itr = 0; //描画の繰り返し回数 | ||
+ | float scalar = 5; //拡大倍率 | ||
+ | float rotation; | ||
+ | float r =0; | ||
+ | void setup() { | ||
+ | size(500, 500, P3D); // 3D座標を指定する | ||
+ | background(255); //背景を白くする | ||
+ | rotation = (1 + sqrt(5)) / 2; | ||
+ | } | ||
+ | void draw() { | ||
+ | translate(width / 2, height / 2); //描画ウィンドウの中心に移動 | ||
+ | rotateY(r); | ||
+ | fill(0); //点を黒く塗る | ||
+ | |||
+ | float theta = 2 * PI * itr * rotation; //回転角 | ||
+ | PVector v = PVector.fromAngle(theta); | ||
+ | v.mult(scalar * sqrt(itr)); | ||
+ | ellipse(v.x, v.y, scalar, scalar); //点を描画 | ||
+ | |||
+ | itr++; | ||
+ | r = r + 0.01; | ||
+ | } | ||
+ | </pre> | ||
+ | |||
== リンク == | == リンク == |
2022年11月4日 (金) 00:04時点における版
- 自然界のらせん(渦巻き)
- 巻貝の貝殻
- 台風
- 銀河の星の渦
- ひまわりの種の配列
- 座標系
- 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座標
目次 |
再帰的な描画と対数らせん
- ベクトル操作:(x,y)の2つの値を1まとめに扱う。位置や運動を整理して扱うことができる。参考サイト(閉鎖されました)
正方形の中に正方形を再帰的に描く
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); //点を描画 }
座標の3D回転
- X軸を中心にフェルマーらせんを回転
- rotateX()を使う (https://processing.org/reference/rotateX_.html)
- size()にP3Dを指定
int itr = 0; //描画の繰り返し回数 float scalar = 5; //拡大倍率 float rotation; float r =0; void setup() { size(500, 500, P3D); // 3D座標を指定する background(255); //背景を白くする rotation = (1 + sqrt(5)) / 2; } void draw() { translate(width / 2, height / 2); //描画ウィンドウの中心に移動 rotateX(r); fill(0); //点を黒く塗る float theta = 2 * PI * itr * rotation; //回転角 PVector v = PVector.fromAngle(theta); v.mult(scalar * sqrt(itr)); ellipse(v.x, v.y, scalar, scalar); //点を描画 itr++; r = r + 0.01; }
- Y軸を中心にフェルマーらせんを回転
- rotateY()を使う (https://processing.org/reference/rotatYX_.html)
- size()にP3Dを指定
int itr = 0; //描画の繰り返し回数 float scalar = 5; //拡大倍率 float rotation; float r =0; void setup() { size(500, 500, P3D); // 3D座標を指定する background(255); //背景を白くする rotation = (1 + sqrt(5)) / 2; } void draw() { translate(width / 2, height / 2); //描画ウィンドウの中心に移動 rotateY(r); fill(0); //点を黒く塗る float theta = 2 * PI * itr * rotation; //回転角 PVector v = PVector.fromAngle(theta); v.mult(scalar * sqrt(itr)); ellipse(v.x, v.y, scalar, scalar); //点を描画 itr++; r = r + 0.01; }