Index: trunk/src/org/openstreetmap/josm/actions/OrthogonalizeAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/OrthogonalizeAction.java	(revision 13701)
+++ trunk/src/org/openstreetmap/josm/actions/OrthogonalizeAction.java	(revision 13712)
@@ -33,4 +33,5 @@
 import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.Notification;
+import org.openstreetmap.josm.tools.Geometry;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
 import org.openstreetmap.josm.tools.Logging;
@@ -166,6 +167,5 @@
 
         try {
-            final SequenceCommand command = orthogonalize(sel);
-            MainApplication.undoRedo.add(new SequenceCommand(tr("Orthogonalize"), command));
+            MainApplication.undoRedo.add(orthogonalize(sel));
         } catch (InvalidUserInputException ex) {
             Logging.debug(ex);
@@ -205,5 +205,6 @@
             }
         }
-        if (wayDataList.isEmpty() && nodeList.size() > 2) {
+        final int nodesCount = nodeList.size();
+        if (wayDataList.isEmpty() && nodesCount > 2) {
             final WayData data = new WayData(nodeList);
             final Collection<Command> commands = orthogonalize(Collections.singletonList(data), Collections.<Node>emptyList());
@@ -212,17 +213,16 @@
             throw new InvalidUserInputException("usage");
         } else {
-            if (nodeList.size() == 2 || nodeList.isEmpty()) {
+            if (nodesCount <= 2) {
                 OrthogonalizeAction.rememberMovements.clear();
                 final Collection<Command> commands = new LinkedList<>();
 
-                if (nodeList.size() == 2) {  // fixed direction
+                if (nodesCount == 2) {  // fixed direction, or single node to move
                     commands.addAll(orthogonalize(wayDataList, nodeList));
-                } else if (nodeList.isEmpty()) {
-                    List<List<WayData>> groups = buildGroups(wayDataList);
-                    for (List<WayData> g: groups) {
+                } else if (nodesCount == 1) {
+                    commands.add(orthogonalize(wayDataList, nodeList.get(0)));
+                } else if (nodesCount == 0) {
+                    for (List<WayData> g : buildGroups(wayDataList)) {
                         commands.addAll(orthogonalize(g, nodeList));
                     }
-                } else {
-                    throw new IllegalStateException();
                 }
 
@@ -265,4 +265,47 @@
             }
         }
+    }
+
+    /**
+     * Try to orthogonalize the given ways by moving only a single given node
+     * @param wayDataList list of ways
+     * @param singleNode common node to ways to orthogonalize. Only this one will be moved
+     * @return the command to move the node
+     * @throws InvalidUserInputException if the command cannot be computed
+     */
+    private static Command orthogonalize(List<WayData> wayDataList, Node singleNode) throws InvalidUserInputException {
+        List<EastNorth> rightAnglePositions = new ArrayList<>();
+        int wayCount = wayDataList.size();
+        for (WayData wd : wayDataList) {
+            int n = wd.wayNodes.size();
+            int i = wd.wayNodes.indexOf(singleNode);
+            Node n0, n2;
+            if (i == 0 && n >= 3 && singleNode.equals(wd.wayNodes.get(n-1))) {
+                n0 = wd.wayNodes.get(n-2);
+                n2 = wd.wayNodes.get(1);
+            } else if (i > 0 && i < n-1) {
+                n0 = wd.wayNodes.get(i-1);
+                n2 = wd.wayNodes.get(i+1);
+            } else {
+                continue;
+            }
+            EastNorth n0en = n0.getEastNorth();
+            EastNorth n1en = singleNode.getEastNorth();
+            EastNorth n2en = n2.getEastNorth();
+            double angle = Geometry.getNormalizedAngleInDegrees(Geometry.getCornerAngle(n0en, n1en, n2en));
+            if (wayCount == 1 || (80 <= angle && angle <= 100)) {
+                EastNorth c = n0en.getCenter(n2en);
+                double r = n0en.distance(n2en) / 2d;
+                double vX = n1en.east() - c.east();
+                double vY = n1en.north() - c.north();
+                double magV = Math.sqrt(vX*vX + vY*vY);
+                rightAnglePositions.add(new EastNorth(c.east() + vX / magV * r,
+                                                     c.north() + vY / magV * r));
+            }
+        }
+        if (rightAnglePositions.isEmpty()) {
+            throw new InvalidUserInputException("Unable to orthogonalize " + singleNode);
+        }
+        return new MoveCommand(singleNode, Main.getProjection().eastNorth2latlon(Geometry.getCentroidEN(rightAnglePositions)));
     }
 
@@ -307,5 +350,5 @@
                     totSum = EN.sum(totSum, w.segSum);
                 }
-                headingAll = EN.polar(new EastNorth(0., 0.), totSum);
+                headingAll = EN.polar(EastNorth.ZERO, totSum);
             } else {
                 headingAll = EN.polar(headingNodes.get(0).getEastNorth(), headingNodes.get(1).getEastNorth());
@@ -334,5 +377,5 @@
         // calculate the centroid of all nodes
         // it is used as rotation center
-        EastNorth pivot = new EastNorth(0., 0.);
+        EastNorth pivot = EastNorth.ZERO;
         for (Node n : allNodes) {
             pivot = EN.sum(pivot, n.getEastNorth());
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/RightAngleBuildingTest.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/RightAngleBuildingTest.java	(revision 13701)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/RightAngleBuildingTest.java	(revision 13712)
@@ -4,5 +4,5 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.util.Collections;
+import java.util.Arrays;
 import java.util.List;
 
@@ -52,15 +52,12 @@
                                                      .primitives(w)
                                                      .highlight(pair.b);
-                if (angles.stream().noneMatch(
-                        p -> Math.abs(p.a - 90) >= maxAngleDelta && Math.abs(p.a - 180) >= minAngleDelta)) {
-                    builder.fix(() -> {
-                        try {
-                            return OrthogonalizeAction.orthogonalize(Collections.singleton(w));
-                        } catch (InvalidUserInputException e) {
-                            Logging.warn(e);
-                            return null;
-                        }
-                    });
-                }
+                builder.fix(() -> {
+                    try {
+                        return OrthogonalizeAction.orthogonalize(Arrays.asList(w, pair.b));
+                    } catch (InvalidUserInputException e) {
+                        Logging.warn(e);
+                        return null;
+                    }
+                });
                 errors.add(builder.build());
                 return;
Index: trunk/src/org/openstreetmap/josm/tools/Geometry.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Geometry.java	(revision 13701)
+++ trunk/src/org/openstreetmap/josm/tools/Geometry.java	(revision 13712)
@@ -16,4 +16,5 @@
 import java.util.Set;
 import java.util.function.Predicate;
+import java.util.stream.Collectors;
 
 import org.openstreetmap.josm.Main;
@@ -796,5 +797,5 @@
     }
 
-    /** 
+    /**
      * Get angles in radians and return it's value in range [0, 180].
      *
@@ -814,4 +815,21 @@
      */
     public static EastNorth getCentroid(List<Node> nodes) {
+        return getCentroidEN(nodes.stream().map(Node::getEastNorth).collect(Collectors.toList()));
+    }
+
+    /**
+     * Compute the centroid/barycenter of nodes
+     * @param nodes Coordinates for which the centroid is wanted
+     * @return the centroid of nodes
+     * @since 13712
+     */
+    public static EastNorth getCentroidEN(List<EastNorth> nodes) {
+
+        final int size = nodes.size();
+        if (size == 1) {
+            return nodes.get(0);
+        } else if (size == 2) {
+            return nodes.get(0).getCenter(nodes.get(1));
+        }
 
         BigDecimal area = BigDecimal.ZERO;
@@ -819,8 +837,8 @@
         BigDecimal east = BigDecimal.ZERO;
 
-        // See https://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon for the equation used here
-        for (int i = 0; i < nodes.size(); i++) {
-            EastNorth n0 = nodes.get(i).getEastNorth();
-            EastNorth n1 = nodes.get((i+1) % nodes.size()).getEastNorth();
+        // See https://en.wikipedia.org/wiki/Centroid#Centroid_of_a_polygon for the equation used here
+        for (int i = 0; i < size; i++) {
+            EastNorth n0 = nodes.get(i);
+            EastNorth n1 = nodes.get((i+1) % size);
 
             if (n0 != null && n1 != null && n0.isValid() && n1.isValid()) {
