@SuppressWarnings({"checkstyle:parameternumber", "checkstyle:cyclomaticcomplexity",
            "checkstyle:npathcomplexity"})
    private void crossSegmentTwoShadowLines(
            int shadowX0, int shadowY0,
            int shadowX1, int shadowY1,
            int sx0, int sy0,
            int sx1, int sy1) {
        // Update the global bounds of the shadow.
        final int shadowYmin = Math.min(shadowY0, shadowY1);
        final int shadowYmax = Math.max(shadowY0, shadowY1);

        if (shadowYmin != this.boundingMinY && shadowYmax != this.boundingMaxY) {
            // Shadow is not contributing to the crossing computation.
            return;
        }

        if (sy0 < shadowYmin && sy1 < shadowYmin) {
            // The segment is entirely at the bottom of the shadow.
            return;
        }
        if (sy0 > shadowYmax && sy1 > shadowYmax) {
            // The segment is entirely at the top of the shadow.
            return;
        }

        final int shadowXmin = Math.min(shadowX0, shadowX1);
        final int shadowXmax = Math.max(shadowX0, shadowX1);

        if (sx0 < shadowXmin && sx1 < shadowXmin) {
            // The segment is entirely at the left of the shadow.
            return;
        }
        if (sx0 > shadowXmax && sx1 > shadowXmax) {
            // The line is entirely at the right of the shadow
            final OutputParameter<Integer> param = new OutputParameter<>();
            if (shadowYmin == shadowYmax) {
                final int cross = this.crossings;
                this.crossings = Segment2ai.calculatesCrossingsAndXPointShadowSegment(
                        cross,
                        shadowXmax, shadowYmin,
                        sx0, sy0, sx1, sy1,
                        shadowYmin == this.boundingMinY, shadowYmax == this.boundingMaxY, param);
                if (cross != this.crossings) {
                    final int xintercept = param.get().intValue();
                    setCrossingCoordinateForYMax(xintercept, shadowYmin);
                    setCrossingCoordinateForYMin(xintercept, shadowYmin);
                    this.crossings = cross;
                }
            } else {
                if (shadowYmin == this.boundingMinY) {
                    final int cross = Segment2ai.calculatesCrossingsAndXPointShadowSegment(
                            this.crossings,
                            shadowXmax, shadowYmin,
                            sx0, sy0, sx1, sy1,
                            shadowYmin == this.boundingMinY, false, param);
                    if (cross != this.crossings) {
                        final int xintercept = param.get().intValue();
                        setCrossingCoordinateForYMax(xintercept, shadowYmin);
                        setCrossingCoordinateForYMin(xintercept, shadowYmin);
                        this.crossings = cross;
                    }
                }
                if (shadowYmax == this.boundingMaxY) {
                    final int cross = Segment2ai.calculatesCrossingsAndXPointShadowSegment(
                            this.crossings,
                            shadowXmax, shadowYmax,
                            sx0, sy0, sx1, sy1,
                            false, shadowYmax == this.boundingMaxY, param);
                    if (cross != this.crossings) {
                        final int xintercept = param.get().intValue();
                        setCrossingCoordinateForYMax(xintercept, shadowYmax);
                        setCrossingCoordinateForYMin(xintercept, shadowYmax);
                        this.crossings = cross;
                    }
                }
            }
        } else if (Segment2ai.intersectsSegmentSegment(
                shadowX0, shadowY0, shadowX1, shadowY1,
                sx0, sy0, sx1, sy1)) {
            // The segment is intersecting the shadowed segment.
            this.crossings = GeomConstants.SHAPE_INTERSECTS;
        } else {
            final int side1;
            final int side2;
            if (shadowY0 <= shadowY1) {
                side1 = Segment2ai.findsSideLinePoint(
                        shadowX0, shadowY0,
                        shadowX1, shadowY1,
                        sx0, sy0);
                side2 = Segment2ai.findsSideLinePoint(
                        shadowX0, shadowY0,
                        shadowX1, shadowY1,
                        sx1, sy1);
            } else {
                side1 = Segment2ai.findsSideLinePoint(
                        shadowX1, shadowY1,
                        shadowX0, shadowY0,
                        sx0, sy0);
                side2 = Segment2ai.findsSideLinePoint(
                        shadowX1, shadowY1,
                        shadowX0, shadowY0,
                        sx1, sy1);
            }
            if (side1 >= 0 || side2 >= 0) {
                final int x0;
                final int x1;
                if (shadowYmin == shadowY0) {
                    x0 = shadowX0;
                    x1 = shadowX1;
                } else {
                    x0 = shadowX1;
                    x1 = shadowX0;
                }
                crossSegmentShadowLine(
                        x0, shadowYmin,
                        sx0, sy0, sx1, sy1, true, false);
                crossSegmentShadowLine(
                        x1, shadowYmax,
                        sx0, sy0, sx1, sy1, false, true);
            }
        }
    }
@ SuppressWarnings ( { "checkstyle:parameternumber" , "checkstyle:cyclomaticcomplexity" , "checkstyle:npathcomplexity" } ) private void crossSegmentTwoShadowLines ( int shadowX0 , int shadowY0 , int shadowX1 , int shadowY1 , int sx0 , int sy0 , int sx1 , int sy1 ) { final int shadowYmin = Math . min ( shadowY0 , shadowY1 ) ; final int shadowYmax = Math . max ( shadowY0 , shadowY1 ) ; if ( shadowYmin != this . boundingMinY && shadowYmax != this . boundingMaxY ) { return ; } if ( sy0 < shadowYmin && sy1 < shadowYmin ) { return ; } if ( sy0 > shadowYmax && sy1 > shadowYmax ) { return ; } final int shadowXmin = Math . min ( shadowX0 , shadowX1 ) ; final int shadowXmax = Math . max ( shadowX0 , shadowX1 ) ; if ( sx0 < shadowXmin && sx1 < shadowXmin ) { return ; } if ( sx0 > shadowXmax && sx1 > shadowXmax ) { final OutputParameter < Integer > param = new OutputParameter < > ( ) ; if ( shadowYmin == shadowYmax ) { final int cross = this . crossings ; this . crossings = Segment2ai . calculatesCrossingsAndXPointShadowSegment ( cross , shadowXmax , shadowYmin , sx0 , sy0 , sx1 , sy1 , shadowYmin == this . boundingMinY , shadowYmax == this . boundingMaxY , param ) ; if ( cross != this . crossings ) { final int xintercept = param . get ( ) . intValue ( ) ; setCrossingCoordinateForYMax ( xintercept , shadowYmin ) ; setCrossingCoordinateForYMin ( xintercept , shadowYmin ) ; this . crossings = cross ; } } else { if ( shadowYmin == this . boundingMinY ) { final int cross = Segment2ai . calculatesCrossingsAndXPointShadowSegment ( this . crossings , shadowXmax , shadowYmin , sx0 , sy0 , sx1 , sy1 , shadowYmin == this . boundingMinY , false , param ) ; if ( cross != this . crossings ) { final int xintercept = param . get ( ) . intValue ( ) ; setCrossingCoordinateForYMax ( xintercept , shadowYmin ) ; setCrossingCoordinateForYMin ( xintercept , shadowYmin ) ; this . crossings = cross ; } } if ( shadowYmax == this . boundingMaxY ) { final int cross = Segment2ai . calculatesCrossingsAndXPointShadowSegment ( this . crossings , shadowXmax , shadowYmax , sx0 , sy0 , sx1 , sy1 , false , shadowYmax == this . boundingMaxY , param ) ; if ( cross != this . crossings ) { final int xintercept = param . get ( ) . intValue ( ) ; setCrossingCoordinateForYMax ( xintercept , shadowYmax ) ; setCrossingCoordinateForYMin ( xintercept , shadowYmax ) ; this . crossings = cross ; } } } } else if ( Segment2ai . intersectsSegmentSegment ( shadowX0 , shadowY0 , shadowX1 , shadowY1 , sx0 , sy0 , sx1 , sy1 ) ) { this . crossings = GeomConstants . SHAPE_INTERSECTS ; } else { final int side1 ; final int side2 ; if ( shadowY0 <= shadowY1 ) { side1 = Segment2ai . findsSideLinePoint ( shadowX0 , shadowY0 , shadowX1 , shadowY1 , sx0 , sy0 ) ; side2 = Segment2ai . findsSideLinePoint ( shadowX0 , shadowY0 , shadowX1 , shadowY1 , sx1 , sy1 ) ; } else { side1 = Segment2ai . findsSideLinePoint ( shadowX1 , shadowY1 , shadowX0 , shadowY0 , sx0 , sy0 ) ; side2 = Segment2ai . findsSideLinePoint ( shadowX1 , shadowY1 , shadowX0 , shadowY0 , sx1 , sy1 ) ; } if ( side1 >= 0 || side2 >= 0 ) { final int x0 ; final int x1 ; if ( shadowYmin == shadowY0 ) { x0 = shadowX0 ; x1 = shadowX1 ; } else { x0 = shadowX1 ; x1 = shadowX0 ; } crossSegmentShadowLine ( x0 , shadowYmin , sx0 , sy0 , sx1 , sy1 , true , false ) ; crossSegmentShadowLine ( x1 , shadowYmax , sx0 , sy0 , sx1 , sy1 , false , true ) ; } } }
Determine where the segment is crossing the two shadow lines.

@param shadowX0 x coordinate of the reference point of the first shadow line.
@param shadowY0 y coordinate of the reference point of the first shadow line.
@param shadowX1 x coordinate of the reference point of the second shadow line.
@param shadowY1 y coordinate of the reference point of the second shadow line.
@param sx0 x coordinate of the first point of the segment.
@param sy0 y coordinate of the first point of the segment.
@param sx1 x coordinate of the second point of the segment.
@param sy1 y coordinate of the second point of the segment.