Changeset 1768 in josm
- Timestamp:
- 2009-07-11T15:37:10+02:00 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/AlignInCircleAction.java
r1713 r1768 6 6 import java.awt.event.ActionEvent; 7 7 import java.awt.event.KeyEvent; 8 import java.math.BigDecimal; 9 import java.math.MathContext; 8 10 import java.util.Collection; 9 11 import java.util.LinkedList; … … 35 37 } 36 38 37 public double determinant(double[][] mat) {38 double result = 0;39 40 if (mat.length == 1) {41 result = mat[0][0];42 return result;43 }44 45 if (mat.length == 2) {46 result = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0];47 return result;48 }49 50 for (int i = 0; i < mat[0].length; i++) {51 double temp[][] = new double[mat.length - 1][mat[0].length - 1];52 for (int j = 1; j < mat.length; j++) {53 for (int k = 0; k < mat[0].length; k++) {54 if (k < i) {55 temp[j - 1][k] = mat[j][k];56 } else if (k > i) {57 temp[j - 1][k - 1] = mat[j][k];58 }59 }60 }61 result += mat[0][i] * Math.pow(-1, i) * determinant(temp);62 }63 return result;64 }65 66 39 public double distance(EastNorth n, EastNorth m) { 67 40 double easd, nord; … … 69 42 nord = n.north() - m.north(); 70 43 return Math.sqrt(easd * easd + nord * nord); 71 }72 73 public EastNorth circumcenter(EastNorth i, EastNorth j, EastNorth k) {74 // move to 0,0, to eliminate numeric errors75 double ie = i.east() - i.east();76 double in = i.north() - i.north();77 double je = j.east() - i.east();78 double jn = j.north() - i.north();79 double ke = k.east() - i.east();80 double kn = k.north() - i.north();81 double[][] ma = { { ie, in, 1 }, { je, jn, 1 }, { ke, kn, 1 } };82 double[][] mbx = { { (ie * ie + in * in), in, 1 }, { (je * je + jn * jn), jn, 1 },83 { (ke * ke + kn * kn), kn, 1 } };84 double[][] mby = { { ie * ie + in * in, ie, 1 }, { je * je + jn * jn, je, 1 }, { ke * ke + kn * kn, ke, 1 } };85 double a = determinant(ma);86 double bx = determinant(mbx);87 double by = determinant(mby);88 EastNorth result = new EastNorth(bx / (2 * a) + i.east(), -by / (2 * a) + i.north());89 90 Node n = new Node(Main.proj.eastNorth2latlon(result));91 if (n.getCoor().isOutSideWorld()) {92 JOptionPane.showMessageDialog(Main.parent, tr("Some of the nodes are (almost) in the line"));93 return null;94 }95 return result;96 44 } 97 45 … … 139 87 140 88 for (OsmPrimitive osm : sel) { 141 if (osm instanceof Node) 89 if (osm instanceof Node) { 142 90 nodes.add((Node) osm); 143 else if (osm instanceof Way)91 } else if (osm instanceof Way) { 144 92 ways.add((Way) osm); 93 } 145 94 } 146 95 … … 164 113 165 114 center = ((Node) nodes.toArray()[way.nodes.contains(nodes.toArray()[0]) ? 1 : 0]).getEastNorth(); 166 if (nodes.size() == 2) 115 if (nodes.size() == 2) { 167 116 radius = distance(((Node) nodes.toArray()[0]).getEastNorth(), ((Node) nodes.toArray()[1]).getEastNorth()); 117 } 168 118 } 169 119 nodes = new LinkedList<Node>(); … … 171 121 172 122 for (Node n : way.nodes) { 173 if (!nodes.contains(n)) 123 if (!nodes.contains(n)) { 174 124 nodes.add(n); 125 } 175 126 } 176 127 } … … 181 132 } 182 133 183 // Get average position of circumcircles of the triangles of all triplets of neighbour nodes184 134 if (center == null) { 185 186 135 // Compute the centroid of nodes 187 136 137 BigDecimal area = new BigDecimal("0"); 138 BigDecimal north = new BigDecimal("0"); 139 BigDecimal east = new BigDecimal("0"); 140 188 141 // See http://en.wikipedia.org/w/index.php?title=Centroid&oldid=294224857#Centroid_of_polygon for the equation used here 189 double area = 0; 190 double north = 0; 191 double east = 0; 192 193 // Integrate the area, east and north centroid, we'll compute the final value based on the result of integration 194 for (int i=0; i<nodes.size(); i++) { 142 for (int i = 0; i < nodes.size(); i++) { 195 143 EastNorth n0 = ((Node) nodes.toArray()[i]).getEastNorth(); 196 144 EastNorth n1 = ((Node) nodes.toArray()[(i+1) % nodes.size()]).getEastNorth(); 197 145 198 area += n0.east()*n1.north()-n1.east()*n0.north(); 199 east += (n0.east() +n1.east()) *(n0.east()*n1.north()-n1.east()*n0.north()); 200 north += (n0.north()+n1.north())*(n0.east()*n1.north()-n1.east()*n0.north()); 201 } 202 area /= 2; 203 north /= 6*area; 204 east /= 6*area; 205 center = new EastNorth(east, north); 206 } 207 146 BigDecimal x0 = new BigDecimal(n0.east()); 147 BigDecimal y0 = new BigDecimal(n0.north()); 148 BigDecimal x1 = new BigDecimal(n1.east()); 149 BigDecimal y1 = new BigDecimal(n1.north()); 150 151 BigDecimal k = x0.multiply(y1, MathContext.DECIMAL128).subtract(y0.multiply(x1, MathContext.DECIMAL128)); 152 153 area = area.add(k, MathContext.DECIMAL128); 154 east = east.add(k.multiply(x0.add(x1, MathContext.DECIMAL128), MathContext.DECIMAL128)); 155 north = north.add(k.multiply(y0.add(y1, MathContext.DECIMAL128), MathContext.DECIMAL128)); 156 157 } 158 159 BigDecimal d = new BigDecimal("2"); 160 area = area.divide(d, MathContext.DECIMAL128); 161 d = new BigDecimal("6"); 162 north = north.divide(d.multiply(area, MathContext.DECIMAL128), MathContext.DECIMAL128); 163 east = east.divide(d.multiply(area, MathContext.DECIMAL128), MathContext.DECIMAL128); 164 165 center = new EastNorth(east.doubleValue(), north.doubleValue()); 166 167 } 208 168 // Node "center" now is central to all selected nodes. 209 169 … … 226 186 pc = new PolarCoor(((Node) nodes.toArray()[0]).getEastNorth(), center, 0); 227 187 228 if (pc.angle > (new PolarCoor(((Node) nodes.toArray()[1]).getEastNorth(), center, 0).angle)) 188 if (pc.angle > (new PolarCoor(((Node) nodes.toArray()[1]).getEastNorth(), center, 0).angle)) { 229 189 angle *= -1; 190 } 230 191 231 192 pc.radius = radius;
Note:
See TracChangeset
for help on using the changeset viewer.