public static Shape getWallShadow(Point2D source, Line2D wall, double panelWidth, double panelHeight) {
        final Path2D shadow = new Path2D.Double();

        final LineEquation eq = new LineEquation(wall);
        final boolean clockwise = eq.getRelativePostion(source);
        final Point2D p1 = clockwise ? wall.getP1() : wall.getP2();
        final Point2D p2 = clockwise ? wall.getP2() : wall.getP1();
        final Point2D p1proj = getProjectionOnEdge(source, p1, panelWidth, panelHeight);
        final Point2D p2proj = getProjectionOnEdge(source, p2, panelWidth, panelHeight);

        // WARNING the points below are added in a specific order to avoid
        // hourglass-like polygons

        // add the wall as one side of the polygon
        shadow.moveTo((int) p2.getX(), (int) p2.getY());
        shadow.lineTo((int) p1.getX(), (int) p1.getY());
        // add the projection of the second point of the wall
        shadow.lineTo((int) p1proj.getX(), (int) p1proj.getY());
        // add possible corners between the 2 projections
        Side s = Side.get(p1proj, panelWidth, panelHeight);
        final Side s2 = Side.get(p2proj, panelWidth, panelHeight);
        while (s != s2) {
            final Point2D corner = s.getCorner(panelWidth, panelHeight);
            shadow.lineTo(corner.getX(), corner.getY());
            s = s.next();
        }
        // add the projection of the first point of the wall
        shadow.lineTo((int) p2proj.getX(), (int) p2proj.getY());
        shadow.closePath();
        return shadow;
    }