定点绕定轴旋转
通过两个已知点,绕定轴旋转360次,每次旋转一度,获得360个点,一次相连,可以获得一个近似圆。
网上找的公式基本都是左手坐标系下的选择公式,故而进行了多次坐标转换
1、3.2版本
public static List<Vector3d> Translate(List<Vector3> list) { List<Vector3d> zuoshou = new List<Vector3d>();//存左手坐标系下的各点坐标 List<Vector3d> shijiezuobiao = new List<Vector3d>();//存世界坐标系下的各点坐标 List<Vector3d> jieguoweidu = new List<Vector3d>();//存世界坐标转换过来的经纬度坐标 List<Vector3d> zuizhong = new List<Vector3d>();//存经纬度不变,高程设为新值的经纬度坐标 //由双击球体获取点位置和球心三点生成平面,过圆心垂直此平面的法向量,作为旋转轴 Vector3 p1 = new Vector3(list[0].X, list[0].Z, list[0].Y); Vector3 p2 = new Vector3(list[1].X, list[1].Z, list[1].Y); Vector3 xuanzhuanzhou = new Vector3(); xuanzhuanzhou.X = 1; xuanzhuanzhou.Y = (p1.X * p2.Z - p2.X * p1.Z) / (p1.Z * p2.Y - p2.Z * p1.Y); xuanzhuanzhou.Z = (p1.X * p2.Y - p2.X * p1.Y) / (p1.Y * p2.Z - p1.Z * p2.Y); xuanzhuanzhou.Normalize(); zuoshou.Add(new Vector3d(list[0].X, list[0].Z, list[0].Y)); double x11, x12, x13, x21, x22, x23, x31, x32, x33; Vector3d pos = new Vector3d(); int iii = 1; for (int i = 0; i < 360; i++) { jiaodu = Math.PI * iii / 180; x11 = Math.Cos(jiaodu) + xuanzhuanzhou.X * xuanzhuanzhou.X * (1 - Math.Cos(jiaodu)); x12 = xuanzhuanzhou.X * xuanzhuanzhou.Y * (1 - Math.Cos(jiaodu)) - xuanzhuanzhou.Z * Math.Sin(jiaodu); x13 = xuanzhuanzhou.X * xuanzhuanzhou.Z * (1 - Math.Cos(jiaodu)) + xuanzhuanzhou.Y * Math.Sin(jiaodu); x21 = xuanzhuanzhou.X * xuanzhuanzhou.Y * (1 - Math.Cos(jiaodu)) + xuanzhuanzhou.Z * Math.Sin(jiaodu); x22 = Math.Cos(jiaodu) + xuanzhuanzhou.Y * xuanzhuanzhou.Y * (1 - Math.Cos(jiaodu)); x23 = xuanzhuanzhou.Y * xuanzhuanzhou.Z * (1 - Math.Cos(jiaodu)) - xuanzhuanzhou.X * Math.Sin(jiaodu); x31 = xuanzhuanzhou.X * xuanzhuanzhou.Z * (1 - Math.Cos(jiaodu)) - xuanzhuanzhou.Y * Math.Sin(jiaodu); x32 = xuanzhuanzhou.Y * xuanzhuanzhou.Z * (1 - Math.Cos(jiaodu)) + xuanzhuanzhou.X * Math.Sin(jiaodu); x33 = Math.Cos(jiaodu) + xuanzhuanzhou.Z * xuanzhuanzhou.Z * (1 - Math.Cos(jiaodu)); double posX = zuoshou[0].X * x11 + zuoshou[0].Y * x21 + zuoshou[0].Z * x31; double posY = zuoshou[0].X * x12 + zuoshou[0].Y * x22 + zuoshou[0].Z * x32; double posZ = zuoshou[0].X * x13 + zuoshou[0].Y * x23 + zuoshou[0].Z * x33; zuoshou.Add(new Vector3d(posX, posY, posZ)); iii++; } for (int i = 0; i < zuoshou.Count; i++)//将左手坐标系下点转换为世界坐标系下点坐标 { shijiezuobiao.Add(new Vector3d(zuoshou[i].X, zuoshou[i].Z, zuoshou[i].Y)); } for (int ii = 0; ii < shijiezuobiao.Count; ii++)//将世界坐标转换为经纬度坐标 { jieguoweidu.Add(new Vector3d(ConvertWorldPositionToGeoPosition(shijiezuobiao[ii]))); } for (int iiii = 0; iiii < jieguoweidu.Count; iiii++)//设置轨道圆的半径,值离地面高度 { zuizhong.Add(new Vector3d(jieguoweidu[iiii].X, jieguoweidu[iiii].Y, 1000000)); } return zuizhong; }
2、5.0版本
/// </summary> /// 计算点对,返回结果保存经纬度 /// </summary> /// <param name="list">旋转轴起始点世界坐标,两个点</param> /// <param name="Clist">中间需要旋转的点的世界坐标</param> /// <param name="jiaodu">旋转角度</param> /// <returns></returns> public static List<PointList> Translate(List<Vector3> listtt, List<Vector3> Clisttt, double jiaodu) { //将世界坐标转为左手坐标 var list = new List<Vector3>(); var Clist = new List<Vector3>(); for (int i = 0; i < listtt.Count; i++) { list.Add(new Vector3(listtt.ElementAt(i).X, listtt.ElementAt(i).Z, listtt.ElementAt(i).Y)); } for (int i = 0; i < Clisttt.Count; i++) { Clist.Add(new Vector3(Clisttt.ElementAt(i).X, Clisttt.ElementAt(i).Z, Clisttt.ElementAt(i).Y)); } var LeftList = new List<PointList>();//存左手坐标系下的各点坐标 var WorldList = new List<PointList>();//存世界坐标系下的各点坐标 var LatLonList = new List<PointList>();//存世界坐标转换过来的经纬度坐标,弧度制 var RetureList = new List<PointList>();//存返回坐标,经纬度,高 Vector3 p1 = new Vector3(list[0].X, list[0].Y, list[0].Z); Vector3 p2 = new Vector3(list[1].X, list[1].Y, list[1].Z); Vector3 xuanzhuanzhou = new Vector3(); double x11, x12, x13, x21, x22, x23, x31, x32, x33; double x111, x121, x131, x211, x221, x231, x311, x321, x331; jiaodu = System.Math.PI * jiaodu / 180; var jiaodu2 = -jiaodu; //CList最少存储2 //if (Clist.Count == 1) //{ //} for (int i = 0; i < Clist.Count; i++) { #region //确定旋转轴 if (i == 0) { xuanzhuanzhou.X = Clist.ElementAt(1).X - Clist.ElementAt(0).X; xuanzhuanzhou.Y = Clist.ElementAt(1).Y - Clist.ElementAt(0).Y; xuanzhuanzhou.Z = Clist.ElementAt(1).Z - Clist.ElementAt(0).Z; var mo = System.Math.Sqrt(xuanzhuanzhou.X * xuanzhuanzhou.X + xuanzhuanzhou.Y * xuanzhuanzhou.Y + xuanzhuanzhou.Z * xuanzhuanzhou.Z); xuanzhuanzhou.X = xuanzhuanzhou.X / mo; xuanzhuanzhou.Y = xuanzhuanzhou.Y / mo; xuanzhuanzhou.Z = xuanzhuanzhou.Z / mo; } else if (i == Clist.Count - 1) { xuanzhuanzhou.X = Clist.ElementAt(Clist.Count - 2).X - Clist.ElementAt(Clist.Count - 1).X; xuanzhuanzhou.Y = Clist.ElementAt(Clist.Count - 2).Y - Clist.ElementAt(Clist.Count - 1).Y; xuanzhuanzhou.Z = Clist.ElementAt(Clist.Count - 2).Z - Clist.ElementAt(Clist.Count - 1).Z; var mo = System.Math.Sqrt(xuanzhuanzhou.X * xuanzhuanzhou.X + xuanzhuanzhou.Y * xuanzhuanzhou.Y + xuanzhuanzhou.Z * xuanzhuanzhou.Z); xuanzhuanzhou.X = xuanzhuanzhou.X / mo; xuanzhuanzhou.Y = xuanzhuanzhou.Y / mo; xuanzhuanzhou.Z = xuanzhuanzhou.Z / mo; } else { xuanzhuanzhou.X = Clist.ElementAt(i - 1).X - Clist.ElementAt(i + 1).X; xuanzhuanzhou.Y = Clist.ElementAt(i - 1).Y - Clist.ElementAt(i + 1).Y; xuanzhuanzhou.Z = Clist.ElementAt(i - 1).Z - Clist.ElementAt(i + 1).Z; var mo = System.Math.Sqrt(xuanzhuanzhou.X * xuanzhuanzhou.X + xuanzhuanzhou.Y * xuanzhuanzhou.Y + xuanzhuanzhou.Z * xuanzhuanzhou.Z); xuanzhuanzhou.X = xuanzhuanzhou.X / mo; xuanzhuanzhou.Y = xuanzhuanzhou.Y / mo; xuanzhuanzhou.Z = xuanzhuanzhou.Z / mo; } #endregion #region 坐标计算 Vector3 pos = new Vector3(); x11 = System.Math.Cos(jiaodu) + xuanzhuanzhou.X * xuanzhuanzhou.X * (1 - System.Math.Cos(jiaodu)); x12 = xuanzhuanzhou.X * xuanzhuanzhou.Y * (1 - System.Math.Cos(jiaodu)) - xuanzhuanzhou.Z * System.Math.Sin(jiaodu); x13 = xuanzhuanzhou.X * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu)) + xuanzhuanzhou.Y * System.Math.Sin(jiaodu); x21 = xuanzhuanzhou.X * xuanzhuanzhou.Y * (1 - System.Math.Cos(jiaodu)) + xuanzhuanzhou.Z * System.Math.Sin(jiaodu); x22 = System.Math.Cos(jiaodu) + xuanzhuanzhou.Y * xuanzhuanzhou.Y * (1 - System.Math.Cos(jiaodu)); x23 = xuanzhuanzhou.Y * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu)) - xuanzhuanzhou.X * System.Math.Sin(jiaodu); x31 = xuanzhuanzhou.X * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu)) - xuanzhuanzhou.Y * System.Math.Sin(jiaodu); x32 = xuanzhuanzhou.Y * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu)) + xuanzhuanzhou.X * System.Math.Sin(jiaodu); x33 = System.Math.Cos(jiaodu) + xuanzhuanzhou.Z * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu)); double posX = Clist.ElementAt(i).X * x11 + Clist.ElementAt(i).Y * x21 + Clist.ElementAt(i).Z * x31; double posY = Clist.ElementAt(i).X * x12 + Clist.ElementAt(i).Y * x22 + Clist.ElementAt(i).Z * x32; double posZ = Clist.ElementAt(i).X * x13 + Clist.ElementAt(i).Y * x23 + Clist.ElementAt(i).Z * x33; x111 = System.Math.Cos(jiaodu2) + xuanzhuanzhou.X * xuanzhuanzhou.X * (1 - System.Math.Cos(jiaodu2)); x121 = xuanzhuanzhou.X * xuanzhuanzhou.Y * (1 - System.Math.Cos(jiaodu2)) - xuanzhuanzhou.Z * System.Math.Sin(jiaodu2); x131 = xuanzhuanzhou.X * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu2)) + xuanzhuanzhou.Y * System.Math.Sin(jiaodu2); x211 = xuanzhuanzhou.X * xuanzhuanzhou.Y * (1 - System.Math.Cos(jiaodu2)) + xuanzhuanzhou.Z * System.Math.Sin(jiaodu2); x221 = System.Math.Cos(jiaodu2) + xuanzhuanzhou.Y * xuanzhuanzhou.Y * (1 - System.Math.Cos(jiaodu2)); x231 = xuanzhuanzhou.Y * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu2)) - xuanzhuanzhou.X * System.Math.Sin(jiaodu2); x311 = xuanzhuanzhou.X * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu2)) - xuanzhuanzhou.Y * System.Math.Sin(jiaodu2); x321 = xuanzhuanzhou.Y * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu2)) + xuanzhuanzhou.X * System.Math.Sin(jiaodu2); x331 = System.Math.Cos(jiaodu2) + xuanzhuanzhou.Z * xuanzhuanzhou.Z * (1 - System.Math.Cos(jiaodu2)); double posX1 = Clist.ElementAt(i).X * x111 + Clist.ElementAt(i).Y * x211 + Clist.ElementAt(i).Z * x311; double posY1 = Clist.ElementAt(i).X * x121 + Clist.ElementAt(i).Y * x221 + Clist.ElementAt(i).Z * x321; double posZ1 = Clist.ElementAt(i).X * x131 + Clist.ElementAt(i).Y * x231 + Clist.ElementAt(i).Z * x331; #endregion if(i==0) { LeftList.Add(new PointList { StartPoint = new Vector3(posX1, posY1, posZ1), EndPoint = new Vector3(posX, posY, posZ) }); } else { LeftList.Add(new PointList { StartPoint = new Vector3(posX, posY, posZ), EndPoint = new Vector3(posX1, posY1, posZ1) }); } } #region 坐标变换 //将左手坐标系下点转换为世界坐标系下点坐标 for (int i = 0; i < LeftList.Count; i++) { WorldList.Add(new PointList { StartPoint = new Vector3(LeftList.ElementAt(i).StartPoint.X, LeftList.ElementAt(i).StartPoint.Z, LeftList.ElementAt(i).StartPoint.Y), EndPoint = new Vector3(LeftList.ElementAt(i).EndPoint.X, LeftList.ElementAt(i).EndPoint.Z, LeftList.ElementAt(i).EndPoint.Y) }); } // 将世界坐标转换为经纬度坐标 for (int i = 0; i < WorldList.Count; i++) { var TempStart = new Vector3(); var TempEnd = new Vector3(); TempStart = SpatialCalculator.CartesianToSpherical(WorldList.ElementAt(i).StartPoint); TempEnd = SpatialCalculator.CartesianToSpherical(WorldList.ElementAt(i).EndPoint); LatLonList.Add(new PointList { StartPoint = TempStart, EndPoint = TempEnd }); } //将弧度转换为度,并调整存储位置 for (int i = 0; i < LatLonList.Count; i++) { var TempStart = new Vector3(); var TempEnd = new Vector3(); ///LatLonList里面,X,Y,Z分别存储的是高,纬度,经度.绘制数据源里面的点需要经纬高,这里需要重新变换赋值。 TempStart.X = (LatLonList.ElementAt(i).StartPoint.Z * 180) / System.Math.PI; TempStart.Y = (LatLonList.ElementAt(i).StartPoint.Y * 180) / System.Math.PI; TempStart.Z = LatLonList.ElementAt(i).StartPoint.X - 6378137; TempEnd.X = (LatLonList.ElementAt(i).EndPoint.Z * 180) / System.Math.PI; TempEnd.Y = (LatLonList.ElementAt(i).EndPoint.Y * 180) / System.Math.PI; TempEnd.Z = LatLonList.ElementAt(i).EndPoint.X - 6378137; TempStart.Z = listenaltitude.GetAltitude(TempStart.Y, TempStart.X); TempEnd.Z = listenaltitude.GetAltitude(TempEnd.Y, TempEnd.X); RetureList.Add(new PointList { StartPoint = TempStart, EndPoint = TempEnd }); } LeftList.Clear(); WorldList.Clear(); LatLonList.Clear(); #endregion return RetureList; }