Line.java

/**
A simple <code>Line</code> class for homework #2.

@author Walt Leipold
*/
public class Line extends Shape implements PrinterPlottable
{
    /**
    Construct a <code>Line</code> object.

    @param x1 x-coordinate of first endpoint
    @param y1 y-coordinate of first endpoint
    @param x2 x-coordinate of second endpoint
    @param y2 y-coordinate of second endpoint
    */
    public Line(double x1,double y1,double x2,double y2)
    {
        super(x1,y1);
        this.x2 = x2;
        this.y2 = y2;
    }


    /** 
    @return the x-coord of the 'other' endpoint of the 
    <code>Line</code> (The x-coord of the first endpoint can be 
    obtained by calling <code>getX()</code>.)
    */
    public double getEndX()
    {
        return x2;
    }


    /** 
    @return the y-coord of the 'other' endpoint of the 
    <code>Line</code> (The y-coord of the first endpoint can be 
    obtained by calling <code>getY()</code>.)
    */
    public double getEndY()
    {
        return y2;
    }


    /**
    @return a <code>String</code> describing this <code>Line</code>
    */
    public String toString()
    {
        return getClass().getName() + "[" +
            "x1=" + formatNum(getX()) + "," +
            "y1=" + formatNum(getY()) + "," +
            "x2=" + formatNum(x2) + "," +
            "y2=" + formatNum(y2) + "]";
    }


    /**
    Draw this <code>Line</code> on the given plot context using
    a specified character.

    @param pc the <code>PlotContext</code> to draw on
    @param drawChar the character to draw with
    */
    public void draw(PlotContext pc,char drawChar)
    {
        drawRecursiveLine(pc,
            (int)Math.round(getX()),
            (int)Math.round(getY()),
            (int)Math.round(x2),
            (int)Math.round(y2),
            drawChar);
        // A DDA (digital differential analyzer) would be a better
        // algorithm, but this is good enough for a proof-of-concept 
        // implementation...
    }


    /**
    Brute-force recursive line-drawing.  Does *way* too many
    setPoint()s of the same darn point...
    */
    private void drawRecursiveLine(PlotContext pc,
        int xa,int ya,int xb,int yb,
        char drawChar)
    {
        int xc = (xa+xb)/2;
        int yc = (ya+yb)/2;
        pc.setPoint(xa,ya,drawChar);
        pc.setPoint(xb,yb,drawChar);
        pc.setPoint(xc,yc,drawChar);
        if (iabs(xa-xc) > 1 || iabs(ya-yc) > 1)
            drawRecursiveLine(pc,xa,ya,xc,yc,drawChar);
        if (iabs(xc-xb) > 1 || iabs(yc-yb) > 1)
            drawRecursiveLine(pc,xc,yc,xb,yb,drawChar);
    }


    private int iabs(int n) { return n>=0 ? n : -n; }


    private double x2,y2;
}