らせん
提供:kuhalaboWiki
(版間での差分)
(→再帰的な描画と対数らせん) |
|||
| 269行: | 269行: | ||
} | } | ||
</pre> | </pre> | ||
| + | |||
| + | == リンク == | ||
| + | |||
| + | [[スケーラブルアート論]] | ||
| + | |||
| + | [[Category:授業]] | ||
2021年9月16日 (木) 23:15時点における版
- 自然界のらせん(渦巻き)
- 巻貝の貝殻
- 台風
- 銀河の星の渦
- ひまわりの種の配列
- 座標系
- 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); //点を描画
}