package com.momega.spacesimulator.service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.util.Assert; import com.momega.spacesimulator.model.KeplerianElements; import com.momega.spacesimulator.model.KeplerianOrbit; import com.momega.spacesimulator.model.MovingObject; import com.momega.spacesimulator.model.Timestamp; import com.momega.spacesimulator.model.UserOrbitalPoint; import com.momega.spacesimulator.model.Vector3d; import com.momega.spacesimulator.utils.VectorUtils; /** * Created by martin on 10/17/14. */ @Component public class UserPointService { private static final Logger logger = LoggerFactory.getLogger(UserPointService.class); public void computeUserPoints(MovingObject movingObject, Timestamp newTimestamp) { for(UserOrbitalPoint userOrbitalPoint : movingObject.getUserOrbitalPoints()) { computeUserPoint(userOrbitalPoint, newTimestamp); } } public void computeUserPoint(UserOrbitalPoint userOrbitalPoint, Timestamp newTimestamp) { KeplerianElements keplerianElements = userOrbitalPoint.getKeplerianElements(); KeplerianElements spacecraftKeplerianElements = userOrbitalPoint.getMovingObject().getKeplerianElements(); KeplerianOrbit keplerianOrbit = spacecraftKeplerianElements.getKeplerianOrbit(); keplerianElements.setKeplerianOrbit(keplerianOrbit); double theta = keplerianElements.getTrueAnomaly(); Vector3d position = keplerianElements.getCartesianPosition(); userOrbitalPoint.setPosition(position); Timestamp timestamp = userOrbitalPoint.getMovingObject().getKeplerianElements().timeToAngle(newTimestamp, theta, true); userOrbitalPoint.setTimestamp(timestamp); } /** * Creates the user orbital point * @param movingObject the {@link com.momega.spacesimulator.model.PhysicalBody} * @param modelCoordinates the model coordinates * @return new instance of the {@link com.momega.spacesimulator.model.UserOrbitalPoint}. The point is registered * to the physicalbody */ public UserOrbitalPoint createUserOrbitalPoint(MovingObject movingObject, Vector3d modelCoordinates, Timestamp timestamp) { UserOrbitalPoint userPoint = new UserOrbitalPoint(); userPoint.setPosition(modelCoordinates); userPoint.setVisible(true); userPoint.setMovingObject(movingObject); createKeplerianElementsByPosition(movingObject, userPoint, modelCoordinates, timestamp); userPoint.setName("User Point"); movingObject.getUserOrbitalPoints().add(userPoint); return userPoint; } public UserOrbitalPoint createUserOrbitalPoint(MovingObject movingObject, String name, double trueAnomaly, Timestamp timestamp) { UserOrbitalPoint userPoint = new UserOrbitalPoint(); userPoint.setVisible(true); userPoint.setName(name); userPoint.setMovingObject(movingObject); updateUserOrbitalPoint(userPoint, trueAnomaly, movingObject, timestamp); Vector3d position = userPoint.getKeplerianElements().getKeplerianOrbit().getCartesianPosition(trueAnomaly); userPoint.setPosition(position); logger.info("User point '{}' created", name); movingObject.getUserOrbitalPoints().add(userPoint); return userPoint; } /** * Updates the position of the orbital point * @param userOrbitalPoint the orbital point * @param newPosition new position */ public void updateUserOrbitalPoint(UserOrbitalPoint userOrbitalPoint, Vector3d newPosition, Timestamp timestamp) { MovingObject movingObject = (MovingObject) userOrbitalPoint.getMovingObject(); createKeplerianElementsByPosition(movingObject, userOrbitalPoint, newPosition, timestamp); } /** * updates the elements of the user orbital point * @param userOrbitalPoint the orbital point * @param trueAnomaly new true anomaly * @param movingObject the moving object */ public void updateUserOrbitalPoint(UserOrbitalPoint userOrbitalPoint, Double trueAnomaly, MovingObject movingObject, Timestamp timestamp) { Assert.notNull(trueAnomaly); KeplerianOrbit keplerianOrbit = movingObject.getKeplerianElements().getKeplerianOrbit(); createKeplerianElementsByOrbit(movingObject, userOrbitalPoint, keplerianOrbit, trueAnomaly, timestamp); } protected void createKeplerianElementsByPosition(MovingObject movingObject, UserOrbitalPoint userPoint, Vector3d position, Timestamp timestamp) { KeplerianOrbit keplerianOrbit = movingObject.getKeplerianElements().getKeplerianOrbit(); logger.debug("orbit = {}", keplerianOrbit.toString()); Vector3d v = position.subtract(keplerianOrbit.getReferenceFrame().getPosition()); v = VectorUtils.transform(keplerianOrbit, v); logger.debug("vector = {}", v.asArray()); double theta = Math.atan2(v.getY(), v.getX()); logger.info("theta = {}", Math.toDegrees(theta)); createKeplerianElementsByOrbit(movingObject, userPoint, keplerianOrbit, theta, timestamp); } protected void createKeplerianElementsByOrbit(MovingObject movingObject, UserOrbitalPoint userPoint, KeplerianOrbit keplerianOrbit, double trueAnomaly, Timestamp timestamp) { Assert.notNull(movingObject); Assert.notNull(userPoint); KeplerianElements keplerianElements = new KeplerianElements(); keplerianElements.setTrueAnomaly(trueAnomaly); keplerianElements.setKeplerianOrbit(keplerianOrbit); userPoint.setKeplerianElements(keplerianElements); userPoint.setTimestamp(movingObject.getKeplerianElements().timeToAngle(timestamp, trueAnomaly, true)); } /** * Deletes the user defined point * @param movingObject the moving object the point belong * @param point the given point */ public void deleteUserPoint(MovingObject movingObject, UserOrbitalPoint point) { movingObject.getUserOrbitalPoints().remove(point); } }