示例#1
0
        /// <summary>
        /// 两个圆形的相交
        /// </summary>
        /// <param name="circle2D"></param>
        /// <returns></returns>
        public List <Vector2D> Intersect(Circle2D source)
        {
            List <Vector2D> intersects = null;

            //假如两个圆形重合,或者一个圆在另外一个内部,则返回不会有交点
            if (this.IsAlmostEqualTo(source))
            {
                return(intersects);
            }
            //获取圆点之间的距离
            var c_d = source.Central.Distance(source.Central);
            //获取半径的总长度
            var r_d = this.Radius + source.Radius;
            //获取两个半径的差值
            var r_ans = Math.Abs(this.Radius - source.Radius);

            //假如圆点之间的距离,要大于半径,则说明相离
            if (c_d.AreCompare(r_d) == 1)
            {
                return(intersects);
            }
            //两个原点的距离要小于半径的差值,说明一定是包含
            else if (c_d.AreCompare(r_ans) == -1)
            {
                return(intersects);
            }
            else
            {
                double a, b, c, p, q, r, cos, sin;

                a = 2 * this.Radius * (this.Central.X - source.Central.X);
                b = 2 * this.Radius * (this.Central.Y - source.Central.Y);
                c = Math.Pow(source.Radius, 2) - Math.Pow(this.Radius, 2) - Math.Pow(this.Central.X - source.Central.X, 2) - Math.Pow(this.Central.Y - source.Central.Y, 2);
                p = Math.Pow(a, 2) + Math.Pow(b, 2);
                q = -2 * a * c;
                r = Math.Pow(c, 2) - Math.Pow(b, 2);

                //说明是相切,那么只有一个解
                if (r_d.AreCompare(c_d) == 0 || c_d.AreCompare(r_ans) == 0)
                {
                    cos = -q / p / 2;
                    sin = Math.Sqrt(1 - Math.Pow(cos, 2));
                    Vector2D intersect = new Vector2D();
                    intersect.X = this.Radius * cos + this.Central.X;
                    intersect.Y = this.Radius * sin + this.Central.Y;
                    intersects  = new List <Vector2D>();
                    //由于sin可能有正负两种情况,则先计算的交点是否正确
                    if (source.Central.Distance(intersect).AreCompare(source.Radius) == 0)
                    {
                        intersects.Add(intersect);
                    }
                    else
                    {
                        intersect.Y = -this.Radius * sin + this.Central.Y;
                        intersects.Add(intersect);
                    }
                    return(intersects);
                }
                //说明两个多边形相交
                else
                {
                    intersects = new List <Vector2D>();
                    cos        = (Math.Sqrt(Math.Pow(q, 2) - 4 * p * r) - q) / 2 * p;
                    sin        = Math.Sqrt(1 - Math.Pow(cos, 2));
                    //第一个点
                    Vector2D intersect1 = new Vector2D();
                    intersect1.X = this.Radius * cos + this.Central.X;
                    intersect1.Y = this.Radius * sin + this.Central.Y;
                    if (source.Central.Distance(intersect1).AreCompare(source.Radius) == 0)
                    {
                        intersects.Add(intersect1);
                    }
                    else
                    {
                        intersect1.Y = -this.Radius * sin + this.Central.Y;
                        intersects.Add(intersect1);
                    }

                    cos = (-Math.Sqrt(Math.Pow(q, 2) - 4 * p * r) - q) / 2 * p;
                    sin = Math.Sqrt(1 - Math.Pow(cos, 2));
                    Vector2D intersect2 = new Vector2D();
                    intersect2.X = this.Radius * cos + this.Central.X;
                    intersect2.Y = this.Radius * sin + this.Central.Y;
                    if (source.Central.Distance(intersect2).AreCompare(source.Radius) == 0)
                    {
                        intersects.Add(intersect2);
                    }
                    else
                    {
                        intersect2.Y = -this.Radius * sin + this.Central.Y;
                        intersects.Add(intersect2);
                    }

                    //特殊情况,两个点计算到同一点,如圆形坐标对称,正好是互相反转关系,则需要对其中一个坐标进行调整
                    if (intersect1.IsAlmostEqualTo(intersect2))
                    {
                        intersect2.Y = -intersect2.Y;
                    }
                    return(intersects);
                }
            }
        }