Date:2024-01-25
The Strange Attractors | Code and Equations
カオスで美しい軌道を描くStrange Attractor。時間の経過するとともに空間上の軌跡(数値)を取るといったことからコードを使用したグラフィック制作に利用する方が多くいます。
本記事はStrange Attractorを利用した作品例と幾つかのサンプルコード・出力結果を紹介しています。
Index
- Sample Graphic of barbe_generative_diary
- Sample Code with openFrameworks
- The Strange Attractors
The Aizawa Attractor
The Chua Attractor
The Halvorsen Attractor
The Lorenz Attractor
The Newton – Leipnik Attractor
Sample Graphic of barbe_generative_diary
以前、barbe_generative_diaryにてStrange Attractorを利用したグラフィックサンプル。
Sample Code for openFrameworks
Sample codeはopenFrameworksを利用していますが、個々のAttractorの数式はProcessingなど他のツールでも利用できます。scale(大きさ)の数値などは任意。
#pragma once
#include "ofMain.h"
class ofApp : public ofBaseApp{
public:
void setup() override;
void update() override;
void draw() override;
void exit() override;
void keyPressed(int key) override;
void keyReleased(int key) override;
void mouseMoved(int x, int y ) override;
void mouseDragged(int x, int y, int button) override;
void mousePressed(int x, int y, int button) override;
void mouseReleased(int x, int y, int button) override;
void mouseScrolled(int x, int y, float scrollX, float scrollY) override;
void mouseEntered(int x, int y) override;
void mouseExited(int x, int y) override;
void windowResized(int w, int h) override;
void dragEvent(ofDragInfo dragInfo) override;
void gotMessage(ofMessage msg) override;
//Attractors
void aizawaAtt();
void chuaAtt();
void halvorsenAtt();
void lorenzAtt();
void newtonLeipnikAtt();
float x, y, z;
float alpha; // α
float beta; // β
float camma; // γ
float delta; // δ
float epsilon; // ε
float zehta; // ζ
float rho; // ρ
float Gx;
float dt; // time
float scale;
vector pos;
// ofEasyCam camera;
};
#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup(){
ofBackground(0);
x = 0.01;
y = 0;
z = 0;
}
//--------------------------------------------------------------
void ofApp::update(){
pos.push_back(glm::vec3(x, y, z));
}
//--------------------------------------------------------------
void ofApp::draw(){
// camera.begin();
ofTranslate(ofGetWidth()/2, ofGetHeight()/2);
//Attractors
aizawaAtt();
// chuaAtt();
// halvorsenAtt();
// lorenzAtt();
// newtonLeipnikAtt();
update();
ofSetColor(255);
ofNoFill();
ofBeginShape();
for(glm::vec3 v : pos){
ofVertex(v.x * scale, v.y * scale, v.z * scale);
}
ofEndShape();
// camera.end();
}
//--------------------------------------------------------------
void ofApp::aizawaAtt(){
alpha = 0.95; // α
beta = 0.7; // β
camma = 0.6; // γ
delta = 3.5; // δ
epsilon = 0.25; // ε
zehta = 0.1; // ρ
scale = 150.0;
dt = 0.01;
float dx = (z - beta) * x - delta * y;
float dy = delta * x + (z - beta) * y;
float dz = camma + alpha * z - pow(z,3) / 3 - (pow(x,2) + pow(y,2)) * (1 + epsilon * z) + zehta * z * pow(x,3);
x = x + dx * dt;
y = y + dy * dt;
z = z + dz * dt;
}
//--------------------------------------------------------------
void ofApp::chuaAtt(){
alpha = 15.6; // α
beta = 1.0; // β
camma = 25.58; // γ
delta = -1; // δ
epsilon = 0; // ε
Gx = epsilon*x + (delta + epsilon) * (abs(x + 1) - abs(x - 1));
scale = 60.0;
dt = 0.01;
float dx = alpha * (y - x - Gx);
float dy = beta * (x - y + z);
float dz = -(camma * y);
x = x + dx * dt;
y = y + dy * dt;
z = z + dz * dt;
}
//--------------------------------------------------------------
void ofApp::halvorsenAtt(){
alpha = 1.4; // α
scale = 25.0;
dt = 0.005;
float dx = -alpha*x -4*y -4*z - y*y;
float dy = -alpha*y -4*z -4*x - z*z;
float dz = -alpha*z -4*x -4*y - x*x;
x = x + dx * dt;
y = y + dy * dt;
z = z + dz * dt;
}
//--------------------------------------------------------------
void ofApp::lorenzAtt(){
beta = 8.0/3.0; // β
delta = 10; // δ
rho = 28; // ρ
scale = 7.0;
dt = 0.01;
float dx = (delta * (y - x));
float dy = (x * (rho - z) - y);
float dz = (x * y - beta * z);
x = x + dx * dt;
y = y + dy * dt;
z = z + dz * dt;
}
//--------------------------------------------------------------
void ofApp::newtonLeipnikAtt(){
alpha = 0.4; // α
beta = 0.175; // β
scale = 300.0;
dt = 0.01;
float dx = -alpha * x + y + 10 * y * z;
float dy = -x - 0.4 * y + 5 * x * z;
float dz = beta * z - 5 * x * y;
x = x + dx * dt;
y = y + dy * dt;
z = z + dz * dt;
}
The Strange Attractors
The Aizawa Attractor
Equations: 方程式
dx/dt = (z – β)x – δy
dy/dt = δx + (z – β)y
dz/dt = γ + αz – pow(z,3) / 3 – (pow(x,2) + pow(y,2))(1 + ε * z) + ρz pow(x,3)
Parameter: パラメーター
α = 0.95
β = 0.7
γ = 0.6
δ = 3.5
ε = 0.25
ρ = 0.1
dt = 0.01
void ofApp::aizawaAtt(){
alpha = 0.95; // α
beta = 0.7; // β
camma = 0.6; // γ
delta = 3.5; // δ
epsilon = 0.25; // ε
zehta = 0.1; // ρ
scale = 150.0;
dt = 0.01;
float dx = (z - beta) * x - delta * y;
float dy = delta * x + (z - beta) * y;
float dz = camma + alpha * z - pow(z,3) / 3 - (pow(x,2) + pow(y,2)) * (1 + epsilon * z) + zehta * z * pow(x,3);
x = x + dx * dt;
y = y + dy * dt;
z = z + dz * dt;
}
The Chua Attractor
Equations: 方程式
dx/dt = α(y – x – G(x))
dy/dt = β(x – y + z)
dz/dt = -γy
Parameter: パラメーター
α = 15.6
β = 1.0
γ = 25.58
δ = -1
ε = 0
G(x) = εx + (δ + ε)(abs(x + 1) – abs(x – 1))
dt = 0.01
void ofApp::chuaAtt(){
alpha = 15.6; // α
beta = 1.0; // β
camma = 25.58; // γ
delta = -1; // δ
epsilon = 0; // ε
Gx = epsilon*x + (delta + epsilon) * (abs(x + 1) - abs(x - 1));
scale = 60.0;
dt = 0.01;
float dx = alpha * (y - x - Gx);
float dy = beta * (x - y + z);
float dz = -(camma * y);
x = x + dx * dt;
y = y + dy * dt;
z = z + dz * dt;
}
The Halvorsen Attractor
Equations: 方程式
dx/dt = -αx – 4y – 4z – yy
dy/dt = -αy – 4z – 4x – zz
dz/dt = -αz – 4x – 4y – xx
Parameter: パラメーター
α = 1.4
dt = 0.005
void ofApp::halvorsenAtt(){
alpha = 1.4; // α
scale = 25.0;
dt = 0.005;
float dx = -alpha*x -4*y -4*z - y*y;
float dy = -alpha*y -4*z -4*x - z*z;
float dz = -alpha*z -4*x -4*y - x*x;
x = x + dx * dt;
y = y + dy * dt;
z = z + dz * dt;
}
The Lorenz Attractor
Equations: 方程式
dx/dt = δ(y – x)
dy/dt = x(ρ – z) – y
dz/dt = xy – βz
Parameter: パラメーター
β = 8.0/3.0
δ = 10
ρ = 28
dt = 0.01
void ofApp::lorenzAtt(){
beta = 8.0/3.0; // β
delta = 10; // δ
rho = 28; // ρ
scale = 7.0;
dt = 0.01;
float dx = (delta * (y - x));
float dy = (x * (rho - z) - y);
float dz = (x * y - beta * z);
x = x + dx * dt;
y = y + dy * dt;
z = z + dz * dt;
}
The Newton – Lepnik Attractor
Equations: 方程式
dx/dt = -αx + y + 10yz
dy/dt = -x – 0.4y + 5xz
dz/dt = βz – 5xy
Parameter: パラメーター
α = 0.4
β = 0.175
dt = 0.01
void ofApp::newtonLeipnikAtt(){
alpha = 0.4; // α
beta = 0.175; // β
scale = 300.0;
dt = 0.01;
float dx = -alpha * x + y + 10 * y * z;
float dy = -x - 0.4 * y + 5 * x * z;
float dz = beta * z - 5 * x * y;
x = x + dx * dt;
y = y + dy * dt;
z = z + dz * dt;
}
barbe_generative_library
Grid systems in graphic design – Josef Müller-Brockmann
グリッドシステムとは。
グリッドシステムとは、連続した行と列に基づいてテキストやイメージを配置しデザインの整合性と視認性を高めるレイアウト手法です。元々は印刷レイアウトのために考えられたものですが、現在ではWebデザインなど、あらゆるデザイン設計において利用され、ProcessingやP5jsなど2Dでグラフィックを制作する場合にも、このグリッドシステムから学べる事は多い。
ーーーーー
► 『Grid systems in graphic design 』(Josef Müller-Brockmann)
1981年に刊行された完全日本語訳版。
初版/ 2019.11.9
ページ数/184ページ
出版社/ボーンデジタル
言語/日本語
ーーーーー
BGD_SOUNDS (barbe_generative_diary SOUNDS)
BGD_SOUNDS では、Sound Visualization(音の視覚化)実験に使用する目的でストックされた、多くのフィールドレコーディング音源の共有と販売を始めています。ほぼすべての音源は、192kHz-32bit floatで録音され、ロイヤリティーフリーにて自由に使用できます。定期的にリリースされますので、音源が必要な方はフォローにて最新情報をチェックしてみてください。