/// <summary> /// True if the point is in the shape. /// </summary> /// <param name="pt">The point to test set.</param> public bool Contains(C2DPoint pt) { if (!BoundingRect.Contains(pt)) { return(false); } var IntersectedPts = new C2DPointSet(); var Ray = new C2DLine(pt, new C2DVector(BoundingRect.Width(), 0.000001)); // Make sure to leave if (!this.Crosses(Ray, IntersectedPts)) { return(false); } else { IntersectedPts.SortByDistance(Ray.point); if (IntersectedPts[0].PointEqualTo(pt)) { // For integers, the pt can start On a line, meaning it's INSIDE, but the ray could cross again // so just return true. Because the equality test is really a test for proximity, this leads to the // possibility that a point could lie just outside the shape but be considered to be inside. This would // only be a problem with very small shapes that are a very long way from the origin. E.g. a 1m2 object // 1 million metres from the origin and a point 0.1mm away from the edge would give rise to a relative // difference of 0.0001 / 1000000 = 0.000000001 which would just be consider to be inside. return(true); } else { // Return true if the ray return((IntersectedPts.Count & (int)1) > 0); } } }
/// <summary> /// True if it crosses the ray. Provides the intersection points. /// </summary> /// <param name="Ray">The infinite line.</param> /// <param name="IntersectionPts">Output. The intersection points.</param> public bool CrossesRay(C2DLine Ray, C2DPointSet IntersectionPts) { double dDist = Ray.point.Distance(BoundingRect.GetCentre()); var LineTemp = new C2DLine(Ray); LineTemp.vector.SetLength(dDist + BoundingRect.Width() + BoundingRect.Height()); return(Crosses(LineTemp, IntersectionPts)); }