text: // Geometric Tools, LLC
  // Copyright (c) 1998-2014
  // Distributed under the Boost Software License, Version 1.0.
  // http://www.boost.org/LICENSE_1_0.txt
  // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
  //
  // File Version: 5.0.1 (2010/10/01)
  
  #include "Wm5MathematicsPCH.h"
  #include "Wm5PerspProjEllipsoid.h"
  #include "Wm5EigenDecomposition.h"
  
  namespace Wm5
  {
  //----------------------------------------------------------------------------
  template <typename Real>
  void PerspectiveProjectEllipsoid (const Ellipsoid3<Real>& ellipsoid,
      const Vector3<Real>& eye, const Plane3<Real>& plane,
      const Vector3<Real>& U, const Vector3<Real>& V, Vector3<Real>& P,
      Ellipse2<Real>& ellipse)
  {
      // Get coefficients for ellipsoid as X^T*A*X + B^T*X + C = 0.
      Matrix3<Real> A;
      Vector3<Real> B;
      Real C;
      ellipsoid.ToCoefficients(A, B, C);
  
      // Compute matrix M (see PerspectiveProjectionEllipsoid.pdf).
      Vector3<Real> AE = A*eye;
      Real EAE = eye.Dot(AE);
      Real BE = B.Dot(eye);
      Real QuadE = ((Real)4)*(EAE + BE + C);
      Vector3<Real> Bp2AE = B + ((Real)2)*AE;
      Matrix3<Real> mat = Matrix3<Real>(Bp2AE, Bp2AE) - QuadE*A;
  
      // Compute coefficients for projected ellipse.
      Vector3<Real> MU = mat*U;
      Vector3<Real> MV = mat*V;
      Vector3<Real> MN = mat*plane.Normal;
      Real DmNdE = -plane.DistanceTo(eye);
      P = eye + DmNdE*plane.Normal;
  
      Matrix2<Real> AOut;
      Vector2<Real> BOut;
      Real COut;
      AOut[0][0] = U.Dot(MU);
      AOut[0][1] = U.Dot(MV);
      AOut[1][1] = V.Dot(MV);
      AOut[1][0] = AOut[0][1];
      BOut[0] = ((Real)2)*DmNdE*(U.Dot(MN));
      BOut[1] = ((Real)2)*DmNdE*(V.Dot(MN));
      COut = DmNdE*DmNdE*(plane.Normal.Dot(MN));
      ellipse.FromCoefficients(AOut, BOut, COut);
  }
  //----------------------------------------------------------------------------
  
  //----------------------------------------------------------------------------
  // Explicit instantiation.
  //----------------------------------------------------------------------------
  template WM5_MATHEMATICS_ITEM
  void PerspectiveProjectEllipsoid<float> (const Ellipsoid3<float>&,
      const Vector3<float>&, const Plane3<float>&, const Vector3<float>&,
      const Vector3<float>&, Vector3<float>&, Ellipse2<float>&);
  
  template WM5_MATHEMATICS_ITEM
  void PerspectiveProjectEllipsoid<double> (const Ellipsoid3<double>&,
      const Vector3<double>&, const Plane3<double>&, const Vector3<double>&,
      const Vector3<double>&, Vector3<double>&, Ellipse2<double>&);
  //----------------------------------------------------------------------------
  }
  