Skip to content

Instantly share code, notes, and snippets.

@jo
Created March 29, 2012 12:17
Show Gist options
  • Save jo/2236714 to your computer and use it in GitHub Desktop.
Save jo/2236714 to your computer and use it in GitHub Desktop.
Order points geometrically to build a line
// Build a line from unsorted points,
// in a way that the length of the line is minimal.
var pointsToLine = (function() {
// distance between two points
function dist(p1, p2) {
return Math.sqrt(Math.pow(p1[0] - p2[0], 2) + Math.pow(p1[1] - p2[1], 2));
}
// find insertion index
function findIdx(line, point) {
var idx = 0,
i, dx, min;
if (line.length === 0) {
return 0;
}
// check alignment
if (line.length === 1) {
if (dist(origin, point) > dist(origin, line[0])) {
return 1;
} else {
return 0;
}
}
for (i = 0; i < line.length; i++) {
dx = dist(point, line[i]);
if (!min || dx <= min) {
min = dx;
idx = i;
}
}
// check before
if (idx > 0 && dist(line[idx - 1], line[idx]) < dist(line[idx - 1], point)) {
idx++;
} else {
// check after
if (idx < (line.length - 1) && dist(line[idx + 1], line[idx]) > dist(line[idx + 1], point)) {
idx++;
}
}
return idx;
}
// insert points into line
return function(points, line) {
line || (line = []);
points.forEach(function(point) {
line.splice(findIdx(line, point), 0, point);
});
return line;
};
}();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment