cloudflight
2024-10-12 46e3091f9cdefc7e2ffbc69bcb9c39650b1c0587
WinFrmUI/Yw.WinFrmUI.Hydro.Q3d.Core/Map/Drawer.Draw.cs
@@ -789,57 +789,113 @@
        // 根据旋转角度计算旋转后的坐标
        // 根据旋转角度计算旋转后的坐标
        private PointF Get平面旋转Point(PointF p, PointF MapC)
        /// <summary>
        /// 计算围绕竖直线Z轴旋转后的坐标
        /// </summary>
        /// <param name="p">世界坐标</param>
        /// <param name="MapC"></param>
        /// <returns></returns>
        private PointF3D Get平面旋转Point(PointF3D p, PointF3D MapC)
        {
            PointF center = MapC;
            PointF3D center = MapC;
            double radian = Rotation * Math.PI / 180;  // 角度转弧度
            float x = (float)(Math.Cos(radian) * (p.X - center.X) - Math.Sin(radian) * (p.Y - center.Y) + center.X);
            float y = (float)(Math.Sin(radian) * (p.X - center.X) + Math.Cos(radian) * (p.Y - center.Y) + center.Y);
            return new PointF(x, y);
            float z = p.Z;
            return new PointF3D(x, y, z);
        }
        private PointF Get平面还原Point(PointF p, PointF MapC)
        /// <summary>
        /// 计算围绕竖直线Z轴旋转前的坐标
        /// </summary>
        /// <param name="p">p是世界坐标</param>
        /// <param name="MapC"></param>
        /// <returns></returns>
        private PointF3D Get平面还原Point(PointF3D p, PointF3D MapC)
        {
            PointF center = MapC;
            PointF3D center = MapC;
            double radian = -Rotation * Math.PI / 180;  // 角度转弧度
            float x = (float)(Math.Cos(radian) * (p.X - center.X) - Math.Sin(radian) * (p.Y - center.Y) + center.X);
            float y = (float)(Math.Sin(radian) * (p.X - center.X) + Math.Cos(radian) * (p.Y - center.Y) + center.Y);
            return new PointF(x, y);
            float z = p.Z;
            return new PointF3D(x, y, z);
        }
        private PointF Get俯视角旋转Point(PointF p, float z, PointF MapC)
        /// <summary>
        /// 将世界坐标投影到xy平面,建立投影坐标系,法向量为Z轴
        /// </summary>
        /// <param name="p"></param>
        /// <param name="z"></param>
        /// <param name="MapC"></param>
        /// <returns></returns>
        private PointF Get俯视角投影Point(PointF3D p, PointF3D MapC)
        {
            PointF center = MapC;
            PointF3D center = MapC;
            double radian_fushi = 俯视弧度;
            float sin = (float)Math.Sin(radian_fushi);
            float cos = (float)Math.Cos(radian_fushi);
            float x = (float)p.X;
            float y = (float)(sin * (p.Y - center.Y) + center.Y) + cos * z;
            float y = (float)(sin * (p.Y - center.Y) + center.Y) + cos * p.Z - center.Z;
            float z = p.Z;
            return new PointF(x, y);
        }
        private PointF Get俯视角还原Point(PointF p, float z, PointF MapC)
        /// <summary>
        /// 计算围绕X轴旋转前的坐标
        /// </summary>
        /// <param name="p"></param>
        /// <param name="z"></param>
        /// <param name="MapC"></param>
        /// <returns></returns>
        private PointF3D Get俯视角投影还原Point(PointF3D p, PointF3D MapC)
        {
            PointF center = MapC;
            PointF3D center = MapC;
            double radian_fushi = 俯视弧度;
            float sin = (float)Math.Sin(radian_fushi);
            float cos = (float)Math.Cos(radian_fushi);
            float x = (float)p.X;
            float y = (p.Y - center.Y - cos * z) / sin + center.Y;
            return new PointF(x, y);
            float x = p.X;
            float y = (p.Y - center.Y - cos * p.Z + center.Z) / sin + center.Y;
            float z = p.Z;
            return new PointF3D(x, y, z);
        }
        private PointF GetRotateVector(PointF p, PointF p0)
        /// <summary>
        /// 输入两个<屏幕坐标>的点,返回连接两点<世界坐标>的向量
        /// 该方法用来计算鼠标拖动/双击定位/鼠标位置缩放时,视角中心点的移动
        /// </summary>
        /// <param name="p">屏幕坐标</param>
        /// <param name="p0">屏幕坐标</param>
        /// <returns></returns>
        private PointF3D GetWorldVectorByScreenPoints(PointF p, PointF p0)
        {
            double radian = Rotation * Math.PI / 180;  // 角度转弧度
            float x = (float)(Math.Cos(radian) * (p.X - p0.X) - Math.Sin(radian) * (p.Y - p0.Y));
            float y = (float)(Math.Sin(radian) * (p.X - p0.X) + Math.Cos(radian) * (p.Y - p0.Y));
            return new PointF(x, y);
            double radian_fushi = 俯视弧度;
            var wp0 = ScreenToMap(p0);
            var wp = ScreenToMap(p);
            //通过p0到p的点,构造一个二维向量
            var vector = new Vector2(wp.X - wp0.X, wp.Y - wp0.Y);
            //通过俯视角度,根据vector的Y分量,计算新的y和z分量
            float y = (float)(vector.Y * Math.Sin(radian_fushi));
            float z = (float)(vector.Y * Math.Cos(radian_fushi));
            //构造一个新的向量
            var vector3 = new Vector3(vector.X, y, z);
            //通过平面旋转,将vector3,还原到世界坐标
            var vector3_ = Get平面还原Point(new PointF3D(vector3.X, vector3.Y, vector3.Z), new PointF3D(0, 0, 0));
            //对vector3_取反向量
            //,得到最终的向量
            return new PointF3D(vector3_.X, vector3_.Y, vector3_.Z);
            //float x = (float)(Math.Cos(radian) * (p.X - p0.X) - Math.Sin(radian) * (p.Y - p0.Y));
            //float y = (float)(Math.Sin(radian) * (p.X - p0.X) + Math.Cos(radian) * (p.Y - p0.Y));
            //float z = (float)(Math.Sin(radian_fushi) * (p.Y - p0.Y)); // 添加俯视角度的影响
            //return new PointF3D(x / Zoom.X, y / Zoom.Y, z/Zoom.Z);
        }
        /// <summary>
        /// 获取世界投影坐标
        /// </summary>
@@ -848,12 +904,13 @@
        /// <returns></returns>
        private PointF WorldPointToMapPoint(PointF point, float z, PointF3D offset = null)
        {
            if (offset == null) offset = new PointF3D(0, 0, 0);
            point = new PointF(point.X + offset.X, point.Y + offset.Y);
            PointF3D point3d = new PointF3D(point.X + offset.X, point.Y + offset.Y, z + offset.Z);
            var pointR = Get平面旋转Point(point, MapCenter);
            var pointR = Get平面旋转Point(point3d, MapCenter);
            var pointT = Get俯视角旋转Point(pointR, z + offset.Z, MapCenter);
            var pointT = Get俯视角投影Point(pointR, MapCenter);
            //var n=new PointF((float)pointR.X - Z(z).X, (float)(pointR.Y - Z(z).Y));
            return pointT;
@@ -865,21 +922,21 @@
        }
        private PointF WorldPointToMapPoint(NodeViewModel junction, PointF3D offset = null)
        {
            PointF p;
            if (junction == null) return new PointF(0, 0);
            p = WorldPointToMapPoint(junction.Position, junction.Z, offset);
            var p = WorldPointToMapPoint(junction.Position, junction.Z, offset);
            return p;
        }
        private PointF CubeWorldPointToMapPoint(NodeViewModel junction, PointF3D offset = null)
        {
            PointF p;
            if (junction == null) return new PointF(0, 0);
            var point = junction.Position;
            var point = junction.Position3D;
            var z = junction.Z;
            if (offset == null) offset = new PointF3D(0, 0, 0);
            point = new PointF(point.X + offset.X, point.Y + offset.Y);
            var pointR = Get平面旋转Point(point, new PointF(0, 0));
            var pointT = Get俯视角旋转Point(pointR, z + offset.Z, new PointF(0, 0));
            point = new PointF3D(point.X + offset.X, point.Y + offset.Y, point.Z + offset.Z);
            var pointR = Get平面旋转Point(point, new PointF3D(0, 0, 0));
            var pointT = Get俯视角投影Point(pointR, new PointF3D(0, 0, 0));
            //var n=new PointF((float)pointR.X - Z(z).X, (float)(pointR.Y - Z(z).Y));
            return pointT;
        }
@@ -968,32 +1025,22 @@
        }
        private PointF MapPointToWorldPoint(PointF3D point)
        {
            return MapPointToWorldPoint(new PointF(point.X, point.Y), point.Z);
        }
        /// <summary>
        /// 获取地图投影坐标
        /// </summary>
        /// <param name="point"></param>
        /// <param name="z"></param>
        /// <returns></returns>
        public PointF MapPointToWorldPoint(PointF point, float z = 0)
        public PointF3D MapPointToWorldPoint(PointF point, float z = 0)
        {
            var pointT = Get俯视角还原Point(point, z, MapCenter);
            var pointT = Get俯视角投影还原Point(new PointF3D(point.X, point.Y, z), MapCenter);
            pointT = Get平面还原Point(pointT, MapCenter);
            //var n=new PointF((float)pointR.X - Z(z).X, (float)(pointR.Y - Z(z).Y));
            return pointT;
        }
        private PointF GetMapPoint_还原(NodeViewModel junction)
        {
            PointF p;
            p = MapPointToWorldPoint(junction.Position, junction.Z);
            return p;
        }