Segment.java

  1. /* Copyright 2002-2025 CS GROUP
  2.  * Licensed to CS GROUP (CS) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * CS licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *   http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.orekit.models.earth.ionosphere.nequick;

  18. import org.hipparchus.util.FastMath;
  19. import org.orekit.bodies.GeodeticPoint;

  20. /** Performs the computation of the coordinates along the integration path.
  21.  * @author Bryan Cazabonne
  22.  * @since 13.0
  23.  */
  24. public class Segment {

  25.     /** Threshold for zenith segment. */
  26.     private static final double THRESHOLD = 1.0;

  27.     /** Supporting ray. */
  28.     private final Ray ray;

  29.     /** Integration start. */
  30.     private final double y;

  31.     /** Odd points offset. */
  32.     private final double g;

  33.     /** Integration step [m]. */
  34.     private final double deltaN;

  35.     /** Number of points. */
  36.     private final int nbPoints;

  37.     /**
  38.      * Constructor.
  39.      *
  40.      * @param n   number of intervals for integration (2 points per interval, hence 2n points will be generated)
  41.      * @param ray ray-perigee parameters
  42.      * @param s1  lower boundary of integration
  43.      * @param s2  upper boundary for integration
  44.      */
  45.     public Segment(final int n, final Ray ray, final double s1, final double s2) {

  46.         this.ray = ray;

  47.         // Integration step (Eq. 195)
  48.         deltaN = (s2 - s1) / n;

  49.         // Eq. 196
  50.         g = 0.5773502691896 * deltaN;

  51.         // Eq. 197
  52.         y = s1 + (deltaN - g) * 0.5;

  53.         nbPoints = 2 * n;

  54.     }

  55.     /** Get point along the ray.
  56.      * @param index point index (between O included and {@link #getNbPoints()} excluded)
  57.      * @return point on ray
  58.      * @since 13.0
  59.      */
  60.     public GeodeticPoint getPoint(final int index) {

  61.         final int    p = index / 2;
  62.         final double s = y + p * deltaN + (index % 2) * g;

  63.         // Heights (Eq. 178)
  64.         final double height = FastMath.sqrt(s * s + ray.getRadius() * ray.getRadius()) -
  65.                               NeQuickModel.RE;

  66.         if (ray.getRadius() < THRESHOLD) {
  67.             // zenith segment
  68.             return new GeodeticPoint(ray.getLatitude(), ray.getLongitude(), height);
  69.         } else {
  70.             // Great circle parameters (Eq. 179 to 181)
  71.             final double tanDs = s / ray.getRadius();
  72.             final double cosDs = 1.0 / FastMath.sqrt(1.0 + tanDs * tanDs);
  73.             final double sinDs = tanDs * cosDs;

  74.             // Latitude (Eq. 182 to 183)
  75.             final double sinLatS = ray.getScLat().sin() * cosDs + ray.getScLat().cos() * sinDs * ray.getCosineAz();
  76.             final double cosLatS = FastMath.sqrt(1.0 - sinLatS * sinLatS);

  77.             // Longitude (Eq. 184 to 187)
  78.             final double sinLonS = sinDs * ray.getSineAz() * ray.getScLat().cos();
  79.             final double cosLonS = cosDs - ray.getScLat().sin() * sinLatS;

  80.             return new GeodeticPoint(FastMath.atan2(sinLatS, cosLatS),
  81.                                      FastMath.atan2(sinLonS, cosLonS) + ray.getLongitude(),
  82.                                      height);
  83.         }
  84.     }

  85.     /** Get number of points.
  86.      * <p>
  87.      * Note there are 2 points per interval, so {@code index} must be between 0 (included)
  88.      * and 2n (excluded) for a segment built with {@code n} intervals
  89.      * </p>
  90.      * @return number of points
  91.      */
  92.     public int getNbPoints() {
  93.         return nbPoints;
  94.     }

  95.     /**
  96.      * Get the integration step.
  97.      *
  98.      * @return the integration step in meters
  99.      */
  100.     public double getInterval() {
  101.         return deltaN;
  102.     }

  103. }