in modules/actions/move.js [242:290]
function unZorroIntersection(intersection, graph) {
var vertex = graph.entity(intersection.nodeId);
var way1 = graph.entity(intersection.movedId);
var way2 = graph.entity(intersection.unmovedId);
var isEP1 = intersection.movedIsEP;
var isEP2 = intersection.unmovedIsEP;
// don't move the vertex if it is the endpoint of both ways.
if (isEP1 && isEP2) return graph;
var nodes1 = graph.childNodes(way1).filter(function(n) { return n !== vertex; });
var nodes2 = graph.childNodes(way2).filter(function(n) { return n !== vertex; });
if (way1.isClosed() && way1.first() === vertex.id) nodes1.push(nodes1[0]);
if (way2.isClosed() && way2.first() === vertex.id) nodes2.push(nodes2[0]);
var edge1 = !isEP1 && geoChooseEdge(nodes1, projection(vertex.loc), projection);
var edge2 = !isEP2 && geoChooseEdge(nodes2, projection(vertex.loc), projection);
var loc;
// snap vertex to nearest edge (or some point between them)..
if (!isEP1 && !isEP2) {
var epsilon = 1e-6, maxIter = 10;
for (var i = 0; i < maxIter; i++) {
loc = geoVecInterp(edge1.loc, edge2.loc, 0.5);
edge1 = geoChooseEdge(nodes1, projection(loc), projection);
edge2 = geoChooseEdge(nodes2, projection(loc), projection);
if (Math.abs(edge1.distance - edge2.distance) < epsilon) break;
}
} else if (!isEP1) {
loc = edge1.loc;
} else {
loc = edge2.loc;
}
graph = graph.replace(vertex.move(loc));
// if zorro happened, reorder nodes..
if (!isEP1 && edge1.index !== way1.nodes.indexOf(vertex.id)) {
way1 = way1.removeNode(vertex.id).addNode(vertex.id, edge1.index);
graph = graph.replace(way1);
}
if (!isEP2 && edge2.index !== way2.nodes.indexOf(vertex.id)) {
way2 = way2.removeNode(vertex.id).addNode(vertex.id, edge2.index);
graph = graph.replace(way2);
}
return graph;
}