Skip to content

Instantly share code, notes, and snippets.

@bycoffe
Created May 14, 2013 13:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save bycoffe/5575904 to your computer and use it in GitHub Desktop.
Save bycoffe/5575904 to your computer and use it in GitHub Desktop.
Point-in-polygon
<!doctype html>
<meta charset="utf-8">
<html>
<head>
<style type="text/css">
#canvas {
width: 800px;
height: 400px;
border: 1px solid #666;
}
path {
fill: none;
stroke-width: 1px;
stroke: #666;
}
circle {
fill: steelblue;
}
circle.selected {
fill: #ff0000;
}
</style>
</head>
<body>
<div id="canvas"></div>
<span id="clear">[clear]</span>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
;(function() {
var copy,
coords = [],
width = 800,
height = 400,
margin = 50,
line = d3.svg.line(),
dragStart = function() {
coords = [];
g.selectAll("path").remove();
},
drawPath = function(terminator) {
g.append("path").attr({
d: line(coords)
});
if (terminator) {
g.select("#terminator").remove();
g.append("path").attr({
id: "terminator",
d: line([coords[0], coords[coords.length-1]])
});
}
},
dragMove = function() {
dot.classed("selected", false);
coords.push(d3.mouse(this));
dot.each(function(d, i) {
point = [d3.select(this).attr("cx"), d3.select(this).attr("cy")];
if (pointInPolygon(point, coords)) {
d3.select(this).classed("selected", true)
}
});
drawPath();
},
dragEnd = function() {
drawPath(true);
}
drag = d3.behavior.drag()
.on("dragstart", dragStart)
.on("drag", dragMove)
.on("dragend", dragEnd),
// from https://github.com/substack/point-in-polygon
pointInPolygon = function (point, vs) {
// ray-casting algorithm based on
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
var xi, xj, i, intersect,
x = point[0],
y = point[1],
inside = false;
for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
xi = vs[i][0],
yi = vs[i][1],
xj = vs[j][0],
yj = vs[j][1],
intersect = ((yi > y) != (yj > y))
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
},
svg = d3.select("#canvas").append("svg").attr({
width: width,
height: height
}).call(drag),
g = svg.append("g"),
randPoint = function(min, max) {
return Math.floor(Math.random() * (max-min)) + min;
},
points = function(numPoints) {
var data = [];
for (i=0; i < numPoints; i++) {
data.push({x: randPoint(margin, width-margin), y: randPoint(margin, height-margin)});
}
return data;
},
dot = g.selectAll("circle")
.data(points(1000))
.enter().append("circle")
.attr({
cx: function(d, i) {
return d.x;
},
cy: function(d, i) {
return d.y;
},
r: 3
});
d3.select("#clear").on("click", function() {
dot.classed("selected", false);
dragStart();
})
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment