- バウハウスの基礎理論である「基本形態と三原色の対応(イッテン/カンディンスキーの造形秩序)」をプログラミングの視点で読み解く
- 静的な図形配置に「質量(Mass)」と「バネの復元力(フックの法則)」を与え、カンティレバー構造のような弾性と動的均衡を再現する
- p5.jsの実装コードを通じて、デザイン理論を「触って動かせる数理モデル」へと翻訳するプロセスを体感する
どうもクリエイティブコーダーのワタタクです。
前回の『【バウハウスってなに?】ものづくりとアートをひとつにして、毎日の暮らしを便利で美しく変えた学校』という記事で、バウハウスとは「感覚まかせに『描く』のではなく、建築のように機能とルールから『設計する』表現」であると言語化しました。
今回はその実践編として、バウハウスの造形理論をp5.jsのコードと物理演算(数理モデル)へと翻訳してみます。単なる静止画のレイアウトではなく、マウスカーソルに反応して「しなり」ながら元の秩序へと戻る、動きのあるバウハウス構成(Kinetic Composition)を作っていきましょう。
この記事を書いた人


クリエイティブコーダー
「才能」ではなく「発見」で描く。文系・36歳からの上達ログ。
- ゼロから独学でクリエイティブコーディングに挑戦し、以下の実績を達成
- 開始1年8ヶ月目までに公募6つに挑戦し、3つ入選(勝率50%)
- KITTE大阪の18メートルあるAxCROSS大型スクリーン
- 虎ノ門ヒルズステーションタワーB2F TOKYO NODE エントランスサイネージで展示
- UN:O(東京大手町)にある会員限定のサテライトオフィスにて2作品選出・常設展示
- 開始1年8ヶ月目までに公募6つに挑戦し、3つ入選(勝率50%)
- 開始1年9ヶ月目に、虎ノ門ヒルズ49階、地上250mのインフィニティプールへ作品提供・展示
視覚的イメージと造形秩序(イッテン的形態・色彩の対比)
バウハウスの造形教育、とりわけヨハネス・イッテンの予備課程(Vorkurs)が提示した本質は、「対比(コントラスト)の極大化によるエネルギーの可視化」です。
画面構成における造形秩序として、今回は以下の3つの要素を基軸に置きます。
基本形態と色彩の不可分な対応(イッテン/カンディンスキー的照応)
- 正方形(Square) / 赤(Red): 重力、静止、物質性、堅牢な大地性。水平・垂直の直交軸を象徴します。
- 三角形(Triangle) / 黄(Yellow): 運動、鋭利、能動性、空間を切り裂く放射のベクトルを象徴します。
- 円(Circle) / 青(Blue): 精神性、浮遊、連続性、中心に向かって凝集する求心力を象徴します。
動的均衡(Dynamic Equilibrium)と極性対比
シンメトリー(左右対称)による平穏な静止ではなく、サイズの異なる図形や非対称なグリッドの分割線によって生じる「視覚的な重心の引き合い(張力:Tension)」を画面に生み出します。
また、無彩色(オフホワイトの地と漆黒のライン)と鮮烈な三原色の明暗対比をパラメータとして設定し、静的な配置ではなく動的なリズムを構築します。
コード・物理挙動への落とし込み(バネ運動・境界線の数理)
これらの造形秩序をアルゴリズムとして知覚化するために、以下の数理モデルを組み合わせます。
減衰調和振動子(Damped Harmonic Oscillator / Spring Physics)
バウハウスの家具に見られるスチールパイプのしなり(カンティレバー構造)のような「弾性」を再現するため、マウスインタラクションと定位置への帰還にフックの法則を適用します。
F = -kx – cv
図形が硬直した静物ではなく、外力(マウスの接近)に対して優雅にしなり、減衰しながら元の厳密な建築的秩序へと回帰する挙動をシミュレートします。
空間の境界とカラーマッピングの考え方
今回のプロトタイプはp5.jsの2D描画機能で直感的に動かせる形に落とし込んでいますが、さらにピクセル単位(GLSLのフラグメントシェーダー等)へ発展させる場合は、符号付き距離場(Signed Distance Functions: SDF)を用いて図形同士の境界線を数学的に定義したり、中間色を排した厳密な閾値処理で明暗対比を定着させたりと、数理的な拡張も自在に行えます。
実装プロトタイプ(p5.jsコードと解説)
以下は、p5.jsを用いて「正方形(赤)」「三角形(黄)」「円(青)」の三原形態と三原色、そしてそれらを結ぶ「張力(Spring Physics)」の動的均衡をリアルタイムに描写するコードです。
マウスを動かすと、それぞれの図形が持つ「質量」に応じた弾性で逃げ、また元の秩序へと戻ろうとします。


/**
* Bauhaus Kinetic Composition: Form, Color, and Dynamic Tension
* Inspired by Johannes Itten's preliminary course principles.
*/
let forms = [];
function setup() {
createCanvas(windowWidth, windowHeight);
pixelDensity(displayDensity());
rectMode(CENTER);
noStroke();
// 3つの基本形態をイッテンの思想に基づいて初期化
// 赤・正方形(重厚・安定)、黄・三角形(鋭角・活動)、青・円(流動・求心)
forms.push(new BauhausForm('square', color(215, 38, 30), width * 0.3, height * 0.6, 140, 2.2));
forms.push(new BauhausForm('triangle', color(245, 197, 24), width * 0.65, height * 0.35, 160, 1.2));
forms.push(new BauhausForm('circle', color(18, 78, 137), width * 0.45, height * 0.45, 110, 0.7));
}
function draw() {
// バウハウスの紙面を想起させる、わずかに温かみのある無彩色の地(オフホワイト)
background(242, 239, 233);
// 構造線(グリッドと張力の視覚化)
drawStructuralGrid();
// 各形態の更新
for (let i = 0; i < forms.length; i++) {
forms[i].update();
}
// 形態同士を結ぶ緊張線の描画(カンディンスキー的結合)
drawTensionLines();
// 形態本体のレンダリング
for (let i = 0; i < forms.length; i++) {
forms[i].display();
}
}
// 構造的な基準線を描き、空間に建築的な秩序を与える
function drawStructuralGrid() {
stroke(210, 205, 195);
strokeWeight(1);
// 水平・垂直の分割線
line(width * 0.1, height * 0.6, width * 0.9, height * 0.6);
line(width * 0.65, height * 0.1, width * 0.65, height * 0.9);
// 漆黒(Black)のアクセントバー:空間の引き締め
fill(20, 20, 20);
noStroke();
rect(width * 0.5, height * 0.92, width * 0.8, 4);
}
// 形態間の相互作用を示す張力線
function drawTensionLines() {
stroke(40, 40, 40, 180);
strokeWeight(1.5);
for (let i = 0; i < forms.length; i++) {
for (let j = i + 1; j < forms.length; j++) {
drawingContext.setLineDash([4, 6]); // 破線による緊張の表現
line(forms[i].pos.x, forms[i].pos.y, forms[j].pos.x, forms[j].pos.y);
drawingContext.setLineDash([]);
}
}
}
class BauhausForm {
constructor(type, col, x, y, size, mass) {
this.type = type;
this.color = col;
this.anchor = createVector(x, y);
this.pos = createVector(x, y);
this.vel = createVector(0, 0);
this.acc = createVector(0, 0);
this.size = size;
this.mass = mass; // 質量:重い形態ほどゆっくりと動く
this.k = 0.04; // バネ定数
this.damp = 0.86; // 減衰係数
this.angle = 0;
}
update() {
// マウスカーソルとの距離による斥力(空間の歪み)
let mouse = createVector(mouseX, mouseY);
let dir = p5.Vector.sub(this.pos, mouse);
let d = dir.mag();
if (d < 250 && d > 0.001) {
dir.normalize();
let force = (250 - d) * 0.08;
this.applyForce(dir.mult(force));
}
// アンカー位置(定位置)へ引き戻すバネの復元力:F = -kx
let springForce = p5.Vector.sub(this.anchor, this.pos).mult(this.k);
this.applyForce(springForce);
// 物理挙動の積分
this.vel.add(this.acc);
this.vel.mult(this.damp);
this.pos.add(this.vel);
this.acc.mult(0);
// 三角形のみ速度に応じて微小な回転トルクを生じさせる(鋭利な運動性の表現)
if (this.type === 'triangle') {
this.angle = this.vel.x * 0.03;
}
}
applyForce(force) {
let f = p5.Vector.div(force, this.mass);
this.acc.add(f);
}
display() {
push();
translate(this.pos.x, this.pos.y);
rotate(this.angle);
noStroke();
fill(this.color);
if (this.type === 'circle') {
circle(0, 0, this.size);
// 中心の幾何学的焦点
fill(242, 239, 233);
circle(0, 0, 8);
} else if (this.type === 'square') {
rect(0, 0, this.size, this.size);
// 内側の線条対比
stroke(20, 20, 20);
strokeWeight(2);
line(-this.size * 0.3, -this.size * 0.3, this.size * 0.3, this.size * 0.3);
} else if (this.type === 'triangle') {
let r = this.size * 0.6;
triangle(
0, -r,
r * cos(PI / 6), r * sin(PI / 6),
-r * cos(PI / 6), r * sin(PI / 6)
);
}
pop();
}
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}パラメータ調整の要点
単なる図形のアニメーションではなく、バウハウスの造形思想をコードに宿らせるために、以下の3つのパラメータを設計しています。
- 質量係数(
this.mass)による性格付け- 赤の正方形は
2.2と最も重く設定し、重力と静止の性格を与える。 - 一方、青の円は
0.7と軽く設定し、マウスの動きに敏感に浮遊することで、形態論における「精神性・軽快さ」を物理パラメータのように。
- 赤の正方形は
- バネ定数(
this.k)と減衰(this.damp)による「しなり」- 単なる定位置への吸着ではなく、バウハウスの鋼管家具(カンティレバー構造)のような適度なしなりと反発を感じさせるため、
damp = 0.86の微振動を残すアンダーダンプ状態のように。
- 単なる定位置への吸着ではなく、バウハウスの鋼管家具(カンティレバー構造)のような適度なしなりと反発を感じさせるため、
- 破線の張力線(
setLineDash)による力の場の可視化- カンディンスキーの著書『点と線から面へ』に示される「見えない力の場」を可視化するため、図形同士が離れるほど破線が伸び、画面全体の緊張度(Tension)を直感的に把握できるようにしています。
まとめ:デザイン理論は「動かせる数理」になる
歴史や美術の教科書で学ぶ「形と色のルール」も、こうして物理演算や座標のパラメータに翻訳してみると、一気に生きた実験場へと変わります。
ぜひ this.mass(質量)や this.k(バネの硬さ)の値を書き換えて、自分だけの「動的均衡」を探ってみてください。


それでは今日もレッツワクワクコーディング。

