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;
}