610 lines
22 KiB
C#
610 lines
22 KiB
C#
using Autodesk.Revit.DB;
|
||
|
||
namespace ShrlAlgo.RvKits.RvIndependent.MetroGauges;
|
||
|
||
using Curve = LandXMLData.Curve;
|
||
using Interval = LandXMLData.Interval;
|
||
using LandXMLData_Alignment = LandXMLData.Alignment;
|
||
using LandXMLData_CircCurve = LandXMLData.CircCurve;
|
||
using LandXMLData_Spiral = LandXMLData.Spiral;
|
||
using Line = LandXMLData.Line;
|
||
|
||
public class CircuitHelper
|
||
{
|
||
/// <summary>
|
||
/// 获取线路所有竖曲线区间
|
||
/// </summary>
|
||
/// <param name="al"></param>
|
||
/// <returns></returns>
|
||
public Dictionary<LandXMLData_CircCurve, List<SpaceXYZ>> DictCir(LandXMLData_Alignment al)
|
||
{
|
||
var prof = al.GroundProfile;
|
||
Dictionary<LandXMLData_CircCurve, List<SpaceXYZ>> dictcir = new();
|
||
for (int i = 0; i < prof.Count - 1; i++)
|
||
{
|
||
if (prof[i].GetType() == typeof(CircCurve))
|
||
{
|
||
LandXMLData_CircCurve c = (LandXMLData_CircCurve)prof[i];
|
||
SpaceXYZ stap = new(prof[i - 1].First, prof[i - 1].Second);
|
||
SpaceXYZ pi = new(prof[i].First, prof[i].Second);
|
||
SpaceXYZ endp = new(prof[i + 1].First, prof[i + 1].Second);
|
||
List<SpaceXYZ> pts = GetStartCenterEnd(c, stap, pi, endp);
|
||
dictcir.Add(c, pts);
|
||
}
|
||
}
|
||
|
||
return dictcir;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 得到区域内的参考点
|
||
/// </summary>
|
||
/// <param name="align"></param>
|
||
/// <param name="reg"></param>
|
||
/// <param name="interval"></param>
|
||
/// <returns></returns>
|
||
public List<XYZ> Get3DRefPointOfRegion(LandXMLData_Alignment align, Region reg, double interval)
|
||
{
|
||
List<XYZ> pts = new();
|
||
for (double i = reg.StartStation; i < reg.EndStation; i += interval)
|
||
{
|
||
XYZ pt = new(GetHorizonCoord(i, align).X, GetHorizonCoord(i, align).Y, GetElevAtStation(i, align));
|
||
pts.Add(pt);
|
||
}
|
||
|
||
XYZ lastp = GetHorizonCoord(reg.EndStation, align);
|
||
XYZ lastpt = new(lastp.X, lastp.Y, GetElevAtStation(reg.EndStation, align));
|
||
pts.Add(lastpt);
|
||
|
||
return pts;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取圆曲线上的点(坐标英制)
|
||
/// </summary>
|
||
/// <param name="length">沿着线路方向从圆曲线起点行走过的距离</param>
|
||
/// <param name="c"></param>
|
||
/// <returns></returns>
|
||
public SpaceXYZ GetArcPtCoord(double length, Curve c)
|
||
{
|
||
double r = Math.Sqrt(
|
||
Math.Pow(c.Center.Second - c.Start.Second, 2.0) + Math.Pow(c.Center.First - c.Start.First, 2.0)
|
||
);
|
||
//弧度
|
||
double rad = length / r;
|
||
//计算圆心起点直线与X轴弧度(带符号)
|
||
double num3 = Math.Atan2(c.Start.First - c.Center.First, c.Start.Second - c.Center.Second);
|
||
double Xrad = num3 < 0.0 ? (2 * Math.PI) + num3 : num3;
|
||
//总弧度
|
||
double Totalrad = c.Length / r;
|
||
//斜率判断圆弧左转右转(起点与圆心直线斜率小于终点与圆心直线斜率,左转,逆时针;大于则右转)
|
||
int dir = -1;
|
||
if (
|
||
((c.Start.Second - c.Center.Second) * (c.End.First - c.Center.First))
|
||
- ((c.Start.First - c.Center.First) * (c.End.Second - c.Center.Second))
|
||
< 0.0
|
||
)
|
||
{
|
||
rad = -rad;
|
||
}
|
||
|
||
if (Math.Abs(Totalrad) > Math.PI)
|
||
{
|
||
rad = -rad;
|
||
}
|
||
|
||
double x = (r * Math.Cos((-dir * rad) + Xrad)) + c.Center.Second;
|
||
double y = (r * Math.Sin((-dir * rad) + Xrad)) + c.Center.First;
|
||
return new SpaceXYZ(x * 1000 / 304.8, y * 1000 / 304.8, 0);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 纵断圆弧高程(英制)
|
||
/// </summary>
|
||
/// <param name="station"></param>
|
||
/// <param name="c"></param>
|
||
/// <param name="circleCenter"></param>
|
||
/// <param name="radius"></param>
|
||
/// <returns></returns>
|
||
public static double GetArcY(double station, LandXMLData_CircCurve c, SpaceXYZ circleCenter, double radius)
|
||
{
|
||
double[] y = new double[2];
|
||
//(x-x0)^2*+y0^2-R^2
|
||
double num = Math.Pow(radius, 2.0) - Math.Pow(station - circleCenter.Station, 2.0);
|
||
//4*R^2-4(x-x0)^2
|
||
//double num2 = 4.0 * Math.Pow(circleCenter.Bottom, 2.0) - 4.0 * num;
|
||
//y-y0的开方
|
||
double num3 = Math.Sqrt(num);
|
||
//y-y0值的不同符号
|
||
y[0] = circleCenter.Elevation - num3;
|
||
y[1] = circleCenter.Elevation + num3;
|
||
SpaceXYZ pvi = new(c.First, c.Second);
|
||
double elevation;
|
||
{
|
||
double l1 = GetLength(pvi, new SpaceXYZ(station, y[0]));
|
||
double l2 = GetLength(pvi, new SpaceXYZ(station, y[1]));
|
||
elevation = l1 <= l2 ? y[0] : y[1];
|
||
}
|
||
|
||
return elevation * 1000 / 304.8;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取圆心坐标
|
||
/// </summary>
|
||
/// <param name="x1"></param>
|
||
/// <param name="y1"></param>
|
||
/// <param name="x2"></param>
|
||
/// <param name="y2"></param>
|
||
/// <param name="r"></param>
|
||
/// <param name="bump"></param>
|
||
/// <returns></returns>
|
||
public SpaceXYZ GetCircleCenter(double x1, double y1, double x2, double y2, double r, bool bump)
|
||
{
|
||
double c1 = ((x2 * x2) - (x1 * x1) + (y2 * y2) - (y1 * y1)) / (2 * (x2 - x1));
|
||
double c2 = (y2 - y1) / (x2 - x1); //斜率
|
||
double a = (c2 * c2) + 1;
|
||
double b = (2 * x1 * c2) - (2 * c1 * c2) - (2 * y1);
|
||
double c = (x1 * x1) - (2 * x1 * c1) + (c1 * c1) + (y1 * y1) - (r * r);
|
||
//为true时,为凹曲线,false为凸曲线
|
||
if (bump)
|
||
{
|
||
double y = (-b + Math.Sqrt((b * b) - (4 * a * c))) / (2 * a);
|
||
double x = c1 - (c2 * y);
|
||
return new SpaceXYZ(x, y);
|
||
}
|
||
else
|
||
{
|
||
double y = (-b - Math.Sqrt((b * b) - (4 * a * c))) / (2 * a);
|
||
double x = c1 - (c2 * y);
|
||
return new SpaceXYZ(x, y);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取任意桩号位置的高程
|
||
/// </summary>
|
||
/// <param name="station"></param>
|
||
/// <param name="al"></param>
|
||
/// <returns></returns>
|
||
public double GetElevAtStation(double station, LandXMLData_Alignment al)
|
||
{
|
||
double elev = 0.0;
|
||
var prof = al.GroundProfile;
|
||
//var liprof = al.Profile.ProfileCurve;
|
||
//var prof = liprof[0];
|
||
Dictionary<LandXMLData_CircCurve, List<SpaceXYZ>> dictcir = DictCir(al);
|
||
//+0.1保证终点桩号的小数能满足条件
|
||
for (int i = 0; i < prof.Count - 1; i++)
|
||
{
|
||
if (station >= prof[i].First && station <= prof[i + 1].First + 0.1)
|
||
{
|
||
SpaceXYZ stap = new(prof[i].First, prof[i].Second);
|
||
SpaceXYZ endp = new(prof[i + 1].First, prof[i + 1].Second);
|
||
elev = GetLineY(station, stap, endp);
|
||
|
||
foreach (KeyValuePair<LandXMLData_CircCurve, List<SpaceXYZ>> cir in dictcir)
|
||
{
|
||
if (station >= cir.Value[0].Station && station <= cir.Value[2].Station)
|
||
{
|
||
elev = GetArcY(station, cir.Key, cir.Value[1], cir.Key.Radius);
|
||
return elev;
|
||
}
|
||
}
|
||
|
||
return elev;
|
||
}
|
||
}
|
||
|
||
//if (prof[i].GetType() == typeof(TextPoint2D))
|
||
//{
|
||
// SpaceXYZ stap = new SpaceXYZ(prof[i].First, prof[i].Second);
|
||
// SpaceXYZ endp = new SpaceXYZ(prof[i + 1].First, prof[i + 1].Second);
|
||
// elev = GetLinePtY(station, stap, endp);
|
||
//}
|
||
|
||
//GetStartAndEndSta()
|
||
return elev;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取任意桩号位置的水平坐标
|
||
/// </summary>
|
||
/// <param name="station"></param>
|
||
/// <param name="al"></param>
|
||
/// <returns></returns>
|
||
public SpaceXYZ GetHorizonCoord(double station, LandXMLData_Alignment al)
|
||
{
|
||
List<Interval> hc = al.CoordGeom.HorizonCurve;
|
||
SpaceXYZ p = new(0.0, 0.0, 0.0);
|
||
Dictionary<Interval, Region> dicts = GetIntervalRegion(al);
|
||
//if (station > al.Length + al.StationStart)
|
||
//{
|
||
// return p;
|
||
//}
|
||
foreach (KeyValuePair<Interval, Region> dict in dicts)
|
||
{
|
||
double sta = dict.Value.StartStation;
|
||
double end = dict.Value.EndStation;
|
||
//加0.1保证终点桩号的小数能满足条件
|
||
if (station >= dict.Value.StartStation && station <= dict.Value.EndStation + 0.1)
|
||
{
|
||
double distance = station - dict.Value.StartStation;
|
||
if (dict.Key.GetType() == typeof(Autodesk.Revit.DB.Curve))
|
||
{
|
||
Curve c = (Curve)dict.Key;
|
||
//公制转英制,但是显示的时候英制转为公制
|
||
p = GetArcPtCoord(distance, c);
|
||
//ReferencePoint refpt = formdoc.FamilyCreate.NewReferencePoint(p);
|
||
//refpts.Append(refpt);
|
||
//SpaceXYZ spt = new SpaceXYZ(p.X, p.Y, p.Z);
|
||
//spt.Station = j + station;
|
||
//spt.Bottom = GetElevAtStation(spt.Station, al);
|
||
//spts.Add(spt);
|
||
}
|
||
else if (dict.Key.GetType() == typeof(Line))
|
||
{
|
||
Line l = (Line)dict.Key;
|
||
|
||
p = GetLinePtCoord(distance, l);
|
||
}
|
||
//else if (dict.Key.GetType() == typeof(landxml.Spiral))
|
||
else
|
||
{
|
||
LandXMLData_Spiral s = (LandXMLData_Spiral)dict.Key;
|
||
|
||
p = GetSpiralPtCoord(distance, s);
|
||
}
|
||
}
|
||
}
|
||
|
||
return p;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 得到平曲线参考点
|
||
/// </summary>
|
||
/// <param name="al"></param>
|
||
/// <param name="doc"></param>
|
||
/// <returns></returns>
|
||
public List<XYZ> GetHorizonPts(LandXMLData_Alignment al, Document doc)
|
||
{
|
||
List<XYZ> pts = new();
|
||
var hc = al.CoordGeom.HorizonCurve;
|
||
//double station = al.StationStart;
|
||
|
||
for (int i = 0; i < hc.Count; i++)
|
||
{
|
||
//if (i - 1 >= 0)
|
||
//{
|
||
// station += hc[i - 1].Length;
|
||
//}
|
||
if (hc[i].GetType() == typeof(Autodesk.Revit.DB.Curve))
|
||
{
|
||
Curve c = (Curve)hc[i];
|
||
for (int j = 0; j < c.Length; j++)
|
||
{
|
||
//公制转英制,但是显示的时候英制转为公制
|
||
XYZ p = GetArcPtCoord(j, c);
|
||
pts.Add(p);
|
||
//ReferencePoint refpt = formdoc.FamilyCreate.NewReferencePoint(p);
|
||
//refpts.Append(refpt);
|
||
//SpaceXYZ spt = new SpaceXYZ(p.X, p.Y, p.Z);
|
||
//spt.Station = j + station;
|
||
//spt.Bottom = GetElevAtStation(spt.Station, al);
|
||
//spts.Add(spt);
|
||
}
|
||
}
|
||
else if (hc[i].GetType() == typeof(Autodesk.Revit.DB.Line))
|
||
{
|
||
Line l = (Line)hc[i];
|
||
for (int j = 0; j < l.Length; j++)
|
||
{
|
||
XYZ p = GetLinePtCoord(j, l);
|
||
pts.Add(p);
|
||
}
|
||
}
|
||
else if (hc[i].GetType() == typeof(Spiral))
|
||
{
|
||
LandXMLData_Spiral s = (LandXMLData_Spiral)hc[i];
|
||
for (int j = 0; j < s.Length; j++)
|
||
{
|
||
XYZ p = GetSpiralPtCoord(j, s);
|
||
pts.Add(p);
|
||
}
|
||
}
|
||
}
|
||
//最后一点
|
||
|
||
XYZ last = new XYZ(hc[hc.Count - 1].End.Second, hc[hc.Count - 1].End.First, 0.0) * 1000 / 304.8;
|
||
pts.Add(last);
|
||
//ReferencePointArray array = new ReferencePointArray();
|
||
//for (int i = 0; i < pts.Count; i++)
|
||
//{
|
||
// ReferencePoint refp = doc.FamilyCreate.NewReferencePoint(pts[i]);
|
||
// array.Append(refp);
|
||
//}
|
||
return pts;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 按曲线类型获取区域
|
||
/// </summary>
|
||
/// <param name="al"></param>
|
||
/// <returns></returns>
|
||
public Dictionary<Interval, Region> GetIntervalRegion(LandXMLData_Alignment al)
|
||
{
|
||
var hc = al.CoordGeom.HorizonCurve;
|
||
|
||
Dictionary<Interval, Region> regions = new();
|
||
regions.Clear();
|
||
double currentsta = al.StationStart;
|
||
double endsta = 0.0;
|
||
if (al != null)
|
||
{
|
||
for (int i = 0; i < hc.Count; i++)
|
||
{
|
||
if (i - 1 >= 0)
|
||
{
|
||
//currentsta += Math.Round(hc[i - 1].Length, 3, MidpointRounding.AwayFromZero);
|
||
currentsta += hc[i - 1].Length;
|
||
}
|
||
|
||
Region re = new(currentsta, endsta);
|
||
if (hc[i].GetType() == typeof(Autodesk.Revit.DB.Curve))
|
||
{
|
||
Curve c = (Curve)hc[i];
|
||
//re.EndStation = Math.Round(c.Length + currentsta, 3, MidpointRounding.AwayFromZero);
|
||
re.EndStation = c.Length + currentsta;
|
||
}
|
||
else if (hc[i].GetType() == typeof(Autodesk.Revit.DB.Line))
|
||
{
|
||
Line l = (Line)hc[i];
|
||
//re.EndStation = Math.Round(l.Length + currentsta, 3, MidpointRounding.AwayFromZero);
|
||
re.EndStation = l.Length + currentsta;
|
||
}
|
||
else
|
||
{
|
||
LandXMLData_Spiral s = (LandXMLData_Spiral)hc[i];
|
||
re.EndStation = s.Length + currentsta;
|
||
}
|
||
|
||
regions.Add(hc[i], re);
|
||
}
|
||
}
|
||
|
||
//return allregions;
|
||
return regions;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 计算两点直线距离
|
||
/// </summary>
|
||
/// <param name="p1"></param>
|
||
/// <param name="p2"></param>
|
||
/// <returns></returns>
|
||
public static double GetLength(SpaceXYZ p1, SpaceXYZ p2)
|
||
{
|
||
double num = p1.Station - p2.Station;
|
||
double num2 = p1.Elevation - p2.Elevation;
|
||
return Math.Sqrt((num * num) + (num2 * num2));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取直线上的点(坐标英制)
|
||
/// </summary>
|
||
/// <param name="length">沿着线路方向从直线起点行走过的距离</param>
|
||
/// <param name="line"></param>
|
||
/// <returns></returns>
|
||
public SpaceXYZ GetLinePtCoord(double length, Line line)
|
||
{
|
||
XYZ startCoord = new(line.Start.Second, line.Start.First, 0);
|
||
XYZ endCoord = new(line.End.Second, line.End.First, 0);
|
||
//Autodesk.Revit.DB.Point stapt = Autodesk.Revit.DB.Point.Create(startCoord);
|
||
XYZ xyz = endCoord - startCoord;
|
||
double length2 = xyz.GetLength();
|
||
//if (length > line.Length)
|
||
//{
|
||
// System.Windows.MessageBox.ShowAhead("长度错误");
|
||
//}
|
||
XYZ p = xyz * length / length2;
|
||
XYZ pt = p + startCoord;
|
||
|
||
SpaceXYZ sp = new(pt.X * 1000 / 304.8, pt.Y * 1000 / 304.8, pt.Z * 1000 / 304.8);
|
||
|
||
return sp;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 纵断直线高程(英制)
|
||
/// </summary>
|
||
/// <param name="station"></param>
|
||
/// <param name="startpoint"></param>
|
||
/// <param name="endpoint"></param>
|
||
/// <returns></returns>
|
||
public double GetLineY(double station, SpaceXYZ startpoint, SpaceXYZ endpoint)
|
||
{
|
||
double deltaY = endpoint.Elevation - startpoint.Elevation;
|
||
double deltaX = endpoint.Station - startpoint.Station;
|
||
double k = deltaY / deltaX;
|
||
double c = startpoint.Elevation - (k * startpoint.Station);
|
||
double elev = (k * station) + c;
|
||
return elev * 1000 / 304.8;
|
||
//double[] lineBetween2Points = GetLineBetween2Points(startpoint, endpoint);
|
||
//if (lineBetween2Points[1] != 0.0)
|
||
//{
|
||
// return (-lineBetween2Points[0] * station - lineBetween2Points[2]) / lineBetween2Points[1];
|
||
//}
|
||
//if (startpoint.Bottom <= endpoint.Bottom)
|
||
//{
|
||
// return endpoint.Bottom;
|
||
//}
|
||
//return startpoint.Bottom;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取缓和曲线上的点(坐标英制)
|
||
/// </summary>
|
||
/// <param name="length">沿着线路方向从缓和曲线起点行走过的距离</param>
|
||
/// <param name="spiral">缓和曲线</param>
|
||
/// <returns>坐标点</returns>
|
||
public SpaceXYZ GetSpiralPtCoord(double length, LandXMLData_Spiral spiral)
|
||
{
|
||
//左右转向
|
||
double num =
|
||
((spiral.PI.Second - spiral.Start.Second) * (spiral.End.First - spiral.Start.First))
|
||
- ((spiral.PI.First - spiral.Start.First) * (spiral.End.Second - spiral.Start.Second));
|
||
//转角符号右为正,左为负
|
||
double direction = num >= 0.0 ? 1 : -1;
|
||
//根据起始半径,1:起点为直线,起始曲率半径无穷大;0:起点为圆曲线,起始半径为圆曲线半径,判断是前缓和曲线还是后缓和曲线,前为1,后为0
|
||
int fOrb = spiral.RadiusStart is double.PositiveInfinity or double.MaxValue ? 1 : 0;
|
||
//n3为1取终点半径,n3为0取起点半径(圆曲线半径)
|
||
double R = fOrb != 0 ? spiral.RadiusEnd : spiral.RadiusStart;
|
||
//(缓和曲线长/圆曲线半径)^2 用于计算TotalX,TotalY
|
||
num = spiral.Length * spiral.Length / (R * R);
|
||
//x,y方向总距离
|
||
spiral.TotalX = spiral.Length * (1.0 - (num / 40.0) + (num * num / 3456.0));
|
||
spiral.TotalY = num * R / 6.0 * (1.0 - (num / 56.0) + (num * num / 7040.0));
|
||
//当前长度
|
||
double l = length;
|
||
double totalx = 0.0;
|
||
double totaly = 0.0;
|
||
double num8 = 1.0;
|
||
|
||
if (fOrb == 0)
|
||
{
|
||
l = spiral.Length - length;
|
||
num8 = -1.0;
|
||
//x,y方向总距离
|
||
totalx = spiral.TotalX;
|
||
totaly = spiral.TotalY;
|
||
}
|
||
|
||
num = l * l / (2.0 * R * spiral.Length);
|
||
|
||
double x = totalx + (num8 * l * (1.0 - (num * num / 10.0) + (Math.Pow(num, 4.0) / 216.0)));
|
||
double y =
|
||
direction * (-totaly + (l * ((num / 3.0) - (Math.Pow(num, 3.0) / 42.0) + (Math.Pow(num, 5.0) / 1320.0))));
|
||
//转东北距同时转英制
|
||
return TransformXYtoNE(x, y, direction * num8, spiral);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取圆弧纵断线起点圆心终点
|
||
/// </summary>
|
||
/// <param name="c"></param>
|
||
/// <param name="start"></param>
|
||
/// <param name="pi"></param>
|
||
/// <param name="end"></param>
|
||
/// <returns></returns>
|
||
public List<SpaceXYZ> GetStartCenterEnd(LandXMLData_CircCurve c, SpaceXYZ start, SpaceXYZ pi, SpaceXYZ end)
|
||
{
|
||
List<SpaceXYZ> li = new();
|
||
//圆心角
|
||
|
||
double w = c.CurveLength / c.Radius;
|
||
//交点距圆弧起点桩号距离(X轴)
|
||
double l = Math.Tan(w / 2) * c.Radius;
|
||
//起点交点连线
|
||
double θ1 = RadianFromHorizon(start, pi);
|
||
//交点终点连线
|
||
double θ2 = RadianFromHorizon(pi, end);
|
||
//圆曲线起点
|
||
SpaceXYZ startpoint = new(pi.Station - (l * Math.Cos(θ1)), pi.Elevation - (l * Math.Sin(θ1)));
|
||
SpaceXYZ endpoint = new(pi.Station + (l * Math.Cos(θ2)), pi.Elevation + (l * Math.Sin(θ2)));
|
||
li.Add(startpoint);
|
||
if (θ2 - θ1 > 0)
|
||
{
|
||
//凹曲线
|
||
//SpaceXYZ centerpoint = new SpaceXYZ(start.Station - c.Radius * Math.Sin(θ1), start.Bottom + c.Radius * Math.Cos(θ1));
|
||
SpaceXYZ centerpoint = GetCircleCenter(
|
||
startpoint.Station,
|
||
startpoint.Elevation,
|
||
endpoint.Station,
|
||
endpoint.Elevation,
|
||
c.Radius,
|
||
true
|
||
);
|
||
li.Add(centerpoint);
|
||
}
|
||
else
|
||
{
|
||
//凸曲线
|
||
//SpaceXYZ centerpoint = new SpaceXYZ(start.Station + c.Radius * Math.Sin(θ1), start.Bottom - c.Radius * Math.Cos(θ1));
|
||
SpaceXYZ centerpoint = GetCircleCenter(
|
||
startpoint.Station,
|
||
startpoint.Elevation,
|
||
endpoint.Station,
|
||
endpoint.Elevation,
|
||
c.Radius,
|
||
false
|
||
);
|
||
li.Add(centerpoint);
|
||
}
|
||
|
||
//圆曲线终点
|
||
li.Add(endpoint);
|
||
return li;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 纵断直线与X的夹角(弧度)
|
||
/// </summary>
|
||
/// <param name="start"></param>
|
||
/// <param name="end"></param>
|
||
/// <returns></returns>
|
||
public double RadianFromHorizon(SpaceXYZ start, SpaceXYZ end)
|
||
{
|
||
return Math.Atan((start.Elevation - end.Elevation) / (start.Station - end.Station));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 坐标转换
|
||
/// </summary>
|
||
/// <param name="point"></param>
|
||
/// <param name="transform"></param>
|
||
/// <returns></returns>
|
||
public static XYZ TransformPoint(XYZ point, Transform transform)
|
||
{
|
||
double x = point.X;
|
||
double y = point.Y;
|
||
double z = point.Z;
|
||
|
||
//获取变换的原点和基向量
|
||
XYZ b0 = transform.get_Basis(0);
|
||
XYZ b1 = transform.get_Basis(1);
|
||
XYZ b2 = transform.get_Basis(2);
|
||
XYZ origin = transform.Origin;
|
||
|
||
//对原来坐标系统的点在新的坐标系统进行变换
|
||
double xTemp = (x * b0.X) + (y * b1.X) + (z * b2.X) + origin.X;
|
||
double yTemp = (x * b0.Y) + (y * b1.Y) + (z * b2.Y) + origin.Y;
|
||
double zTemp = (x * b0.Z) + (y * b1.Z) + (z * b2.Z) + origin.Z;
|
||
|
||
return new XYZ(xTemp, yTemp, zTemp);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 缓和曲线坐标转东北距(坐标英制)
|
||
/// </summary>
|
||
/// <param name="x"></param>
|
||
/// <param name="y"></param>
|
||
/// <param name="signTotalY"></param>
|
||
/// <param name="spi"></param>
|
||
/// <returns></returns>
|
||
public SpaceXYZ TransformXYtoNE(double x, double y, double signTotalY, LandXMLData_Spiral spi)
|
||
{
|
||
double DeltaY = spi.End.First - spi.Start.First;
|
||
double DeltaX = spi.End.Second - spi.Start.Second;
|
||
spi.TotalY = signTotalY * spi.TotalY;
|
||
double num3 =
|
||
((spi.TotalX * DeltaY) - (spi.TotalY * DeltaX)) / (Math.Pow(spi.TotalX, 2.0) + Math.Pow(spi.TotalY, 2.0));
|
||
double num4 =
|
||
((spi.TotalX * DeltaX) + (spi.TotalY * DeltaY)) / (Math.Pow(spi.TotalX, 2.0) + Math.Pow(spi.TotalY, 2.0));
|
||
double num5 = (num4 * x) - (num3 * y);
|
||
double num6 = (num3 * x) + (num4 * y);
|
||
num6 += spi.Start.First;
|
||
return new SpaceXYZ((num5 + spi.Start.Second) * 1000 / 304.8, num6 * 1000 / 304.8, 0.0);
|
||
}
|
||
}
|