pseudocode.js | |
---|---|
preprocess(polygons)Usage:
Arguments:
var polygons = [ [{ x: 5, y:4 }, {x: 10, y: 4}, {x: 1, y: 1}], [{ x: 5, y:4 }, {x: 10, y: 4}, {x: 15, y: 10}] ]; Returns:
| var preprocess = function(polygons){ |
| var verticesByLocation = {}
var location = function(vertex){
return vertex.x+"_"+vertex.y;
}; |
| var vertices = []; |
Algorithm
| var polygonId = 0;
_(polygons).each(function(polygon){ |
| var vertexId = 0; |
| var verticesOfPolygon = vertices[polygonId++] = [];
_(polygon).each(function(_vertex){ |
| var vertexLocation = location(_vertex);
var vertex = vertices[vertexLocation];
if(!vertex) |
| vertex = vertices[vertexLocation] = {
x: _vertex.x,
y: _vertex.y,
memberships: []
}; |
| vertex.memberships.push({
polygonId: polygonId,
vertexId: vertexId
}); |
| vertexId++;
});
});
return vertices;
};
var quadstream = (function(){ |
Arguments:
| return function(vertices, fileDepth, maxLevel, bounds){ |
| var spots = {}; |
| var spotAddress = function(level, i, j){
return [level,i,j].join('_');
}; |
| var addressOfVertex = function(level, x, y){
var gridSideLength = Math.pow(2, level);
var normalizedX = (x - bounds.x) / bounds.width;
var normalizedY = (y - bounds.y) / bounds.height;
var i = Math.floor(normalizedX * gridSideLength);
var j = Math.floor(normalizedY * gridSideLength);
return spotAddress(level, i, j);
}; |
| var stream = function(vertex){
for(var level = 0; level < maxLevel; level++){
var vertexAddress = addressOfVertex(level, vertex.x, vertex.y); |
| if(spots[vertexAddress]){
continue; |
| }
else
{ |
| spots[vertexAddress] = vertex;
break;
}
}
}; |
Calling
Conceptually, the tree contains nodes with:
| var streamAll = function(vertices){
_(vertices).each(stream);
};
var criticalVertices = function(){ |
Select vertices that close gap. | return _(vertices).filter(function(vertex){ |
Assume the containing polygon is also a polygon. This assures that vertices along the outside border
between two adjacent polygons
| vertex.memberships.length > 2;
});
}
var streamCriticalVertices = function(){
streamAll(criticalVertices());
};
var streamExtremeVertices = function(){ |
Find vertices that define polygon bounding boxes. This is so clients can build bounding boxes from the vertices that are in file "1". Also at this stage, store the bounding box of the overall tree. | };
var streamOtherVertices = function(){ |
If | streamAll(vertices);
};
var getVerticesForFile = function(file_level, file_i, file_j){ |
Save on object creation by re-using an empty array reference
| var emptyArray = [];
var recurse = function(level, i, j){
var vertex = spots[spotAddress(level, i, j)]; |
Include all subtrees | var vertices = [];
if( file_level === 0 )
? [vertex] : [];
if(vertex && level < file_level + fileDepth){
vertices.push( recurse(level + 1, 2 * i , 2 * j));
vertices.push( recurse(level + 1, 2 * i + 1 , 2 * j));
vertices.push( recurse(level + 1, 2 * i , 2 * j + 1));
vertices.push( recurse(level + 1, 2 * i + 1 , 2 * j + 1));
return vertices;
}
else
return emptyArray;
};
recurse(0, 0, 0);
};
var buildFiles = function(){ |
| var files = {}
return files;
} |
Assumption: it's all in memory. | streamCriticalVertices();
streamExtremeVertices();
streamOtherVertices();
return buildFiles();
}
})();
|