Attempt to detect shape orientation and reflect accordingly

This commit is contained in:
Bryan Housel
2016-12-15 17:43:46 -05:00
parent 72c51bc283
commit 94933ac455
+44 -40
View File
@@ -63,50 +63,54 @@ export function actionReflect(wayId, projection) {
}
// lol hacky debug
var ssr = getSmallestSurroundingRectangle(graph, targetWay);
var nodes = targetWay.nodes;
for (var d = 0; d < nodes.length - 1; d++) {
var node = graph.entity(nodes[d]);
if (d < 4) {
node = node.move(projection.invert(ssr.poly[d]));
graph = graph.replace(node);
} else {
graph = graph.remove(node);
}
var nodes = targetWay.nodes,
p, q;
// choose line pq = axis of symmetry
var angle = ssr.angle * (180 / Math.PI);
if (angle < 0) angle += 180;
var isVertical = (angle > 60 && angle < 120);
console.log('angle=' + angle + ', isVertical = ' + isVertical);
if (isVertical) {
p = [
(ssr.poly[0][0] + ssr.poly[1][0]) / 2,
(ssr.poly[0][1] + ssr.poly[1][1]) / 2
];
q = [
(ssr.poly[2][0] + ssr.poly[3][0]) / 2,
(ssr.poly[2][1] + ssr.poly[3][1]) / 2
];
} else {
p = [
(ssr.poly[3][0] + ssr.poly[4][0]) / 2,
(ssr.poly[3][1] + ssr.poly[4][1]) / 2
];
q = [
(ssr.poly[1][0] + ssr.poly[2][0]) / 2,
(ssr.poly[1][1] + ssr.poly[2][1]) / 2
];
}
// reflect c across pq
// http://math.stackexchange.com/questions/65503/point-reflection-over-a-line
var dx = q[0] - p[0];
var dy = q[1] - p[1];
var a = (dx * dx - dy * dy) / (dx * dx + dy * dy);
var b = 2 * dx * dy / (dx * dx + dy * dy);
for (var i = 0; i < nodes.length - 1; i++) {
var node = graph.entity(nodes[i]);
var c = projection(node.loc);
var c2 = [
a * (c[0] - p[0]) + b * (c[1] - p[1]) + p[0],
b * (c[0] - p[0]) - a * (c[1] - p[1]) + p[1]
];
node = node.move(projection.invert(c2));
graph = graph.replace(node);
}
graph = graph.replace(targetWay.update(
{ nodes: [nodes[0], nodes[1], nodes[2], nodes[3], nodes[0]] })
);
return graph;
// end debug
// Get the bounding rectangle of the area
var boundingRect = targetWay.extent(graph).rectangle();
// rectangle returned as [ lon (x) top left, lat (y) top left, lon (x) bottom right, lat (y) bottom right]
// Obtain the left and right lonlat's
var left = boundingRect[0];
var right = boundingRect[2];
// Determine the mid-point that we will flip on
var midPoint = left + ((right - left) / 2);
// Obtain all of the nodes on the way, iterate over them to translate then aggreate up
return _(targetWay.nodes)
.map(function (nodeId) {
return graph.entity(nodeId);
})
// Only process each node once, as the first node will be listed twice in the way
.uniqBy(function (node) { return node.id; })
// Get distance from midPoint and produce a translated node
.map(function (node) {
var delta = node.loc[0] - midPoint;
return node.move([node.loc[0]-(2*delta), node.loc[1]]);
})
// Chain together consecutive updates to the graph for each updated node and return
.reduce(function (accGraph, value) {
return accGraph.replace(value);
}, graph);
};
}