Changeset 23422 in osm for applications/editors/josm/plugins/routes/src/org
- Timestamp:
- 2010-09-30T22:11:24+02:00 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/routes/src/org/openstreetmap/josm/plugins/routes/paint/AbstractLinePainter.java
r23189 r23422 17 17 public abstract class AbstractLinePainter implements PathPainter { 18 18 19 20 21 22 23 24 25 26 27 28 29 30 31 19 // Following two method copied from http://blog.persistent.info/2004/03/java-lineline-intersections.html 20 protected boolean getLineLineIntersection(Line2D.Double l1, 21 Line2D.Double l2, 22 Point intersection) 23 { 24 double x1 = l1.getX1(), y1 = l1.getY1(), 25 x2 = l1.getX2(), y2 = l1.getY2(), 26 x3 = l2.getX1(), y3 = l2.getY1(), 27 x4 = l2.getX2(), y4 = l2.getY2(); 28 double dx1 = x2 - x1; 29 double dx2 = x4 - x3; 30 double dy1 = y2 - y1; 31 double dy2 = y4 - y3; 32 32 33 33 double ua = (dx2 * (y1 - y3) - dy2 * (x1 - x3)) / (dy2 * dx1 - dx2 * dy1); 34 34 35 36 37 38 39 40 41 42 35 if (Math.abs(dy2 * dx1 - dx2 * dy1) < 0.0001) { 36 intersection.x = (int)l1.x2; 37 intersection.y = (int)l1.y2; 38 return false; 39 } else { 40 intersection.x = (int)(x1 + ua * (x2 - x1)); 41 intersection.y = (int)(y1 + ua * (y2 - y1)); 42 } 43 43 44 45 44 return true; 45 } 46 46 47 48 49 50 47 protected double det(double a, double b, double c, double d) 48 { 49 return a * d - b * c; 50 } 51 51 52 53 54 52 protected Point shiftPoint(Point2D p1, Point2D p2, double shift) { 53 double dx = p2.getX() - p1.getX(); 54 double dy = p2.getY() - p1.getY(); 55 55 56 57 58 56 // Perpendicular vector 57 double ndx = -dy; 58 double ndy = dx; 59 59 60 61 62 63 60 // Normalize 61 double length = Math.sqrt(ndx * ndx + ndy * ndy); 62 ndx = ndx / length; 63 ndy = ndy / length; 64 64 65 66 65 return new Point((int)(p1.getX() + shift * ndx), (int)(p1.getY() + shift * ndy)); 66 } 67 67 68 69 70 68 protected Line2D.Double shiftLine(Point2D p1, Point2D p2, double shift) { 69 double dx = p2.getX() - p1.getX(); 70 double dy = p2.getY() - p1.getY(); 71 71 72 73 72 Point2D point1 = shiftPoint(p1, p2, shift); 73 Point2D point2 = new Point2D.Double(point1.getX() + dx, point1.getY() + dy); 74 74 75 76 77 75 return new Line2D.Double( 76 point1, point2); 77 } 78 78 79 79 protected GeneralPath getPath(Graphics2D g, MapView mapView, List<Node> nodes, double shift) { 80 80 81 81 GeneralPath path = new GeneralPath(); 82 82 83 84 85 83 if (nodes.size() < 2) { 84 return path; 85 } 86 86 87 88 89 90 87 Point p1 = null; 88 Point p2 = null; 89 Point p3 = null; 90 Point lastPoint = null; 91 91 92 93 92 for (Node n: nodes) { 93 Point p = mapView.getPoint(n); 94 94 95 96 97 98 99 100 101 95 if (!p.equals(p3)) { 96 p1 = p2; 97 p2 = p3; 98 p3 = p; 99 } else { 100 continue; 101 } 102 102 103 104 105 106 107 108 109 103 p = null; 104 if (p2 != null) { 105 if (p1 == null) { 106 p = shiftPoint(p2, p3, shift); 107 } else { 108 Line2D.Double line1 = shiftLine(p1, p2, shift); 109 Line2D.Double line2 = shiftLine(p2, p3, shift); 110 110 111 111 /*path.moveTo((float)line1.x1, (float)line1.y1); 112 112 path.lineTo((float)line1.x2, (float)line1.y2); 113 113 path.moveTo((float)line2.x1, (float)line2.y1); 114 114 path.lineTo((float)line2.x2, (float)line2.y2);*/ 115 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 116 p = new Point(); 117 if (!getLineLineIntersection(line1, line2, p)) { 118 p = null; 119 } else { 120 int dx = p.x - p2.x; 121 int dy = p.y - p2.y; 122 int distance = (int)Math.sqrt(dx * dx + dy * dy); 123 if (distance > 10) { 124 p.x = p2.x + dx / (distance / 10); 125 p.y = p2.y + dy / (distance / 10); 126 } 127 } 128 } 129 } 130 130 131 132 133 134 135 136 137 131 if (p != null && lastPoint != null) { 132 drawSegment(g, mapView, path, lastPoint, p); 133 } 134 if (p != null) { 135 lastPoint = p; 136 } 137 } 138 138 139 140 141 142 139 if (p2 != null && p3 != null && lastPoint != null) { 140 p3 = shiftPoint(p3, p2, -shift); 141 drawSegment(g, mapView, path, lastPoint, p3); 142 } 143 143 144 145 144 return path; 145 } 146 146 147 148 149 150 151 152 153 154 155 156 LineClip clip = new LineClip();157 drawIt = clip.cohenSutherland(p1.x, p1.y, p2.x, p2.y, bounds.x, bounds.y, bounds.x+bounds.width, bounds.y+bounds.height);158 159 160 161 162 163 164 165 166 167 168 169 170 147 private void drawSegment(Graphics2D g, NavigatableComponent nc, GeneralPath path, Point p1, Point p2) { 148 boolean drawIt = false; 149 if (Main.isOpenjdk) { 150 /** 151 * Work around openjdk bug. It leads to drawing artefacts when zooming in a lot. (#4289, #4424) 152 * (It looks like int overflow when clipping.) We do custom clipping. 153 */ 154 Rectangle bounds = g.getClipBounds(); 155 bounds.grow(100, 100); // avoid arrow heads at the border 156 LineClip clip = new LineClip(p1, p2, bounds); 157 drawIt = clip.execute(); 158 if (drawIt) { 159 p1 = clip.getP1(); 160 p2 = clip.getP2(); 161 } 162 } else { 163 drawIt = isSegmentVisible(nc, p1, p2); 164 } 165 if (drawIt) { 166 /* draw segment line */ 167 path.moveTo(p1.x, p1.y); 168 path.lineTo(p2.x, p2.y); 169 } 170 } 171 171 172 173 174 175 176 177 178 172 private boolean isSegmentVisible(NavigatableComponent nc, Point p1, Point p2) { 173 if ((p1.x < 0) && (p2.x < 0)) return false; 174 if ((p1.y < 0) && (p2.y < 0)) return false; 175 if ((p1.x > nc.getWidth()) && (p2.x > nc.getWidth())) return false; 176 if ((p1.y > nc.getHeight()) && (p2.y > nc.getHeight())) return false; 177 return true; 178 } 179 179 180 180
Note:
See TracChangeset
for help on using the changeset viewer.