在SceneControl中通过鼠标单击获得三维射线、产生三维的点

我的思路是这样的:在SceneControl的空白处点击,不可能确定一个三维点,应该可以得到无数点,这些点在一条直线上,且与观察点共线,我现在想得到z值为0的那个点,于是我通过SceneControl的单击事件数据e获取屏幕坐标e.x和e.y,然后用DisplayTransformation.ToMapPoint方法将屏幕坐标转换为实际的地图坐标Point,然后给该点的z值赋值0,按说这样就可以通过鼠标单击得到一个具有指定z值的三维点了。可是我在DisplayTransformation.ToMapPoint返回的地图坐标不准确,比如如果e.x= 55,e.y=66,那么通过该方法得到的点的地图坐标是Point.X = 55,Point.Y = -66,也就是说x没有变化,y只是变成了对应的负数,很疑惑。

之前的代码是这样的:

 private void PipeSceneControl_OnMouseDown(object sender, ISceneControlEvents_OnMouseDownEvent e)
        {
            ISceneGraph pSG = this.PipeSceneControl.SceneGraph;
            IScreenDisplay pSD = pSG as IScreenDisplay;
            IDisplayTransformation pDT = pSD.DisplayTransformation;
            //pDT.Bounds = PipeSceneControl.Scene.Extent;
            //pDT.VisibleBounds = PipeSceneControl.Scene.Extent;
            IPoint Pnt = pDT.ToMapPoint(e.x, e.y);
            Pnt.Z = 0;          
        }

上面的代码得不到想要的结果,然后又问了很多人,也在ESRI论坛上发了帖子,都无果,看来还得靠自己看帮助文档了。

我一直在找一个函数,这个函数可以得到观察点与所点击的屏幕坐标所确定的射线,后来终于在ICamara接口下面找到这个方法了。

public IRay ICamera.GetIdentifyVector(int x,int y)可以实现上述功能,得到了射线后,我可以根据我想要的点的z值(或x值或y值)推算出另外两个坐标值,从而确定该点。

下面的代码通过单击获得Z=0的点:

 private void PipeSceneControl_OnMouseDown(object sender, ISceneControlEvents_OnMouseDownEvent e)
        {
            double ValueZ = 0.0;//假设所单击的点的坐标的Z值为0
            ICamera pCamara = this.PipeSceneControl.Camera;
            IRay pRay = pCamara.GetIdentifyRay(e.x, e.y);
            IVector3D pVecotor3D = pRay.Vector;
            pVecotor3D.Normalize();
            double a = (ValueZ - pRay.Origin.Z) / pVecotor3D.ZComponent;
            IPoint Pnt = new PointClass();
            Pnt.Z = ValueZ;
            Pnt.X = pRay.Origin.X + pVecotor3D.XComponent * a;
            Pnt.Y = pRay.Origin.Y + pVecotor3D.YComponent * a;

            (Pnt as IZAware).ZAware = true;
            IGraphicsContainer3D pGC3D = this.PipeSceneControl.Scene.BasicGraphicsLayer as IGraphicsContainer3D;
            pGC3D.DeleteAllElements();
            IElement pElement = new MarkerElementClass();
            IRgbColor pColor = new RgbColorClass();
            pColor.Red = 255;
            ISimpleMarkerSymbol pMarkerSymbol = new SimpleMarkerSymbolClass();
            pMarkerSymbol.Size = 30;
            pMarkerSymbol.Color = pColor;
            (pElement as IMarkerElement).Symbol = pMarkerSymbol;
            pElement.Geometry = Pnt;
            pGC3D.AddElement(pElement);
            this.PipeSceneControl.Scene.SceneGraph.RefreshViewers();
        }

在SceneControl中点击,效果图如下:


©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页