Example usage for org.apache.commons.math3.util MathUtils normalizeAngle

List of usage examples for org.apache.commons.math3.util MathUtils normalizeAngle

Introduction

In this page you can find the example usage for org.apache.commons.math3.util MathUtils normalizeAngle.

Prototype

public static double normalizeAngle(double a, double center) 

Source Link

Document

Normalize an angle in a 2&pi wide interval around a center value.

Usage

From source file:fr.cs.examples.conversion.PropagatorConversion.java

/** Program entry point.
 * @param args program arguments (unused here)
 *//*from  ww  w .j  a  v a  2 s .co  m*/
public static void main(String[] args) {
    try {

        // configure Orekit
        Autoconfiguration.configureOrekit();

        // gravity field
        NormalizedSphericalHarmonicsProvider provider = GravityFieldFactory.getNormalizedProvider(2, 0);
        double mu = provider.getMu();

        // inertial frame
        Frame inertialFrame = FramesFactory.getEME2000();

        // Initial date
        AbsoluteDate initialDate = new AbsoluteDate(2004, 01, 01, 23, 30, 00.000, TimeScalesFactory.getUTC());

        // Initial orbit (GTO)
        final double a = 24396159; // semi major axis in meters
        final double e = 0.72831215; // eccentricity
        final double i = FastMath.toRadians(7); // inclination
        final double omega = FastMath.toRadians(180); // perigee argument
        final double raan = FastMath.toRadians(261); // right ascention of ascending node
        final double lM = 0; // mean anomaly
        Orbit initialOrbit = new KeplerianOrbit(a, e, i, omega, raan, lM, PositionAngle.MEAN, inertialFrame,
                initialDate, mu);
        final double period = initialOrbit.getKeplerianPeriod();

        // Initial state definition
        final SpacecraftState initialState = new SpacecraftState(initialOrbit);

        // Adaptive step integrator with a minimum step of 0.001 and a maximum step of 1000
        final double minStep = 0.001;
        final double maxStep = 1000.;
        final double dP = 1.e-2;
        final OrbitType orbType = OrbitType.CARTESIAN;
        final double[][] tol = NumericalPropagator.tolerances(dP, initialOrbit, orbType);
        final AbstractIntegrator integrator = new DormandPrince853Integrator(minStep, maxStep, tol[0], tol[1]);

        // Propagator
        NumericalPropagator numProp = new NumericalPropagator(integrator);
        numProp.setInitialState(initialState);
        numProp.setOrbitType(orbType);

        // Force Models:
        // 1 - Perturbing gravity field (only J2 is considered here)
        ForceModel gravity = new HolmesFeatherstoneAttractionModel(
                FramesFactory.getITRF(IERSConventions.IERS_2010, true), provider);

        // Add force models to the propagator
        numProp.addForceModel(gravity);

        // Propagator factory
        PropagatorBuilder builder = new KeplerianPropagatorBuilder(mu, inertialFrame, OrbitType.KEPLERIAN,
                PositionAngle.TRUE);

        // Propagator converter
        PropagatorConverter fitter = new FiniteDifferencePropagatorConverter(builder, 1.e-6, 5000);

        // Resulting propagator
        KeplerianPropagator kepProp = (KeplerianPropagator) fitter.convert(numProp, 2 * period, 251);

        // Step handlers
        StatesHandler numStepHandler = new StatesHandler();
        StatesHandler kepStepHandler = new StatesHandler();

        // Set up operating mode for the propagator as master mode
        // with fixed step and specialized step handler
        numProp.setMasterMode(60., numStepHandler);
        kepProp.setMasterMode(60., kepStepHandler);

        // Extrapolate from the initial to the final date
        numProp.propagate(initialDate.shiftedBy(10. * period));
        kepProp.propagate(initialDate.shiftedBy(10. * period));

        // retrieve the states
        List<SpacecraftState> numStates = numStepHandler.getStates();
        List<SpacecraftState> kepStates = kepStepHandler.getStates();

        // Print the results on the output file
        File output = new File(new File(System.getProperty("user.home")), "elements.dat");
        PrintStream stream = new PrintStream(output);
        stream.println("# date Anum Akep Enum Ekep Inum Ikep LMnum LMkep");
        for (SpacecraftState numState : numStates) {
            for (SpacecraftState kepState : kepStates) {
                if (numState.getDate().compareTo(kepState.getDate()) == 0) {
                    stream.println(numState.getDate() + " " + numState.getA() + " " + kepState.getA() + " "
                            + numState.getE() + " " + kepState.getE() + " "
                            + FastMath.toDegrees(numState.getI()) + " " + FastMath.toDegrees(kepState.getI())
                            + " " + FastMath.toDegrees(MathUtils.normalizeAngle(numState.getLM(), FastMath.PI))
                            + " "
                            + FastMath.toDegrees(MathUtils.normalizeAngle(kepState.getLM(), FastMath.PI)));
                    break;
                }
            }
        }
        stream.close();
        System.out.println("Results saved as file " + output);

        File output1 = new File(new File(System.getProperty("user.home")), "elts_pv.dat");
        PrintStream stream1 = new PrintStream(output1);
        stream.println("# date pxn pyn pzn vxn vyn vzn pxk pyk pzk vxk vyk vzk");
        for (SpacecraftState numState : numStates) {
            for (SpacecraftState kepState : kepStates) {
                if (numState.getDate().compareTo(kepState.getDate()) == 0) {
                    final double pxn = numState.getPVCoordinates().getPosition().getX();
                    final double pyn = numState.getPVCoordinates().getPosition().getY();
                    final double pzn = numState.getPVCoordinates().getPosition().getZ();
                    final double vxn = numState.getPVCoordinates().getVelocity().getX();
                    final double vyn = numState.getPVCoordinates().getVelocity().getY();
                    final double vzn = numState.getPVCoordinates().getVelocity().getZ();
                    final double pxk = kepState.getPVCoordinates().getPosition().getX();
                    final double pyk = kepState.getPVCoordinates().getPosition().getY();
                    final double pzk = kepState.getPVCoordinates().getPosition().getZ();
                    final double vxk = kepState.getPVCoordinates().getVelocity().getX();
                    final double vyk = kepState.getPVCoordinates().getVelocity().getY();
                    final double vzk = kepState.getPVCoordinates().getVelocity().getZ();
                    stream1.println(numState.getDate() + " " + pxn + " " + pyn + " " + pzn + " " + vxn + " "
                            + vyn + " " + vzn + " " + pxk + " " + pyk + " " + pzk + " " + vxk + " " + vyk + " "
                            + vzk);
                    break;
                }
            }
        }
        stream1.close();
        System.out.println("Results saved as file " + output1);

    } catch (OrekitException oe) {
        System.err.println(oe.getLocalizedMessage());
        System.exit(1);
    } catch (FileNotFoundException fnfe) {
        System.err.println(fnfe.getLocalizedMessage());
        System.exit(1);
    }
}

From source file:fr.amap.viewer3d.object.camera.TrackballCamera.java

private float normalizeTheta(float theta) {

    return (float) MathUtils.normalizeAngle(theta, 0);
    //normalize between 0 and 2pi
    /*while(theta < 0){
    theta += Math.PI * 2;/*w  ww  . j  ava2 s.co m*/
    }
    while(theta > (Math.PI * 2)){
    theta -= (Math.PI  * 2);
    } 
            
    return theta;*/
}

From source file:fr.cs.examples.bodies.Phasing.java

/** Improve orbit to better match Earth phasing parameters.
 * @param previous previous orbit//from   w  w w .  j  av a2 s. c om
 * @param nbOrbits number of orbits in the phasing cycle
 * @param nbDays number of days in the phasing cycle
 * @param propagator propagator to use
 * @return an improved Earth phased orbit
 * @exception OrekitException if orbit cannot be propagated
 */
private CircularOrbit improveEarthPhasing(CircularOrbit previous, int nbOrbits, int nbDays,
        Propagator propagator) throws OrekitException {

    propagator.resetInitialState(new SpacecraftState(previous));

    // find first ascending node
    double period = previous.getKeplerianPeriod();
    SpacecraftState firstState = findFirstCrossing(0.0, true, previous.getDate(),
            previous.getDate().shiftedBy(2 * period), 0.01 * period, propagator);

    // go to next cycle, one orbit at a time
    SpacecraftState state = firstState;
    for (int i = 0; i < nbOrbits; ++i) {
        final AbsoluteDate previousDate = state.getDate();
        state = findLatitudeCrossing(0.0, previousDate.shiftedBy(period), previousDate.shiftedBy(2 * period),
                0.01 * period, period, propagator);
        period = state.getDate().durationFrom(previousDate);
    }

    double cycleDuration = state.getDate().durationFrom(firstState.getDate());
    double deltaT;
    if (((int) FastMath.rint(cycleDuration / Constants.JULIAN_DAY)) != nbDays) {
        // we are very far from expected duration
        deltaT = nbDays * Constants.JULIAN_DAY - cycleDuration;
    } else {
        // we are close to expected duration
        GeodeticPoint startPoint = earth.transform(firstState.getPVCoordinates().getPosition(),
                firstState.getFrame(), firstState.getDate());
        GeodeticPoint endPoint = earth.transform(state.getPVCoordinates().getPosition(), state.getFrame(),
                state.getDate());
        double deltaL = MathUtils.normalizeAngle(endPoint.getLongitude() - startPoint.getLongitude(), 0.0);
        deltaT = deltaL * Constants.JULIAN_DAY / (2 * FastMath.PI);
    }

    double deltaA = 2 * previous.getA() * deltaT / (3 * nbOrbits * previous.getKeplerianPeriod());
    return new CircularOrbit(previous.getA() + deltaA, previous.getCircularEx(), previous.getCircularEy(),
            previous.getI(), previous.getRightAscensionOfAscendingNode(), previous.getAlphaV(),
            PositionAngle.TRUE, previous.getFrame(), previous.getDate(), previous.getMu());

}

From source file:fr.cs.examples.propagation.DSSTPropagation.java

/** Print the results in the output file
 *
 *  @param handler orbit handler/*  w  w w.  j a v  a 2  s. c o m*/
 *  @param output output file
 *  @param sart start date of propagation
 *  @throws OrekitException 
 *  @throws IOException 
 */
private void printOutput(final File output, final OrbitHandler handler, final AbsoluteDate start)
        throws OrekitException, IOException {
    // Output format:
    // time_from_start, a, e, i, raan, pa, aM, h, k, p, q, lM, px, py, pz, vx, vy, vz
    final String format = new String(
            " %24.16e %24.16e %24.16e %24.16e %24.16e %24.16e %24.16e %24.16e %24.16e %24.16e %24.16e %24.16e %24.16e %24.16e %24.16e %24.16e %24.16e %24.16e");
    final BufferedWriter buffer = new BufferedWriter(new FileWriter(output));
    buffer.write(
            "##   time_from_start(s)            a(km)                      e                      i(deg)         ");
    buffer.write(
            "         raan(deg)                pa(deg)              mean_anomaly(deg)              ey/h          ");
    buffer.write(
            "           ex/k                    hy/p                     hx/q             mean_longitude_arg(deg)");
    buffer.write(
            "       Xposition(km)           Yposition(km)             Zposition(km)           Xvelocity(km/s)    ");
    buffer.write("      Yvelocity(km/s)         Zvelocity(km/s)");
    buffer.newLine();
    for (Orbit o : handler.getOrbits()) {
        final Formatter f = new Formatter(new StringBuilder(), Locale.ENGLISH);
        // Time from start (s)
        final double time = o.getDate().durationFrom(start);
        // Semi-major axis (km)
        final double a = o.getA() / 1000.;
        // Keplerian elements
        // Eccentricity
        final double e = o.getE();
        // Inclination (degrees)
        final double i = Math.toDegrees(MathUtils.normalizeAngle(o.getI(), FastMath.PI));
        // Right Ascension of Ascending Node (degrees)
        KeplerianOrbit ko = new KeplerianOrbit(o);
        final double ra = Math
                .toDegrees(MathUtils.normalizeAngle(ko.getRightAscensionOfAscendingNode(), FastMath.PI));
        // Perigee Argument (degrees)
        final double pa = Math.toDegrees(MathUtils.normalizeAngle(ko.getPerigeeArgument(), FastMath.PI));
        // Mean Anomaly (degrees)
        final double am = Math
                .toDegrees(MathUtils.normalizeAngle(ko.getAnomaly(PositionAngle.MEAN), FastMath.PI));
        // Equinoctial elements
        // ey/h component of eccentricity vector
        final double h = o.getEquinoctialEy();
        // ex/k component of eccentricity vector
        final double k = o.getEquinoctialEx();
        // hy/p component of inclination vector
        final double p = o.getHy();
        // hx/q component of inclination vector
        final double q = o.getHx();
        // Mean Longitude Argument (degrees)
        final double lm = Math.toDegrees(MathUtils.normalizeAngle(o.getLM(), FastMath.PI));
        // Cartesian elements
        // Position along X in inertial frame (km)
        final double px = o.getPVCoordinates().getPosition().getX() / 1000.;
        // Position along Y in inertial frame (km)
        final double py = o.getPVCoordinates().getPosition().getY() / 1000.;
        // Position along Z in inertial frame (km)
        final double pz = o.getPVCoordinates().getPosition().getZ() / 1000.;
        // Velocity along X in inertial frame (km/s)
        final double vx = o.getPVCoordinates().getVelocity().getX() / 1000.;
        // Velocity along Y in inertial frame (km/s)
        final double vy = o.getPVCoordinates().getVelocity().getY() / 1000.;
        // Velocity along Z in inertial frame (km/s)
        final double vz = o.getPVCoordinates().getVelocity().getZ() / 1000.;
        buffer.write(
                f.format(format, time, a, e, i, ra, pa, am, h, k, p, q, lm, px, py, pz, vx, vy, vz).toString());
        buffer.newLine();
        f.close();
    }
    buffer.close();
}

From source file:fr.cs.examples.bodies.Phasing.java

/** Compute the mean solar time.
 * @param orbit current orbit/*from w ww.  j av a2 s .c  om*/
 * @return mean solar time
 * @exception OrekitException if state cannot be converted
 */
private double meanSolarTime(final Orbit orbit) throws OrekitException {

    // compute angle between Sun and spacecraft in the equatorial plane
    final Vector3D position = orbit.getPVCoordinates().getPosition();
    final double time = orbit.getDate().getComponents(TimeScalesFactory.getUTC()).getTime().getSecondsInDay();
    final double theta = gmst.value(orbit.getDate()).getValue();
    final double sunAlpha = theta + FastMath.PI * (1 - time / (Constants.JULIAN_DAY * 0.5));
    final double dAlpha = MathUtils.normalizeAngle(position.getAlpha() - sunAlpha, 0);

    // convert the angle to solar time
    return 12.0 * (1.0 + dAlpha / FastMath.PI);

}

From source file:org.orekit.bodies.FieldGeodeticPoint.java

/**
 * Build a new instance. The angular coordinates will be normalized so that
 * the latitude is between /2 and the longitude is between .
 *
 * @param latitude latitude of the point
 * @param longitude longitude of the point
 * @param altitude altitude of the point
 *///  w  ww  .  j  a v a2  s . c  o m
public FieldGeodeticPoint(final T latitude, final T longitude, final T altitude) {
    double lat = MathUtils.normalizeAngle(latitude.getReal(), FastMath.PI / 2);
    double lon = MathUtils.normalizeAngle(longitude.getReal(), 0);
    if (lat > FastMath.PI / 2.0) {
        // latitude is beyond the pole -> add 180 to longitude
        lat = FastMath.PI - latitude.getReal();
        lon = MathUtils.normalizeAngle(longitude.getReal() + FastMath.PI, 0);
    }
    final double deltaLat = lat - latitude.getReal();
    final double deltaLon = lon - longitude.getReal();
    this.latitude = latitude.add(deltaLat);
    this.longitude = longitude.add(deltaLon);
    this.altitude = altitude;
}

From source file:org.orekit.bodies.GeodeticPoint.java

/**
 * Build a new instance. The angular coordinates will be normalized so that
 * the latitude is between /2 and the longitude is between .
 *
 * @param latitude latitude of the point
 * @param longitude longitude of the point
 * @param altitude altitude of the point
 *//*from w w w.  j  a  v  a  2 s. c  o m*/
public GeodeticPoint(final double latitude, final double longitude, final double altitude) {
    double lat = MathUtils.normalizeAngle(latitude, FastMath.PI / 2);
    double lon = MathUtils.normalizeAngle(longitude, 0);
    if (lat > FastMath.PI / 2.0) {
        // latitude is beyond the pole -> add 180 to longitude
        lat = FastMath.PI - lat;
        lon = MathUtils.normalizeAngle(longitude + FastMath.PI, 0);
    }
    this.latitude = lat;
    this.longitude = lon;
    this.altitude = altitude;
}

From source file:org.orekit.bodies.OneAxisEllipsoidTest.java

private void checkCartesianToEllipsoidic(double ae, double f, double x, double y, double z, double longitude,
        double latitude, double altitude) throws OrekitException {

    AbsoluteDate date = AbsoluteDate.J2000_EPOCH;
    Frame frame = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
    OneAxisEllipsoid model = new OneAxisEllipsoid(ae, f, frame);
    GeodeticPoint gp = model.transform(new Vector3D(x, y, z), frame, date);
    Assert.assertEquals(longitude, MathUtils.normalizeAngle(gp.getLongitude(), longitude), 1.0e-10);
    Assert.assertEquals(latitude, gp.getLatitude(), 1.0e-10);
    Assert.assertEquals(altitude, gp.getAltitude(), 1.0e-10 * FastMath.abs(ae));
    Vector3D rebuiltNadir = Vector3D.crossProduct(gp.getSouth(), gp.getWest());
    Assert.assertEquals(0, rebuiltNadir.subtract(gp.getNadir()).getNorm(), 1.0e-15);
}

From source file:org.orekit.forces.maneuvers.ConstantThrustManeuverTest.java

@Test
public void testRoughBehaviour() throws OrekitException {
    final double isp = 318;
    final double mass = 2500;
    final double a = 24396159;
    final double e = 0.72831215;
    final double i = FastMath.toRadians(7);
    final double omega = FastMath.toRadians(180);
    final double OMEGA = FastMath.toRadians(261);
    final double lv = 0;

    final double duration = 3653.99;
    final double f = 420;
    final double delta = FastMath.toRadians(-7.4978);
    final double alpha = FastMath.toRadians(351);
    final AttitudeProvider law = new InertialProvider(
            new Rotation(new Vector3D(alpha, delta), Vector3D.PLUS_I));

    final AbsoluteDate initDate = new AbsoluteDate(new DateComponents(2004, 01, 01),
            new TimeComponents(23, 30, 00.000), TimeScalesFactory.getUTC());
    final Orbit orbit = new KeplerianOrbit(a, e, i, omega, OMEGA, lv, PositionAngle.TRUE,
            FramesFactory.getEME2000(), initDate, mu);
    final SpacecraftState initialState = new SpacecraftState(orbit,
            law.getAttitude(orbit, orbit.getDate(), orbit.getFrame()), mass);

    final AbsoluteDate fireDate = new AbsoluteDate(new DateComponents(2004, 01, 02),
            new TimeComponents(04, 15, 34.080), TimeScalesFactory.getUTC());
    final ConstantThrustManeuver maneuver = new ConstantThrustManeuver(fireDate, duration, f, isp,
            Vector3D.PLUS_I);/*  w w w .ja  v  a2s .c  om*/
    Assert.assertEquals(f, maneuver.getThrust(), 1.0e-10);
    Assert.assertEquals(isp, maneuver.getISP(), 1.0e-10);

    double[] absTolerance = { 0.001, 1.0e-9, 1.0e-9, 1.0e-6, 1.0e-6, 1.0e-6, 0.001 };
    double[] relTolerance = { 1.0e-7, 1.0e-4, 1.0e-4, 1.0e-7, 1.0e-7, 1.0e-7, 1.0e-7 };
    AdaptiveStepsizeIntegrator integrator = new DormandPrince853Integrator(0.001, 1000, absTolerance,
            relTolerance);
    integrator.setInitialStepSize(60);
    final NumericalPropagator propagator = new NumericalPropagator(integrator);
    propagator.setInitialState(initialState);
    propagator.setAttitudeProvider(law);
    propagator.addForceModel(maneuver);
    final SpacecraftState finalorb = propagator.propagate(fireDate.shiftedBy(3800));

    final double massTolerance = FastMath.abs(maneuver.getFlowRate())
            * maneuver.getEventsDetectors()[0].getThreshold();
    Assert.assertEquals(2007.8824544261233, finalorb.getMass(), massTolerance);
    Assert.assertEquals(2.6872, FastMath.toDegrees(MathUtils.normalizeAngle(finalorb.getI(), FastMath.PI)),
            1e-4);
    Assert.assertEquals(28970, finalorb.getA() / 1000, 1);

}

From source file:org.orekit.frames.ITRFEquinoxProviderTest.java

@Test
public void testSofaCookbook() throws OrekitException {

    // SOFA cookbook test case:
    //     date       2007 April 05, 12h00m00s.0 UTC
    //     xp         +0.0349282
    //     yp         +0.4833163
    //     UT1  UTC  -0s.072073685
    //     d 1980    -0.0550655
    //     d 1980    -0.0063580
    //     dX 2000    +0.0001725
    //     dY 2000    -0.0002650
    //     dX 2006    +0.0001750
    //     dY 2006    -0.0002259

    Utils.setLoaders(IERSConventions.IERS_1996,
            Utils.buildEOPList(IERSConventions.IERS_1996,
                    new double[][] {
                            { 54192, -0.072073685, 1.4020, 0.0349282, 0.4833163, -0.0550666, -0.0063580,
                                    Double.NaN, Double.NaN },
                            { 54193, -0.072073685, 1.4020, 0.0349282, 0.4833163, -0.0550666, -0.0063580,
                                    Double.NaN, Double.NaN },
                            { 54194, -0.072073685, 1.4020, 0.0349282, 0.4833163, -0.0550666, -0.0063580,
                                    Double.NaN, Double.NaN },
                            { 54195, -0.072073685, 1.4020, 0.0349282, 0.4833163, -0.0550666, -0.0063580,
                                    Double.NaN, Double.NaN },
                            { 54196, -0.072073685, 1.4020, 0.0349282, 0.4833163, -0.0550666, -0.0063580,
                                    Double.NaN, Double.NaN },
                            { 54197, -0.072073685, 1.4020, 0.0349282, 0.4833163, -0.0550666, -0.0063580,
                                    Double.NaN, Double.NaN },
                            { 54198, -0.072073685, 1.4020, 0.0349282, 0.4833163, -0.0550666, -0.0063580,
                                    Double.NaN, Double.NaN },
                            { 54199, -0.072073685, 1.4020, 0.0349282, 0.4833163, -0.0550666, -0.0063580,
                                    Double.NaN, Double.NaN } }));

    EOPHistory eopHistory = FramesFactory.getEOPHistory(IERSConventions.IERS_1996, true);

    TimeScale utc = TimeScalesFactory.getUTC();
    TTScale tt = TimeScalesFactory.getTT();
    UT1Scale ut1 = TimeScalesFactory.getUT1(eopHistory);
    Frame gcrf = FramesFactory.getGCRF();
    Frame itrf = FramesFactory.getITRFEquinox(IERSConventions.IERS_1996, true);
    Frame gtod = itrf.getParent();
    Frame tod = gtod.getParent();

    // time scales checks
    AbsoluteDate date = new AbsoluteDate(new DateComponents(2007, 4, 5), TimeComponents.H12, utc);
    Assert.assertEquals(0.50075444444444,
            date.getComponents(tt).getTime().getSecondsInDay() / Constants.JULIAN_DAY, 5.0e-15);
    Assert.assertEquals(0.499999165813831,
            date.getComponents(ut1).getTime().getSecondsInDay() / Constants.JULIAN_DAY, 1.0e-15);

    // sidereal time check
    double gast = IERSConventions.IERS_1996.getGASTFunction(ut1, eopHistory).value(date).getValue();
    Assert.assertEquals(13.412402380740 * 3600 * 1.0e6, radToMicroAS(MathUtils.normalizeAngle(gast, 0)), 25);

    // nutation/precession/bias matrix check
    Rotation refNPB = new Rotation(
            new double[][] { { +0.999998403176203, -0.001639032970562, -0.000712190961847 },
                    { +0.001639000942243, +0.999998655799521, -0.000045552846624 },
                    { +0.000712264667137, +0.000044385492226, +0.999999745354454 } },
            1.0e-13);/*from w  ww. ja  v  a2  s  .  c  om*/
    Rotation npb = gcrf.getTransformTo(tod, date).getRotation();
    Assert.assertEquals(0.0, radToMicroAS(Rotation.distance(refNPB, npb)), 27.0);

    // celestial to terrestrial frames matrix, without polar motion
    Rotation refWithoutPolarMotion = new Rotation(
            new double[][] { { +0.973104317592265, +0.230363826166883, -0.000703332813776 },
                    { -0.230363798723533, +0.973104570754697, +0.000120888299841 },
                    { +0.000712264667137, +0.000044385492226, +0.999999745354454 } },
            1.0e-13);
    Rotation withoutPM = gcrf.getTransformTo(gtod, date).getRotation();
    Assert.assertEquals(0.0, radToMicroAS(Rotation.distance(refWithoutPolarMotion, withoutPM)), 9);

    // celestial to terrestrial frames matrix, with polar motion
    Rotation refWithPolarMotion = new Rotation(
            new double[][] { { +0.973104317712772, +0.230363826174782, -0.000703163477127 },
                    { -0.230363800391868, +0.973104570648022, +0.000118545116892 },
                    { +0.000711560100206, +0.000046626645796, +0.999999745754058 } },
            1.0e-13);
    Rotation withPM = gcrf.getTransformTo(itrf, date).getRotation();
    Assert.assertEquals(0.0, radToMicroAS(Rotation.distance(refWithPolarMotion, withPM)), 10);

}