1、通过两个已知点,绕定轴旋转360次,每次旋转一度,获得360个点,一次相连,可以获得一个近似圆。
网上找的公式基本都是左手坐标系下的选择公式,故而进行了多次坐标转换
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;
}