public FailureType.Code GetFaultCodeForDataPoint(PolygonalCoordinate dataPoint) { FailureType.Code faultCode = FailureType.Code.NA; CartesianCoordinate centroid = dataPoint.GetArea().GetCentroid(); foreach (var area in Areas) { if (area.CheckIfCoordinateIsInArea(centroid)) { faultCode = area.FaultCode; } } return(faultCode); }
/// <summary> /// Determines whether a point is inside this polygonal area. /// If the point is at an edge or a vertex it is considered to be /// inside the area. It uses the algorithm documented by Paul Bourke. /// <see href="http://web.archive.org/web/20080812141848/http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/"/> /// </summary> /// <param name="coordinate">The <see cref="CartesianCoordinate"/> that will be checked.</param> /// <returns></returns> public bool CheckIfCoordinateIsInArea(CartesianCoordinate coordinate) { var isInside = false; int counter = 0; int i = 1; int n = Coordinates.Count; double xinters; CartesianCoordinate p1, p2; p1 = Coordinates[0]; foreach (var point in Coordinates) { p2 = Coordinates[i % n]; if (coordinate.Y > Math.Min(p1.Y, p2.Y)) { if (coordinate.Y <= Math.Max(p1.Y, p2.Y)) { if (coordinate.X <= Math.Max(p1.X, p2.X)) { if (p1.Y != p2.Y) { xinters = (coordinate.Y - p1.Y) * (p2.X - p1.X) / (p2.Y - p1.Y) + p1.X; if (p1.X == p2.X || coordinate.X <= xinters) { counter++; } } } } } p1 = p2; i++; } if (counter % 2 != 0) { isInside = true; } return(isInside); }