* For dual align, calculates positions of new nodes, aligning them to neighboring segments.
* Elsewhere, just adds the vetor returned by calculateBestMovement to {@link #initialN1en}, {@link #initialN2en}.
* @return best movement vector
*/
private EastNorth calculateBestMovementAndNewNodes(EastNorth mouseEn) {
EastNorth bestMovement = calculateBestMovement(mouseEn);
EastNorth n1movedEn = initialN1en.add(bestMovement), n2movedEn;
// find out the movement distance, in metres
double distance = Main.getProjection().eastNorth2latlon(initialN1en).greatCircleDistance(Main.getProjection().eastNorth2latlon(n1movedEn));
Main.map.statusLine.setDist(distance);
updateStatusLine();
if (dualAlignActive) {
// new positions of selected segment's nodes, without applying dual alignment
n1movedEn = initialN1en.add(bestMovement);
n2movedEn = initialN2en.add(bestMovement);
// calculate intersections of parallel shifted segment and the adjacent lines
newN1en = Geometry.getLineLineIntersection(n1movedEn, n2movedEn, dualAlignSegment1.p1, dualAlignSegment1.p2);
newN2en = Geometry.getLineLineIntersection(n1movedEn, n2movedEn, dualAlignSegment2.p1, dualAlignSegment2.p2);
if (newN1en == null || newN2en == null) return bestMovement;
if (keepSegmentDirection && isOppositeDirection(newN1en, newN2en, initialN1en, initialN2en)) {
EastNorth collapsedSegmentPosition = Geometry.getLineLineIntersection(dualAlignSegment1.p1, dualAlignSegment1.p2, dualAlignSegment2.p1, dualAlignSegment2.p2);
newN1en = collapsedSegmentPosition;
newN2en = collapsedSegmentPosition;
dualAlignSegmentCollapsed = true;
} else {
dualAlignSegmentCollapsed = false;