source: josm/trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/LineClip.java@ 6920

Last change on this file since 6920 was 6920, checked in by Don-vip, 10 years ago

fix #9778, fix #9806 - access OSM API and JOSM website in HTTPS by default + other HTTPS links where applicable + update CONTRIBUTION

  • Property svn:eol-style set to native
File size: 3.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm.visitor.paint;
3
4import static java.awt.geom.Rectangle2D.OUT_BOTTOM;
5import static java.awt.geom.Rectangle2D.OUT_LEFT;
6import static java.awt.geom.Rectangle2D.OUT_RIGHT;
7import static java.awt.geom.Rectangle2D.OUT_TOP;
8
9import java.awt.Point;
10import java.awt.Rectangle;
11
12/**
13 * Computes the part of a line that is visible in a given rectangle.
14 * Using int leads to overflow, so we need long int.
15 */
16public class LineClip {
17 private Point p1, p2;
18 private final Rectangle clipBounds;
19
20 public LineClip(Point p1, Point p2, Rectangle clipBounds) {
21 this.p1 = p1;
22 this.p2 = p2;
23 this.clipBounds = clipBounds;
24 }
25
26 /**
27 * run the clipping algorithm
28 * @return true if the some parts of the line lies within the clip bounds
29 */
30 public boolean execute() {
31 return cohenSutherland(p1.x, p1.y, p2.x, p2.y, clipBounds.x , clipBounds.y, clipBounds.x + clipBounds.width, clipBounds.y + clipBounds.height);
32 }
33
34 /**
35 * @return start point of the clipped line
36 */
37 public Point getP1()
38 {
39 return p1;
40 }
41
42 /**
43 * @return end point of the clipped line
44 */
45 public Point getP2() {
46 return p2;
47 }
48
49 /**
50 * Cohen–Sutherland algorithm.
51 * See <a href="https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm">Wikipedia article</a>
52 * @return true, if line is visible in the given clip region
53 */
54 private boolean cohenSutherland( long x1, long y1, long x2, long y2, long xmin, long ymin, long xmax, long ymax) {
55 int outcode0, outcode1, outcodeOut;
56 boolean accept = false;
57 boolean done = false;
58
59 outcode0 = computeOutCode (x1, y1, xmin, ymin, xmax, ymax);
60 outcode1 = computeOutCode (x2, y2, xmin, ymin, xmax, ymax);
61
62 do {
63 if ((outcode0 | outcode1) == 0 ) {
64 accept = true;
65 done = true;
66 }
67 else if ( (outcode0 & outcode1) > 0 ) {
68 done = true;
69 }
70 else {
71 long x = 0, y = 0;
72 outcodeOut = outcode0 != 0 ? outcode0: outcode1;
73 if ( (outcodeOut & OUT_TOP) > 0 ) {
74 x = x1 + (x2 - x1) * (ymax - y1)/(y2 - y1);
75 y = ymax;
76 }
77 else if ((outcodeOut & OUT_BOTTOM) > 0 ) {
78 x = x1 + (x2 - x1) * (ymin - y1)/(y2 - y1);
79 y = ymin;
80 }
81 else if ((outcodeOut & OUT_RIGHT)> 0) {
82 y = y1 + (y2 - y1) * (xmax - x1)/(x2 - x1);
83 x = xmax;
84 }
85 else if ((outcodeOut & OUT_LEFT) > 0) {
86 y = y1 + (y2 - y1) * (xmin - x1)/(x2 - x1);
87 x = xmin;
88 }
89 if (outcodeOut == outcode0) {
90 x1 = x;
91 y1 = y;
92 outcode0 = computeOutCode(x1, y1, xmin, ymin, xmax, ymax);
93 } else {
94 x2 = x;
95 y2 = y;
96 outcode1 = computeOutCode(x2, y2, xmin, ymin, xmax, ymax);
97 }
98 }
99 }
100 while (!done);
101
102 if(accept) {
103 p1 = new Point((int) x1, (int) y1);
104 p2 = new Point((int) x2, (int) y2);
105 return true;
106 }
107 return false;
108 }
109
110 /**
111 * The outcode of the point.
112 * We cannot use Rectangle.outcode since it does not work with long ints.
113 */
114 private static int computeOutCode (long x, long y, long xmin, long ymin, long xmax, long ymax) {
115 int code = 0;
116 if (y > ymax) {
117 code |= OUT_TOP;
118 }
119 else if (y < ymin) {
120 code |= OUT_BOTTOM;
121 }
122 if (x > xmax) {
123 code |= OUT_RIGHT;
124 }
125 else if (x < xmin) {
126 code |= OUT_LEFT;
127 }
128 return code;
129 }
130}
Note: See TracBrowser for help on using the repository browser.