import java.awt.*;
import java.awt.image.BufferedImage;
// handles line and line drawing
public class Line {
public Point2D point1;
public Point2D point2;
// 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};
// drawing progress variables
private int iteratorVal;
private int D;
public Line(Point2D _point1, Point2D _point2){
point1 = _point1;
point2 = _point2;
}
/**
* 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();
try {
img.setRGB(returnVal[0], returnVal[1], Color.HSBtoRGB(1, 1, 1));
}
catch (ArrayIndexOutOfBoundsException ref){
System.out.println(returnVal[0] + " " + returnVal[1]);
}
}
} else {
for (int i = 0; i <= dy; i++){
nextPix();
try {
img.setRGB(returnVal[0], returnVal[1], Color.HSBtoRGB(.5f, 1, 1));
}
catch (ArrayIndexOutOfBoundsException ref){
System.out.println(returnVal[0] + " " + returnVal[1]);
}
}
}
/*
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());
*/
is_initialised = false;
}
/**
* 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(){
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.intX() - realPoint1.intX(); // round all points to the nearest integer
dy = realPoint2.intY() - realPoint1.intY(); // the line algorithm only works with integer arithmetic
sDy = (int) Math.signum(dy); dy = Math.abs(dy);
xy = new Point2D(realPoint1.intX(),realPoint1.intY()); // 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;
is_initialised = true;
}
/**
* @return the x and y coordinate of the next pixel in the line.
*/
public int[] nextPix(){
if(!is_initialised){initialise();}
//OPTIMIZATION - avoid casting. have a different point class that uses integers instead of float
returnVal[0] = xy.intX();
returnVal[1] = xy.intY();
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.intX();
returnVal[1] = realPoint2.intY();
return returnVal;
}
else {
is_initialised = false;
return null;
}
iteratorVal += 1;
return returnVal;
}
}