C#求两圆相交点,转载自百度知道 作者lrh3321

本文介绍了一个使用C#实现的两圆相交计算程序。该程序定义了点和圆的结构体,并通过输入两个圆的坐标及半径来判断两圆的关系并计算相交点。文章提供了完整的代码实现。
using System;
 
namespace ConsoleZ
{
    struct Point
    {
        public double X;
        public double Y;
        public override string ToString()
        {
            return string.Format("({0},{1})",X,Y);
        }
    }
 
    struct Circle
    {
        public Point Center;
        public double X { get return Center.X; }set { Center.X = value; } }
        public double Y { get return Center.Y; } set { Center.X = value; } }
        public double Radius;
    };
    class Program
    {
        const double ZERO = 1e-9;//误差,小于这个就当作0
        static bool double_equals(double a, double b)
        {
            return Math.Abs(a - b) < ZERO;
        }
 
        static double distance_sqr(Point a, Point b)
        {
            return (a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y);
        }
 
        static double distance(Point a, Point b)
        {
            return Math.Sqrt(distance_sqr(a, b));
        }
 
       static int insect(Circle[] circles, Point[] points)
        {
            double d, a, b, c, p, q, r;
            double[] cos_value = new double[2], sin_value = new double[2];
            if (double_equals(circles[0].Center.X, circles[1].Center.X)
                && double_equals(circles[0].Center.Y, circles[1].Center.Y)
                && double_equals(circles[0].Radius, circles[1].Radius))
            {
                return -1;
            }
 
            d = distance(circles[0].Center, circles[1].Center);
            if (d > circles[0].Radius + circles[1].Radius
                || d < Math.Abs(circles[0].Radius - circles[1].Radius))
            {
                return 0;
            }
 
            a = 2.0 * circles[0].Radius * (circles[0].Center.X - circles[1].Center.X);
            b = 2.0 * circles[0].Radius * (circles[0].Center.Y - circles[1].Center.Y);
            c = circles[1].Radius * circles[1].Radius - circles[0].Radius * circles[0].Radius
                - distance_sqr(circles[0].Center, circles[1].Center);
            p = a * a + b * b;
            q = -2.0 * a * c;
            if (double_equals(d, circles[0].Radius + circles[1].Radius)
                || double_equals(d, Math.Abs(circles[0].Radius - circles[1].Radius)))
            {
                cos_value[0] = -q / p / 2.0;
                sin_value[0] = Math.Sqrt(1 - cos_value[0] * cos_value[0]);
 
                points[0].X = circles[0].Radius * cos_value[0] + circles[0].Center.X;
                points[0].Y = circles[0].Radius * sin_value[0] + circles[0].Center.Y;
 
                if (!double_equals(distance_sqr(points[0], circles[1].Center),
                                   circles[1].Radius * circles[1].Radius))
                {
                    points[0].Y = circles[0].Center.Y - circles[0].Radius * sin_value[0];
                }
                return 1;
            }
 
            r = c * c - b * b;
            cos_value[0] = (Math.Sqrt(q * q - 4.0 * p * r) - q) / p / 2.0;
            cos_value[1] = (-Math.Sqrt(q * q - 4.0 * p * r) - q) / p / 2.0;
            sin_value[0] = Math.Sqrt(1 - cos_value[0] * cos_value[0]);
            sin_value[1] = Math.Sqrt(1 - cos_value[1] * cos_value[1]);
 
            points[0].X = circles[0].Radius * cos_value[0] + circles[0].Center.X;
            points[1].X = circles[0].Radius * cos_value[1] + circles[0].Center.X;
            points[0].Y = circles[0].Radius * sin_value[0] + circles[0].Center.Y;
            points[1].Y = circles[0].Radius * sin_value[1] + circles[0].Center.Y;
 
            if (!double_equals(distance_sqr(points[0], circles[1].Center),
                               circles[1].Radius * circles[1].Radius))
            {
                points[0].Y = circles[0].Center.Y - circles[0].Radius * sin_value[0];
            }
            if (!double_equals(distance_sqr(points[1], circles[1].Center),
                               circles[1].Radius * circles[1].Radius))
            {
                points[1].Y = circles[0].Center.Y - circles[0].Radius * sin_value[1];
            }
            if (double_equals(points[0].Y, points[1].Y)
                && double_equals(points[0].X, points[1].X))
            {
                if (points[0].Y > 0)
                {
                    points[1].Y = -points[1].Y;
                }
                else
                {
                    points[0].Y = -points[0].Y;
                }
            }
            return 2;
        }
        static void Main(string[] args)
        {
            Circle[] circles = new Circle[2];
            Point[] points = new Point[2];
            Console.Write("请输入两圆x,y,半径(以逗号分开):");
            char[] sep = new char[] {' ',',',',' };
            string[] tempstr;
            while (true)
            {
                tempstr=Console.ReadLine().Split(sep,StringSplitOptions.RemoveEmptyEntries);
                if (tempstr.Length!=6)
                {
                    Console.Write("输入有误\n按任意键退出...");
                    Console.ReadKey();
                    Environment.Exit(0);
                }
                circles[0].X = double.Parse(tempstr[0]);
                circles[0].Y= double.Parse(tempstr[1]);
                circles[0].Radius=double.Parse(tempstr[2]);
                circles[1].X = double.Parse(tempstr[3]);
                circles[1].Y = double.Parse(tempstr[4]);
                circles[1].Radius = double.Parse(tempstr[5]);                
                switch (insect(circles, points))
                {
                    case -1:
                        Console.Write("两圆相同\n");
                        break;
                    case 0:
                        Console.Write("不相交\n");
                        break;
                    case 1:
                        Console.WriteLine(points[0]);
                        break;
                    case 2:
                        Console.WriteLine(string.Join(" ", points));
                        break;
                }
            }
        }
    }
 
}
本程序是两圆相交交点,输入信息为两圆心坐标和半径值。如有更好的算法,欢迎交流!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值