diff --git a/puredata/constellations/data/DejaVuSansMono.ttf b/puredata/constellations/data/DejaVuSansMono.ttf new file mode 100644 index 0000000..f578602 Binary files /dev/null and b/puredata/constellations/data/DejaVuSansMono.ttf differ diff --git a/puredata/constellations/planetary_ofelia.pd b/puredata/constellations/planetary_ofelia.pd new file mode 100644 index 0000000..89e626a --- /dev/null +++ b/puredata/constellations/planetary_ofelia.pd @@ -0,0 +1,166 @@ +#N canvas 603 89 568 730 12; +#X declare -path ofelia/abs; +#X obj 22 61 loadbang; +#X obj 22 111 ofWindow; +#X obj 189 416 ofDraw; +#X obj 126 36 declare -path ofelia/abs; +#X text 12 10 <<<; +#X text 532 10 >>>; +#X text 2 690 <<<; +#X text 522 690 >>>; +#X floatatom 221 518 5 0 0 0 delta - -; +#X obj 232 497 hsl 128 15 0 0.03 0 0 empty empty empty -2 -8 0 10 -262144 +-1 -1 0 1; +#X obj 140 473 loadbang; +#X msg 140 498 0.01; +#X obj 189 441 t b a; +#X obj 230 471 bng 15 250 50 0 \$0-ondraw empty s:0-ondraw 17 7 0 10 +-262144 -1 -1; +#N canvas 386 529 1053 366 graph 0; +#N canvas 0 50 450 250 (subpatch) 0; +#X array \$0-graph 1000 float 2; +#X coords 0 300 1000 -300 1000 140 1 0 0; +#X restore 19 18 graph; +#N canvas 487 89 613 270 probe 0; +#X obj 239 118 f; +#X obj 269 118 + 1; +#X obj 207 28 bng 15 250 50 0 empty \$0-ondraw r:0-ondraw 17 7 0 10 +-262144 -1 -1; +#X floatatom 239 168 5 0 0 0 - - -; +#X obj 123 192 tabwrite \$0-graph; +#X obj 239 143 mod 1000; +#X obj 207 58 t b b; +#X floatatom 53 102 5 0 0 0 - - -; +#X obj 53 33 loadbang; +#X msg 53 58 1; +#X obj 499 118 f; +#X obj 529 118 + 1; +#X obj 467 28 bng 15 250 50 0 empty \$0-ondraw r:0-ondraw 17 7 0 10 +-262144 -1 -1; +#X floatatom 499 168 5 0 0 0 - - -; +#X obj 499 143 mod 1000; +#X obj 467 58 t b b; +#X floatatom 313 102 5 0 0 0 - - -; +#X obj 313 33 loadbang; +#X obj 383 192 tabwrite \$0-graph1; +#X msg 313 58 2; +#X obj 53 128 ofelia f \; return _planets[a].pos.x; +#X obj 313 128 ofelia f \; return _planets[a].pos.x; +#X connect 0 0 1 0; +#X connect 0 0 5 0; +#X connect 1 0 0 1; +#X connect 2 0 6 0; +#X connect 3 0 4 1; +#X connect 5 0 3 0; +#X connect 6 0 7 0; +#X connect 6 1 0 0; +#X connect 7 0 20 0; +#X connect 8 0 9 0; +#X connect 9 0 7 0; +#X connect 10 0 11 0; +#X connect 10 0 14 0; +#X connect 11 0 10 1; +#X connect 12 0 15 0; +#X connect 13 0 18 1; +#X connect 14 0 13 0; +#X connect 15 0 16 0; +#X connect 15 1 10 0; +#X connect 16 0 21 0; +#X connect 17 0 19 0; +#X connect 19 0 16 0; +#X connect 20 0 4 0; +#X connect 21 0 18 0; +#X restore 959 -6 pd probe; +#N canvas 0 50 450 250 (subpatch) 0; +#X array \$0-graph1 1000 float 2; +#X coords 0 300 1000 -300 1000 140 1 0 0; +#X restore 19 188 graph; +#X restore 451 39 pd graph; +#X obj 316 293 osc~; +#X obj 316 318 dac~ 1; +#X floatatom 316 244 5 0 0 0 - - -; +#X obj 316 142 bng 15 250 50 0 empty \$0-ondraw r:0-ondraw 17 7 0 10 +-262144 -1 -1; +#X floatatom 316 162 5 0 0 0 - - -; +#X obj 316 268 + 300; +#X obj 418 117 loadbang; +#X msg 418 142 1; +#X obj 373 263 skip 50; +#X floatatom 397 294 5 0 0 0 - - -; +#X floatatom 397 343 5 0 0 0 - - -; +#X obj 397 318 + 300; +#X obj 22 161 ofSetup; +#X msg 22 186 bang; +#X msg 22 211 dir 0 data/DejaVuSansMono.ttf; +#X obj 22 236 pdcontrol; +#X obj 22 461 bng 15 250 50 0 empty empty setup_done 17 7 0 10 -262144 +-1 -1; +#X obj 22 331 t b b; +#X msg 54 356 read -c sim.lua; +#X obj 22 406 ofelia f \; ofSetFrameRate(30) \; return nil \;; +#X obj 22 261 ofelia f \; font = ofTrueTypeFont() \; font:load(a \, +8) \; return nil \;; +#X obj 22 381 ofelia f; +#X obj 221 542 ofelia f -c21 \; _ss.simulate(a[1]) \; ofPushMatrix() +\; ofTranslate(ofGetWidth()/2 \, ofGetHeight()/2) \; for i = 1 \, #_planets +do \; _planets[i].display() \; end \; ofPopMatrix() \;; +#X obj 316 188 ofelia f \; return _planets[a].pos.x; +#X msg 22 86 setPosition 500 0 \, setSize 600 600 \, create; +#N canvas 1 469 721 426 presets 0; +#X obj 20 25 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 +-1; +#X obj 20 82 ofelia f \; _planets = nil \; _planets = ofTable() \; +_planets[1] = _pl.new(100 \, -100 \, 0 \, 0 \, -93.9325 \, _col.blue +\, 10 \, false) \; _planets[2] = _pl.new(100 \, 50 \, -64.7584 \, -50.5328 +\, 46.9666 \, _col.yellow \, 10 \, false) \; _planets[3] = _pl.new(100 +\, 50 \, 64.7584 \, 50.5328 \, 46.9666 \, _col.green \, 10 \, false) +\;; +#X f 97; +#X obj 20 225 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 +-1; +#X obj 20 282 ofelia f \; _planets = nil \; _planets = ofTable() \; +_planets[1] = _pl.new(70 \, -50 \, 0 \, 1 \, 50 \, _col.blue \, 10 +\, false) \; _planets[2] = _pl.new(70 \, 50 \, 0 \, -1 \, -50 \, _col.yellow +\, 10 \, false) \;; +#X f 97; +#X obj 133 11 inlet; +#X connect 0 0 1 0; +#X connect 2 0 3 0; +#X connect 4 0 0 0; +#X restore 55 554 pd presets; +#X obj 22 661 print -n; +#X msg 22 636 setup done!; +#X connect 0 0 39 0; +#X connect 2 0 12 0; +#X connect 8 0 37 0; +#X connect 9 0 8 0; +#X connect 10 0 11 0; +#X connect 11 0 8 0; +#X connect 12 0 13 0; +#X connect 12 1 8 0; +#X connect 15 0 16 0; +#X connect 17 0 20 0; +#X connect 17 0 23 0; +#X connect 18 0 19 0; +#X connect 19 0 38 0; +#X connect 20 0 15 0; +#X connect 21 0 22 0; +#X connect 22 0 19 0; +#X connect 23 0 24 0; +#X connect 24 0 26 0; +#X connect 26 0 25 0; +#X connect 27 0 28 0; +#X connect 28 0 29 0; +#X connect 29 0 30 0; +#X connect 30 0 35 0; +#X connect 31 0 40 0; +#X connect 31 0 42 0; +#X connect 32 0 36 0; +#X connect 32 1 33 0; +#X connect 33 0 36 0; +#X connect 34 0 31 0; +#X connect 35 0 32 0; +#X connect 36 0 34 0; +#X connect 38 0 17 0; +#X connect 39 0 1 0; +#X connect 42 0 41 0; diff --git a/puredata/constellations/sim.lua b/puredata/constellations/sim.lua new file mode 100644 index 0000000..daa0fc3 --- /dev/null +++ b/puredata/constellations/sim.lua @@ -0,0 +1,198 @@ +-- color +_col = ofTable() +_col.red = 0xff0000 +_col.yellow = 0xffff00 +_col.green = 0x00ff00 +_col.cyan = 0x00ffff +_col.blue = 0x0000ff +_col.magenta = 0xff00ff +_col.navy = 0x000080 + +-- pl +_pl = ofTable() +function _pl.new(mass, x0, y0, vx0, vy0, hexcolor, r, fixed) + + local o = ofTable() + o.mass = mass + o.pos = ofVec2f(x0, y0) + o.vel = ofVec2f(vx0, vy0) + o.acc = ofVec2f(0, 0) + o.color = hexcolor + o.r = r + o.fixed = fixed + o.name = "newplanet" + + function o.display() + ofPushMatrix() + ofTranslate(o.pos.x, o.pos.y) + ofFill() + ofSetHexColor(o.color) + ofDrawCircle(0, 0, o.r) + ofSetHexColor(0xffffff) + ofDrawCircle(0, 0, 1) + ofSetHexColor(0xffffff) + local spd = math.sqrt(o.vel.x*o.vel.x + o.vel.y*o.vel.y) + local jerk = math.sqrt(o.acc.x*o.acc.x + o.acc.y*o.acc.y) + -- font:drawString(string.format("(%5.1f %5.1f %2.1f)", spd, jerk, o.mass), 12, 0) + -- font:drawString(string.format("%06x", o.color), 12, 0) + font:drawString(string.format("%.0f", o.mass), 12, 0) + ofPopMatrix() + end + + return o +end + +-- spaces +_spaces = ofTable() + +-- planets +_planets = ofTable() + +-- '10 randomized planets' (TESTING) +-- for i = 1, 10 do +-- _planets[i] = _pl.new(ofRandom(0.1, 1000), ofRandom(-ofGetWidth()/2, ofGetWidth()/2), ofRandom(-ofGetHeight()/2, ofGetHeight()/2), ofRandom(100), ofRandom(100), ofRandom(255), 10, false) +-- end + +-- 'sun_planet_moon' +-- _planets[1] = _pl.new(200, 0, 0, 0, 0, ofRandom(255), 10, true) +-- _planets[2] = _pl.new(10, 160, 0, 0, 240, ofRandom(255), 10, false) +-- _planets[3] = _pl.new(0.001, 140, 0, 0, 240, ofRandom(255), 10, false) + +-- 'sun_planet_comet' +-- _planets[1] = _pl.new(200, 0, 0, 0, 0, ofRandom(255), 10, true) +-- _planets[2] = _pl.new(1, 150, 0, 0, 120, ofRandom(255), 10, false) +-- _planets[3] = _pl.new(0.001, -220, 130, -15, -28, ofRandom(255), 10, false) + +-- 'double_double' +-- _planets[1] = _pl.new(60, -115, -3, 0, -155, 0xcccccc, 10, false) +-- _planets[2] = _pl.new(70, 102, 0, 1, 150, 0xcccc00, 10, false) +-- _planets[3] = _pl.new(55, -77, -2, -1, 42, 0xcc0000, 10, false) +-- _planets[4] = _pl.new(62, 135, 0, -1, -52, 0x00cccc, 10, false) + +-- broucke_henon +-- _planets[1] = _pl.new(100, -100, 0, 0, -93.9325, _col.blue, 10, false) +-- _planets[2] = _pl.new(100, 50, -64.7584, -50.5328, 46.96663, _col.yellow, 10, false) +-- _planets[3] = _pl.new(100, 50, 64.7584, 50.5328, 46.96663, _col.green, 10, false) + +-- 'pair' +_planets[1] = _pl.new(70, -50, 0, 1, 50, _col.blue, 10, false) +_planets[2] = _pl.new(70, 50, 0, -1, -50, _col.yellow, 10, false) + +-- sim +_sim = ofTable() +function _sim.new() + + local o = ofTable() + o.G = 10000 + -- o.MAX_DELTA = 0.03 + -- o.STEPS = 50 + o.BOUNDED = true + + function o.getPositions() + local pos = ofTable() + for i = 1, #_planets do + pos[i] = _planets[i].pos + end + return pos + end + + function o.getVelocities() + local vel = ofTable() + for i = 1, #_planets do + vel[i] = _planets[i].vel + end + return vel + end + + function o.calculateAcceleration(pos) + local acc = ofTable() + for i = 1, #_planets do + acc[i] = ofVec2f.zero() + end + for i = 1, #_planets do + for j = 1, i do + local d = pos[j] - pos[i] + local r2 = d.x*d.x + d.y*d.y + local d_norm = d / math.sqrt(d.x*d.x + d.y*d.y) + + local f = d_norm * o.G * _planets[i].mass * _planets[j].mass / r2 + + acc[i] = acc[i] + f / _planets[i].mass + acc[j] = acc[j] - f / _planets[j].mass + end + end + return acc + end + + function o.calculateVelocities(acc, dt) + local vel = ofTable() + for i = 1, #_planets do + vel[i] = _planets[i].vel + acc[i]*dt + end + return vel + end + + function o.calculatePositions(vel, dt) + local pos = ofTable() + for i = 1, #_planets do + pos[i] = _planets[i].pos + vel[i]*dt + end + return pos + end + + function o.updateVelocities(vel) + for i = 1, #_planets do + if _planets[i].fixed == false then + _planets[i].vel = vel[i] + if _planets[i].pos.x < -ofGetWidth()/2 or _planets[i].pos.x > ofGetWidth()/2 then + _planets[i].vel.x = -_planets[i].vel.x + end + if _planets[i].pos.y < -ofGetHeight()/2 or _planets[i].pos.y > ofGetHeight()/2 then + _planets[i].vel.y = -_planets[i].vel.y + end + end + end + end + + function o.updatePositions(pos) + for i = 1, #_planets do + if _planets[i].fixed == false then + _planets[i].pos = pos[i] + end + end + end + + function o.simulate(delta) + local v1 = o.getVelocities() + local p1 = o.getPositions() + local a1 = o.calculateAcceleration(p1) + + local v2 = o.calculateVelocities(a1, delta / 2) + local p2 = o.calculatePositions(v1, delta / 2) + local a2 = o.calculateAcceleration(p2) + + local v3 = o.calculateVelocities(a2, delta / 2) + local p3 = o.calculatePositions(v2, delta / 2) + local a3 = o.calculateAcceleration(p3) + + local v4 = o.calculateVelocities(a3, delta) + local p4 = o.calculatePositions(v3, delta) + local a4 = o.calculateAcceleration(p4) + + local acc = ofTable() + local vel = ofTable() + for i = 1, #_planets do + acc[i] = (a1[i] / 6 + a2[i] / 3 + a3[i] / 3 + a4[i] / 6) * 1 + vel[i] = (v1[i] / 6 + v2[i] / 3 + v3[i] / 3 + v4[i] / 6) * 1 + -- acc[i] = acc[i] - 1; + end + + o.updatePositions(o.calculatePositions(vel, delta)) + o.updateVelocities(o.calculateVelocities(acc, delta)) + end + + return o +end +_ss = _sim.new() + +return nil