Beispiel #1
0
    public void CreateRotationX()
    {
      double angle = (double)MathHelper.ToRadians(30.0);
      Matrix33D m = Matrix33D.CreateRotationX(angle);
      Assert.IsTrue(Vector3D.AreNumericallyEqual(new Vector3D(0, (double)Math.Cos(angle), (double)Math.Sin(angle)), m * Vector3D.UnitY));

      QuaternionD q = QuaternionD.CreateRotation(Vector3D.UnitX, angle);
      Assert.IsTrue(Vector3D.AreNumericallyEqual(q.Rotate(Vector3D.One), m * Vector3D.One));

      Assert.IsTrue(Matrix33D.AreNumericallyEqual(Matrix33D.CreateRotation(Vector3D.UnitX, angle), m));
    }
Beispiel #2
0
        public void Test1()
        {
            PoseD p = PoseD.Identity;

            Assert.AreEqual(Matrix44D.Identity, p.ToMatrix44D());
            Assert.AreEqual(Matrix33D.Identity, p.Orientation);
            Assert.AreEqual(Vector3D.Zero, p.Position);

            p.Position = new Vector3D(1, 2, 3);

            p.Orientation = Matrix33D.CreateRotation(new Vector3D(3, -4, 9), 0.49);
            Assert.IsTrue(Vector4D.AreNumericallyEqual(new Vector4D(p.ToWorldDirection(Vector3D.UnitX), 0), p * new Vector4D(1, 0, 0, 0)));
            Assert.IsTrue(Vector4D.AreNumericallyEqual(new Vector4D(p.ToWorldDirection(Vector3D.UnitY), 0), p * new Vector4D(0, 1, 0, 0)));
            Assert.IsTrue(Vector4D.AreNumericallyEqual(new Vector4D(p.ToWorldDirection(Vector3D.UnitZ), 0), p * new Vector4D(0, 0, 1, 0)));
            Assert.IsTrue(Vector4D.AreNumericallyEqual(new Vector4D(p.ToWorldPosition(Vector3D.UnitX), 1), p * new Vector4D(1, 0, 0, 1)));
            Assert.IsTrue(Vector4D.AreNumericallyEqual(new Vector4D(p.ToWorldPosition(Vector3D.UnitY), 1), p * new Vector4D(0, 1, 0, 1)));
            Assert.IsTrue(Vector4D.AreNumericallyEqual(new Vector4D(p.ToWorldPosition(Vector3D.UnitZ), 1), p * new Vector4D(0, 0, 1, 1)));
            Assert.IsTrue(Vector4D.AreNumericallyEqual(new Vector4D(p.ToLocalDirection(Vector3D.UnitX), 0), p.Inverse * new Vector4D(1, 0, 0, 0)));
            Assert.IsTrue(Vector4D.AreNumericallyEqual(new Vector4D(p.ToLocalDirection(Vector3D.UnitY), 0), p.Inverse * new Vector4D(0, 1, 0, 0)));
            Assert.IsTrue(Vector4D.AreNumericallyEqual(new Vector4D(p.ToLocalDirection(Vector3D.UnitZ), 0), p.Inverse * new Vector4D(0, 0, 1, 0)));
            Assert.IsTrue(Vector4D.AreNumericallyEqual(new Vector4D(p.ToLocalPosition(Vector3D.UnitX), 1), p.Inverse * new Vector4D(1, 0, 0, 1)));
            Assert.IsTrue(Vector4D.AreNumericallyEqual(new Vector4D(p.ToLocalPosition(Vector3D.UnitY), 1), p.Inverse * new Vector4D(0, 1, 0, 1)));
            Assert.IsTrue(Vector4D.AreNumericallyEqual(new Vector4D(p.ToLocalPosition(Vector3D.UnitZ), 1), p.Inverse * new Vector4D(0, 0, 1, 1)));

            PoseD p2 = PoseD.FromMatrix(new Matrix44D(p.Orientation, Vector3D.Zero));

            Assert.IsTrue(Matrix33D.AreNumericallyEqual(p.Orientation, p2.Orientation));
            Assert.IsTrue(Vector3D.AreNumericallyEqual(p2.Position, Vector3D.Zero));

            Matrix44D m = p2;

            m.SetColumn(3, new Vector4D(p.Position, 1));
            p2 = PoseD.FromMatrix(m);
            Assert.IsTrue(Matrix33D.AreNumericallyEqual(p.Orientation, p2.Orientation));
            Assert.AreEqual(p.Position, p2.Position);
            //Assert.IsTrue(Vector3D.AreNumericallyEqual(p.Position, p2.Position));

            // Test other constructors.
            Assert.AreEqual(Vector3D.Zero, new PoseD(QuaternionD.CreateRotationX(0.3)).Position);
            Assert.AreEqual(Matrix33D.CreateRotationX(0.3), new PoseD(Matrix33D.CreateRotationX(0.3)).Orientation);
            Assert.AreEqual(new Vector3D(1, 2, 3), new PoseD(new Vector3D(1, 2, 3)).Position);
            Assert.AreEqual(Matrix33D.Identity, new PoseD(new Vector3D(1, 2, 3)).Orientation);
        }
Beispiel #3
0
    public void Orthogonalize()
    {
      var m = Matrix33D.CreateRotationX(0.1) * Matrix33D.CreateRotationX(20) * Matrix33D.CreateRotationZ(1000);

      // Introduce error.
      m.M01 += 0.1f;
      m.M22 += 0.1f;

      Assert.IsFalse(m.IsOrthogonal);
      Assert.IsFalse(m.IsRotation);

      m.Orthogonalize();

      Assert.IsTrue(m.IsOrthogonal);
      Assert.IsTrue(m.IsRotation);

      // Orthogonalizing and orthogonal matrix does not change the matrix.
      var n = m;
      n.Orthogonalize();
      Assert.IsTrue(Matrix33D.AreNumericallyEqual(m, n));
    }
Beispiel #4
0
    /// <summary>
    /// Computes the derived values, like sun/moon positions, transformation matrices and light
    /// intensities. This method must be called when the location or time has changed.
    /// </summary>
    /// <remarks>
    /// This method must be called when the input properties <see cref="Latitude"/>,
    /// <see cref="Longitude"/>, <see cref="Altitude"/>, or <see cref="Time"/>) have changed.
    /// </remarks>
    public void Update()
    {
      _epoch2000Centuries = ToEpoch2000Centuries(Time, true);
      _epoch1990Days = ToEpoch1990Days(Time, false);

      // To transform from ecliptic to equatorial, we rotate by the obliquity of the ecliptic.
      _e = 0.409093 - 0.000227 * _epoch2000Centuries;
      EclipticToEquatorial = Matrix33D.CreateRotationX(_e);

      // GMST = Greenwich mean sidereal time (mittlere Greenwich-Sternzeit) in radians.
      double gmst = 4.894961 + 230121.675315 * ToEpoch2000Centuries(Time, false);
      EquatorialToGeographic = Matrix33D.CreateRotationZ(-gmst);

      // The earth axis slowly changes over time (precession). The precession movement repeats
      // itself approx. all 26000 years. When we move from to horizontal or geographics,
      // we need to apply the precession.

      // In Game Engine Gems:
      //var Rx = Matrix33D.CreateRotationX(0.1118 * _epoch2000Centuries);
      //var Ry = Matrix33D.CreateRotationY(-0.00972 * _epoch2000Centuries);
      //var Rz = Matrix33D.CreateRotationZ(0.01118 * _epoch2000Centuries);
      //var precession = Rz * (Ry * Rx);

      // In original article:
      var Ry = Matrix33D.CreateRotationY(-0.00972 * _epoch2000Centuries);
      var Rz = Matrix33D.CreateRotationZ(0.01118 * _epoch2000Centuries);
      var precession = Rz * Ry * Rz;

      // In game engine gems precession is applied in EclipticToWorld and in
      // EquatorialToWorld. This makes no sense since precession cannot be valid for both
      // coordinate systems. --> We assume the precession is given in equatorial space.
      //EclipticToWorld = rLat * rLong * EclipticToEquatorial * precession;

      // Latitude rotation
      var rLat = Matrix33D.CreateRotationY(MathHelper.ToRadians(Latitude) - ConstantsD.PiOver2);

      // Longitude rotation
      // LMST = Local mean sidereal time (mittlere Ortssternzeit) in radians.
      double lmst = gmst + MathHelper.ToRadians(Longitude);
      var rLong = Matrix33D.CreateRotationZ(-lmst);

      // Earth radius at the equator. (We assume a perfect sphere. We do not support geodetic 
      // systems with imperfect earth spheres.)
      const double earthRadius = 6378.137 * 1000;
      var equatorialToHorizontalTranslation = new Vector3D(0, -earthRadius - Altitude, 0);

      // Switching of the coordinate axes between Equatorial (z up) and Horizontal (y up).
      var axisSwitch = new Matrix33D(0, 1, 0,
                                     0, 0, 1,
                                     1, 0, 0);

      EquatorialToWorld = new Matrix44D(axisSwitch * rLat * rLong * precession,
                                        equatorialToHorizontalTranslation);

      _equatorialToWorldNoPrecession = new Matrix44D(axisSwitch * rLat * rLong,
                                                     equatorialToHorizontalTranslation);

      //WorldToGeographic = EquatorialToGeographic * EquatorialToWorld.Minor.Transposed;

      ComputeSunPosition();
      ComputeMoonPosition();
      ComputeEarthPosition();

      //for (int i = 0; i < NumberOfPlanets; i++)
      //{
      //  var planet = (VisiblePlanets)i;
      //  if (planet != VisiblePlanets.Earth)
      //    ComputePlanetData(planet);
      //}
    }