///<summary>得到从一点到另一点的保持up为北的变换矩阵</summary> public static Matrix getMatrixP2P(Vector3 pstart, Vector3 pend, STRUCT_EarthPara earthpara) { Matrix matrix = Matrix.Identity; if (earthpara.SceneMode == ESceneMode.地球) { double angle1 = Math.Atan(pstart.X / pstart.Z); double angle2 = Math.Atan(pend.X / pend.Z); if (angle2 != angle1) { matrix = Matrix.CreateRotationY((float)(angle2 - angle1)); } Vector3 pmid = Vector3.Transform(pstart, matrix); if (pmid != pend) { Vector3 axis = Vector3.Cross(pmid, pend); axis.Normalize(); System.Windows.Media.Media3D.Vector3D v1 = new System.Windows.Media.Media3D.Vector3D(pmid.X, pmid.Y, pmid.Z); System.Windows.Media.Media3D.Vector3D v2 = new System.Windows.Media.Media3D.Vector3D(pend.X, pend.Y, pend.Z); float angle = (float)(System.Windows.Media.Media3D.Vector3D.AngleBetween(v1, v2) / 180.0 * Math.PI); matrix *= Matrix.CreateFromAxisAngle(axis, angle); } } else { matrix = Matrix.CreateTranslation(pend - pstart); } return(matrix); }
///<summary>经纬高转换为坐标点</summary> public static VECTOR3D JWHToPoint(double JD, double WD, double GD, STRUCT_EarthPara earthpara) { if (earthpara.SceneMode == ESceneMode.地球) { double x, y, z, r, r2; r = Para.Radius + GD; y = r * Math.Sin(WD * Math.PI / 180); r2 = r * Math.Cos(WD * Math.PI / 180); x = r2 * Math.Cos((-JD + 180) * Math.PI / 180); z = r2 * Math.Sin((-JD + 180) * Math.PI / 180); return(new VECTOR3D((float)x, (float)y, (float)z)); } else { double x, y, z; x = (JD - earthpara.StartLocation.Longitude) * earthpara.UnitLongLen; y = (WD - earthpara.StartLocation.Latitude) * earthpara.UnitLatLen; z = GD; return(new VECTOR3D((float)x, (float)y, (float)z)); } }
///<summary>经纬高转换为坐标点</summary> public static Vector3 JWHToPoint(double j, double w, double h, STRUCT_EarthPara earthpara) { if (earthpara.SceneMode == ESceneMode.地球) { double x, y, z, r, r2; r = Para.Radius + h; y = r * Math.Sin(w * Math.PI / 180); r2 = r * Math.Cos(w * Math.PI / 180); x = r2 * Math.Cos((-j + 180) * Math.PI / 180); z = r2 * Math.Sin((-j + 180) * Math.PI / 180); return(new Vector3((float)x, (float)y, (float)z)); } else { double x, y, z; x = (j - earthpara.StartLocation.Longitude) * earthpara.UnitLongLen; y = (w - earthpara.StartLocation.Latitude) * earthpara.UnitLatLen; z = h; return(new Vector3((float)x, (float)y, (float)z)); } }
public static Vector3?GetProjectPoint3D(Vector2 ptCursor, Matrix view, Matrix projection, int Width, int Height, Plane plane, STRUCT_EarthPara earthpara) { //计算世界观察矩阵的逆矩阵 Matrix m = Matrix.Invert(view); //计算拾取射线的方向与原点 Vector3 vTemp; vTemp.X = (((2.0f * ptCursor.X) / Width) - 1) / projection.M11; vTemp.Y = -(((2.0f * ptCursor.Y) / Height) - 1) / projection.M22; vTemp.Z = -1.0f; //zh注:右手坐标系,取-1 Vector3 vPickRayDir, vPickRayOrig; vPickRayDir.X = vTemp.X * m.M11 + vTemp.Y * m.M21 + vTemp.Z * m.M31; vPickRayDir.Y = vTemp.X * m.M12 + vTemp.Y * m.M22 + vTemp.Z * m.M32; vPickRayDir.Z = vTemp.X * m.M13 + vTemp.Y * m.M23 + vTemp.Z * m.M33; vPickRayOrig.X = m.M41; vPickRayOrig.Y = m.M42; vPickRayOrig.Z = m.M43; vPickRayDir.Normalize(); Ray ray = new Ray(vPickRayOrig, vPickRayDir); if (earthpara.SceneMode == ESceneMode.地球) //zhh注:地球模式下暂无需求,未实现垂直面的取点 { BoundingSphere sphere = new BoundingSphere(new Vector3(0, 0, 0), Para.Radius); return(GetIntersect(ray, sphere)); } else { //Plane plane = new Plane(new Vector3(0, 0, 1), 0); return(GetIntersect(ray, plane)); } }
///<summary> ///获取2D转3D垂直表面的坐标(地球模式下垂直地面与纬线方向的平面(未实现) 或 平面模式下的y垂直平面) ///distanceY为重直平面距原点的距离 ///</summary> public static Vector3?GetProjectPoint3D2(Vector2 ptCursor, Camera camera, int Width, int Height, float distanceY, STRUCT_EarthPara earthpara) { camera.calCameraByDirection(); Plane plane = new Plane(new Vector3(0, -1, 0), distanceY); //指平面模式下,距原点为distance的与y轴垂直的平面 //zhh注:地球模式下暂无需求,未实现垂直面的取点 return(GetProjectPoint3D(ptCursor, camera.view, camera.projection, Width, Height, plane, earthpara)); }
///<summary>获取2D转3D水平表面的坐标(地球模式下的地平面或平面模式下的z垂直平面)dixtanceZ为距地面距离</summary> public static Vector3?GetProjectPoint3D(Vector2 ptCursor, Camera camera, int Width, int Height, float distanceZ, STRUCT_EarthPara earthpara) { camera.calCameraByDirection(); Plane plane = new Plane(new Vector3(0, 0, -1), distanceZ); //指平面模式下的地平面 return(GetProjectPoint3D(ptCursor, camera.view, camera.projection, Width, Height, plane, earthpara)); }
///<summary>坐标点转换为经纬高</summary> public static System.Windows.Media.Media3D.Point3D PointToJWH(System.Windows.Media.Media3D.Point3D point, STRUCT_EarthPara earthpara) { if (earthpara.SceneMode == ESceneMode.地球) { double j, w, h, r, r2; r = ((System.Windows.Media.Media3D.Vector3D)point).Length; h = r - Para.Radius; w = Math.Asin(point.Y / r) * 180 / Math.PI; r2 = r * Math.Cos(w * Math.PI / 180); j = -Math.Acos(point.X / r2) * 180 / Math.PI + 180; if (point.Z < 0) { j = 360.0 - j; } return(new System.Windows.Media.Media3D.Point3D(j, w, h)); } else { double j, w, h; j = point.X / earthpara.UnitLongLen + earthpara.StartLocation.Longitude; w = point.Y / earthpara.UnitLatLen + earthpara.StartLocation.Latitude; h = point.Z; return(new System.Windows.Media.Media3D.Point3D(j, w, h)); } }