private static Matrix3d ModelToPaper(Viewport vp)
{
Vector3d vd = vp.ViewDirection;
Point3d vc = new Point3d(vp.ViewCenter.X, vp.ViewCenter.Y, 0);
Point3d vt = vp.ViewTarget;
Point3d cp = vp.CenterPoint;
double ta = -vp.TwistAngle;
double vh = vp.ViewHeight;
double height = vp.Height;
double width = vp.Width;
double scale = vh / height;
double lensLength = vp.LensLength;
Vector3d zaxis = vd.GetNormal();
Vector3d xaxis = Vector3d.ZAxis.CrossProduct(vd);
Vector3d yaxis;
if (!xaxis.IsZeroLength())
{
xaxis = xaxis.GetNormal();
yaxis = zaxis.CrossProduct(xaxis);
}
else if (zaxis.Z < 0)
{
xaxis = Vector3d.XAxis * -1;
yaxis = Vector3d.YAxis;
zaxis = Vector3d.ZAxis * -1;
}
else
{
xaxis = Vector3d.XAxis;
yaxis = Vector3d.YAxis;
zaxis = Vector3d.ZAxis;
}
Matrix3d pcsToDCS = Matrix3d.Displacement(Point3d.Origin - cp);
pcsToDCS = pcsToDCS * Matrix3d.Scaling(scale, cp);
Matrix3d dcsToWcs = Matrix3d.Displacement(vc - Point3d.Origin);
Matrix3d mxCoords = Matrix3d.AlignCoordinateSystem(Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, Point3d.Origin,
xaxis, yaxis, zaxis);
dcsToWcs = mxCoords * dcsToWcs;
dcsToWcs = Matrix3d.Displacement(vt - Point3d.Origin) * dcsToWcs;
dcsToWcs = Matrix3d.Rotation(ta, zaxis, vt) * dcsToWcs;
Matrix3d perspectiveMx = Matrix3d.Identity;
if (vp.PerspectiveOn)
{
double vSize = vh;
double aspectRatio = width / height;
double adjustFactor = 1.0 / 42.0;
double adjstLenLgth = vSize * lensLength * Math.Sqrt(1.0 + aspectRatio * aspectRatio) * adjustFactor;
double iDist = vd.Length;
double lensDist = iDist - adjstLenLgth;
double[] dataAry = new double[] {1,0,0,0,0,1,0,0,0,0,
(adjstLenLgth-lensDist)/adjstLenLgth,lensDist*(iDist-adjstLenLgth)/adjstLenLgth,
0,0,-1.0/adjstLenLgth,iDist/adjstLenLgth};
perspectiveMx = new Matrix3d(dataAry);
}
Matrix3d finalMx = pcsToDCS.Inverse() * perspectiveMx * dcsToWcs.Inverse();
return finalMx;
}