import java.awt.*; import java.awt.image.BufferedImage; // handles line and line drawing public class Line2d { public Point2D point1; public Point2D point2; public boolean isDrawn = true; // initializer variables boolean is_initialised = false; private Point2D realPoint1; private Point2D realPoint2; private int dx; private int dy; private int sDy; private char iterator; private Point2D xy; int[] returnVal = new int[]{0,0}; private double gradient; // z gradient of the line in terms of X // drawing progress variables private int iteratorVal; private int D; public Line2d(Point2D _point1, Point2D _point2, boolean _isDrawn){ point1 = _point1; point2 = _point2; isDrawn = _isDrawn; } /** * Draws onto a given image * @param img the image to draw onto */ public void draw(BufferedImage img){ if (!is_initialised){initialise();} if (iterator == 'x'){ for (int i = 0; i <= dx; i++){ nextPix(); if(returnVal[0] >= 0 && returnVal[0] < img.getWidth() && returnVal[1] >= 0 && returnVal[1] < img.getHeight()) { // check if drawing in bounds img.setRGB(returnVal[0], returnVal[1], Color.HSBtoRGB(1, 1, 1)); } } } else { for (int i = 0; i <= dy; i++){ nextPix(); if(returnVal[0] >= 0 && returnVal[0] < img.getWidth() && returnVal[1] >= 0 && returnVal[1] < img.getHeight()) { // check if drawing in bounds img.setRGB(returnVal[0], returnVal[1], Color.HSBtoRGB(.5f, 1, 1)); } } } is_initialised = false; /* debug - draws the start and end of each line in white and green img.setRGB(realPoint1.intX(), realPoint1.intY(), Color.blue.getRGB()); img.setRGB(realPoint2.intX(), realPoint2.intY(), Color.green.getRGB()); */ } /** * Performs the initial calculations required to draw the line * Is automatically called whenever nextpix() or draw() are called when initialise() has not run. */ public void initialise(){ // initialise brensenham algorithm if (point2.x > point1.x) { realPoint1 = point1; realPoint2 = point2; } else { // if dx is less than zero, swap the points around realPoint1 = point2; realPoint2 = point1; } dx = realPoint2.x - realPoint1.x; dy = realPoint2.y - realPoint1.y; sDy = (int) Math.signum(dy); dy = Math.abs(dy); xy = new Point2D(realPoint1.x,realPoint1.y); // starting point // check if dy is greater than or less than dx if (dy < dx){ iterator = 'x'; D = (2*dy) - dx; }else{ iterator='y'; D = (2*dx) - dy; } iteratorVal = 0; // init other variables // dz / dx gradient = (realPoint2.z-realPoint1.z) / (realPoint2.x - realPoint1.x); is_initialised = true; } /** * @return the x and y coordinate of the next pixel in the line. */ public int[] nextPix(){ if(!is_initialised){initialise();} returnVal[0] = xy.x; returnVal[1] = xy.y; if (iterator=='x' && iteratorVal < dx && iteratorVal != -1){ if (D > 0) { D += 2 * (dy - dx); xy.y += sDy; } else { D += 2*dy; } xy.x += 1; // the line is always drawn left to right } else if(iterator =='y' && iteratorVal < dy && iteratorVal != -1) { if (D > 0) { D += 2 * (dx-dy); xy.x += 1; // the line is always drawn left to right } else { D += 2*dx; } xy.y += sDy; } else if(iteratorVal != -1) { iteratorVal = -1; returnVal[0] = realPoint2.x; returnVal[1] = realPoint2.y; return returnVal; } else { is_initialised = false; throw new RuntimeException("Accessed too many line pixels"); } iteratorVal += 1; return returnVal; } public double getZval(int x){ return realPoint1.z + (gradient * (x - realPoint1.x)); } }