Skip to content

Instantly share code, notes, and snippets.

@bastos
Created December 24, 2010 14:46
Show Gist options
  • Save bastos/754305 to your computer and use it in GitHub Desktop.
Save bastos/754305 to your computer and use it in GitHub Desktop.
meatballs.js
// http://www.student.cs.uwaterloo.ca/~swhitmor/article_metaballs.html
var isofield_width;
var isofield_height;
var isofield_max;
var num_metaballs;
var min_threshold;
var max_threshold;
var isofield = [];// [][]
var metaballs = [];
var _canvas;
var ctx;
var Metaball = function(x, y, radius) {
this.x = x;
this.y = y;
this.radius = radius;
return this;
};
function equation(m, x, y) {
var _x = m.x;
var _y = m.y;
var _radius = m.radius;
return (_radius / Math.sqrt((x - _x) * (x - _x) + (y - _y) * (y - _y)));
}
function calculateIsofield() {
isofield_max = 0;
// Calcula a contribuição de cada metaball para a grade
for (var x = 0; x < isofield_width; x++) {
for (var y = 0; y < isofield_height; y++) {
var sum = 0;
for (var i = 0; i < num_metaballs; i++) {
sum += equation(metaballs[i], x, y);
}
if (typeof isofield[x] === 'undefined') {
isofield[x] = [];
}
isofield[x][y] = sum;
if (sum > isofield_max) {
isofield_max = sum;
}
}
}
}
function setup() {
min_threshold = 0.85;
max_threshold = 1.05;
metaballs = [];
metaballs[0] = Metaball(50.0, 50.0, 10.0);
metaballs[1] = Metaball(1.0, 50.0, 3.0);
metaballs[2] = Metaball(10.0, 3.0, 2.0);
num_metaballs = 3;
isofield_width = 100;
isofield_height = 100;
// isofield = new float[isofield_width][isofield_height];
calculateIsofield();
_canvas = document.getElementById('meatballsspace');
$(_canvas).attr({width: (isofield_width * 8), height: (isofield_height * 8)});
ctx = _canvas.getContext('2d');
ctx.fillRect(50, 25, (isofield_width * 8), (isofield_height * 8));
loop();
}
function loop() {
draw();
}
function draw() {
//animateMetaballs();
calculateIsofield();
//while(true) {
// drawMetaballs(); //Coloque isso e loop infinito
//}
}
function mousePressed() {
var cx;
var cy;
if (mouseX == 0) {
cx = 0;
} else {
cx = mouseX / 8;
}
if (mouseY == 0) {
cy = 0;
} else {
cy = mouseY / 8;
}
metaballs[1].x = cx;
metaballs[1].y = cy;
redraw();
}
function animateMetaballs() {
// x = metaballs[1].x;
// if (x > isofield_width + metaballs[1].radius) {
// x = 0;
// }
// else {
// x+=1;
// }
//
// metaballs[1].x = x;
}
function drawMetaballs() {
console.log("Draw meatballs");
var intensity;
var value;
for (var x = 0, ix = 0; x < isofield_width; ix += 8, x++) {
console.log("Draw meatballs 1");
for (var y = 0, iy = 0; y < isofield_height; iy += 8, y++) {
console.log("Draw meatballs 2");
// Calcula influencia de cada metaball no pixel
intensity = isofield[x][y];
value = Math.min(intensity*255, 255);
// if (intensity >= min_threshold && intensity <= max_threshold) {
// value = Math.min(intensity * 255, 255);
// } else {
// value = 0;
// }
// Desenha o pixel
ctx.stroke(value);
ctx.fill(value);
ctx.rect(ix, iy, 8, 8);
}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>index</title>
<script type="text/javascript" src="meatballs.js"></script>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
setup();
});
</script>
</head>
<body>
<canvas width="500" height="500" id="meatballsspace"></canvas>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment