Search in sources :

Example 21 with GeodeticPoint

use of org.orekit.bodies.GeodeticPoint in project Orekit by CS-SI.

the class FootprintOverlapDetector method g.

/**
 * {@inheritDoc}
 * <p>
 * The g function value is the minimum offset among the region points
 * with respect to the Field Of View boundary. It is positive if all region
 * points are outside of the Field Of View, and negative if at least some
 * of the region points are inside of the Field Of View. The minimum is
 * computed by sampling the region, considering only the points for which
 * the spacecraft is above the horizon. The accuracy of the detection
 * depends on the linear sampling step set at detector construction. If
 * the spacecraft is below horizon for all region points, an arbitrary
 * positive value is returned.
 * </p>
 * <p>
 * As per the previous definition, when the region enters the Field Of
 * View, a decreasing event is generated, and when the region leaves
 * the Field Of View, an increasing event is generated.
 * </p>
 */
public double g(final SpacecraftState s) throws OrekitException {
    // initial arbitrary positive value
    double value = FastMath.PI;
    // get spacecraft position in body frame
    final Vector3D scBody = s.getPVCoordinates(body.getBodyFrame()).getPosition();
    // map the point to a sphere
    final GeodeticPoint gp = body.transform(scBody, body.getBodyFrame(), s.getDate());
    final S2Point s2p = new S2Point(gp.getLongitude(), 0.5 * FastMath.PI - gp.getLatitude());
    // for faster computation, we start using only the surrounding cap, to filter out
    // far away points (which correspond to most of the points if the zone is small)
    final Vector3D p = s2p.getVector();
    final double dot = Vector3D.dotProduct(p, capCenter);
    if (dot < capCos) {
        // the spacecraft is outside of the cap, look for the closest cap point
        final Vector3D t = p.subtract(dot, capCenter).normalize();
        final Vector3D close = new Vector3D(capCos, capCenter, capSin, t);
        if (Vector3D.dotProduct(p, close) < -0.01) {
            // we can return the arbitrary initial positive value without performing further computation
            return value;
        }
    }
    // the spacecraft may be visible from some points in the zone, check them all
    final Transform bodyToSc = new Transform(s.getDate(), body.getBodyFrame().getTransformTo(s.getFrame(), s.getDate()), s.toTransform());
    for (final SamplingPoint point : sampledZone) {
        final Vector3D lineOfSightBody = point.getPosition().subtract(scBody);
        if (Vector3D.dotProduct(lineOfSightBody, point.getZenith()) <= 0) {
            // spacecraft is above this sample point local horizon
            // get line of sight in spacecraft frame
            final double offset = fov.offsetFromBoundary(bodyToSc.transformVector(lineOfSightBody));
            value = FastMath.min(value, offset);
        }
    }
    return value;
}
Also used : S2Point(org.hipparchus.geometry.spherical.twod.S2Point) Vector3D(org.hipparchus.geometry.euclidean.threed.Vector3D) GeodeticPoint(org.orekit.bodies.GeodeticPoint) Transform(org.orekit.frames.Transform)

Example 22 with GeodeticPoint

use of org.orekit.bodies.GeodeticPoint in project Orekit by CS-SI.

the class FootprintOverlapDetector method sample.

/**
 * Sample the region.
 * @param body body on which the geographic zone is defined
 * @param zone geographic zone to consider
 * @param samplingStep  linear step used for sampling the geographic zone (in meters)
 * @return sampling points
 * @throws OrekitException if the region cannot be sampled
 */
private static List<SamplingPoint> sample(final OneAxisEllipsoid body, final SphericalPolygonsSet zone, final double samplingStep) throws OrekitException {
    final List<SamplingPoint> sampledZone = new ArrayList<SamplingPoint>();
    // sample the zone boundary
    final List<Vertex> boundary = zone.getBoundaryLoops();
    for (final Vertex loopStart : boundary) {
        int count = 0;
        for (Vertex v = loopStart; count == 0 || v != loopStart; v = v.getOutgoing().getEnd()) {
            ++count;
            final Edge edge = v.getOutgoing();
            final int n = (int) FastMath.ceil(edge.getLength() * body.getEquatorialRadius() / samplingStep);
            for (int i = 0; i < n; ++i) {
                final S2Point intermediate = new S2Point(edge.getPointAt(i * edge.getLength() / n));
                final GeodeticPoint gp = new GeodeticPoint(0.5 * FastMath.PI - intermediate.getPhi(), intermediate.getTheta(), 0.0);
                sampledZone.add(new SamplingPoint(body.transform(gp), gp.getZenith()));
            }
        }
    }
    // sample the zone interior
    final EllipsoidTessellator tessellator = new EllipsoidTessellator(body, new ConstantAzimuthAiming(body, 0.0), 4);
    final List<List<GeodeticPoint>> gpSample = tessellator.sample(zone, samplingStep, samplingStep);
    for (final List<GeodeticPoint> list : gpSample) {
        for (final GeodeticPoint gp : list) {
            sampledZone.add(new SamplingPoint(body.transform(gp), gp.getZenith()));
        }
    }
    return sampledZone;
}
Also used : Vertex(org.hipparchus.geometry.spherical.twod.Vertex) S2Point(org.hipparchus.geometry.spherical.twod.S2Point) ArrayList(java.util.ArrayList) EllipsoidTessellator(org.orekit.models.earth.tessellation.EllipsoidTessellator) S2Point(org.hipparchus.geometry.spherical.twod.S2Point) GeodeticPoint(org.orekit.bodies.GeodeticPoint) ConstantAzimuthAiming(org.orekit.models.earth.tessellation.ConstantAzimuthAiming) ArrayList(java.util.ArrayList) List(java.util.List) GeodeticPoint(org.orekit.bodies.GeodeticPoint) Edge(org.hipparchus.geometry.spherical.twod.Edge)

Example 23 with GeodeticPoint

use of org.orekit.bodies.GeodeticPoint in project Orekit by CS-SI.

the class LongitudeCrossingDetector method g.

/**
 * Compute the value of the detection function.
 * <p>
 * The value is the longitude difference between the spacecraft and the fixed
 * longitude to be crossed, with some sign tweaks to ensure continuity.
 * These tweaks imply the {@code increasing} flag in events detection becomes
 * irrelevant here! As an example, the longitude of a prograde spacecraft
 * will always increase, but this g function will increase and decrease so it
 * will cross the zero value once per orbit, in increasing and decreasing
 * directions on alternate orbits. If eastwards and westwards crossing have to
 * be distinguished, the velocity direction has to be checked instead of looking
 * at the {@code increasing} flag.
 * </p>
 * @param s the current state information: date, kinematics, attitude
 * @return longitude difference between the spacecraft and the fixed
 * longitude, with some sign tweaks to ensure continuity
 * @exception OrekitException if some specific error occurs
 */
public double g(final SpacecraftState s) throws OrekitException {
    // convert state to geodetic coordinates
    final GeodeticPoint gp = body.transform(s.getPVCoordinates().getPosition(), s.getFrame(), s.getDate());
    // longitude difference
    double delta = MathUtils.normalizeAngle(sign * (gp.getLongitude() - longitude), 0.0);
    // ensure continuity
    if (FastMath.abs(delta - previousDelta) > FastMath.PI) {
        sign = -sign;
        delta = MathUtils.normalizeAngle(sign * (gp.getLongitude() - longitude), 0.0);
    }
    previousDelta = delta;
    return delta;
}
Also used : GeodeticPoint(org.orekit.bodies.GeodeticPoint)

Example 24 with GeodeticPoint

use of org.orekit.bodies.GeodeticPoint in project Orekit by CS-SI.

the class EllipsoidTessellator method extractSample.

/**
 * Extract a sample of points from a mesh.
 * @param mesh mesh from which grid should be extracted
 * @param zone zone covered by the mesh
 * @return extracted grid
 * @exception OrekitException if tile direction cannot be computed
 */
private List<GeodeticPoint> extractSample(final Mesh mesh, final SphericalPolygonsSet zone) throws OrekitException {
    // find how to select sample points taking quantization into account
    // to have the largest possible number of points while still
    // being inside the zone of interest
    int selectedAcrossModulus = -1;
    int selectedAlongModulus = -1;
    int selectedCount = -1;
    for (int acrossModulus = 0; acrossModulus < quantization; ++acrossModulus) {
        for (int alongModulus = 0; alongModulus < quantization; ++alongModulus) {
            // count how many points would be selected for the current modulus
            int count = 0;
            for (int across = mesh.getMinAcrossIndex() + acrossModulus; across <= mesh.getMaxAcrossIndex(); across += quantization) {
                for (int along = mesh.getMinAlongIndex() + alongModulus; along <= mesh.getMaxAlongIndex(); along += quantization) {
                    final Mesh.Node node = mesh.getNode(along, across);
                    if (node != null && node.isInside()) {
                        ++count;
                    }
                }
            }
            if (count > selectedCount) {
                // current modulus are better than the selected ones
                selectedAcrossModulus = acrossModulus;
                selectedAlongModulus = alongModulus;
                selectedCount = count;
            }
        }
    }
    // extract the sample points
    final List<GeodeticPoint> sample = new ArrayList<GeodeticPoint>(selectedCount);
    for (int across = mesh.getMinAcrossIndex() + selectedAcrossModulus; across <= mesh.getMaxAcrossIndex(); across += quantization) {
        for (int along = mesh.getMinAlongIndex() + selectedAlongModulus; along <= mesh.getMaxAlongIndex(); along += quantization) {
            final Mesh.Node node = mesh.getNode(along, across);
            if (node != null && node.isInside()) {
                sample.add(toGeodetic(node.getS2P()));
            }
        }
    }
    return sample;
}
Also used : ArrayList(java.util.ArrayList) GeodeticPoint(org.orekit.bodies.GeodeticPoint) S2Point(org.hipparchus.geometry.spherical.twod.S2Point) GeodeticPoint(org.orekit.bodies.GeodeticPoint)

Example 25 with GeodeticPoint

use of org.orekit.bodies.GeodeticPoint in project Orekit by CS-SI.

the class EllipsoidTessellator method sample.

/**
 * Sample a zone of interest into a grid sample of {@link GeodeticPoint geodetic points}.
 * <p>
 * The created points will be entirely within the zone of interest.
 * </p>
 * @param zone zone of interest to sample
 * @param width grid sample cells width as a distance on surface (in meters)
 * @param length grid sample cells length as a distance on surface (in meters)
 * @return a list of lists of points sampling the zone of interest,
 * each sub-list corresponding to a part not connected to the other
 * parts (for example for islands)
 * @exception OrekitException if the zone cannot be sampled
 */
public List<List<GeodeticPoint>> sample(final SphericalPolygonsSet zone, final double width, final double length) throws OrekitException {
    final double splitWidth = width / quantization;
    final double splitLength = length / quantization;
    final Map<Mesh, List<GeodeticPoint>> map = new IdentityHashMap<Mesh, List<GeodeticPoint>>();
    final RegionFactory<Sphere2D> factory = new RegionFactory<Sphere2D>();
    SphericalPolygonsSet remaining = (SphericalPolygonsSet) zone.copySelf();
    S2Point inside = getInsidePoint(remaining);
    while (inside != null) {
        // find a mesh covering at least one connected part of the zone
        final List<Mesh.Node> mergingSeeds = new ArrayList<Mesh.Node>();
        Mesh mesh = new Mesh(ellipsoid, zone, aiming, splitLength, splitWidth, inside);
        mergingSeeds.add(mesh.getNode(0, 0));
        List<GeodeticPoint> sample = null;
        while (!mergingSeeds.isEmpty()) {
            // expand the mesh around the seed
            neighborExpandMesh(mesh, mergingSeeds, zone);
            // extract the sample from the mesh
            // this further expands the mesh so sample cells dimensions are multiples of quantization,
            // hence it must be performed here before checking meshes independence
            sample = extractSample(mesh, zone);
            // check the mesh is independent from existing meshes
            mergingSeeds.clear();
            for (final Map.Entry<Mesh, List<GeodeticPoint>> entry : map.entrySet()) {
                if (!factory.intersection(mesh.getCoverage(), entry.getKey().getCoverage()).isEmpty()) {
                    // the meshes are not independent, they intersect each other!
                    // merge the two meshes together
                    mesh = mergeMeshes(mesh, entry.getKey(), mergingSeeds);
                    map.remove(entry.getKey());
                    break;
                }
            }
        }
        // remove the part of the zone covered by the mesh
        remaining = (SphericalPolygonsSet) factory.difference(remaining, mesh.getCoverage());
        inside = getInsidePoint(remaining);
        map.put(mesh, sample);
    }
    // concatenate the lists from the independent meshes
    final List<List<GeodeticPoint>> sampleLists = new ArrayList<List<GeodeticPoint>>(map.size());
    for (final Map.Entry<Mesh, List<GeodeticPoint>> entry : map.entrySet()) {
        sampleLists.add(entry.getValue());
    }
    return sampleLists;
}
Also used : S2Point(org.hipparchus.geometry.spherical.twod.S2Point) IdentityHashMap(java.util.IdentityHashMap) Sphere2D(org.hipparchus.geometry.spherical.twod.Sphere2D) ArrayList(java.util.ArrayList) SphericalPolygonsSet(org.hipparchus.geometry.spherical.twod.SphericalPolygonsSet) RegionFactory(org.hipparchus.geometry.partitioning.RegionFactory) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) GeodeticPoint(org.orekit.bodies.GeodeticPoint) Map(java.util.Map) IdentityHashMap(java.util.IdentityHashMap)

Aggregations

GeodeticPoint (org.orekit.bodies.GeodeticPoint)133 Test (org.junit.Test)78 Vector3D (org.hipparchus.geometry.euclidean.threed.Vector3D)67 OneAxisEllipsoid (org.orekit.bodies.OneAxisEllipsoid)61 AbsoluteDate (org.orekit.time.AbsoluteDate)45 TopocentricFrame (org.orekit.frames.TopocentricFrame)35 Frame (org.orekit.frames.Frame)34 KeplerianOrbit (org.orekit.orbits.KeplerianOrbit)27 SpacecraftState (org.orekit.propagation.SpacecraftState)26 Propagator (org.orekit.propagation.Propagator)24 OrekitException (org.orekit.errors.OrekitException)23 KeplerianPropagator (org.orekit.propagation.analytical.KeplerianPropagator)23 FieldVector3D (org.hipparchus.geometry.euclidean.threed.FieldVector3D)22 PVCoordinates (org.orekit.utils.PVCoordinates)20 FieldAbsoluteDate (org.orekit.time.FieldAbsoluteDate)19 BodyShape (org.orekit.bodies.BodyShape)17 Orbit (org.orekit.orbits.Orbit)15 Rotation (org.hipparchus.geometry.euclidean.threed.Rotation)13 ArrayList (java.util.ArrayList)12 FieldGeodeticPoint (org.orekit.bodies.FieldGeodeticPoint)12