5. 點和集合間之鄰近函數
Chart出問題可以試著打掉重幹
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 static System.Windows.Forms.VisualStyles.VisualStyleElement.Button;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using static System.Windows.Forms.TextBox;
using System.Runtime.InteropServices.ComTypes;
using System.Collections;
namespace Q5
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
flowLayoutPanel1.FlowDirection = FlowDirection.TopDown;
}
private void Form1_Load(object sender, EventArgs e)
{
}
(double, double)[] defaults = new (double, double)[]
{
( 1.5,1.5),
(2.0,1.0),
(2.5,1.75),
(1.5,2.0),
(3.0,2.0),
(1.0,3.5),
(2.0,3.0),
(3.5,3.0)
};
private void textBox1_TextChanged_1(object sender, EventArgs e)
{
if (!int.TryParse(textBox1.Text, out n))
{
n = 0;
groupBox1.Visible = false;
groupBox2.Visible = false;
return;
}
groupBox1.Visible = true;
groupBox2.Visible = true;
groupBox1.Text = $"請輸入 {n} 個點座標: x和y值";
tx.Text = "6.0";
ty.Text = "4.0";
flowLayoutPanel1.Controls.Clear();
for (int i = 0; i < n; i++)
{
var p = new FlowLayoutPanel();
p.AutoSize = true;
flowLayoutPanel1.Controls.Add(p);
var lbl = new Label();
lbl.Text = $"第x{i + 1}點座標";
var tbx = new System.Windows.Forms.TextBox();
tbx.Text = defaults[i].Item1.ToString();
var tby = new System.Windows.Forms.TextBox();
tby.Text = defaults[i].Item2.ToString();
p.Controls.Add(lbl);
p.Controls.Add(tbx);
p.Controls.Add(tby);
}
}
List<(double, double)> ks;
double x, y;
int n;
void calc()
{
if (n == 0)
{
MessageBox.Show("集合C中輸入點數錯誤,先用預設的8個點及測試點,請再輸入一次!");
ks = defaults.ToList();
x = 6; y = 4;
return;
}
if (!double.TryParse(tx.Text, out x) ||
!double.TryParse(ty.Text, out y))
{
MessageBox.Show("輸入的測試點座標錯誤,先用預設的測試點,請再輸入一次。");
x = 6; y = 4;
}
ks = new List<(double, double)>();
IList list = flowLayoutPanel1.Controls;
for (int i = 0; i < list.Count; i++)
{
object item = list[i];
var flo = ((FlowLayoutPanel)item);
var xx = (System.Windows.Forms.TextBox)flo.Controls[1];
var xy = (System.Windows.Forms.TextBox)flo.Controls[2];
double x = 0, y = 0;
if (!double.TryParse(xx.Text, out x) ||
!double.TryParse(xy.Text, out y))
{
MessageBox.Show("無法解析點 " + (i + 1) + ",已跳過");
continue;
}
ks.Add((x, y));
}
if (ks.Count == 0)
{
ks.AddRange(defaults);
MessageBox.Show("沒有有效點,已改用預設8個點");
}
}
private void button1_Click(object sender, EventArgs e)
{
calc();
var minDist = double.MaxValue;
var minIdx = -1;
for (int i = 0; i < ks.Count; i++)
{
var r = ks[i];
var d = Math.Sqrt(Math.Pow((r.Item1 - x), 2) + Math.Pow((r.Item2 - y), 2));
if (d < minDist)
{
minDist = d;
minIdx = i;
}
}
textBox4.Text = minDist.ToString();
label4.Text = $"測試點與第x{minIdx + 1}距離最近";
}
private void button3_Click(object sender, EventArgs e)
{
calc();
double sum = 0;
for (int i = 0; i < ks.Count; i++)
{
var r = ks[i];
var d = Math.Sqrt(Math.Pow((r.Item1 - x), 2) + Math.Pow((r.Item2 - y), 2));
sum += d;
}
sum /= ks.Count;
textBox6.Text = sum.ToString();
}
private void button4_Click(object sender, EventArgs e)
{
calc();
var series = chart1.Series.First();
series.Points.Clear();
chart1.ChartAreas.First().AxisX.Interval = 1;
chart1.ChartAreas.First().AxisY.Interval = 1;
chart1.ChartAreas.First().AxisX.Minimum = 0;
chart1.ChartAreas.First().AxisY.Minimum = 0;
var max = new List<(double, double)>();
max.AddRange(ks);
max.Add((x, y));
var m = max.Max(r => Math.Max(r.Item1, r.Item2));
chart1.ChartAreas.First().AxisX.Maximum = m;
chart1.ChartAreas.First().AxisY.Maximum = m;
chart1.ChartAreas.First().AxisX.IsStartedFromZero = true;
chart1.ChartAreas.First().AxisY.IsStartedFromZero = true;
for (int i = 0; i < ks.Count; i++)
{
(double, double) s = ks[i];
var pp = series.Points[series.Points.AddXY(s.Item1, s.Item2)];
pp.Label = "x" + (i + 1);
pp.MarkerColor = Color.Red;
pp.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Circle;
}
var p = series.Points[series.Points.AddXY(x, y)];
p.Label = "x";
p.MarkerColor = Color.Blue;
p.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Circle;
}
private void button2_Click(object sender, EventArgs e)
{
calc();
var minDist = double.MinValue;
var minIdx = -1;
for (int i = 0; i < ks.Count; i++)
{
var r = ks[i];
var d = Math.Sqrt(Math.Pow((r.Item1 - x), 2) + Math.Pow((r.Item2 - y), 2));
if (d > minDist)
{
minDist = d;
minIdx = i;
}
}
textBox5.Text = minDist.ToString();
label3.Text = $"測試點與第x{minIdx + 1}距離最遠";
}
}
}
Last updated