任意三点画圆弧

发布时间 2023-12-22 15:13:49作者: echo-efun
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Numerics;
using System.Windows;

namespace WindowsFormsApp2
{
  public partial class FormDrawArc : Form
  {
    public FormDrawArc()
    {
      InitializeComponent();
    }

    PointF[] pt = new PointF[3];
    public double Rad2Deg = 180 / Math.PI;
    private void Form6_MouseDown(object sender, MouseEventArgs e)
    {
      Graphics gs = this.CreateGraphics();

      if (pt[0].X == 0 && pt[0].Y == 0)
      {

        pt[0].X = e.X;
        pt[0].Y = e.Y;
      }
      else if (pt[1].X == 0 && pt[1].Y == 0)
      {

        pt[1].X = e.X;
        pt[1].Y = e.Y;
      }
      else if (pt[2].X == 0 && pt[2].Y == 0)
      {

        pt[2].X = e.X;
        pt[2].Y = e.Y;
        PointF a = pt[0];
        PointF b = pt[1];
        PointF c = pt[2];

        double d = 2 * (a.X - c.X) * (c.Y - b.Y) + 2 * (b.X - c.X) * (a.Y - c.Y);
        double m1 = (Math.Pow(a.X, 2) - Math.Pow(c.X, 2) + Math.Pow(a.Y, 2) - Math.Pow(c.Y, 2));
        double m2 = (Math.Pow(c.X, 2) - Math.Pow(b.X, 2) + Math.Pow(c.Y, 2) - Math.Pow(b.Y, 2));
        double nx = m1 * (c.Y - b.Y) + m2 * (c.Y - a.Y);
        double ny = m1 * (b.X - c.X) + m2 * (a.X - c.X);
        double cx = nx / d;
        double cy = ny / d;
        double dx = cx - a.X;
        double dy = cy - a.Y;
        double distance = Math.Sqrt(dx * dx + dy * dy);
        Vector va = new Vector(a.X - cx, a.Y - cy);
        Vector vb = new Vector(b.X - cx, b.Y - cy);
        Vector vc = new Vector(c.X - cx, c.Y - cy);
        Vector xaxis = new Vector(1, 0);
        float startAngle = (float)Vector.AngleBetween(xaxis, va);
        float sweepAngle = (float)(Vector.AngleBetween(va, vb) + Vector.AngleBetween(vb, vc));
        gs.DrawArc(new Pen(Color.Cyan,3),
            (float)(cx - distance), (float)(cy - distance),
            (float)(distance * 2), (float)(distance * 2),
            startAngle, sweepAngle);

        pt = new PointF[3];
      }
    }
  }
}