revit空间三维坐标与视图窗口坐标互相转换

revit坐标转换,空间三维坐标点(即revit的世界坐标) ,与视图窗口坐标(以视图窗口客户区左上角为原点,非屏幕左上角)的互相转换。

    [Transaction(TransactionMode.Manual)]
    [Regeneration(RegenerationOption.Manual)]
    [Journaling(JournalingMode.NoCommandData)]
    class TTestCmd : IExternalCommand
    {
        protected Application m_app;
        protected Document m_doc;
        protected UIApplication m_uiApp;
        protected UIDocument m_uiDoc;
        public Result Execute(ExternalCommandData commandData, ref string messages, ElementSet elements)
        {
            this.m_uiApp = commandData.Application;
            this.m_uiDoc = this.m_uiApp.ActiveUIDocument;
            this.m_app = this.m_uiApp.Application;
            this.m_doc = this.m_uiDoc.Document;

            Reference refer = null;
            try
            {
                refer = this.m_uiDoc.Selection.PickObject(ObjectType.Element, "PickObject Element");
            }
            catch
            {

            }
            if (refer == null)
                return Result.Failed;
            System.Drawing.PointF ptScreen = GetTransPtRevitToScreen(this.m_uiDoc, refer.GlobalPoint);
            return Result.Failed;
        }
        public static double Hypot(params double[] arD)
        {
            double dSum = 0;
            foreach (double dT in arD)
            {
                dSum += Math.Pow(dT, 2);
            }
            return Math.Sqrt(dSum);
        }
        public static XYZ GetTransPtScreenToRevit(UIDocument uiDoc, System.Drawing.PointF ptScreen)
        {
            Transform mat = GetTransPtRevitToScreenInternal(uiDoc);
            if (mat == null)
                return null;
            return mat.Inverse.OfPoint(new XYZ(ptScreen.X, ptScreen.Y, 0));
        }
        private static System.Drawing.PointF GetTransPtRevitToScreen(UIDocument uiDoc, XYZ ptRevit)
        {
            Transform mat = GetTransPtRevitToScreenInternal(uiDoc);
            if (mat == null)
                return System.Drawing.PointF.Empty;
            XYZ ptScreen = mat.OfPoint(ptRevit);
            return new System.Drawing.PointF(Convert.ToSingle(ptScreen.X), Convert.ToSingle(ptScreen.Y));
        }
        private static Transform GetTransPtRevitToScreenInternal(UIDocument uiDoc)
        {
            if (uiDoc == null)
                return null;
            Autodesk.Revit.DB.View view = uiDoc.ActiveView;
            if (view == null)
                return null;
            UIView uiView = uiDoc.GetOpenUIViews().FirstOrDefault(p => p.ViewId.IntegerValue == view.Id.IntegerValue);
            if (uiView == null)
                return null;
            REVIT_RECT windowRectangle = uiView.GetWindowRectangle();
            IList<XYZ> zoomCorners = uiView.GetZoomCorners();
            if (zoomCorners.Count < 2)
                return null;
            double dDisCorner = zoomCorners[0].DistanceTo(zoomCorners[1]);
            if (dDisCorner < uiDoc.Application.Application.ShortCurveTolerance)
                return null;
            double dScale = Hypot(windowRectangle.Right - windowRectangle.Left, windowRectangle.Bottom - windowRectangle.Top) / dDisCorner;
            Transform matCrop = view.CropBox.Transform;
            Transform mat = Transform.Identity;
            mat.BasisX = new XYZ(matCrop.BasisX.X, -matCrop.BasisY.X, 0);
            mat.BasisY = new XYZ(matCrop.BasisX.Y, -matCrop.BasisY.Y, 0);
            mat.BasisZ = new XYZ(matCrop.BasisX.Z, -matCrop.BasisY.Z, 1);//"1"并没有作用,只是为了可以求逆而已
            mat.Origin = new XYZ(-zoomCorners[0].DotProduct(matCrop.BasisX), zoomCorners[1].DotProduct(matCrop.BasisY), 0);
            mat = mat.ScaleBasisAndOrigin(dScale);
            mat.Origin += new XYZ(windowRectangle.Left, windowRectangle.Top, 0);
            return mat;
        }
    }

猜你喜欢

转载自blog.csdn.net/u010150437/article/details/83931837
今日推荐