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

Last change on this file since 3083 was 2987, checked in by bastiK, 14 years ago

fixed #4289 - rendering goes crazy at high zoom levels,
fixed #4424 - Problems rendering long ways at higher zoom levels

  • Property svn:eol-style set to native
File size: 3.1 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_LEFT;
5import static java.awt.geom.Rectangle2D.OUT_RIGHT;
6import static java.awt.geom.Rectangle2D.OUT_TOP;
7import static java.awt.geom.Rectangle2D.OUT_BOTTOM;
8import java.awt.Point;
9
10/**
11 * Computes the part of a line that is visible in a given rectangle.
12 * Using int leads to overflow, so we need long int.
13 * http://en.wikipedia.org/wiki/Cohen-Sutherland
14 */
15public class LineClip {
16 private Point p1, p2;
17
18 /**
19 * The outcode of the point.
20 * We cannot use Rectangle.outcode since it does not work with long ints.
21 */
22 public int computeOutCode (long x, long y, long xmin, long ymin, long xmax, long ymax) {
23 int code = 0;
24 if (y > ymax) {
25 code |= OUT_TOP;
26 }
27 else if (y < ymin) {
28 code |= OUT_BOTTOM;
29 }
30 if (x > xmax) {
31 code |= OUT_RIGHT;
32 }
33 else if (x < xmin) {
34 code |= OUT_LEFT;
35 }
36 return code;
37 }
38
39 public boolean cohenSutherland( long x1, long y1, long x2, long y2, long xmin, long ymin, long xmax, long ymax)
40 {
41 int outcode0, outcode1, outcodeOut;
42 boolean accept = false;
43 boolean done = false;
44
45 outcode0 = computeOutCode (x1, y1, xmin, ymin, xmax, ymax);
46 outcode1 = computeOutCode (x2, y2, xmin, ymin, xmax, ymax);
47
48 do {
49 if ((outcode0 | outcode1) == 0 ) {
50 accept = true;
51 done = true;
52 }
53 else if ( (outcode0 & outcode1) > 0 ) {
54 done = true;
55 }
56 else {
57 long x = 0, y = 0;
58 outcodeOut = outcode0 != 0 ? outcode0: outcode1;
59 if ( (outcodeOut & OUT_TOP) > 0 ) {
60 x = x1 + (x2 - x1) * (ymax - y1)/(y2 - y1);
61 y = ymax;
62 }
63 else if ((outcodeOut & OUT_BOTTOM) > 0 ) {
64 x = x1 + (x2 - x1) * (ymin - y1)/(y2 - y1);
65 y = ymin;
66 }
67 else if ((outcodeOut & OUT_RIGHT)> 0) {
68 y = y1 + (y2 - y1) * (xmax - x1)/(x2 - x1);
69 x = xmax;
70 }
71 else if ((outcodeOut & OUT_LEFT) > 0) {
72 y = y1 + (y2 - y1) * (xmin - x1)/(x2 - x1);
73 x = xmin;
74 }
75 if (outcodeOut == outcode0) {
76 x1 = x;
77 y1 = y;
78 outcode0 = computeOutCode(x1, y1, xmin, ymin, xmax, ymax);
79 } else {
80 x2 = x;
81 y2 = y;
82 outcode1 = computeOutCode(x2, y2, xmin, ymin, xmax, ymax);
83 }
84 }
85 }
86 while (!done);
87
88 if(accept) {
89 p1 = new Point((int) x1, (int) y1);
90 p2 = new Point((int) x2, (int) y2);
91 return true;
92 }
93 return false;
94 }
95
96 public Point getP1()
97 {
98 return p1;
99 }
100
101 public Point getP2()
102 {
103 return p2;
104 }
105}
Note: See TracBrowser for help on using the repository browser.