一、DataCenter
/// <summary>
/// 点类
/// </summary>
class Point
{
public string name;
public double X;
public double Y;
public double Z;
}
class ConstData
{
public double H0; // 起始高程
// 纵断面相关
public List<Point> flPoints = new List<Point>(); // 文件点集
public double alpha_AB; // 方位角ab
public double alpha_M; // 方位角M
public Point A = new Point(); // A点
public Point B = new Point(); // B点
public Point M = new Point(); // M点
public List<double> ZdmSList = new List<double>(); //部分纵断面面积
public double L_Zdm; //纵断面长度
public List<Point> ZdmPoints=new List<Point>(); //纵断面内插点
public double ZdmS; // 纵断面面积
// 横断面相关
public List<Point> HdmPoints = new List<Point>(); //横断面内插点
public double HdmS; // 横断面面积
}
二、AuxiCal
class AuxiCal
{
/// <summary>
/// 计算方位角
/// </summary>
/// <param name="point1"></param>
/// <param name="point2"></param>
/// <returns></returns>
public static double Cal_Alpha(Point point1,Point point2)
{
double cy = (point2.Y - point1.Y);
double cx = (point2.X - point1.X);
double alpha = Math.Atan(cy/cx);
if (cy > 0 & cx > 0) alpha = alpha;
else if (cy > 0 & cx < 0) alpha = Math.PI+ alpha;
else if (cy < 0 & cx < 0) alpha = Math.PI + alpha;
else if (cy < 0 & cx > 0) alpha = 2*Math.PI + alpha;
else if (cy >= 0 & cx == 0) alpha = Math.PI/2;
else if (cy <= 0 & cx == 0) alpha = Math.PI/2*3;
return alpha;
}
/// <summary>
/// 计算两点间距离
/// </summary>
/// <param name="point1"></param>
/// <param name="point2"></param>
/// <returns></returns>
public static double Cal_L(Point point1, Point point2)
{
double L = Math.Sqrt((point1.X-point2.X)* (point1.X - point2.X) + (point1.Y-point2.Y) * (point1.Y - point2.Y));
return L;
}
/// <summary>
/// 计算两点间梯形面积
/// </summary>
/// <param name="point1"></param>
/// <param name="point2"></param>
/// <param name="H0"></param>
/// <returns></returns>
public static double Cal_S(Point point1, Point point2,double H0)
{
double S = (point2.Z + point1.Z - 2 * H0) / 2 * Cal_L(point1, point2);
return S;
}
/// <summary>
/// 计算内插高程
/// </summary>
/// <param name="P"></param>
/// <param name="Qs"></param>
/// <returns></returns>
public static double Cal_Z(Point P, List<Point> Qs)
{
int i = 0;
double L_=0;
double hL_=0;
List<double> L = new List<double>();
for (i = 0; i < Qs.Count; i++)
{
L.Add(Cal_L(P,Qs[i]));
}
L.Sort();
L.Reverse();
for (int j = 0; j < 5; j++)
{
L_ += 1 / Cal_L(P, Qs[j]);
hL_ += 1 / Cal_L(P, Qs[j])*Qs[j].Z;
}
double h = hL_/L_;
return h;
}
/// <summary>
/// 计算纵断面坐标和高程
/// </summary>
/// <param name="A"></param>
public static void Cal_ZinterPoint(ConstData constData)
{
double k = 10;
while (true)
{
if (k <= constData.L_Zdm)
{
Point xiPoint = new Point();
xiPoint.X = constData.A.X + k * Math.Cos(constData.alpha_AB);
xiPoint.Y = constData.A.Y + k + Math.Cos(constData.alpha_AB);
xiPoint.Z = Cal_Z(xiPoint,constData.flPoints);
constData.ZdmPoints.Add(xiPoint);
k += 10;
}
else
{
break;
}
}
}
/// <summary>
/// 计算纵断面坐标和高程
/// </summary>
/// <param name="A"></param>
public static void Cal_HinterPoint(ConstData constData)
{
double[] Li = new[] { -30.0, -20.0, -10.0, 10.0, 20.0, 30.0 };
for(int i =0;i<6;i++)
{
Point xiPoint = new Point();
xiPoint.X = constData.A.X + Li[i] * Math.Cos(constData.alpha_M);
xiPoint.Y = constData.A.Y + Li[i] + Math.Cos(constData.alpha_M);
xiPoint.Z = Cal_Z(xiPoint, constData.flPoints);
constData.HdmPoints.Add(xiPoint);
}
}
}
三、Form1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// 初始化数据
public string report = "请输入数据";
ConstData constData = new ConstData();
private void 打开ToolStripMenuItem_Click(object sender, EventArgs e)
{
// 打开文件
FileDialog input = new OpenFileDialog();
input.ShowDialog();
StreamReader reader = new StreamReader(input.FileName);
string[] temp = reader.ReadLine()
.Split(new char[] { ',', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
// 读取第一行
constData.H0 = double.Parse(temp[1].Trim());
// 读取第二行第三行
reader.ReadLine();
reader.ReadLine();
// 读取数据
while (true)
{
if (!reader.EndOfStream)
{
temp = reader.ReadLine()
.Split(new char[] { ',', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
Point point = new Point();
point.name = temp[0].Trim();
point.X = double.Parse(temp[1].Trim());
point.Y = double.Parse(temp[2].Trim());
point.Z = double.Parse(temp[3].Trim());
constData.flPoints.Add(point);
}
else
{
break;
}
}
// 读取所有行
StreamReader reader1 = new StreamReader(input.FileName);
richTextBox1.Text = reader1.ReadToEnd();
}
private void 计算ToolStripMenuItem_Click(object sender, EventArgs e)
{
// 纵断面
constData.A = constData.flPoints[0];
constData.B = constData.flPoints[constData.flPoints.Count - 1];
constData.alpha_AB = AuxiCal.Cal_Alpha(constData.A, constData.B);
// 计算部分纵断面面积
constData.ZdmSList.Add(AuxiCal.Cal_S(constData.A, constData.M, constData.H0));
constData.ZdmSList.Add(AuxiCal.Cal_S(constData.B, constData.M, constData.H0));
constData.ZdmSList.Add(constData.ZdmSList[0] + constData.ZdmSList[1]);
// 计算纵断面长度
constData.L_Zdm = AuxiCal.Cal_L(constData.A, constData.B);
// 计算纵断面内插点
AuxiCal.Cal_ZinterPoint(constData);
// 计算纵断面面积
constData.ZdmS = 0;
constData.ZdmS += AuxiCal.Cal_S(constData.A, constData.ZdmPoints[0], constData.H0);
for (int i = 0; i + 1 < constData.ZdmPoints.Count; i++)
{
constData.ZdmS += AuxiCal.Cal_S(constData.ZdmPoints[i], constData.ZdmPoints[i + 1], constData.H0);
}
constData.ZdmS += AuxiCal.Cal_S(constData.B, constData.ZdmPoints[constData.ZdmPoints.Count - 1],
constData.H0);
//横断面
constData.alpha_M = constData.alpha_AB + Math.PI / 2;
constData.M.X = (constData.A.X + constData.B.X) / 2;
constData.M.Y = (constData.A.Y + constData.B.Y) / 2;
constData.M.Z = AuxiCal.Cal_Z(constData.M, constData.flPoints);
// 横断面内插点
AuxiCal.Cal_HinterPoint(constData);
// 横断面累计面积
constData.HdmPoints.Insert(3, constData.M);
for (int i = 0; i + 1 < constData.HdmPoints.Count; i++)
{
constData.HdmS += AuxiCal.Cal_S(constData.HdmPoints[i], constData.HdmPoints[i + 1], constData.H0);
}
// 报告
report = "点名, \t坐标x, \t坐标y, \t高程h\r\n";
for (int i = 0; i < constData.HdmPoints.Count; i++)
{
if (i < 3)
report +=
$"N{(i + 1)} \t{(constData.HdmPoints[i].X).ToString("F3")} \t{(constData.HdmPoints[i].Y).ToString("F3")} \t{(constData.HdmPoints[i].Z).ToString("F3")}\r\n";
else if (i > 3)
report +=
$"N{(i - 1)} \t{(constData.HdmPoints[i].X).ToString("F3")} \t{(constData.HdmPoints[i].Y).ToString("F3")} \t{(constData.HdmPoints[i].Z).ToString("F3")}\r\n";
else
report +=
$"M \t{(constData.HdmPoints[i].X).ToString("F3")} \t{(constData.HdmPoints[i].Y).ToString("F3")} \t{(constData.HdmPoints[i].Z).ToString("F3")}\r\n";
}
richTextBox2.Text = report;
}
private void 关闭程序ToolStripMenuItem_Click(object sender, EventArgs e)
{
Environment.Exit(0);
}
private void 保存报告ToolStripMenuItem_Click(object sender, EventArgs e)
{
FileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.ShowDialog();
StreamWriter writer = new StreamWriter(saveFileDialog.FileName);
writer.WriteLine(report);
writer.Flush();
}
}