using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 五点法
{
public class Point
{
public Point(string str)
{
string[] splitstr=str.Split(',');
n=splitstr[0];
x= Convert.ToDouble(splitstr[1]);
y= Convert.ToDouble(splitstr[2]);
}
public Point()
{ }
public double x;
public double y;
public string n="null";
}
}
主程序
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace 五点法
{
public partial class MDIParent1 : Form
{
private int childFormNumber = 0;
public MDIParent1()
{
InitializeComponent();
}
private void ShowNewForm(object sender, EventArgs e)
{
Form childForm = new Form();
childForm.MdiParent = this;
childForm.Text = "窗口 " + childFormNumber++;
childForm.Show();
}
List<Point> points = new List<Point>();
private void OpenFile(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "文本文件(*.txt)|*.txt|所有文件(*.*)|*.*";
if (openFileDialog.ShowDialog(this) == DialogResult.OK)
{
points.Clear();
string FileName = openFileDialog.FileName;
string[] data = File.ReadAllLines(FileName);
foreach(string line in data)
{
Point point = new Point(line);
points.Add(point);
}
}
}
private void SaveAsToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
saveFileDialog.Filter = "文本文件(*.txt)|*.txt|所有文件(*.*)|*.*";
if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
{
string FileName = saveFileDialog.FileName;
}
}
//不封闭,计算补充点
List<Point> openData;
public List<Point> length(List<Point> p)
{
Point pa = new Point();
Point pb = new Point();
pa.x = p[0].x - 3 * p[1].x + 3 * p[2].x;
pa.y = p[0].y - 3 * p[1].y + 3 * p[2].y;
p.Add(pa);
pb.x = p[1].x - 3 * p[2].x + 3 * p[3].x;
pb.y = p[1].y - 3 * p[2].y + 3 * p[3].y;
p.Add(pb);
return p;
}
public void computePoint(List<Point> p)
{
int num = p.Count;
List<Point> startfragment = p.Take(3).ToList();
List<Point> endfragment = p.Skip(num - 3).ToList();
startfragment.Reverse();
startfragment = length(startfragment);
endfragment = length(endfragment);
openData = new List<Point>(p);
openData.Insert(0, startfragment[3]);
openData.Insert(0, startfragment[4]);
openData.Add(endfragment[3]);
openData.Add(endfragment[4]);
}
//存储内插点
List<List<Point>> insertPointdata = new List<List<Point>>();
//计算cosθ和sinθ,并以元组形式返回
public (double,double) gradient(List<Point> p)
{
double a1 = p[1].x - p[0].x;
double a2 = p[2].x - p[1].x;
double a3 = p[3].x - p[2].x;
double a4 = p[4].x - p[3].x;
double b1 = p[1].y - p[0].y;
double b2 = p[2].y - p[1].y;
double b3 = p[3].y - p[2].y;
double b4 = p[4].y - p[3].y;
double w2 = Math.Abs(a3 * b4 - a4 * b3);
double w3 = Math.Abs(a1 * b2 - a2 * b1);
double a0 = w2 * a2 + w3 * a3;
double b0 = w2 * b2 + w3 * b3;
double cosTheta = a0 / Math.Sqrt(a0 * a0 + b0 * b0);
double sinTheta = b0 / Math.Sqrt(a0 * a0 + b0 * b0);
return (cosTheta, sinTheta);
}
//计算内插点坐标,存储在insertPointdata中
public void insertPoint(List<Point> p,int unm)
{
for (int i = 0; i < p.Count - 5; i++)
{
List<Point> parameterp1 = new List<Point>(p.Skip(i).Take(5).ToList());
List<Point> parameterp2 = new List<Point>(p.Skip(i + 1).Take(5).ToList());
var (cosTheta1, sinTheta1) = gradient(parameterp1);
var (cosTheta2, sinTheta2) = gradient(parameterp2);
double r = Math.Sqrt((parameterp1[3].x - parameterp1[2].x) * (parameterp1[3].x - parameterp1[2].x) +
(parameterp1[3].y - parameterp1[2].y) * (parameterp1[3].y - parameterp1[2].y));
double E0 = parameterp1[2].x;
double E1 = r * cosTheta1;
double E2 = 3 * (parameterp1[3].x - parameterp1[2].x) - r * (cosTheta2 + 2 * cosTheta1);
double E3 = -2 * (parameterp1[3].x - parameterp1[2].x) + r * (cosTheta2 + cosTheta1);
double F0 = parameterp1[2].y;
double F1 = r * sinTheta1;
double F2 = 3 * (parameterp1[3].y - parameterp1[2].y) - r * (sinTheta2 + 2 * sinTheta1);
double F3 = -2 * (parameterp1[3].y - parameterp1[2].y) + r * (sinTheta2 + sinTheta1);
List<Point> LsInsertPoint = new List<Point>();
for (double m = 1 / (double)unm; m < 1;)
{
Point Lsp = new Point();
Lsp.x = E0 + E1 * m + E2 * m * m + E3 * m * m * m;
Lsp.y = F0 + F1 * m + F2 * m * m + F3 * m * m * m;
LsInsertPoint.Add(Lsp);
m += 1 / (double)unm;
}
insertPointdata.Add(LsInsertPoint);
}
}
//初始化部分,每次运算都重置chart、dataGridView控件和存储数据的List数组
public void initialize()
{
dataGridView1.Rows.Clear();
allPoint.Clear();
chart1.Series[0].Points.Clear();
insertPointdata = new List<List<Point>>();
}
//可视化部分,sign=='o'代表不封闭
public void visualization(List<Point> p,char sign='o')
{
int num = p.Count;
if (sign == 'o')
num = num - 1;
for(int i=0;i<num;i++)
{
chart1.Series[0].Points.AddXY(p[i].x, p[i].y);
allPoint.Add(p[i]);
List<Point> lp = new List<Point>(insertPointdata[i]);
for (int j = 0; j < lp.Count; j++)
{
chart1.Series[0].Points.AddXY(lp[j].x, lp[j].y);
allPoint.Add(lp[j]);
}
}
if(sign=='o')
{
chart1.Series[0].Points.AddXY(p[openData.Count - 1].x, p[openData.Count - 1].y);
allPoint.Add(p[p.Count - 1]);
}
else
{
chart1.Series[0].Points.AddXY(p[0].x, p[0].y);
allPoint.Add(p[0]);
}
for (int i = 0; i < allPoint.Count; i++)
{
dataGridView1.Rows.Add();
dataGridView1.Rows[i].Cells[1].Value = allPoint[i].x;
dataGridView1.Rows[i].Cells[2].Value = allPoint[i].y;
dataGridView1.Rows[i].Cells[0].Value = allPoint[i].n;
}
}
List<Point> allPoint = new List<Point>();
private void 不闭合曲线ToolStripMenuItem_Click(object sender, EventArgs e)
{
initialize();
openData = new List<Point>();
computePoint(points);
insertPoint(openData,10);
openData.RemoveAt(0);
openData.RemoveAt(0);
openData.RemoveAt(openData.Count - 1);
openData.RemoveAt(openData.Count - 1);
visualization(openData);
}
private void 闭合曲线ToolStripMenuItem_Click(object sender, EventArgs e)
{
initialize();
List<Point> closeData = new List<Point>(points);
closeData.Insert(0, points[points.Count - 1]);
closeData.Insert(0, points[points.Count - 2]);
closeData.Add(points[0]);
closeData.Add(points[1]);
closeData.Add(points[2]);
insertPoint(closeData, 10);
closeData.RemoveAt(0);
closeData.RemoveAt(0);
closeData.RemoveAt(closeData.Count - 1);
closeData.RemoveAt(closeData.Count - 1);
closeData.RemoveAt(closeData.Count - 1);
visualization(closeData, 'c');
}
}
}