Ticket #3236: alignincircle.patch

File alignincircle.patch, 3.3 KB (added by Daeron, 17 years ago)
  • src/org/openstreetmap/josm/actions/AlignInCircleAction.java

     
    2929 *
    3030 * @author Matthew Newton
    3131 * @author Petr Dlouhý
     32 * @author Teemu Koskinen
    3233 */
    3334public final class AlignInCircleAction extends JosmAction {
    3435
     
    141142            return;
    142143        }
    143144
     145        // Reorder the nodes if they didn't come from a single way
     146        if (ways.size() != 1) {
     147            // First calculate the average point
     148
     149            BigDecimal east = new BigDecimal(0);
     150            BigDecimal north = new BigDecimal(0);
     151
     152            for (Node n : nodes) {
     153                BigDecimal x = new BigDecimal(n.getEastNorth().east());
     154                BigDecimal y = new BigDecimal(n.getEastNorth().north());
     155                east = east.add(x, MathContext.DECIMAL128);
     156                north = north.add(y, MathContext.DECIMAL128);
     157            }
     158            BigDecimal nodesSize = new BigDecimal(nodes.size());
     159            east = east.divide(nodesSize, MathContext.DECIMAL128);
     160            north = north.divide(nodesSize, MathContext.DECIMAL128);
     161
     162            EastNorth average = new EastNorth(east.doubleValue(), north.doubleValue());
     163            List<Node> newNodes = new LinkedList<Node>();
     164
     165            // Then reorder them based on heading from the average point
     166            while (!nodes.isEmpty()) {
     167                double maxHeading = -1.0;
     168                Node maxNode = null;
     169                for (Node n : nodes) {
     170                    double heading = average.heading(n.getEastNorth());
     171                    if (heading > maxHeading) {
     172                        maxHeading = heading;
     173                        maxNode = n;
     174                    }
     175                }
     176                newNodes.add(maxNode);
     177                nodes.remove(maxNode);
     178            }
     179
     180            nodes = newNodes;
     181        }
     182
    144183        if (center == null) {
    145184            // Compute the centroid of nodes
    146185
    147             BigDecimal area = new BigDecimal("0");
    148             BigDecimal north = new BigDecimal("0");
    149             BigDecimal east = new BigDecimal("0");
     186            BigDecimal area = new BigDecimal(0);
     187            BigDecimal north = new BigDecimal(0);
     188            BigDecimal east = new BigDecimal(0);
    150189
    151190            // See http://en.wikipedia.org/w/index.php?title=Centroid&oldid=294224857#Centroid_of_polygon for the equation used here
    152191            for (int i = 0; i < nodes.size(); i++) {
     
    166205
    167206            }
    168207
    169             BigDecimal d = new BigDecimal("2");
    170             area  = area.divide(d, MathContext.DECIMAL128);
    171             d = new BigDecimal("6");
    172             north = north.divide(d.multiply(area, MathContext.DECIMAL128), MathContext.DECIMAL128);
    173             east = east.divide(d.multiply(area, MathContext.DECIMAL128), MathContext.DECIMAL128);
     208            BigDecimal d = new BigDecimal(3, MathContext.DECIMAL128); // 1/2 * 6 = 3
     209            area  = area.multiply(d, MathContext.DECIMAL128);
     210            north = north.divide(area, MathContext.DECIMAL128);
     211            east = east.divide(area, MathContext.DECIMAL128);
    174212
    175213            center = new EastNorth(east.doubleValue(), north.doubleValue());
    176214