Ticket #13385: 13385.patch
File 13385.patch, 5.8 KB (added by , 8 years ago) |
---|
-
src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
108 108 private MapViewPoint prev; 109 109 /* 'prev0' is a point that has distance 'offset' from 'prev' and the 110 110 * line from 'prev' to 'prev0' is perpendicular to the way segment from 111 * 'prev' to the next point.111 * 'prev' to the current point. 112 112 */ 113 113 private double xPrev0; 114 114 private double yPrev0; … … 136 136 return current; 137 137 } 138 138 139 double xCurrent = current.getInViewX(); 140 double yCurrent = current.getInViewY(); 139 141 if (idx == nodes.size() - 1) { 140 142 ++idx; 141 143 if (prev != null) { 142 return mapState.getForView(xPrev0 + current.getInViewX()- prev.getInViewX(),143 yPrev0 + current.getInViewY()- prev.getInViewY());144 return mapState.getForView(xPrev0 + xCurrent - prev.getInViewX(), 145 yPrev0 + yCurrent - prev.getInViewY()); 144 146 } else { 145 147 return current; 146 148 } … … 147 149 } 148 150 149 151 MapViewPoint next = getForIndex(idx + 1); 150 151 double dxNext = next.getInViewX() - current.getInViewX(); 152 double dyNext = next.getInViewY() - current.getInViewY(); 152 double dxNext = next.getInViewX() - xCurrent; 153 double dyNext = next.getInViewY() - yCurrent; 153 154 double lenNext = Math.sqrt(dxNext*dxNext + dyNext*dyNext); 154 155 155 if (lenNext < 1e- 3) {156 if (lenNext < 1e-11) { 156 157 lenNext = 1; // value does not matter, because dy_next and dx_next is 0 157 158 } 158 159 159 double xCurrent0 = current.getInViewX() + offset * dyNext / lenNext; 160 double yCurrent0 = current.getInViewY() - offset * dxNext / lenNext; 160 // calculate the position of the translated current point 161 double om = offset / lenNext; 162 double xCurrent0 = xCurrent + om * dyNext; 163 double yCurrent0 = yCurrent - om * dxNext; 161 164 162 165 if (idx == 0) { 163 166 ++idx; … … 166 169 yPrev0 = yCurrent0; 167 170 return mapState.getForView(xCurrent0, yCurrent0); 168 171 } else { 169 double dxPrev = current.getInViewX() - prev.getInViewX(); 170 double dyPrev = current.getInViewY() - prev.getInViewY(); 171 172 double dxPrev = xCurrent - prev.getInViewX(); 173 double dyPrev = yCurrent - prev.getInViewY(); 172 174 // determine intersection of the lines parallel to the two segments 173 175 double det = dxNext*dyPrev - dxPrev*dyNext; 176 double m = dxNext*(yCurrent0 - yPrev0) - dyNext*(xCurrent0 - xPrev0); 174 177 175 if (Utils.equalsEpsilon(det, 0) ) {178 if (Utils.equalsEpsilon(det, 0) || Math.signum(det) != Math.signum(m)) { 176 179 ++idx; 177 180 prev = current; 178 181 xPrev0 = xCurrent0; … … 180 183 return mapState.getForView(xCurrent0, yCurrent0); 181 184 } 182 185 183 double m = dxNext*(yCurrent0 - yPrev0) - dyNext*(xCurrent0 - xPrev0); 186 double f = m / det; 187 if (f < 0) { 188 ++idx; 189 prev = current; 190 xPrev0 = xCurrent0; 191 yPrev0 = yCurrent0; 192 return mapState.getForView(xCurrent0, yCurrent0); 193 } 194 // the position of the intersection or intermittent point 195 double cx = xPrev0 + f * dxPrev; 196 double cy = yPrev0 + f * dyPrev; 184 197 185 double cx = xPrev0 + m * dxPrev / det; 186 double cy = yPrev0 + m * dyPrev / det; 198 if (f > 1) { 199 // check if the intersection point is too far away, this will happen for sharp angles 200 double dxI = cx - xCurrent; 201 double dyI = cy - yCurrent; 202 double lenISq = dxI * dxI + dyI * dyI; 203 204 if (lenISq > Math.abs(2 * offset * offset)) { 205 // intersection point is too far away, calculate intermittent points for capping 206 double dxPrev0 = xCurrent0 - xPrev0; 207 double dyPrev0 = yCurrent0 - yPrev0; 208 double lenPrev0 = Math.sqrt(dxPrev0 * dxPrev0 + dyPrev0 * dyPrev0); 209 f = 1 + Math.abs(offset / lenPrev0); 210 double cxCap = xPrev0 + f * dxPrev; 211 double cyCap = yPrev0 + f * dyPrev; 212 xPrev0 = cxCap; 213 yPrev0 = cyCap; 214 // calculate a virtual prev point which lies on a line that goes through current and 215 // is perpendicular to the line that goes through current and the intersection 216 // so that the next capping point is calculated with it. 217 double lenI = Math.sqrt(lenISq); 218 double xv = xCurrent + dyI / lenI; 219 double yv = yCurrent - dxI / lenI; 220 221 prev = mapState.getForView(xv, yv); 222 return mapState.getForView(cxCap, cyCap); 223 } 224 } 187 225 ++idx; 188 226 prev = current; 189 227 xPrev0 = xCurrent0;