//returns whether to go left or right in the BST, given a certain point and certain target normal //informally this predicate aims to find the point whose adjacent edges e1, e2 have normals n1, n2 such that //n1 <= normal <= n2 protected int NormalBSTPredicate(TPoint2D point, double normal) { TPoint2D leftNeighbor, rightNeighbor; Points.TryGetPredecessor(point, out leftNeighbor); Points.TryGetSuccessor(point, out rightNeighbor); //when at the start, pick left normal to point straight left var leftNormal = leftNeighbor != null?Normal(leftNeighbor, point, IsUpper) : ConvertToHullAngle(Math.PI); //when at the end, pick right normal to point straight right var rightNormal = rightNeighbor != null?Normal(point, rightNeighbor, IsUpper) : ConvertToHullAngle(0.0); var leftSign = Math.Sign(IsUpper ? normal - rightNormal : rightNormal - normal); var rightSign = Math.Sign(IsUpper ? normal - leftNormal : leftNormal - normal); //point was found if (leftSign == -rightSign || leftSign == 0 || rightSign == 0) { return(0); } //go left if (leftSign == rightSign && leftSign == 1) { return(-1); } //go right if (leftSign == rightSign && leftSign == -1) { return(1); } throw new InvalidOperationException("Illegal case detected"); }