Update to Worldwind release 0.4.1
[worldwind-tracker.git] / gov / nasa / worldwind / view / ScheduledOrbitViewStateIterator.java
blob9f6350a6e5e68656f6b2ce5b138495da7fa2ff5d
1 /*
2 Copyright (C) 2001, 2006 United States Government as represented by
3 the Administrator of the National Aeronautics and Space Administration.
4 All Rights Reserved.
5 */
6 package gov.nasa.worldwind.view;
8 import gov.nasa.worldwind.geom.*;
9 import gov.nasa.worldwind.util.Logging;
11 /**
12 * @author dcollins
13 * @version $Id: ScheduledOrbitViewStateIterator.java 3422 2007-11-01 17:31:06Z tgaskins $
15 public class ScheduledOrbitViewStateIterator extends BasicOrbitViewStateIterator
17 private final int maxSmoothing;
19 protected ScheduledOrbitViewStateIterator(long lengthMillis, OrbitViewAnimator animator, boolean doSmoothing)
21 this(new ScheduledOrbitViewInterpolator(lengthMillis), animator, doSmoothing);
24 protected ScheduledOrbitViewStateIterator(ScheduledOrbitViewInterpolator interpolator, OrbitViewAnimator animator,
25 boolean doSmoothing)
27 super(false, interpolator, animator);
29 if (interpolator == null)
31 String message = Logging.getMessage("nullValue.OrbitViewInterpolatorIsNull");
32 Logging.logger().severe(message);
33 throw new IllegalArgumentException(message);
35 if (animator == null)
37 String message = Logging.getMessage("nullValue.OrbitViewAnimatorIsNull");
38 Logging.logger().severe(message);
39 throw new IllegalArgumentException(message);
42 this.maxSmoothing = maxSmoothingFromFlag(doSmoothing);
45 public final boolean isSmoothing()
47 return this.maxSmoothing != 0;
50 public void doNextState(double interpolant, OrbitView orbitView)
52 if (orbitView == null)
54 String message = Logging.getMessage("nullValue.OrbitViewIsNull");
55 Logging.logger().severe(message);
56 throw new IllegalArgumentException(message);
59 double smoothedInterpolant = interpolantSmoothed(interpolant, this.maxSmoothing);
60 super.doNextState(smoothedInterpolant, orbitView);
63 private static double interpolantSmoothed(double interpolant, int smoothingIterations)
65 // Apply iterative hermite smoothing.
66 double smoothed = interpolant;
67 for (int i = 0; i < smoothingIterations; i++)
69 smoothed = smoothed * smoothed * (3.0 - 2.0 * smoothed);
71 return smoothed;
74 private static int maxSmoothingFromFlag(boolean doSmoothing)
76 if (doSmoothing)
77 return 1;
78 else
79 return 0;
82 // ============== Factory Functions ======================= //
83 // ============== Factory Functions ======================= //
84 // ============== Factory Functions ======================= //
86 public static ScheduledOrbitViewStateIterator createLatLonIterator(
87 OrbitView orbitView,
88 LatLon latLon)
90 if (orbitView == null)
92 String message = Logging.getMessage("nullValue.ViewIsNull");
93 Logging.logger().severe(message);
94 throw new IllegalArgumentException(message);
96 if (latLon == null)
98 String message = Logging.getMessage("nullValue.LatLonIsNull");
99 Logging.logger().severe(message);
100 throw new IllegalArgumentException(message);
103 LatLon begin = new LatLon(orbitView.getLatitude(), orbitView.getLongitude());
104 return createLatLonIterator(
105 begin, latLon);
108 public static ScheduledOrbitViewStateIterator createLatLonIterator(
109 LatLon begin, LatLon end)
111 if (begin == null || end == null)
113 String message = Logging.getMessage("nullValue.LatLonIsNull");
114 Logging.logger().severe(message);
115 throw new IllegalArgumentException(message);
118 // TODO: length-scaling factory function
119 final long DEFAULT_LENGTH_MILLIS = 4000;
120 boolean smoothed = true;
121 return createLatLonIterator(
122 begin, end,
123 DEFAULT_LENGTH_MILLIS, smoothed);
126 public static ScheduledOrbitViewStateIterator createLatLonIterator(
127 LatLon begin, LatLon end,
128 long lengthMillis, boolean smoothed)
130 if (begin == null || end == null)
132 String message = Logging.getMessage("nullValue.LatLonIsNull");
133 Logging.logger().severe(message);
134 throw new IllegalArgumentException(message);
136 if (lengthMillis < 0)
138 String message = Logging.getMessage("generic.ArgumentOutOfRange", lengthMillis);
139 Logging.logger().severe(message);
140 throw new IllegalArgumentException(message);
143 OrbitViewPropertyAccessor.LatLonAccessor propertyAccessor
144 = OrbitViewPropertyAccessor.createLatitudeAndLongitudeAccessor();
145 OrbitViewAnimator animator = new BasicOrbitViewAnimator.LatLonAnimator(begin, end, propertyAccessor);
146 return new ScheduledOrbitViewStateIterator(
147 lengthMillis,
148 animator,
149 smoothed);
152 public static ScheduledOrbitViewStateIterator createPositionIterator(
153 Position begin, Position end,
154 long lengthMillis, boolean smoothed)
156 if (begin == null || end == null)
158 String message = Logging.getMessage("nullValue.LatLonIsNull");
159 Logging.logger().severe(message);
160 throw new IllegalArgumentException(message);
162 if (lengthMillis < 0)
164 String message = Logging.getMessage("generic.ArgumentOutOfRange", lengthMillis);
165 Logging.logger().severe(message);
166 throw new IllegalArgumentException(message);
169 OrbitViewPropertyAccessor.LatLonAccessor llPropertyAccessor
170 = OrbitViewPropertyAccessor.createLatitudeAndLongitudeAccessor();
171 OrbitViewAnimator llAnimator = new BasicOrbitViewAnimator.LatLonAnimator(
172 begin.getLatLon(), end.getLatLon(), llPropertyAccessor);
174 OrbitViewPropertyAccessor.DoubleAccessor altPropertyAccessor = OrbitViewPropertyAccessor.createAltitudeAccessor();
175 OrbitViewAnimator altAnimator = new BasicOrbitViewAnimator.DoubleAnimator(
176 begin.getElevation(), end.getElevation(), altPropertyAccessor);
177 OrbitViewAnimator animator
178 = new BasicOrbitViewAnimator.CompoundAnimator(llAnimator, altAnimator);
180 return new ScheduledOrbitViewStateIterator(
181 lengthMillis,
182 animator,
183 smoothed);
186 public static ScheduledOrbitViewStateIterator createPositionHeadingIterator(
187 Position begin, Position end, Angle beginHeading, Angle endHeading,
188 long lengthMillis, boolean smoothed)
190 if (begin == null || end == null)
192 String message = Logging.getMessage("nullValue.LatLonIsNull");
193 Logging.logger().severe(message);
194 throw new IllegalArgumentException(message);
196 if (lengthMillis < 0)
198 String message = Logging.getMessage("generic.ArgumentOutOfRange", lengthMillis);
199 Logging.logger().severe(message);
200 throw new IllegalArgumentException(message);
203 OrbitViewPropertyAccessor.LatLonAccessor llPropertyAccessor
204 = OrbitViewPropertyAccessor.createLatitudeAndLongitudeAccessor();
205 OrbitViewAnimator llAnimator = new BasicOrbitViewAnimator.LatLonAnimator(
206 begin.getLatLon(), end.getLatLon(), llPropertyAccessor);
208 OrbitViewPropertyAccessor.DoubleAccessor altPropertyAccessor = OrbitViewPropertyAccessor.createAltitudeAccessor();
209 OrbitViewAnimator altAnimator = new BasicOrbitViewAnimator.DoubleAnimator(
210 begin.getElevation(), end.getElevation(), altPropertyAccessor);
212 OrbitViewPropertyAccessor.AngleAccessor propertyAccessor = OrbitViewPropertyAccessor.createHeadingAccessor();
213 OrbitViewAnimator headingAnimator = new BasicOrbitViewAnimator.AngleAnimator(
214 beginHeading, endHeading, propertyAccessor);
216 OrbitViewAnimator animator
217 = new BasicOrbitViewAnimator.CompoundAnimator(llAnimator, altAnimator, headingAnimator);
219 return new ScheduledOrbitViewStateIterator(
220 lengthMillis,
221 animator,
222 smoothed);
225 public static ScheduledOrbitViewStateIterator createPositionHeadingPitchIterator(
226 Position begin, Position end, Angle beginHeading, Angle endHeading, Angle beginPitch, Angle endPitch,
227 long lengthMillis, boolean smoothed)
229 if (begin == null || end == null)
231 String message = Logging.getMessage("nullValue.LatLonIsNull");
232 Logging.logger().severe(message);
233 throw new IllegalArgumentException(message);
235 if (lengthMillis < 0)
237 String message = Logging.getMessage("generic.ArgumentOutOfRange", lengthMillis);
238 Logging.logger().severe(message);
239 throw new IllegalArgumentException(message);
242 OrbitViewPropertyAccessor.LatLonAccessor llPropertyAccessor
243 = OrbitViewPropertyAccessor.createLatitudeAndLongitudeAccessor();
244 OrbitViewAnimator llAnimator = new BasicOrbitViewAnimator.LatLonAnimator(
245 begin.getLatLon(), end.getLatLon(), llPropertyAccessor);
247 OrbitViewPropertyAccessor.DoubleAccessor altPropertyAccessor = OrbitViewPropertyAccessor.createAltitudeAccessor();
248 OrbitViewAnimator altAnimator = new BasicOrbitViewAnimator.DoubleAnimator(
249 begin.getElevation(), end.getElevation(), altPropertyAccessor);
251 OrbitViewPropertyAccessor.AngleAccessor headingropertyAccessor = OrbitViewPropertyAccessor.createHeadingAccessor();
252 OrbitViewAnimator headingAnimator = new BasicOrbitViewAnimator.AngleAnimator(
253 beginHeading, endHeading, headingropertyAccessor);
255 OrbitViewPropertyAccessor.AngleAccessor pitchPropertyAccessor = OrbitViewPropertyAccessor.createPitchAccessor();
256 OrbitViewAnimator pitchAnimator = new BasicOrbitViewAnimator.AngleAnimator(
257 beginPitch, endPitch, pitchPropertyAccessor);
259 OrbitViewAnimator animator
260 = new BasicOrbitViewAnimator.CompoundAnimator(llAnimator, altAnimator, headingAnimator, pitchAnimator);
262 return new ScheduledOrbitViewStateIterator(
263 lengthMillis,
264 animator,
265 smoothed);
268 public static ScheduledOrbitViewStateIterator createAltitudeIterator(
269 OrbitView orbitView,
270 double value)
272 double begin = orbitView.getAltitude();
273 return createAltitudeIterator(
274 begin, value);
277 public static ScheduledOrbitViewStateIterator createAltitudeIterator(
278 double begin, double end)
280 // TODO: length-scaling factory function
281 final long DEFAULT_LENGTH_MILLIS = 4000;
282 boolean smoothed = true;
283 return createAltitudeIterator(
284 begin, end,
285 DEFAULT_LENGTH_MILLIS, smoothed);
288 public static ScheduledOrbitViewStateIterator createAltitudeIterator(
289 double begin, double end,
290 long lengthMillis, boolean smoothed)
292 if (lengthMillis < 0)
294 String message = Logging.getMessage("generic.ArgumentOutOfRange", lengthMillis);
295 Logging.logger().severe(message);
296 throw new IllegalArgumentException(message);
299 OrbitViewPropertyAccessor.DoubleAccessor propertyAccessor = OrbitViewPropertyAccessor.createAltitudeAccessor();
300 OrbitViewAnimator animator = new BasicOrbitViewAnimator.DoubleAnimator(begin, end, propertyAccessor);
301 return new ScheduledOrbitViewStateIterator(
302 lengthMillis,
303 animator,
304 smoothed);
307 public static ScheduledOrbitViewStateIterator createHeadingIterator(
308 OrbitView orbitView,
309 Angle value)
311 if (value == null)
313 String message = Logging.getMessage("nullValue.AngleIsNull");
314 Logging.logger().severe(message);
315 throw new IllegalArgumentException(message);
318 Angle begin = orbitView.getHeading();
319 return createHeadingIterator(
320 begin,
321 value);
324 public static ScheduledOrbitViewStateIterator createHeadingIterator(
325 Angle begin,
326 Angle end)
328 if (begin == null || end == null)
330 String message = Logging.getMessage("nullValue.AngleIsNull");
331 Logging.logger().severe(message);
332 throw new IllegalArgumentException(message);
335 final long MIN_LENGTH_MILLIS = 500;
336 final long MAX_LENGTH_MILLIS = 3000;
337 long lengthMillis = getScaledLengthMillis(
338 begin, end, Angle.POS180,
339 MIN_LENGTH_MILLIS, MAX_LENGTH_MILLIS);
340 boolean smoothed = true;
341 return createHeadingIterator(
342 begin,
343 end,
344 lengthMillis, smoothed);
347 public static ScheduledOrbitViewStateIterator createHeadingIterator(
348 Angle begin,
349 Angle end,
350 long lengthMillis, boolean smoothed)
352 if (begin == null || end == null)
354 String message = Logging.getMessage("nullValue.AngleIsNull");
355 Logging.logger().severe(message);
356 throw new IllegalArgumentException(message);
358 if (lengthMillis < 0)
360 String message = Logging.getMessage("generic.ArgumentOutOfRange", lengthMillis);
361 Logging.logger().severe(message);
362 throw new IllegalArgumentException(message);
365 OrbitViewPropertyAccessor.AngleAccessor propertyAccessor = OrbitViewPropertyAccessor.createHeadingAccessor();
366 OrbitViewAnimator animator = new BasicOrbitViewAnimator.AngleAnimator(begin, end, propertyAccessor);
367 return new ScheduledOrbitViewStateIterator(
368 lengthMillis,
369 animator,
370 smoothed);
373 public static ScheduledOrbitViewStateIterator createPitchIterator(
374 OrbitView orbitView,
375 Angle value)
377 if (value == null)
379 String message = Logging.getMessage("nullValue.AngleIsNull");
380 Logging.logger().severe(message);
381 throw new IllegalArgumentException(message);
384 Angle begin = orbitView.getPitch();
385 return createPitchIterator(
386 begin,
387 value);
390 public static ScheduledOrbitViewStateIterator createPitchIterator(
391 Angle begin,
392 Angle end)
394 if (begin == null || end == null)
396 String message = Logging.getMessage("nullValue.AngleIsNull");
397 Logging.logger().severe(message);
398 throw new IllegalArgumentException(message);
401 final long MIN_LENGTH_MILLIS = 500;
402 final long MAX_LENGTH_MILLIS = 1500;
403 long lengthMillis = getScaledLengthMillis(
404 begin, end, Angle.POS90,
405 MIN_LENGTH_MILLIS, MAX_LENGTH_MILLIS);
406 boolean smoothed = true;
407 return createPitchIterator(
408 begin,
409 end,
410 lengthMillis, smoothed);
413 public static ScheduledOrbitViewStateIterator createPitchIterator(
414 Angle begin,
415 Angle end,
416 long lengthMillis, boolean smoothed)
418 if (begin == null || end == null)
420 String message = Logging.getMessage("nullValue.AngleIsNull");
421 Logging.logger().severe(message);
422 throw new IllegalArgumentException(message);
424 if (lengthMillis < 0)
426 String message = Logging.getMessage("generic.ArgumentOutOfRange", lengthMillis);
427 Logging.logger().severe(message);
428 throw new IllegalArgumentException(message);
431 OrbitViewPropertyAccessor.AngleAccessor propertyAccessor = OrbitViewPropertyAccessor.createPitchAccessor();
432 OrbitViewAnimator animator = new BasicOrbitViewAnimator.AngleAnimator(begin, end, propertyAccessor);
433 return new ScheduledOrbitViewStateIterator(
434 lengthMillis,
435 animator,
436 smoothed);
439 public static ScheduledOrbitViewStateIterator createHeadingAndPitchIterator(
440 OrbitView orbitView,
441 Angle heading, Angle pitch)
443 if (heading == null || pitch == null)
445 String message = Logging.getMessage("nullValue.AngleIsNull");
446 Logging.logger().severe(message);
447 throw new IllegalArgumentException(message);
450 Angle beginHeading = orbitView.getHeading();
451 Angle beginPitch = orbitView.getPitch();
452 return createHeadingAndPitchIterator(
453 beginHeading, heading,
454 beginPitch, pitch);
457 public static ScheduledOrbitViewStateIterator createHeadingAndPitchIterator(
458 Angle beginHeading, Angle endHeading,
459 Angle beginPitch, Angle endPitch)
461 if (beginHeading == null || endHeading == null || beginPitch == null || endPitch == null)
463 String message = Logging.getMessage("nullValue.AngleIsNull");
464 Logging.logger().severe(message);
465 throw new IllegalArgumentException(message);
468 final long MIN_LENGTH_MILLIS = 500;
469 final long MAX_LENGTH_MILLIS = 3000;
470 long headingLengthMillis = getScaledLengthMillis(
471 beginHeading, endHeading, Angle.POS180,
472 MIN_LENGTH_MILLIS, MAX_LENGTH_MILLIS);
473 long pitchLengthMillis = getScaledLengthMillis(
474 beginPitch, endPitch, Angle.POS90,
475 MIN_LENGTH_MILLIS, MAX_LENGTH_MILLIS / 2L);
476 long lengthMillis = headingLengthMillis + pitchLengthMillis;
477 boolean smoothed = true;
478 return createHeadingAndPitchIterator(
479 beginHeading, endHeading,
480 beginPitch, endPitch,
481 lengthMillis, smoothed);
484 public static ScheduledOrbitViewStateIterator createHeadingAndPitchIterator(
485 Angle beginHeading, Angle endHeading,
486 Angle beginPitch, Angle endPitch,
487 long lengthMillis, boolean smoothed)
489 if (beginHeading == null || endHeading == null || beginPitch == null || endPitch == null)
491 String message = Logging.getMessage("nullValue.AngleIsNull");
492 Logging.logger().severe(message);
493 throw new IllegalArgumentException(message);
495 if (lengthMillis < 0)
497 String message = Logging.getMessage("generic.ArgumentOutOfRange", lengthMillis);
498 Logging.logger().severe(message);
499 throw new IllegalArgumentException(message);
502 OrbitViewPropertyAccessor.AngleAccessor headingPropertyAccessor
503 = OrbitViewPropertyAccessor.createHeadingAccessor();
504 OrbitViewPropertyAccessor.AngleAccessor pitchPropertyAccessor
505 = OrbitViewPropertyAccessor.createPitchAccessor();
506 OrbitViewAnimator headingAnimator
507 = new BasicOrbitViewAnimator.AngleAnimator(beginHeading, endHeading, headingPropertyAccessor);
508 OrbitViewAnimator pitchAnimator
509 = new BasicOrbitViewAnimator.AngleAnimator(beginPitch, endPitch, pitchPropertyAccessor);
510 OrbitViewAnimator animator
511 = new BasicOrbitViewAnimator.CompoundAnimator(headingAnimator, pitchAnimator);
512 return new ScheduledOrbitViewStateIterator(
513 lengthMillis,
514 animator,
515 smoothed);
518 public static ScheduledOrbitViewStateIterator createZoomIterator(
519 OrbitView orbitView,
520 double value)
522 double begin = orbitView.getZoom();
523 return createZoomIterator(
524 begin, value);
527 public static ScheduledOrbitViewStateIterator createZoomIterator(
528 double begin, double end)
530 // TODO: length-scaling factory function
531 final long DEFAULT_LENGTH_MILLIS = 4000;
532 boolean smoothed = true;
533 return createZoomIterator(
534 begin, end,
535 DEFAULT_LENGTH_MILLIS, smoothed);
538 public static ScheduledOrbitViewStateIterator createZoomIterator(
539 double begin, double end,
540 long lengthMillis, boolean smoothed)
542 if (lengthMillis < 0)
544 String message = Logging.getMessage("generic.ArgumentOutOfRange", lengthMillis);
545 Logging.logger().severe(message);
546 throw new IllegalArgumentException(message);
549 OrbitViewPropertyAccessor.DoubleAccessor propertyAccessor = OrbitViewPropertyAccessor.createZoomAccessor();
550 OrbitViewAnimator animator = new BasicOrbitViewAnimator.DoubleAnimator(begin, end, propertyAccessor);
551 return new ScheduledOrbitViewStateIterator(
552 lengthMillis,
553 animator,
554 smoothed);
557 public static ScheduledOrbitViewStateIterator createLookAtLatLonIterator(
558 OrbitView orbitView,
559 LatLon latLon)
561 if (orbitView == null)
563 String message = Logging.getMessage("nullValue.ViewIsNull");
564 Logging.logger().fine(message);
565 throw new IllegalArgumentException(message);
567 if (latLon == null)
569 String message = Logging.getMessage("nullValue.LatLonIsNull");
570 Logging.logger().fine(message);
571 throw new IllegalArgumentException(message);
574 LatLon begin = new LatLon(orbitView.getLookAtLatitude(), orbitView.getLookAtLongitude());
575 return createLookAtLatLonIterator(
576 begin, latLon);
579 public static ScheduledOrbitViewStateIterator createLookAtLatLonIterator(
580 LatLon begin, LatLon end)
582 if (begin == null || end == null)
584 String message = Logging.getMessage("nullValue.LatLonIsNull");
585 Logging.logger().fine(message);
586 throw new IllegalArgumentException(message);
589 // TODO: length-scaling factory function
590 final long DEFAULT_LENGTH_MILLIS = 4000;
591 boolean smoothed = true;
592 return createLookAtLatLonIterator(
593 begin, end,
594 DEFAULT_LENGTH_MILLIS, smoothed);
597 public static ScheduledOrbitViewStateIterator createLookAtLatLonIterator(
598 LatLon begin, LatLon end,
599 long lengthMillis, boolean smoothed)
601 if (begin == null || end == null)
603 String message = Logging.getMessage("nullValue.LatLonIsNull");
604 Logging.logger().fine(message);
605 throw new IllegalArgumentException(message);
607 if (lengthMillis < 0)
609 String message = Logging.getMessage("generic.ArgumentOutOfRange");
610 Logging.logger().fine(message);
611 throw new IllegalArgumentException(message);
614 OrbitViewPropertyAccessor.LatLonAccessor propertyAccessor
615 = OrbitViewPropertyAccessor.createLookAtLatitudeAndLongitudeAccessor();
616 OrbitViewAnimator animator = new BasicOrbitViewAnimator.LatLonAnimator(begin, end, propertyAccessor);
617 return new ScheduledOrbitViewStateIterator(
618 lengthMillis,
619 animator,
620 smoothed);
623 private static long getScaledLengthMillis(
624 Angle begin, Angle end, Angle max,
625 long minLengthMillis, long maxLengthMillis)
627 Angle angularDistance = begin.angularDistanceTo(end);
628 double scaleFactor = angularRatio(angularDistance, max);
629 return (long) mixDouble(scaleFactor, minLengthMillis, maxLengthMillis);
632 private static double angularRatio(Angle x, Angle y)
634 if (x == null || y == null)
636 String message = Logging.getMessage("nullValue.AngleIsNull");
637 Logging.logger().severe(message);
638 throw new IllegalArgumentException(message);
641 double unclampedRatio = x.divide(y);
642 return clampDouble(unclampedRatio, 0, 1);
645 private static double clampDouble(double value, double min, double max)
647 return value < min ? min : (value > max ? max : value);
650 private static double mixDouble(double amount, double value1, double value2)
652 if (amount < 0)
653 return value1;
654 else if (amount > 1)
655 return value2;
656 return value1 * (1.0 - amount) + value2 * amount;