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