// ********************************************************************** // // <copyright> // // BBN Technologies // 10 Moulton Street // Cambridge, MA 02138 // (617) 873-8000 // // Copyright (C) BBNT Solutions LLC. All rights reserved. // // </copyright> // ********************************************************************** // // $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/graphicLoader/PathGLPoint.java,v $ // $RCSfile: PathGLPoint.java,v $ // $Revision: 1.6 $ // $Date: 2009/02/25 22:34:04 $ // $Author: dietrick $ // // ********************************************************************** package com.bbn.openmap.graphicLoader; import java.awt.Graphics; import com.bbn.openmap.omGraphics.OMGraphic; import com.bbn.openmap.omGraphics.OMPoly; import com.bbn.openmap.proj.GreatCircle; import com.bbn.openmap.proj.Length; import com.bbn.openmap.proj.ProjMath; import com.bbn.openmap.proj.Projection; import com.bbn.openmap.proj.coords.LatLonPoint; import com.bbn.openmap.util.Debug; /** * The PathGLPoint is a GLPoint that follows a certain path, as * opposed to just wandering around randomly. */ public class PathGLPoint extends GLPoint { double[] pathPoints = null; OMPoly poly = null; int pathIndex = 0; double currentSegDist = 0; double nextSegOffset = 0f; double rate = Length.METER.toRadians(10000); public PathGLPoint(OMPoly path, int radius, boolean isOval) { super(0f, 0f, radius, isOval); setPoly(path); } public void move(float factor) { if (!stationary) { moveAlong(); } } public double[] getSegmentCoordinates(int currentPathIndex) { double[] latlons = new double[4]; if (pathIndex > pathPoints.length - 2 || pathIndex < 0) { pathIndex = 0; } if (pathPoints.length >= 4) { int la1 = pathIndex; int lo1 = pathIndex + 1; int la2 = pathIndex + 2; int lo2 = pathIndex + 3; if (lo2 >= pathPoints.length) { if (poly.isPolygon()) { Debug.message("graphicloader", "PathGLPoint.moveAlong(): index to big, wrapping... "); la2 = 0; lo2 = 1; } else { pathIndex = 0; Debug.message("graphicloader", "PathGLPoint.moveAlong(): index to big, no wrapping, starting over... "); return getSegmentCoordinates(pathIndex); } } latlons[0] = pathPoints[la1]; latlons[1] = pathPoints[lo1]; latlons[2] = pathPoints[la2]; latlons[3] = pathPoints[lo2]; } return latlons; } public void moveAlong() { if (Debug.debugging("graphicloader")) { Debug.output("PathGLPoint.moveAlong(): segment " + (pathIndex / 2) + " of " + (pathPoints.length / 2)); } double azimuth; LatLonPoint newPoint; double[] latlons = getSegmentCoordinates(pathIndex); double segLength = GreatCircle.sphericalDistance(latlons[0], latlons[1], latlons[2], latlons[3]); if (Debug.debugging("graphicloader")) { Debug.output("PathGLPoint.moveAlong(): segment Length " + segLength + ", and already have " + currentSegDist + " of it."); } double needToTravel = rate; int originalPathIndex = pathIndex; int loopingTimes = 0; while (needToTravel >= segLength - currentSegDist) { needToTravel -= (segLength - currentSegDist); currentSegDist = 0f; pathIndex += 2; // Move to the next segment of the poly if (Debug.debugging("graphicloader")) { Debug.output("PathGLPoint to next segment(" + (pathIndex / 2) + "), need to travel " + needToTravel); } latlons = getSegmentCoordinates(pathIndex); if (pathIndex == originalPathIndex) { loopingTimes++; if (loopingTimes > 1) { Debug.output("PathGLPoint looping on itself, setting to stationary"); setStationary(true); return; } } segLength = GreatCircle.sphericalDistance(latlons[0], latlons[1], latlons[2], latlons[3]); } if (Debug.debugging("graphicloader")) { Debug.output("Moving PathGLPoint within current(" + (pathIndex / 2) + ") segment, segLength: " + segLength + ", ntt: " + needToTravel); } // Staying on this segment, just calculate where the // next point on the segment is. azimuth = GreatCircle.sphericalAzimuth(latlons[0], latlons[1], latlons[2], latlons[3]); newPoint = GreatCircle.sphericalBetween(latlons[0], latlons[1], currentSegDist + needToTravel, azimuth); setLat(newPoint.getY()); setLon(newPoint.getX()); currentSegDist = GreatCircle.sphericalDistance(latlons[0], latlons[1], (float)newPoint.getRadLat(), (float)newPoint.getRadLon()); } public boolean generate(Projection p) { boolean ret = super.generate(p); if (poly != null) { poly.generate(p); } return ret; } public void render(Graphics g) { if (poly != null) { poly.render(g); } super.render(g); } public void setPoly(OMPoly p) { poly = p; if (poly.getRenderType() == OMGraphic.RENDERTYPE_LATLON) { pathPoints = poly.getLatLonArray(); setLat(ProjMath.radToDeg(pathPoints[0])); setLon(ProjMath.radToDeg(pathPoints[1])); setStationary(false); } else { setStationary(true); } } public OMPoly getPoly() { return poly; } }