@Test
 public void testMiss() throws OrekitException {
   final CircularOrbit circ =
       new CircularOrbit(
           7178000.0,
           0.5e-4,
           -0.5e-4,
           FastMath.toRadians(0.),
           FastMath.toRadians(270.),
           FastMath.toRadians(5.300),
           PositionAngle.MEAN,
           FramesFactory.getEME2000(),
           date,
           mu);
   final LofOffset upsideDown =
       new LofOffset(circ.getFrame(), LOFType.VVLH, RotationOrder.XYX, FastMath.PI, 0, 0);
   final LofOffsetPointing pointing =
       new LofOffsetPointing(earthSpheric, upsideDown, Vector3D.PLUS_K);
   try {
     pointing.getTargetPV(circ, date, circ.getFrame());
     Assert.fail("an exception should have been thrown");
   } catch (OrekitException oe) {
     Assert.assertEquals(
         OrekitMessages.ATTITUDE_POINTING_LAW_DOES_NOT_POINT_TO_GROUND, oe.getSpecifier());
   }
 }
  private double[] stateToArray(
      SpacecraftState state, OrbitType orbitType, PositionAngle angleType, boolean withMass) {
    double[] array = new double[withMass ? 7 : 6];
    switch (orbitType) {
      case CARTESIAN:
        {
          CartesianOrbit cart = (CartesianOrbit) orbitType.convertType(state.getOrbit());
          array[0] = cart.getPVCoordinates().getPosition().getX();
          array[1] = cart.getPVCoordinates().getPosition().getY();
          array[2] = cart.getPVCoordinates().getPosition().getZ();
          array[3] = cart.getPVCoordinates().getVelocity().getX();
          array[4] = cart.getPVCoordinates().getVelocity().getY();
          array[5] = cart.getPVCoordinates().getVelocity().getZ();
        }
        break;
      case CIRCULAR:
        {
          CircularOrbit circ = (CircularOrbit) orbitType.convertType(state.getOrbit());
          array[0] = circ.getA();
          array[1] = circ.getCircularEx();
          array[2] = circ.getCircularEy();
          array[3] = circ.getI();
          array[4] = circ.getRightAscensionOfAscendingNode();
          array[5] = circ.getAlpha(angleType);
        }
        break;
      case EQUINOCTIAL:
        {
          EquinoctialOrbit equ = (EquinoctialOrbit) orbitType.convertType(state.getOrbit());
          array[0] = equ.getA();
          array[1] = equ.getEquinoctialEx();
          array[2] = equ.getEquinoctialEy();
          array[3] = equ.getHx();
          array[4] = equ.getHy();
          array[5] = equ.getL(angleType);
        }
        break;
      case KEPLERIAN:
        {
          KeplerianOrbit kep = (KeplerianOrbit) orbitType.convertType(state.getOrbit());
          array[0] = kep.getA();
          array[1] = kep.getE();
          array[2] = kep.getI();
          array[3] = kep.getPerigeeArgument();
          array[4] = kep.getRightAscensionOfAscendingNode();
          array[5] = kep.getAnomaly(angleType);
        }
        break;
    }

    if (withMass) {
      array[6] = state.getMass();
    }

    return array;
  }
  /** Test if both constructors are equivalent */
  @Test
  public void testLof() throws OrekitException {

    //  Satellite position
    final CircularOrbit circ =
        new CircularOrbit(
            7178000.0,
            0.5e-4,
            -0.5e-4,
            FastMath.toRadians(0.),
            FastMath.toRadians(270.),
            FastMath.toRadians(5.300),
            PositionAngle.MEAN,
            FramesFactory.getEME2000(),
            date,
            mu);

    // Create lof aligned law
    // ************************
    final LofOffset lofLaw = new LofOffset(circ.getFrame(), LOFType.VVLH);
    final LofOffsetPointing lofPointing =
        new LofOffsetPointing(earthSpheric, lofLaw, Vector3D.PLUS_K);
    final Rotation lofRot = lofPointing.getAttitude(circ, date, circ.getFrame()).getRotation();

    // Compare to body center pointing law
    // *************************************
    final BodyCenterPointing centerLaw = new BodyCenterPointing(earthSpheric.getBodyFrame());
    final Rotation centerRot = centerLaw.getAttitude(circ, date, circ.getFrame()).getRotation();
    final double angleBodyCenter = centerRot.applyInverseTo(lofRot).getAngle();
    Assert.assertEquals(0., angleBodyCenter, Utils.epsilonAngle);

    // Compare to nadir pointing law
    // *******************************
    final NadirPointing nadirLaw = new NadirPointing(earthSpheric);
    final Rotation nadirRot = nadirLaw.getAttitude(circ, date, circ.getFrame()).getRotation();
    final double angleNadir = nadirRot.applyInverseTo(lofRot).getAngle();
    Assert.assertEquals(0., angleNadir, Utils.epsilonAngle);
  }
  @Test
  public void testIntersectionFromPoints() throws OrekitException {
    AbsoluteDate date =
        new AbsoluteDate(
            new DateComponents(2008, 03, 21), TimeComponents.H12, TimeScalesFactory.getUTC());

    Frame frame = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
    OneAxisEllipsoid earth = new OneAxisEllipsoid(6378136.460, 1 / 298.257222101, frame);

    // Satellite on polar position
    // ***************************
    final double mu = 3.9860047e14;
    CircularOrbit circ =
        new CircularOrbit(
            7178000.0,
            0.5e-4,
            0.,
            FastMath.toRadians(90.),
            FastMath.toRadians(60.),
            FastMath.toRadians(90.),
            PositionAngle.MEAN,
            FramesFactory.getEME2000(),
            date,
            mu);

    // Transform satellite position to position/velocity parameters in EME2000 and ITRF200B
    PVCoordinates pvSatEME2000 = circ.getPVCoordinates();
    PVCoordinates pvSatItrf =
        frame.getTransformTo(FramesFactory.getEME2000(), date).transformPVCoordinates(pvSatEME2000);
    Vector3D pSatItrf = pvSatItrf.getPosition();

    // Test first visible surface points
    GeodeticPoint geoPoint =
        new GeodeticPoint(FastMath.toRadians(70.), FastMath.toRadians(60.), 0.);
    Vector3D pointItrf = earth.transform(geoPoint);
    Line line = new Line(pSatItrf, pointItrf, 1.0e-10);
    GeodeticPoint geoInter = earth.getIntersectionPoint(line, pSatItrf, frame, date);
    Assert.assertEquals(geoPoint.getLongitude(), geoInter.getLongitude(), Utils.epsilonAngle);
    Assert.assertEquals(geoPoint.getLatitude(), geoInter.getLatitude(), Utils.epsilonAngle);

    // Test second visible surface points
    geoPoint = new GeodeticPoint(FastMath.toRadians(65.), FastMath.toRadians(-120.), 0.);
    pointItrf = earth.transform(geoPoint);
    line = new Line(pSatItrf, pointItrf, 1.0e-10);
    geoInter = earth.getIntersectionPoint(line, pSatItrf, frame, date);
    Assert.assertEquals(geoPoint.getLongitude(), geoInter.getLongitude(), Utils.epsilonAngle);
    Assert.assertEquals(geoPoint.getLatitude(), geoInter.getLatitude(), Utils.epsilonAngle);

    // Test non visible surface points
    geoPoint = new GeodeticPoint(FastMath.toRadians(30.), FastMath.toRadians(60.), 0.);
    pointItrf = earth.transform(geoPoint);
    line = new Line(pSatItrf, pointItrf, 1.0e-10);

    geoInter = earth.getIntersectionPoint(line, pSatItrf, frame, date);

    // For polar satellite position, intersection point is at the same longitude but different
    // latitude
    Assert.assertEquals(1.04437199, geoInter.getLongitude(), Utils.epsilonAngle);
    Assert.assertEquals(1.36198012, geoInter.getLatitude(), Utils.epsilonAngle);

    // Satellite on equatorial position
    // ********************************
    circ =
        new CircularOrbit(
            7178000.0,
            0.5e-4,
            0.,
            FastMath.toRadians(1.e-4),
            FastMath.toRadians(0.),
            FastMath.toRadians(0.),
            PositionAngle.MEAN,
            FramesFactory.getEME2000(),
            date,
            mu);

    // Transform satellite position to position/velocity parameters in EME2000 and ITRF200B
    pvSatEME2000 = circ.getPVCoordinates();
    pvSatItrf =
        frame.getTransformTo(FramesFactory.getEME2000(), date).transformPVCoordinates(pvSatEME2000);
    pSatItrf = pvSatItrf.getPosition();

    // Test first visible surface points
    geoPoint = new GeodeticPoint(FastMath.toRadians(5.), FastMath.toRadians(0.), 0.);
    pointItrf = earth.transform(geoPoint);
    line = new Line(pSatItrf, pointItrf, 1.0e-10);
    Assert.assertTrue(line.toSubSpace(pSatItrf).getX() < 0);
    geoInter = earth.getIntersectionPoint(line, pSatItrf, frame, date);
    Assert.assertEquals(geoPoint.getLongitude(), geoInter.getLongitude(), Utils.epsilonAngle);
    Assert.assertEquals(geoPoint.getLatitude(), geoInter.getLatitude(), Utils.epsilonAngle);

    // With the point opposite to satellite point along the line
    GeodeticPoint geoInter2 =
        earth.getIntersectionPoint(
            line, line.toSpace(new Vector1D(-line.toSubSpace(pSatItrf).getX())), frame, date);
    Assert.assertTrue(
        FastMath.abs(geoInter.getLongitude() - geoInter2.getLongitude()) > FastMath.toRadians(0.1));
    Assert.assertTrue(
        FastMath.abs(geoInter.getLatitude() - geoInter2.getLatitude()) > FastMath.toRadians(0.1));

    // Test second visible surface points
    geoPoint = new GeodeticPoint(FastMath.toRadians(-5.), FastMath.toRadians(0.), 0.);
    pointItrf = earth.transform(geoPoint);
    line = new Line(pSatItrf, pointItrf, 1.0e-10);
    geoInter = earth.getIntersectionPoint(line, pSatItrf, frame, date);
    Assert.assertEquals(geoPoint.getLongitude(), geoInter.getLongitude(), Utils.epsilonAngle);
    Assert.assertEquals(geoPoint.getLatitude(), geoInter.getLatitude(), Utils.epsilonAngle);

    // Test non visible surface points
    geoPoint = new GeodeticPoint(FastMath.toRadians(40.), FastMath.toRadians(0.), 0.);
    pointItrf = earth.transform(geoPoint);
    line = new Line(pSatItrf, pointItrf, 1.0e-10);
    geoInter = earth.getIntersectionPoint(line, pSatItrf, frame, date);
    Assert.assertEquals(-0.00768481, geoInter.getLongitude(), Utils.epsilonAngle);
    Assert.assertEquals(0.32180410, geoInter.getLatitude(), Utils.epsilonAngle);

    // Satellite on any position
    // *************************
    circ =
        new CircularOrbit(
            7178000.0,
            0.5e-4,
            0.,
            FastMath.toRadians(50.),
            FastMath.toRadians(0.),
            FastMath.toRadians(90.),
            PositionAngle.MEAN,
            FramesFactory.getEME2000(),
            date,
            mu);

    // Transform satellite position to position/velocity parameters in EME2000 and ITRF200B
    pvSatEME2000 = circ.getPVCoordinates();
    pvSatItrf =
        frame.getTransformTo(FramesFactory.getEME2000(), date).transformPVCoordinates(pvSatEME2000);
    pSatItrf = pvSatItrf.getPosition();

    // Test first visible surface points
    geoPoint = new GeodeticPoint(FastMath.toRadians(40.), FastMath.toRadians(90.), 0.);
    pointItrf = earth.transform(geoPoint);
    line = new Line(pSatItrf, pointItrf, 1.0e-10);
    geoInter = earth.getIntersectionPoint(line, pSatItrf, frame, date);
    Assert.assertEquals(geoPoint.getLongitude(), geoInter.getLongitude(), Utils.epsilonAngle);
    Assert.assertEquals(geoPoint.getLatitude(), geoInter.getLatitude(), Utils.epsilonAngle);

    // Test second visible surface points
    geoPoint = new GeodeticPoint(FastMath.toRadians(60.), FastMath.toRadians(90.), 0.);
    pointItrf = earth.transform(geoPoint);
    line = new Line(pSatItrf, pointItrf, 1.0e-10);
    geoInter = earth.getIntersectionPoint(line, pSatItrf, frame, date);
    Assert.assertEquals(geoPoint.getLongitude(), geoInter.getLongitude(), Utils.epsilonAngle);
    Assert.assertEquals(geoPoint.getLatitude(), geoInter.getLatitude(), Utils.epsilonAngle);

    // Test non visible surface points
    geoPoint = new GeodeticPoint(FastMath.toRadians(0.), FastMath.toRadians(90.), 0.);
    pointItrf = earth.transform(geoPoint);
    line = new Line(pSatItrf, pointItrf, 1.0e-10);
    geoInter = earth.getIntersectionPoint(line, pSatItrf, frame, date);
    Assert.assertEquals(
        FastMath.toRadians(89.5364061088196), geoInter.getLongitude(), Utils.epsilonAngle);
    Assert.assertEquals(
        FastMath.toRadians(35.555543683351125), geoInter.getLatitude(), Utils.epsilonAngle);
  }