根据圆上三点画扇形
已知圆上三点坐标,要根据这三点坐标画圆弧,找了半天,也没发现完善的现成代码,想了半天算法,发现自己已经把解析几何忘了个差不多了。没办法最后根据余弦定理自己写了一个。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace DrawArc
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private static void CalcDegree(ref Point O, ref Point A, ref Point B, out double angleAB, out double angleA, out double angleB)
{
//x轴上的向量
int Xx = 100;
int Xy = 0;
//oa向量
int ax = A.X - O.X;
int ay = A.Y - O.Y;
//ob向量
int bx = B.X - O.X;
int by = B.Y - O.Y;
CalcAngle(ax, ay, Xx, Xy,out angleA);
CalcAngle(bx, by, Xx, Xy, out angleB);
CalcAngle(ax, ay, bx, by, out angleAB);
//坐标变换
ConvertAngelToOrig(ref O, ref A, ref angleA);
ConvertAngelToOrig(ref O, ref B, ref angleB);
}
private static void CalcAngle(int vx, int vy, int vx2, int vy2, out double angle)
{
//double dA = Math.Sqrt(vx * vx + vy * vy);
//double dB = Math.Sqrt(vx2 * vx2 + vy2 * vy2);
//double dC = Math.Sqrt((vx2 - vx) * (vx2 - vx) + (vy2 - vy) * (vy2 - vy));
// angle = Math.Acos((dA * dA + dB * dB - dC * dC) / 2 * dA * dA) * (180 / Math.PI);
int Point_Mul_a = (vx * vx2) + (vy * vy2);
double Mul_a = Math.Sqrt(vx * vx + vy * vy) * Math.Sqrt(vx2 * vx2 + vy2 * vy2);
//计算夹角余弦值
double Cos_a = Point_Mul_a / Mul_a;
double A_Cos = Math.Acos(Cos_a);
//求出几何坐标系中的角度,即按逆时针的方法
angle = A_Cos * (180 / Math.PI);
}
private static void ConvertAngelToOrig(ref Point O, ref Point A, ref double angleA)
{
if (A.Y <= O.Y && A.X >= O.X)//1
{
angleA = 360 - angleA;
}
else if (A.Y <= O.Y && A.X < O.X)//2
{
angleA = 360 - angleA;
}
}
private void button1_Click(object sender, EventArgs e)
{
PaintArc();
}
private void PaintArc()
{
//三个点,O为原点,A、B为圆上另外两点
Point Point_O = new Point(200, 200);
//Point Point_A = new Point(100, 100);
//Point Point_B = new Point(300, 100);
//Point Point_A = new Point(150, 150);
//Point Point_B = new Point(250, 150);
//Point Point_A = new Point(250, 150);
//Point Point_B = new Point(250, 250);
//Point Point_A = new Point(250, 250);
//Point Point_B = new Point(150, 150);
//Point Point_A = new Point(250, 250);
//Point Point_B = new Point(250, 150);
Point Point_A = new Point(150, 250);
Point Point_B = new Point(250, 150);
double angleA;
double angleB;
double angleAB;
CalcDegree(ref Point_O, ref Point_A, ref Point_B, out angleAB, out angleA, out angleB);
double distance = Math.Sqrt((Point_A.X - Point_O.X) * (Point_A.X - Point_O.X) + (Point_A.Y - Point_O.Y) * (Point_A.Y - Point_O.Y));
float topLeftX = (float)(Point_O.X - distance);
float topLeftY = (float)(Point_O.Y - distance);
//初始化画板
Graphics gr = this.CreateGraphics();
Brush br = new SolidBrush(Color.Red);
Pen pe = new Pen(Color.Black, 10);
//画出圆弧
double delta = angleB - angleA;
if ((delta > 0 && delta < 180) || (delta < -180))//A->B
{
gr.DrawArc(pe, topLeftX, topLeftY, (float)(2 * distance), (float)(2 * distance), (float)(angleA), (float)(angleAB));
}
else//B->A
{
gr.DrawArc(pe, topLeftX, topLeftY, (float)(2 * distance), (float)(2 * distance), (float)(angleB), (float)(angleAB));
}
//画出点
gr.FillEllipse(br, Point_O.X, Point_O.Y, 7, 7);
gr.FillEllipse(br, Point_A.X, Point_A.Y, 7, 7);
gr.FillEllipse(br, Point_B.X, Point_B.Y, 7, 7);
pe.Dispose();
br.Dispose();
gr.Dispose();
}
}
}