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); }