private Vector3?GetInterWithNextCircle(int i)
    {
        if (planeInter[i].type != PlaneSphereIntersection.eType.Circle)
        {
            return(null);
        }

        int nextIndex = (i + 1) % 4;

        if (planeInter[nextIndex].type != PlaneSphereIntersection.eType.Circle)
        {
            return(null);
        }

        PlanePlaneIntersection ppI = new PlanePlaneIntersection(plane[i], plane[nextIndex]);
        LineSphereIntersection lsI = new LineSphereIntersection(ppI.O, ppI.D, center, radius);

        if (lsI.type == LineSphereIntersection.eType.None)
        {
            return(null);
        }

        if (lsI.type == LineSphereIntersection.eType.OnePoint)
        {
            return(lsI.I0);
        }
        Vector3 OI0    = (lsI.I0 - camPosition);
        Vector3 OI1    = (lsI.I1 - camPosition);
        Vector3 camDir = camTransform.forward;

        if (Vector3.Dot(camDir, OI0) < 0)
        {
            if (Vector3.Dot(camDir, OI1) < 0)
            {
                return(null);
            }
            return(lsI.I0);
        }
        else
        {
            if (Vector3.Dot(camDir, OI1) < 0)
            {
                return(lsI.I0);
            }
        }

        float d0 = OI0.sqrMagnitude;
        float d1 = OI1.sqrMagnitude;

        return(d0 > d1 ? lsI.I1 : lsI.I0);
    }
    private bool GetPointsForCircleIntersection(int index, out Vector3 start, out Vector3 end)
    {
        PlanePlaneIntersection ppI = new PlanePlaneIntersection(plane[index], backPlane);
        LineSphereIntersection lsI = new LineSphereIntersection(ppI.O, ppI.D, center, radius);

        if (lsI.type == LineSphereIntersection.eType.None)
        {
            Debug.LogError("This should not be possible");
            start = end = Vector3.zero;
            return(false);
        }

        if (lsI.type == LineSphereIntersection.eType.OnePoint)
        {
            // just grazing the surface, don't add a segment for that
            start = end = Vector3.zero;
            return(false);
        }

        bool b0 = IsInFront(lsI.I0);
        bool b1 = IsInFront(lsI.I1);

        if (!b0 && !b1)
        {
            start = end = Vector3.zero;
            return(false);
        }
        int previousIndex = (index + 3) % 4;

        if (!b0)
        {
            if (circleInter[previousIndex].HasValue)
            {
                start = circleInter[previousIndex].Value;
                end   = circleInter[index].HasValue ? circleInter[index].Value : lsI.I1;
                return(true);
            }
            if (circleInter[index].HasValue)
            {
                start = lsI.I1;
                end   = circleInter[index].Value;
                return(true);
            }
            start = end = Vector3.zero;
            return(false);
        }
        if (!b1)
        {
            if (circleInter[previousIndex].HasValue)
            {
                start = circleInter[previousIndex].Value;
                end   = circleInter[index].HasValue ? circleInter[index].Value : lsI.I0;
                return(true);
            }
            if (circleInter[index].HasValue)
            {
                start = lsI.I0;
                end   = circleInter[index].Value;
                return(true);
            }
            start = end = Vector3.zero;
            return(false);
        }



        if (plane[previousIndex].Distance(lsI.I0) < plane[previousIndex].Distance(lsI.I1))
        {
            start = circleInter[previousIndex].HasValue ? circleInter[previousIndex].Value : lsI.I0;
            end   = circleInter[index].HasValue ? circleInter[index].Value : lsI.I1;
        }
        else
        {
            start = circleInter[previousIndex].HasValue ? circleInter[previousIndex].Value : lsI.I1;
            end   = circleInter[index].HasValue ? circleInter[index].Value : lsI.I0;
        }
        return(true);
    }