maybe this simplified code may help you to do the math as well.
Matrix3d ps2wcs = pvp2.GetModelToPaperTransform().Inverse();
public static Matrix3d GetModelToPaperTransform(this Autodesk.AutoCAD.DatabaseServices.Viewport pvp)
{
Point3d center = new Point3d(pvp.ViewCenter.X, pvp.ViewCenter.Y, 0.0);
Vector3d v = new Vector3d(pvp.CenterPoint.X - center.X, pvp.CenterPoint.Y - center.Y, 0.0);
return Matrix3d.Displacement(v)
* Matrix3d.Scaling(pvp.CustomScale, center)
* Matrix3d.Rotation(pvp.TwistAngle, Vector3d.ZAxis, Point3d.Origin)
* Matrix3d.WorldToPlane(new Plane(pvp.ViewTarget, pvp.ViewDirection));
}
Credits to Gile, see http://www.acadnetwork.com/topic-19.0.html#c2
...
using GeometryExtensions;
...
//Create the Paperspace Viewport boundary in Modelspace.
[CommandMethod("msPVPByGile")]
public void CreateViewportBorderInModelSpaceByGile()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
if (db.TileMode)
{
ed.WriteMessage("\nStart from within Paperspace!");
return;
}
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
BlockTableRecord ps = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForWrite);
LayoutManager layMgr = LayoutManager.Current;
Layout lay = (Layout)tr.GetObject(layMgr.GetLayoutId(layMgr.CurrentLayout), OpenMode.ForRead);
Viewport pvp2 = (Viewport)tr.GetObject(lay.GetViewports()[1], OpenMode.ForRead);
Polyline vpPoly = pvp2.GetPaperSpaceBoundary();
Polyline msKader = (Polyline)vpPoly.Clone();
ps.AppendEntity(vpPoly);
tr.AddNewlyCreatedDBObject(vpPoly, true);
//Matrix3d ps2wcs = pvp2.PSDCS2DCS() * pvp2.DCS2WCS();
Matrix3d ps2wcs = pvp2.DCS2WCS() * pvp2.PSDCS2DCS();
msKader.TransformBy(ps2wcs);
ms.AppendEntity(msKader);
tr.AddNewlyCreatedDBObject(msKader, true);
tr.Commit();
}
}
public static class ViewportExtensions
{
public static Polyline GetPaperSpaceBoundary(this Autodesk.AutoCAD.DatabaseServices.Viewport pvp)
{
Polyline vpPoly = null;
if (!pvp.NonRectClipOn)
{
Extents3d vpExt = pvp.GeometricExtents;
vpPoly = new Polyline(4);
vpPoly.AddVertexAt(0, new Point2d(vpExt.MinPoint.X, vpExt.MinPoint.Y), 0, 0, 0);
vpPoly.AddVertexAt(1, new Point2d(vpExt.MaxPoint.X, vpExt.MinPoint.Y), 0, 0, 0);
vpPoly.AddVertexAt(2, new Point2d(vpExt.MaxPoint.X, vpExt.MaxPoint.Y), 0, 0, 0);
vpPoly.AddVertexAt(3, new Point2d(vpExt.MinPoint.X, vpExt.MaxPoint.Y), 0, 0, 0);
vpPoly.Closed = true;
}
else
{
vpPoly = (Polyline)pvp.NonRectClipEntityId.GetObject(OpenMode.ForRead).Clone();
}
return vpPoly;
}
}