View Javadoc

1   package cz.cuni.amis.pogamut.defcon.utils.quadtree;
2   
3   import java.util.Iterator;
4   import java.util.List;
5   
6   import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
7   
8   public class RectangularFillTester {
9   
10  	enum Side {
11  		UPPER,
12  		UPPER_RIGHT,
13  		RIGHT,
14  		BOTTOM_RIGHT,
15  		BOTTOM,
16  		BOTTOM_LEFT,
17  		LEFT,
18  		UPPER_LEFT
19  	}
20  
21  	/**
22  	 * Checks whether a given list of points, read clockwise, form a rectangle
23  	 * with the given vertices.
24  	 * 
25  	 * @param points
26  	 * @param x1
27  	 * @param y1
28  	 * @param x2
29  	 * @param y2
30  	 * @return
31  	 */
32  	public static boolean isSameRectangle(List<? extends Location> points,
33  			double x1, double y1, double x2, double y2) {
34  
35  		if (points.size() < 4)
36  			return false;		
37  
38  		Iterator<? extends Location> iter = points.iterator();
39  		Location point = iter.next();
40  
41  		Side side =
42  				getSideToWhichPointBelongs(
43  						point.getX(), point.getY(), x1, y1, x2, y2);
44  		
45  		if (side == null)
46  			return false;
47  		
48  		Side old_side;
49  		int direction = 0;
50  		
51  		while (iter.hasNext()) {
52  			point = iter.next();
53  			old_side = side;
54  
55  			side =
56  					getSideToWhichPointBelongs(
57  							point.getX(), point.getY(), x1, y1, x2, y2);
58  			
59  			if (side == null)
60  				return false;
61  			
62  			if (old_side != side && direction == 0) {
63  
64  				direction = (side.ordinal() - old_side.ordinal()) / 2;
65  
66  				if (direction < -1)
67  					direction = 1;
68  				else if (direction > 1)
69  					direction = -1;
70  			}
71  			
72  			if (old_side != side) {
73  				if (edgeJumpInDirection(side, old_side, direction))
74  					continue;
75  				
76  				if ((old_side.ordinal() + direction) % Side.values().length != side
77  							.ordinal())
78  					return false;
79  			}
80  		}
81  
82  		return true;
83  	}
84  
85  	private static boolean edgeJumpInDirection(Side side, Side old_side,
86  			int direction) {
87  
88  		if (side.ordinal() % 2 == 0)
89  			return false;
90  
91  		int tmp_val = (side.ordinal() - old_side.ordinal()) / 2;
92  		if (tmp_val < -1)
93  			tmp_val = 1;
94  
95  		return tmp_val == direction;
96  	}
97  
98  	private static Side getSideToWhichPointBelongs(double x, double y,
99  			double x1, double y1, double x2, double y2) {
100 		if (x == x2 && y == y1)
101 			return Side.UPPER_RIGHT;
102 		else if (x == x2 && y == y2)
103 			return Side.BOTTOM_RIGHT;
104 		else if (x == x1 && y == y2)
105 			return Side.BOTTOM_LEFT;
106 		else if (x == x1 && y == y1)
107 			return Side.UPPER_LEFT;
108 		else if (checkIfBelongsToLine(x, y, x1, y1, x2, y1))
109 			return Side.UPPER;
110 		else if (checkIfBelongsToLine(x, y, x2, y1, x2, y2))
111 			return Side.RIGHT;
112 		else if (checkIfBelongsToLine(x, y, x2, y2, x1, y2))
113 			return Side.BOTTOM;
114 		else if (checkIfBelongsToLine(x, y, x1, y2, x1, y1))
115 			return Side.LEFT;
116 		
117 		return null;
118 	}
119 
120 	private static boolean checkIfBelongsToLine(double whatX, double whatY,
121 			double whereX1, double whereY1, double whereX2, double whereY2) {
122 
123 		if (whereX1 == whereX2) {
124 			if (whatX == whereX1) {
125 				if (whatY >= whereY1 && whatY <= whereY2 ||
126 						whatY <= whereY1 && whatY >= whereY2)
127 					return true;
128 			}
129 			return false;
130 		}
131 
132 		if (whereY1 == whereY2) {
133 			if (whatY == whereY1) {
134 				if (whatX >= whereX1 && whatX <= whereX2 ||
135 						whatX <= whereX1 && whatX >= whereX2)
136 					return true;
137 			}
138 			return false;
139 		}
140 
141 		return false;
142 	}
143 }