Last active
October 20, 2018 07:21
-
-
Save thole/6174d17f932b1521c9a1 to your computer and use it in GitHub Desktop.
surounding box
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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