Skip to content

Instantly share code, notes, and snippets.

@thole
Last active October 20, 2018 07:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thole/6174d17f932b1521c9a1 to your computer and use it in GitHub Desktop.
Save thole/6174d17f932b1521c9a1 to your computer and use it in GitHub Desktop.
surounding box
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//www.goodboydigital.com/pixijs/bloom/pixi.min.js"></script>
<script>
var GrahamScan = {
execute : function(points) {
if (points.length < 3) {
return points;
}
var minimum = function(Q) {
Q.sort(function(a,b) {
return a.y - b.y;
});
return 0;
}
var distance = function(a, b) {
return (b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y);
}
var filter_equal_angles = function(p0, Q) {
for(var i=1; i < Q.length; i++) {
if (Q[i-1].polar == Q[i].polar) {
var d1 = distance(p0, Q[i-1]);
var d2 = distance(p0, Q[i]);
if (d2 > d1) {
Q.splice(i, 1);
} else {
Q.splice(i-1, 1);
}
}
}
}
var cartesian_angle = function(x, y) {
if (x > 0 && y > 0)
return Math.atan( y / x);
else if (x < 0 && y > 0)
return Math.atan(-x / y) + Math.PI / 2;
else if (x < 0 && y < 0)
return Math.atan( y / x) + Math.PI;
else if (x > 0 && y < 0)
return Math.atan(-x / y) + Math.PI / 2 + Math.PI;
else if (x == 0 && y > 0)
return Math.PI / 2;
else if (x < 0 && y == 0)
return Math.PI;
else if (x == 0 && y < 0)
return Math.PI / 2 + Math.PI;
else return 0;
}
var calculate_angle = function(p1, p2) {
return cartesian_angle(p2.x - p1.x, p2.y - p1.y)
}
var calculate_polar_angles = function(p0, Q) {
for(var i=0; i < Q.length; i++) {
Q[i].polar = calculate_angle(p0, Q[i]);
}
}
var ccw = function(p1, p2, p3) {
return (p2.x - p1.x)*(p3.y - p1.y) - (p2.y - p1.y)*(p3.x - p1.x);
}
var Q = points.slice(); // Make copy
var min = minimum(Q);
var p0 = Q[min];
Q.splice(min, 1);
calculate_polar_angles(p0, Q);
Q.sort(function(a,b) {
return a.polar - b.polar;
});
filter_equal_angles(p0, Q);
var S = [];
S.push(p0);
S.push(Q[0]);
S.push(Q[1]);
for(var i=2; i < Q.length; ++i) {
var pi = Q[i];
while(ccw(S[S.length - 2], S[S.length - 1], pi) <= 0) {
S.pop();
}
S.push(pi);
}
return S;
}
};
var width = 960,
height = 500;
var resolution=window.devicePixelRatio;
var renderer = PIXI.autoDetectRenderer(width, height,{'resolution':resolution,autoResize:true,antialias:true,backgroundColor : 0x000000})
document.body.appendChild(renderer.view);
var stage = new PIXI.Container();
var nodes = d3.range(50).map(function() { return {x:Math.random()*width,y:Math.random()*height,speed: Math.random() * 2}; });
var graphic = new PIXI.Graphics();
stage.addChild(graphic)
animate();
function animate() {
nodes.forEach(function(d){
d.y = (d.y + d.speed) % height;
})
var e = GrahamScan.execute(nodes);
graphic.clear();
nodes.forEach(function(d){
graphic.lineStyle(0);
graphic.beginFill(e.indexOf(d) < 0 ? 0x000000 : 0xFF0000, 0.75);
graphic.drawCircle(d.x, d.y, 3);
graphic.endFill();
stage.addChild(graphic)
});
var starPoint = e.pop()
graphic.lineStyle(1, 0xFF0000, 2);
graphic.moveTo(starPoint.x,starPoint.y);
e.forEach(function(d){
graphic.lineTo(d.x, d.y);
});
graphic.lineTo(starPoint.x,starPoint.y);
graphic.endFill();
renderer.render(stage);
requestAnimationFrame( animate );
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment