View Javadoc

1   package cz.cuni.amis.pogamut.ut2004.agent.module.sensor;
2   
3   import cz.cuni.amis.pogamut.base3d.worldview.object.ILocated;
4   import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
5   import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId;
6   import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPoint;
7   import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPointNeighbourLink;
8   import cz.cuni.amis.utils.HashCode;
9   import cz.cuni.amis.utils.NullCheck;
10  import cz.cuni.amis.utils.SafeEquals;
11  
12  /**
13   * NavLinkPair representing info about links between two navpoints, such info comprises of
14   * 1 or 2 {@link NavPointNeighbourLink}.
15   * 
16   * {@link NavLinkPair#hashCode()} and {@link NavLinkPair#equals(Object)} overridden.
17   * 
18   * @author Jimmy
19   */
20  public class NavLinkPair {
21  	
22  	private NavPointNeighbourLink link1;
23  	private NavPointNeighbourLink link2;
24  
25  	private NavPoint nav1;
26  	private NavPoint nav2;
27  	
28  	private Location x1, x2;
29  	
30  	private int hashCode;
31  	
32  	public NavLinkPair(NavPointNeighbourLink first) {
33  		link1 = first;
34  		
35  		NullCheck.check(link1, "first");
36  		
37  		HashCode hc = new HashCode();
38  		hc.add(link1.hashCode());
39  		hashCode = hc.getHash();
40  		
41  		nav1 = link1.getFromNavPoint();
42  		nav2 = link1.getToNavPoint();
43  		x1 = link1.getFromNavPoint().getLocation();
44  		x2 = link1.getToNavPoint().getLocation();
45  		
46  //		NullCheck.check(nav1, "first.getFromNavPoint()");
47  //		NullCheck.check(nav2, "first.getToNavPoint()");
48  //		NullCheck.check(nav1.getId(), "first.getFromNavPoint().getId()");
49  //		NullCheck.check(nav2.getId(), "first.getToNavPoint().getId()");
50  //		NullCheck.check(x1, "first.getFromNavPoint().getLocation()");
51  //		NullCheck.check(x2, "first.getToNavPoint().getLocation()");
52  	}
53  	
54  	/**
55  	 * If 'first' is NULL and 'second' is NULL ... throws {@link IllegalArgumentException}.
56  	 * 
57  	 * If 'first' is NULL and 'second' is NOT ... it swaps 'first' and 'second'.
58  	 * 
59  	 * If 'first' is NOT NULL and 'second' is NOT NULL ... it may swap them to satisfy {@link NavLinkPair#hashCode()} implementation.
60  	 * 
61  	 * @param first
62  	 * @param second
63  	 */
64  	public NavLinkPair(NavPointNeighbourLink first, NavPointNeighbourLink second) {
65  		if (first == null) {
66  			first = second;
67  			second = null;
68  		} else
69  		if (second != null) {
70  			if (first.hashCode() > second.hashCode()) {
71  				NavPointNeighbourLink temp = second;
72  				second = first;
73  				first = temp;
74  			}
75  		}
76  		
77  		link1 = first;
78  		link2 = second;
79  		
80  		NullCheck.check(link1, "'first' and 'second'");
81  		
82  		HashCode hc = new HashCode();
83  		hc.add(link1.hashCode());
84  		if (link2 != null) {
85  			hc.add(link2.hashCode());
86  		}
87  		hashCode = hc.getHash();
88  		
89  		nav1 = link1.getFromNavPoint();
90  		nav2 = link1.getToNavPoint();
91  		x1 = nav1.getLocation();
92  		x2 = nav2.getLocation();	
93  		
94  //		NullCheck.check(nav1, "first/second.getFromNavPoint()");
95  //		NullCheck.check(nav2, "first/second.getToNavPoint()");
96  //		NullCheck.check(nav1.getId(), "first/second.getFromNavPoint().getId()");
97  //		NullCheck.check(nav2.getId(), "first/second.getToNavPoint().getId()");
98  //		NullCheck.check(x1, "first/second.getFromNavPoint().getLocation()");
99  //		NullCheck.check(x2, "first/second.getToNavPoint().getLocation()");
100 	} 
101 	
102 	@Override
103 	public int hashCode() {
104 		return hashCode;
105 	}
106 	
107 	@Override
108 	public boolean equals(Object obj) {
109 		if (obj == null) return false;
110 		if (!(obj instanceof NavLinkPair)) return false;
111 		if (hashCode != obj.hashCode()) return false;
112 		NavLinkPair pair = (NavLinkPair)obj;
113 		return SafeEquals.equals(link1, pair.getNavLink1()) && SafeEquals.equals(link2, pair.getNavLink2());
114 	}
115 	
116 	/**
117 	 * Returns first {@link NavPointNeighbourLink}, this is NEVER NULL.
118 	 * @return
119 	 */
120 	public NavPointNeighbourLink getNavLink1() {
121 		return link1;
122 	}
123 	
124 	/**
125 	 * Returns second {@link NavPointNeighbourLink}, may be null.
126 	 * @return
127 	 */
128 	public NavPointNeighbourLink getNavLink2() {
129 		return link2;
130 	}
131 	
132 	/**
133 	 * Returns first's {@link NavPointNeighbourLink#getFromNavPoint()}, this is NEVER NULL.
134 	 * @return
135 	 */
136 	public NavPoint getNavPoint1() {
137 		return nav1;
138 	}
139 	
140 	/**
141 	 * Returns first's {@link NavPointNeighbourLink#getToNavPoint()}, this is NEVER NULL.
142 	 * @return
143 	 */
144 	public NavPoint getNavPoint2() {
145 		return nav2;
146 	}
147 	
148 	/**
149 	 * Does this {@link NavLinkPair} contains (as either end) 'navPoint'.
150 	 * @param navPoint
151 	 * @return
152 	 */
153 	public boolean isLinkNavPoint(NavPoint navPoint) {
154 		if (navPoint == null) return false;
155 		return SafeEquals.equals(navPoint.getId(), nav1.getId()) || SafeEquals.equals(navPoint.getId(), nav2.getId());
156 	}
157 	
158 	/**
159 	 * Does this {@link NavLinkPair} contains (as either end) 'navPoint'.
160 	 * @param navPoint
161 	 * @return
162 	 */
163 	public boolean isLinkNavPoint(UnrealId navPointId) {
164 		if (navPointId == null) return false;
165 		return SafeEquals.equals(navPointId, nav1.getId()) || SafeEquals.equals(navPointId, nav2.getId());
166 	}
167 	
168 	/**
169 	 * Returns link that ends in 'navPointLinkEndsInId', if such exists.
170 	 * 
171 	 * @param navPointLinkEndsInId
172 	 * @return
173 	 */
174 	public NavPointNeighbourLink getLinkLeadingTo(UnrealId navPointLinkEndsInId) {
175 		if (navPointLinkEndsInId == null) return null;
176 		if (link1 != null && link1.getToNavPoint() != null) {
177 			if (link1.getToNavPoint().getId().equals(navPointLinkEndsInId)) return link1;
178 		}
179 		if (link2 != null && link2.getToNavPoint() != null) {
180 			if (link2.getToNavPoint().getId().equals(navPointLinkEndsInId)) return link1;
181 		}
182 		return null;
183 	}
184 	
185 	/**
186 	 * Returns link that originates in 'navPointLinkIsComingFromId', if such exists.
187 	 * 
188 	 * @param navPointLinkIsComingFromId
189 	 * @return
190 	 */
191 	public NavPointNeighbourLink getLinkComingFrom(UnrealId navPointLinkIsComingFromId) {
192 		if (navPointLinkIsComingFromId == null) return null;
193 		if (link1 != null && link1.getFromNavPoint() != null) {
194 			if (link1.getFromNavPoint().getId().equals(navPointLinkIsComingFromId)) return link1;
195 		}
196 		if (link2 != null && link2.getFromNavPoint() != null) {
197 			if (link2.getFromNavPoint().getId().equals(navPointLinkIsComingFromId)) return link1;
198 		}
199 		return null;
200 	}
201 	
202 	/**
203 	 * Returns link that ends in 'navPointLinkEndsIn', if such exists.
204 	 * 
205 	 * @param navPointLinkEndsIn
206 	 * @return
207 	 */
208 	public NavPointNeighbourLink getLinkLeadingTo(NavPoint navPointLinkEndsIn) {
209 		if (navPointLinkEndsIn == null) return null;
210 		if (link1 != null && link1.getToNavPoint() != null) {
211 			if (link1.getToNavPoint().getId().equals(navPointLinkEndsIn.getId())) return link1;
212 		}
213 		if (link2 != null && link2.getToNavPoint() != null) {
214 			if (link2.getToNavPoint().getId().equals(navPointLinkEndsIn.getId())) return link1;
215 		}
216 		return null;
217 	}
218 	
219 	/**
220 	 * Returns link that originates in 'navPointLinkIsComingFrom', if such exists.
221 	 * 
222 	 * @param navPointLinkIsComingFrom
223 	 * @return
224 	 */
225 	public NavPointNeighbourLink getLinkComingFrom(NavPoint navPointLinkIsComingFrom) {
226 		if (navPointLinkIsComingFrom == null) return null;
227 		if (link1 != null && link1.getFromNavPoint() != null) {
228 			if (link1.getFromNavPoint().getId().equals(navPointLinkIsComingFrom.getId())) return link1;
229 		}
230 		if (link2 != null && link2.getFromNavPoint() != null) {
231 			if (link2.getFromNavPoint().getId().equals(navPointLinkIsComingFrom.getId())) return link1;
232 		}
233 		return null;
234 	}
235 	
236 	/**
237 	 * Get vector of the first link.
238 	 * @return
239 	 */
240 	public Location getFirstVector() {			
241 		if (link1 == null) return null;
242 		return link1.getToNavPoint().getLocation().sub(link1.getFromNavPoint().getLocation());
243 	}
244 	
245 	/**
246 	 * Get vector of the second link.
247 	 * @return
248 	 */
249 	public Location getSecondVector() {			
250 		if (link2 == null) return null;
251 		return link2.getToNavPoint().getLocation().sub(link2.getFromNavPoint().getLocation());
252 	}
253 	
254 	/**
255 	 * Distance "point" from "link". 
256 	 * 
257 	 * See: http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
258 	 * 
259 	 * @param point
260 	 * @return
261 	 */
262 	public double getDistance(ILocated point) {
263 		if (point == null) return Double.MAX_VALUE;
264 		if (x1 == null || x2 == null) return Double.MAX_VALUE;
265 		
266 		// SEE: http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
267 		Location x0 = point.getLocation();
268 		double distance = x0.sub(x1).cross(x0.sub(x2)).getLength() / x2.sub(x1).getLength();
269 		
270 		return distance;
271 	}
272 
273 }