public void Insert(TPoint2D point) { var count = Points.Size; //always insert first two points if (count != 1) { var farRight = point.X > RightMost.X; var farLeft = point.X < LeftMost.X; var withinBounds = !farRight && !farLeft; //don't insert when point lies inside the range of the convex hull but on the wrong side if (withinBounds) { var orientation = Geometry2D.Orient(LeftMost.AsVector(), RightMost.AsVector(), point.AsVector()); var pointLiesAbove = orientation == 1; if (pointLiesAbove != IsUpper) { return; } } TPoint2D startPoint, endPoint; Points.TryFind(p => UpdatePredicate(point, p, true), out startPoint); Points.TryFind(p => UpdatePredicate(point, p, false), out endPoint); //point outside of hull if (startPoint != null || endPoint != null) { if (startPoint != RightMost && endPoint != LeftMost) { SearchPredicate <TPoint2D> inRangePredicate = p => { if (startPoint != null && p.X <= startPoint.X) { return(1); } if (endPoint != null && p.X >= endPoint.X) { return(-1); } return(0); }; //delete everything after start up to end TPoint2D element; Points.TryFind(inRangePredicate, out element); while (element != null) { Points.Delete(element); Points.TryFind(inRangePredicate, out element); } } } //point inside of hull else { return; } } Points.Insert(point, pointWithSameX => { if (IsUpper) { return(point.Y > pointWithSameX.Y); } return(point.Y < pointWithSameX.Y); }); }