You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

240 lines
9.1 KiB
C#

1 month ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using NaturalNeighbor;
namespace TestNeighborInterpolator
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 执行计算.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
private void btnOK_Click(object sender, EventArgs e)
{
string strFile = "C:\\GeoIntelligent\\Test\\厚度图数据\\39SO(300).csv";
string strResult = "C:\\GeoIntelligent\\Test\\厚度图数据\\39SO(300)-Result.csv";
IEnumerable<Vector3> points = this.ReadData(strFile);
Interpolator2d interpolator = Interpolator2d.Create(points.ToArray(), 0.5);
Vector2 minLoc = interpolator.MinValue.Value;
Vector2 maxLoc = interpolator.MaxValue.Value;
double dWidth = maxLoc.X - minLoc.X;
double dHeight = maxLoc.Y - minLoc.Y;
int nCols = 200;
int nRows = 200;
double scaleX = dWidth / (nCols - 1);
double scaleY = dHeight / (nRows - 1);
float dScale = (float)Math.Min(scaleX, scaleY);
int nCalCols = (int)Math.Floor(dWidth / dScale);
int nCalRows = (int)Math.Floor(dHeight / dScale);
Vector2[] result = new Vector2[nCalRows * nCalCols];
for (int i = 0; i < nCalRows; ++i)
{
var x = minLoc.X + i * dScale;
for (int j = 0; j < nCalCols; ++j)
{
var y = minLoc.Y + j * dScale;
result[i * nCalCols + j] = new Vector2(x, y);
}
}
double[] resultZ = new double[nCalRows * nCalCols];
interpolator.LookupRange(result, resultZ);
using (StreamWriter sw = new StreamWriter(strResult, false, Encoding.Default))
{
for (int i = 0; i < nCalRows; i++)
{
for (int j = 0; j < nCalCols; j++)
{
sw.WriteLine($"{result[i * nCalCols + j].X},{result[i * nCalCols + j].Y},{resultZ[i * nCalCols + j]}");
}
}
}
MessageBox.Show("OK");
//string strFile = "C:\\GeoIntelligent\\Test\\厚度图数据\\39SO(300).csv";
//string strResult = "C:\\GeoIntelligent\\Test\\厚度图数据\\39SO(300)-Result.csv";
//IEnumerable<Vector3> points = this.ReadData(strFile);
//Vector3 rangeMin = new Vector3();
//Vector3 rangeMax = new Vector3();
////this.CalculateRange(points.ToArray(), ref rangeMin, ref rangeMax);
//Interpolator2d interpolator = Interpolator2d.Create(points.ToArray(), 0.5);
//Vector2 minLoc = interpolator.MinValue.Value;
//Vector2 maxLoc = interpolator.MaxValue.Value;
//double dWidth = maxLoc.X - minLoc.X;
//double dHeight = maxLoc.Y - minLoc.Y;
//int nCols = 200;
//int nRows = 200;
//double scaleX = dWidth / (nCols - 1);
//double scaleY = dHeight / (nRows - 1);
//float dScale = (float)Math.Min(scaleX, scaleY);
//int nCalCols = (int)Math.Floor(dWidth / dScale);
//int nCalRows = (int)Math.Floor(dHeight / dScale);
//// 生成网格文件
//Vector2[] result = new Vector2[nCalRows * nCalCols];
//for (int i = 0; i < nCalCols; ++i)
//{
// var x = minLoc.X + i * dScale;
// for (int j = 0; j < nCalRows; ++j)
// {
// var y = minLoc.Y + j * dScale;
// result[i * nCalRows + j] = new Vector2(x, y);
// }
//}
//double[] resultZ = new double[nCalRows * nCalCols];
//interpolator.LookupRange(result, resultZ);
//SetGridData(rangeMin.X, rangeMin.Y, resultZ, nCalCols, nCalRows, (double)dScale, (double)dScale
// , rangeMin.Z, rangeMax.Z, null, 0);
//DestoryXy();
///*
////using (StreamWriter sw = new StreamWriter(strResult, false, Encoding.Default))
////{
//// for (int i = 0; i < nCalRows; i++)
//// {
//// for (int j = 0; j < nCalCols; j++)
//// {
//// sw.WriteLine($"{result[i * nCalCols + j].X},{result[i * nCalCols + j].Y},{resultZ[i * nCalCols + j]}");
//// }
//// }
////}*/
//MessageBox.Show("OK");
}
private IEnumerable<Vector3> ReadData(string filename)
{
using (StreamReader txt = new StreamReader(File.Open(filename, FileMode.Open)
, Encoding.Default))
{
txt.ReadLine(); // Skip columns
var s = txt.ReadLine();
while (s != null)
{
var parts = s.Split(',');
if (parts.Length == 3 &&
double.TryParse(parts[0], out var x) &&
double.TryParse(parts[1], out var y) &&
double.TryParse(parts[2], out var z))
{
yield return new Vector3((float)x, (float)y, (float)z);
}
s = txt.ReadLine();
}
}
}
/// <summary>
/// 窗口退出.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
private void btnQuit_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
}
/// <summary>
/// 选择输入文件.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
private void btnFileInput_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "*.csv|*.csv|*.xyz|*.xyz|*.*|*.*||";
ofd.RestoreDirectory = true;
if(ofd.ShowDialog() == DialogResult.OK)
{
this.txtInput.Text = ofd.FileName;
}
}
/// <summary>
/// 选择输出文件.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
private void btnFileOutput_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "*.dfd|*.dfd|*.pcg|*.pcg|*.*|*.*||";
sfd.RestoreDirectory = true;
sfd.OverwritePrompt = true;
if(sfd.ShowDialog() == DialogResult.OK)
{
this.txtOutput.Text = sfd.FileName;
}
}
public void CalculateRange(IReadOnlyList<Vector3> points, ref Vector3 pointMin, ref Vector3 pointMax)
{
if (points.Count == 0)
{
pointMin = pointMax = Vector3.Zero;
return;
}
float minX = float.MaxValue;
float minY = float.MaxValue;
float minZ = float.MaxValue;
float maxX = float.MinValue;
float maxY = float.MinValue;
float maxZ = float.MinValue;
for (int i = 0; i < points.Count; ++i)
{
var pt = points[i];
minX = Math.Min(minX, pt.X);
maxX = Math.Max(maxX, pt.X);
minY = Math.Min(minY, pt.Y);
maxY = Math.Max(maxY, pt.Y);
minZ = Math.Min(minZ, pt.Z);
maxZ = Math.Max(maxZ, pt.Z);
}
pointMin.X = minX;
pointMin.Y = minY;
pointMin.Z = minZ;
pointMax.X = maxX;
pointMax.Y = maxY;
pointMax.Z = maxZ;
}
#if DEBUG
const string DLL_FILE = "GridUtility.dll";
#else
const string DLL_FILE = "GridUtility.dll";
#endif
[DllImport(DLL_FILE, EntryPoint = "SetGridData", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
public static extern void SetGridData(double xMin, double yMin, double[] pDataZ
, double nCols, int nRows, double dx, double dy
, double zMin, double zMax
, double[] borderData, int borderDataSize);
[DllImport(DLL_FILE, EntryPoint = "Destroy", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
public static extern void DestoryXy();
}
}