예제 #1
0
        /// <summary>
        /// Gets the points that are furthest apart.
        /// </summary>
        /// <param name="nIndx1">Ouput. The first index.</param>
        /// <param name="nIndx2">Ouput. The second index.</param>
        /// <param name="dDist">Ouput. The distance.</param>
        public void GetExtremePoints(ref int nIndx1, ref int nIndx2,
                                     ref double dDist)
        {
            // First take a guess at them.
            GetExtremePointsEst(ref nIndx1, ref nIndx2, ref dDist, 0);

            // Set up a circle to bound the 2 guesses.
            C2DVector Vec = new C2DVector(this[nIndx1], this[nIndx2]);

            Vec.Multiply(0.5);
            C2DCircle Circle = new C2DCircle(this[nIndx1] + new C2DPoint(Vec), dDist / 2);

            // Now, if the guess was wrong, there must be a point outside the circle which is part of
            // the right solution. Go through all these, check and reset the result each time.
            for (int i = 0; i < Count; i++)
            {
                if (i != nIndx1 && i != nIndx2)
                {
                    if (!Circle.Contains(this[i]))
                    {
                        double dDistCheck = 0;
                        int    nCheck1    = GetFurthestPoint(i, ref dDistCheck);
                        if (dDistCheck > dDist)
                        {
                            nIndx1 = i;
                            nIndx2 = nCheck1;
                            dDist  = dDistCheck;
                        }
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Gets the minimum bounding circle.
        /// </summary>
        /// <param name="Circle">Ouput. The Circle.</param>
        public void GetBoundingCircle(C2DCircle Circle)
        {
            if (this.Count < 3)
            {
                if (this.Count == 2)
                {
                    Circle.SetMinimum(this[0], this[1]);
                }
                else if (this.Count == 1)
                {
                    Circle.Set(this[0], 0);
                }
                else
                {
                    Debug.Assert(false, "Point set with no points. Cannot calculate bounding circle.");
                }
                return;
            }

            int    nIndx1 = 0;
            int    nIndx2 = 0;;
            int    nIndx3 = 0;;
            double dDist  = 0;;

            // First get the points that are furthest away from each other.
            GetExtremePoints(ref nIndx1, ref nIndx2, ref dDist);
            // Set the circle to bound these.
            Circle.SetMinimum(this[nIndx1], this[nIndx2]);
            // Set up a flag to show if we are circumscibed. (Once we are, we always will be).
            bool bCircum = false;

            // Cycle through and if any points aren't in the circle, then set the circle to be circumscribed.
            for (int i = 0; i < Count; i++)
            {
                if (i != nIndx1 && i != nIndx2)
                {
                    if (!Circle.Contains(this[i]))
                    {
                        nIndx3 = i;
                        Circle.SetCircumscribed(this[nIndx1], this[nIndx2], this[nIndx3]);
                        bCircum = true;
                        // Break out and try again.
                        break;
                    }
                }
            }

            // If we didn't succeed first time then go through again setting it to be circumscribed every time.
            if (bCircum)
            {
                for (int i = 0; i < Count; i++)
                {
                    if (i != nIndx1 && i != nIndx2 && i != nIndx3)
                    {
                        if (!Circle.Contains(this[i]))
                        {
                            double Dist1 = this[i].Distance(this[nIndx1]);
                            double Dist2 = this[i].Distance(this[nIndx2]);
                            double Dist3 = this[i].Distance(this[nIndx3]);
                            if (Dist1 < Dist2 && Dist1 < Dist3)
                            {
                                // Closest to point 1 so elimitate this
                                nIndx1 = i;
                            }
                            else if (Dist2 < Dist3)
                            {
                                // Closest to point 2 so elimitate this
                                nIndx2 = i;
                            }
                            else
                            {
                                // Closest to point 3 so elimitate this
                                nIndx3 = i;
                            }
                            Circle.SetCircumscribed(this[nIndx1], this[nIndx2], this[nIndx3]);
                        }
                    }
                }
            }
        }