Skip to content

Instantly share code, notes, and snippets.

@okaq
Created May 17, 2014 02:01
Show Gist options
  • Save okaq/eb6819f620c557084d4d to your computer and use it in GitHub Desktop.
Save okaq/eb6819f620c557084d4d to your computer and use it in GitHub Desktop.
Random Fields
<!DOCTYPE html>
<html lang="en">
<head id="zeta">
<title>okaq</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=1920,height=1080,initial-scale=1" />
<link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAMklEQVR4nGLhfLGBgZaAiaamj1owasGoBaMWjFowasGoBaMWjFowasGoBVQEgAAAAP//cfIB5JfeIs4AAAAASUVORK5CYII=" />
<style type="text/css">
html,body{width:1920px;height:1080px;background-color:rgba(4,8,16,1.0);}
</style>
<script type="text/javascript">
// ok
console.log("hello vobu boru!");
// async load
(function() {
var async_load = function() {
g.init();
}
window.addEventListener("load", async_load, false);
})();
// game
var g = {
"init": function() {
console.log("g init");
d.init();
s.init();
r.render(s.root);
f.init();
r.nodes();
}
}
// dom
var d = {
"init": function() {
// s.init();
d.alpha = document.getElementById("alpha");
d.beta = {};
d.beta.can = document.createElement("canvas");
d.beta.con = d.beta.can.getContext("2d");
console.log(d.beta.can, d.beta.con);
d.beta.can.width = 786;
d.beta.can.height = 786;
d.beta.can.style.position = "absolute";
d.beta.can.style.top = "64px";
d.beta.can.style.left = "64px";
d.alpha.appendChild(d.beta.can);
d.gamma = {};
d.gamma.can = document.createElement("canvas");
d.gamma.con = d.gamma.can.getContext("2d");
d.gamma.can.width = 786;
d.gamma.can.height = 786;
d.gamma.can.style.position = "absolute";
d.gamma.can.style.top = "64px";
d.gamma.can.style.left = "920px";
d.alpha.appendChild(d.gamma.can);
}
}
// render
var r = {
"render": function(r0) {
// console.log(r0.b.length);
if (r0.b.length != 0) {
for (var i = 0; i < r0.b.length; i++) {
r.render(r0.b[i]);
}
} else {
// console.log(r0);
// only leaves should be rendered
// for now render all
d.beta.con.fillStyle = r0.c.rgba; // rgba.rand();
/* grad */
var g0 = d.beta.con.createLinearGradient(r0.x, r0.y, r0.x, r0.y + r0.h);
var d0 = 1.0 / r0.c.back.length;
var off = 0.0;
for (var i = 0; i < r0.c.back.length; i++) {
g0.addColorStop(off, r0.c.back[i]);
off = off + d0;
}
d.beta.con.fillStyle = g0;
d.beta.con.fillRect(r0.x, r0.y, r0.w, r0.h);
// circle
var g1 = d.beta.con.createLinearGradient(r0.x, r0.y, r0.x, r0.y + r0.h);
var d1 = 1.0 / r0.c.fore.length;
var off2 = 0.0;
for (var i = 0; i < r0.c.fore.length; i++) {
g1.addColorStop(off2, r0.c.fore[i]);
off2 = off2 + d1;
}
d.beta.con.fillStyle = g1;
// d.beta.con.fillStyle = rgba.rand();
d.beta.con.beginPath();
d.beta.con.arc(r0.x + (r0.w / 2), r0.y + (r0.h / 2), (r0.w / 4), 0, Math.PI * 2, true);
d.beta.con.fill();
d.beta.con.closePath();
}
},
"nodes": function() {
d.gamma.con.fillStyle = rgba.rand();
d.gamma.con.fillRect(0,0,d.gamma.can.width,d.gamma.can.height);
for (node in f.g) {
// console.trace(node);
}
for (var y = 0; y < f.y; y++) {
for (var x = 0; x < f.x; x++) {
var i0 = y * f.y + x;
var i1 = i0 * 4;
var i2 = i1 + 4;
var sub = f.pix.subarray(i1, i2);
d.gamma.con.fillStyle = rgba.css2(sub);
d.gamma.con.fillRect(x*f.w,y*f.h,f.w,f.h);
}
}
}
}
// struct
var s = {
"init": function() {
s.depth = 3;
s.root = new rect();
s.branch(s.root);
// for (var i = 0; i < 1; i++) {
// recurse
// s.branch(s.root);
// }
},
"branch": function(r0) {
var f0 = Math.random();
if (r0.depth >= s.depth || f0 >= 0.5) {
return;
}
var w1 = r0.w / 2;
var h1 = r0.h / 2;
var r1 = new rect();
r1.x = r0.x;
r1.y = r0.y;
r1.w = w1;
r1.h = h1;
r1.depth = r0.depth + 1;
r0.b.push(r1);
var r2 = new rect();
r2.x = r0.x + w1;
r2.y = r0.y;
r2.w = w1;
r2.h = h1;
r2.depth = r0.depth + 1;
r0.b.push(r2);
var r3 = new rect();
r3.x = r0.x;
r3.y = r0.y + h1;
r3.w = w1;
r3.h = h1;
r3.depth = r0.depth + 1;
r0.b.push(r3);
var r4 = new rect();
r4.x = r0.x + w1;
r4.y = r0.y + h1;
r4.w = w1;
r4.h = h1;
r4.depth = r0.depth + 1;
r0.b.push(r4);
for (var i = 0; i < r0.b.length; i++) {
s.branch(r0.b[i]);
}
}
}
// rect class
var rect = function() {
this.x = 0;
this.y = 0;
this.w = d.beta.can.width;
this.h = d.beta.can.height;
this.b = []; // branch - up to 4 nodes
this.c = new circle();
this.c.rgba = rgba.rand(1.0);
this.c.back = rgba.list(8);
this.c.fore = rgba.list(8);
this.depth = 0;
}
// circle class
var circle = function() {
// margins
// dimension
// color / style
this.rgba = rgba.rand();
}
// rect tree class
var tree = {
"init": function() {
tree.g = [];
},
"add": function() {
}
}
// color (rgba)
var rgba = {
"rand": function(a1) {
var r0 = rgba.rb();
var g0 = rgba.rb();
var b0 = rgba.rb();
var a0 = Math.random() || a1;
var c0 = [r0,g0,b0,a0];
return rgba.css(c0);
},
"css": function(c0) {
// alpha channel range test
if (c0[3] > 1.0) {
c0[3] = c0[3] / 255;
}
var s0 = c0.join(",");
var s1 = "rgba(" + s0 + ")";
return s1;
},
"css2": function(sub) {
// Uint8Array[4]
var s0 = "rgba(";
for (var i = 0; i < sub.length; i++) {
/*
// var i1 = 0;
if ((i % 3) == 0) {
var i1 = sub[i] / 255.0;
s0 += parseInt(i1);
} else {
var i1 = sub[i];
s0 += parseInt(i1);
}
// s0 += parseInt(i1);
*/
if (i < sub.length - 1) {
// s0 += parseInt(sub[i]);
s0 += sub[i].toString();
s0 += ",";
} else {
// alpha channel
s0 += (sub[i]/255.0).toString();
}
}
s0 += ")";
return s0;
},
"rb": function() {
// rand byte
return (Math.random() * 255) >>> 0;
},
"list": function(n0) {
var c0 = [];
for (var i = 0; i < n0; i++) {
c0[i] = rgba.rand();
}
return c0;
}
}
// random field
var f = {
"init": function() {
// graph : {} // {"A": {val:6,adj:["B", "C"]}}
// node : {} adj : [indicies]
f.g = {}
f.g["A"] = new node();
f.g["B"] = new node();
f.stride = 8;
f.w = (d.gamma.can.width / f.stride) >>> 0;
f.h = (d.gamma.can.height / f.stride) >>> 0;
f.pix = f.field(f.stride, f.stride);
// console.log(f.pix);
f.state = {};
// a "path" is a seq (array) of points
// the "field" is color encoded to denote UST, direction, terminus
// path loops can be culled upon finding goal
f.x = 64;
f.y = 64;
f.w = (d.gamma.can.width / f.x) >>> 0;
f.h = (d.gamma.can.height / f.y) >>> 0;
f.pix = f.field(f.x, f.y);
f.trials = 100;
f.sum = 0;
for (var i = 0; i < f.trials; i++) {
f.start = new pt(f.x, f.y);
f.goal = new pt(f.x, f.y);
// console.log(f.start, f.goal);
f.path = [f.start];
f.step();
f.sum += f.path.length;
}
console.log(f.sum/f.trials);
},
"step": function() {
// iterate markov process
// f.path = [f.start];
while (true) {
var p0 = f.path[f.path.length-1];
if (p0.x == f.goal.x && p0.y == f.goal.y) {
break;
}
var p1 = p0.rw();
if (p1.x < 0) {
p1.x = 0;
}
if (p1.x > f.x) {
p1.x = f.x;
}
if (p1.y < 0) {
p1.y = 0;
}
if (p1.y > f.y) {
p1.y = f.y;
}
if (p1.x == p0.x && p0.y == p1.y) {
continue;
} else {
f.path.push(p1);
}
}
// console.log(f.path);
},
"field": function(x0, y0) {
// rgba per block
// stride length to determine w,h
// color encoding to determine start,stop,visited,direction
// member of UST (uniform spanning tree)
// current start node
// color encoding set/get methods
// init to red
var l0 = x0 * y0;
var l1 = l0 * 4;
var a0 = new Uint8Array(l1);
for (var i = 0; i < l0; i++) {
var i1 = i * 4;
a0[i1] = (Math.random()*255) >>> 0;
a0[i1+1] = 0;
a0[i1+2] = 0;
a0[i1+3] = (Math.random()*255) >>> 0;
}
// return new Uint8Array(x0*y0);
return a0;
}
}
var node = function() {
this.val = 0;
this.adj = [];
}
var pt = function(x0, y0) {
// this.x = x0 || 0;
// this.y = y0 || 0;
this.x = (Math.random() * x0) >>> 0;
this.y = (Math.random() * y0) >>> 0;
this.rw = function() {
var p0 = new pt(0,0);
p0.x = this.x;
p0.y = this.y;
var r0 = Math.random();
if (r0 < 0.25) {
p0.x -= 1;
return p0;
}
if (r0 >= 0.25 && r0 < 0.5) {
p0.x += 1;
return p0;
}
if (r0 >= 0.5 && r0 < 0.75) {
p0.y -= 1;
return p0;
}
if (r0 >= 0.75) {
p0.y += 1;
return p0;
}
}
}
</script>
</head>
<body id="alpha">
</body>
</html>
<!--
circles
RMF vector draw
-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment