/*
* Licensed Materials - Property of Rogue Wave Software, Inc.
* © Copyright Rogue Wave Software, Inc. 2014, 2017
* © Copyright IBM Corp. 2009, 2014
* © Copyright ILOG 1996, 2009
* All Rights Reserved.
*
* Note to U.S. Government Users Restricted Rights:
* The Software and Documentation were developed at private expense and
* are "Commercial Items" as that term is defined at 48 CFR 2.101,
* consisting of "Commercial Computer Software" and
* "Commercial Computer Software Documentation", as such terms are
* used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
* as applicable.
*/
package simulation;
//import ilog.views.maps.defense.symbology.app6a.IlvApp6aSymbol;
import ilog.views.IlvPoint;
import ilog.views.graphic.IlvPolyPoints;
import ilog.views.maps.IlvGeodeticComputation;
import ilog.views.maps.projection.IlvEllipsoid;
import ilog.views.sdm.IlvSDMEngine;
/**
* Class for enemy unit being targets of missiles.
*
* @see Mobile
*
*/
public class PathConstrainedMobile extends Mobile {
private IlvPolyPoints path;
private int segmentIndex;
private double distance;
private double distanceToSegment;
/**
* Creates a target with a different symboloc tag.
*
* @param tag
*
* @param sym
* symbology.
* @param road
* @param randomLocation
*/
protected PathConstrainedMobile(String tag, IlvSDMEngine sym, IlvPolyPoints road, boolean randomLocation) {
super(tag, sym);
this.path = road;
int index = 0;
if (randomLocation) {
index = (int) (SimulationContext.random() * (road.getPointsCardinal() - 1));
}
double lon0 = road.getPointAt(index, null).getX();
double lat0 = road.getPointAt(index, null).getY();
segmentIndex = index;
distance = 0;
for (int i = 0; i < segmentIndex; i++) {
IlvPoint current = path.getPointAt(i, null);
IlvPoint next = path.getPointAt(i + 1, null);
double dy = next.getY() - current.getY();
double dx = next.getX() - current.getX();
double segmentLength = Math.sqrt(dx * dx + dy * dy);
distance += segmentLength;
}
distanceToSegment = distance;
setLocation(symbol, null, lon0, lat0);
updateLocation();
}
private IlvPoint computeCoordinatesFromDistance(double dist) {
IlvPoint result = null;
int segmentCount = path.getPointsCardinal() - 1;
double remainingDistance = -1;
for (int i = segmentIndex; i < segmentCount; i++) {
remainingDistance = dist - distanceToSegment;
IlvPoint current = path.getPointAt(i, null);
IlvPoint next = path.getPointAt(i + 1, null);
double dy = next.getY() - current.getY();
double dx = next.getX() - current.getX();
double segmentLength = Math.sqrt(dx * dx + dy * dy);
if (remainingDistance < segmentLength) {
// interpolate
double alpha = remainingDistance / segmentLength;
double x = current.getX() + alpha * dx;
double y = current.getY() + alpha * dy;
result = new IlvPoint(x, y);
break;
}
distanceToSegment += segmentLength;
segmentIndex++;
}
return result;
}
Override
public void updateLocation() {
if (isWrecked()) {
return;
}
double olon = getLongitude(symbol);
double olat = getLatitude(symbol);
long updateTime = System.currentTimeMillis();
double dt;
if (!paused) {
if (lastUpdateTime == 0) {
dt = 0;
} else {
dt = (updateTime - lastUpdateTime) / 1000.0;
}
dt *= SimulationContext.getTimeAcceleration();
// distance ran.
double speed = getHorizontalSpeed();
double distMeter = dt * speed;
// approximate distance
IlvGeodeticComputation gc = new IlvGeodeticComputation(IlvEllipsoid.SPHERE);
gc.setLatitude1(olat);
gc.setLongitude1(olon);
gc.setDistance(distMeter);
gc.setForwardAzimuth(getDirection());
gc.computeGeodeticForward();
double newLon = gc.getLongitude2();
double newLat = gc.getLatitude2();
double dLat = newLat - olat;
double dLon = newLon - olon;
double distLonLat = Math.sqrt(dLat * dLat + dLon * dLon);
distance += distLonLat;
// compute new coordinates on the path
IlvPoint p = computeCoordinatesFromDistance(distance);
if (p == null) {
wreck();
return;
}
// set direction
IlvPoint current = path.getPointAt(segmentIndex, null);
IlvPoint next = path.getPointAt(segmentIndex + 1, null);
double dir = Math.atan2(next.getX() - current.getX(), next.getY() - current.getY());
setDirection(dir);
setSymbolProperty(MODIFIER_DIRECTION_OF_MOVEMENT_INDICATOR, "" + Math.toDegrees(getDirection() - Math.PI / 2), //$NON-NLS-1$
false);
lastUpdateTime = updateTime;
// update location
boolean ia = symbology.getModel().isAdjusting();
if (!ia)
symbology.getModel().setAdjusting(true);
setLocation(symbol, symbology, p.getX(), p.getY());
if (!ia)
symbology.getModel().setAdjusting(false);
}
lastUpdateTime = updateTime;
updateStatus();
}
}