1

So I'm writing a version of the Bresenham line algorithm. I wrote a class, and I tried converting it to java 8 style (this is my first time trying out java 8). I wanted the user of the class to either pass in a lambda that returns a boolean (whether to continue) or to pass in a lambda that returns void (to complete to the end of the algorithm).

When I wrote two separate lambda interfaces though, I get the error The method Line(int, int, int, int, BresenhamPlotter.BresenhamPlotFunctionAlwaysContinue) is ambiguous for the type BresenhamPlotter

This was my first attempt at the class, but I got that error in the first method.

public class BresenhamPlotter {

    /**
     * The Interface BresenhamPlotFunction.
     */
    public interface BresenhamPlotFunction {

        /**
         * Plot function, pass it into a plotting algorithm.
         *
         * @param x
         *            the x position
         * @param y
         *            the y position
         * @return True to continue, false to stop the algorithm early
         */
        public boolean plotFunction(int x, int y);
    }

    public interface BresenhamPlotFunctionAlwaysContinue {
        /**
         * Plot function, pass it into a plotting algorithm.
         *
         * @param x
         *            the x position
         * @param y
         *            the y position
         */
        public void plotFunction(int x, int y);
    }

    /**
     * Plots a line using the Bresenham line algorithm from (x0, y0) to (x1, y1) and plots each point using the plot function.
     *
     * @param x0
     *            the start x
     * @param y0
     *            the start y
     * @param x1
     *            the end x
     * @param y1
     *            the end y
     * @param plot
     *            the plot function
     */
    public static void Line(final int x0, final int y0, final int x1, final int y1, final BresenhamPlotFunctionAlwaysContinue plot) {
        Line(x0, y0, x1, y1, (x, y) -> {
            plot.plotFunction(x, y);
            return true;
        });
    }

    /**
     * Plots a line using the Bresenham line algorithm from (x0, y0) to (x1, y1) and plots each point using the plot function.
     *
     * @param x0
     *            the start x
     * @param y0
     *            the start y
     * @param x1
     *            the end x
     * @param y1
     *            the end y
     * @param plot
     *            the plot function
     */
    public static void Line(int x0, int y0, final int x1, final int y1, final BresenhamPlotFunction plot) {
        final int w = x1 - x0;
        final int h = y1 - y0;
        int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0;
        if (w < 0) {
            dx1 = -1;
        } else if (w > 0) {
            dx1 = 1;
        }
        if (h < 0) {
            dy1 = -1;
        } else if (h > 0) {
            dy1 = 1;
        }
        if (w < 0) {
            dx2 = -1;
        } else if (w > 0) {
            dx2 = 1;
        }
        int longest = Math.abs(w);
        int shortest = Math.abs(h);
        if (!(longest > shortest)) {
            longest = Math.abs(h);
            shortest = Math.abs(w);
            if (h < 0) {
                dy2 = -1;
            } else if (h > 0) {
                dy2 = 1;
            }
            dx2 = 0;
        }
        int numerator = longest >> 1;
        for (int i = 0; i <= longest; i++) {
            plot.plotFunction(x0, y0);
            numerator += shortest;
            if (!(numerator < longest)) {
                numerator -= longest;
                x0 += dx1;
                y0 += dy1;
            } else {
                x0 += dx2;
                y0 += dy2;
            }
        }
    }

    /**
     * Plots a line using the Bresenham line algorithm from (x0, y0) to (x1, y1) and returns a list of the points.
     *
     * @param x0
     *            the start x
     * @param y0
     *            the start y
     * @param x1
     *            the end x
     * @param y1
     *            the end y
     * @return the list of plotted points
     */
    public static List<Point> Line(int x0, int y0, final int x1, final int y1) {
        final List<Point> points = new ArrayList<>();
        final int w = x1 - x0;
        final int h = y1 - y0;
        int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0;
        if (w < 0) {
            dx1 = -1;
        } else if (w > 0) {
            dx1 = 1;
        }
        if (h < 0) {
            dy1 = -1;
        } else if (h > 0) {
            dy1 = 1;
        }
        if (w < 0) {
            dx2 = -1;
        } else if (w > 0) {
            dx2 = 1;
        }
        int longest = Math.abs(w);
        int shortest = Math.abs(h);
        if (!(longest > shortest)) {
            longest = Math.abs(h);
            shortest = Math.abs(w);
            if (h < 0) {
                dy2 = -1;
            } else if (h > 0) {
                dy2 = 1;
            }
            dx2 = 0;
        }
        int numerator = longest >> 1;
        for (int i = 0; i <= longest; i++) {
            points.add(new Point(x0, y0));
            numerator += shortest;
            if (!(numerator < longest)) {
                numerator -= longest;
                x0 += dx1;
                y0 += dy1;
            } else {
                x0 += dx2;
                y0 += dy2;
            }
        }
        return points;
    }
}

I changed the first method to an anonymous class to avoid the error

Line(x0, y0, x1, y1, new BresenhamPlotFunction() {

    @Override
    public boolean plotFunction(final int x, final int y) {
        plot.plotFunction(x, y);
        return true;
    }
});

but now when I try to call the method, I get an ambiguity error

BresenhamPlotter.Line(3, 0, 3, 5, (x, y) -> doStuff(x,y));

How can I fix this without using an anonymous class or changing the interface parameters?

Chris Hayes
  • 11,471
  • 4
  • 32
  • 47
Kyranstar
  • 1,650
  • 2
  • 14
  • 35

0 Answers0