Worldwind public release 0.2
[worldwind-tracker.git] / gov / nasa / worldwind / geom / Frustum.java
blob7c817d07904e2bdef5ffdf49bd040b05b8701c40
1 /*
2 Copyright (C) 2001, 2006 United States Government
3 as represented by the Administrator of the
4 National Aeronautics and Space Administration.
5 All Rights Reserved.
6 */
7 package gov.nasa.worldwind.geom;
9 import gov.nasa.worldwind.*;
11 //todo: check javadoc accuracy,
13 /**
14 * Instances of <code>Frustum</code> are immutable. </p>
16 * @author Tom Gaskins
17 * @version $Id: Frustum.java 1774 2007-05-08 01:03:37Z dcollins $
19 public class Frustum
21 private final Plane left;
22 private final Plane right;
23 private final Plane bottom;
24 private final Plane top;
25 private final Plane near;
26 private final Plane far;
28 /**
29 * Create a default frustum with six <code>Plane</code>s. This defines a box of dimension (2, 2, 2) centered at the
30 * origin.
32 public Frustum()
34 this.near = new Plane(0d, 0d, 1d, 1d);
35 this.far = new Plane(0d, 0d, 0d - 1d, 1d);
36 this.left = new Plane(1d, 0d, 0d, 1d);
37 this.right = new Plane(0d - 1d, 0d, 0d, 1d);
38 this.bottom = new Plane(0d, 1d, 0d, 1d);
39 this.top = new Plane(0d, 0d - 1d, 0d, 1d);
42 /**
43 * Create a frustum from six <code>Plane</code>s, which define its boundaries. Does not except null arguments.
45 * @param near the near plane
46 * @param far the far plane
47 * @param left the left side of the view frustum
48 * @param right the right side of the view frustm
49 * @param top the top of the view frustum
50 * @param bottom the bottom of the view frustum
51 * @throws IllegalArgumentException if any argument is null
53 public Frustum(Plane near, Plane far, Plane left, Plane right, Plane bottom, Plane top)
55 if (near == null || far == null || left == null || right == null || bottom == null || top == null)
57 String message = WorldWind.retrieveErrMsg("nullValue.PlaneIsNull");
58 WorldWind.logger().log(java.util.logging.Level.FINE, message);
59 throw new IllegalArgumentException(message);
61 this.near = near;
62 this.far = far;
63 this.left = left;
64 this.right = right;
65 this.bottom = bottom;
66 this.top = top;
69 /**
70 * Obtain the near <code>Plane</code>.
72 * @return the near <code>Plane</code>
74 public final Plane getNear()
76 return this.near;
79 /**
80 * Obtain the far <code>Plane</code>.
82 * @return the far <code>Plane</code>
84 public final Plane getFar()
86 return this.far;
89 /**
90 * Obtain the left <code>Plane</code>.
92 * @return the left <code>Plane</code>
94 public final Plane getLeft()
96 return this.left;
99 /**
100 * Obtain the right <code>Plane</code>.
102 * @return the right <code>Plane</code>
104 public final Plane getRight()
106 return this.right;
110 * Obtain the bottom <code>Plane</code>.
112 * @return the bottom <code>Plane</code>
114 public final Plane getBottom()
116 return this.bottom;
120 * Obtain the top <code>Plane</code>.
122 * @return the top <code>Plane</code>
124 public final Plane getTop()
126 return this.top;
130 * @param m
131 * @return
132 * @throws IllegalArgumentException if <code>m</code> is null
134 public final Frustum getInverseTransformed(Matrix m)
136 if (m == null)
138 String message = WorldWind.retrieveErrMsg("nullValue.MatrixIsNull");
139 WorldWind.logger().log(java.util.logging.Level.FINE, message);
140 throw new IllegalArgumentException(message);
143 // Assumes orthogonal matrices with translation.
144 Matrix it = m.getTranspose();
146 Plane n = new Plane(it.transform(this.near.getVector()));
147 Plane f = new Plane(it.transform(this.far.getVector()));
148 Plane l = new Plane(it.transform(this.left.getVector()));
149 Plane r = new Plane(it.transform(this.right.getVector()));
150 Plane b = new Plane(it.transform(this.bottom.getVector()));
151 Plane t = new Plane(it.transform(this.top.getVector()));
153 return new Frustum(n, f, l, r, b, t);
157 * @param extent
158 * @return
159 * @throws IllegalArgumentException if <code>extent</code> is null
161 public final boolean intersects(Extent extent)
163 if (extent == null)
165 String message = WorldWind.retrieveErrMsg("nullValue.ExtentIsNull");
166 WorldWind.logger().log(java.util.logging.Level.FINE, message);
167 throw new IllegalArgumentException(message);
170 // See if the extent's bounding sphere is within or intersects the frustum.
171 Point c = extent.getCenter();
172 double nr = -extent.getRadius();
174 if (this.far.dot(c) <= nr)
175 return false;
176 if (this.left.dot(c) <= nr)
177 return false;
178 if (this.right.dot(c) <= nr)
179 return false;
180 if (this.top.dot(c) <= nr)
181 return false;
182 if (this.bottom.dot(c) <= nr)
183 return false;
184 //noinspection RedundantIfStatement
185 if (this.near.dot(c) <= nr)
186 return false;
188 return true;
192 * @param point
193 * @return
194 * @throws IllegalArgumentException if <code>point</code> is null
196 public final boolean contains(Point point)
198 if (point == null)
200 String message = WorldWind.retrieveErrMsg("nullValue.PointIsNull");
201 WorldWind.logger().log(java.util.logging.Level.FINE, message);
202 throw new IllegalArgumentException(message);
205 if (this.far.dot(point) < 0)
206 return false;
207 if (this.left.dot(point) < 0)
208 return false;
209 if (this.right.dot(point) < 0)
210 return false;
211 if (this.top.dot(point) < 0)
212 return false;
213 if (this.bottom.dot(point) < 0)
214 return false;
215 //noinspection RedundantIfStatement
216 if (this.near.dot(point) < 0)
217 return false;
219 return true;
222 @Override
223 public String toString()
225 return "near: " + near.toString() + "... far: " + far.toString() + "... left: " + left.toString()
226 + "... right: " + right.toString() + "... bottom: " + bottom.toString() + "... top: " + top.toString();
229 @Override
230 public boolean equals(Object o)
232 if (this == o)
233 return true;
234 if (o == null || getClass() != o.getClass())
235 return false;
237 final gov.nasa.worldwind.geom.Frustum frustum = (gov.nasa.worldwind.geom.Frustum) o;
239 if (!bottom.equals(frustum.bottom))
240 return false;
241 if (!far.equals(frustum.far))
242 return false;
243 if (!left.equals(frustum.left))
244 return false;
245 if (!near.equals(frustum.near))
246 return false;
247 if (!right.equals(frustum.right))
248 return false;
249 //noinspection RedundantIfStatement
250 if (!top.equals(frustum.top))
251 return false;
253 return true;
256 @Override
257 public int hashCode()
259 int result;
260 result = near.hashCode();
261 result = 31 * result + far.hashCode();
262 result = 29 * result + left.hashCode();
263 result = 23 * result + right.hashCode();
264 result = 19 * result + bottom.hashCode();
265 result = 17 * result + top.hashCode();
266 return result;