Ejemplo n.º 1
0
        static double Area(IList<Geo> array)
        {
            var count = 0;
            double area = 0;
            var v0 = new Geo(array[0]);
            var v1 = new Geo(array[1]);
            var p0 = new Geo(v0);
            var p1 = new Geo(v1);
            var p2 = new Geo();
            var size = array.Count - 1;
            double angle;

            for (var i = 2; i < size; i++)
            {
                count += 1;
                p2 = new Geo(array[i]);
                angle = p0.Angle(p1, p2);
                area += angle;
                p0 = p1;
                p1 = p2;
            }

            count += 1;
            p2 = v0;
            angle = p0.Angle(p1, p2);
            area += angle;
            p0 = p1;
            p1 = p2;

            count += 1;
            p2 = v1;
            angle = p0.Angle(p1, p2);
            area += angle;

            return area - ((count - 2) * Math.PI);
        }
        /// <summary>
        /// compute a polygonal approximation of an arc centered at pc, beginning at 
        /// p0 and ending at p1, going clockwise and including the two end points.
        /// </summary>
        /// <param name="center">center point</param>
        /// <param name="start">starting point</param>
        /// <param name="end">ending point</param>
        /// <param name="err">
        /// The maximum angle between approximates allowed, in radians.
        /// Smaller values will look better but will result in more returned points.
        /// </param>
        /// <returns></returns>
        public static GeoArray ApproximateArc(this Geo center, Geo start, Geo end, double err)
        {
            var theta = start.Angle(center, end);
            // if the rest of the code is undefined in this situation, just skip it.
            if (Double.IsNaN(theta))
            {
                return new GeoArray(new[]
                                        {
                                            start,
                                            end
                                        });
            }

            var n = (int)(2.0 + Math.Abs(theta / err)); // number of points
            // (counting the end
            // points)
            var result = new Geo[n];
            result[0] = start;
            var dtheta = theta / (n - 1);

            var rho = 0.0; // angle starts at 0 (directly at p0)

            for (var i = 1; i < n - 1; i++)
            {
                rho += dtheta;
                // Rotate p0 around this so it has the right azimuth.
                result[i] = Rotation.Rotate(center, start, 2.0 * Math.PI - rho, false);
            }
            result[n - 1] = end;

            return new GeoArray(result);
        }