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));
}
}