import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.awt.image.BufferedImage;
import java.util.Random;
/* This program takes in a number (N) from the user and then draws N lines in a window with random start and endpoints
* Lines are drawn not with a built-in method, but using the Bresenham algorithm.
* The lines are drawn with random lengths, slopes, and colors.
*
* To compile: type the following into your terminal, ensuring that the terminal is in the same directory as the program
* "javac --release 8 Bresenham.java"
* To run: type the following into your terminal, ensuring that the terminal is in the same directory as the program
* "java Bresenham"
*/
public class Bresenham extends JPanel{
private BufferedImage canvas;
public static void main(String[] args) {
//get N from user input
Scanner sc= new Scanner(System.in);
System.out.print("Enter how many lines to be drawn: ");
int N= sc.nextInt();
sc.close();
//set predefined window that lines will be drawn within.
JFrame frame = new JFrame("Bresenham Algorithm");
Bresenham panel = new Bresenham();
frame.add(panel);
frame.pack();
frame.setVisible(true);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//These test cases show that lines can be drawn in any direction using the algorithm
/*
panel.brz(75,75,10,75);
panel.brz(75,75,75,10);
panel.brz(75,75,140,75);
panel.brz(75,75,75,140);
panel.brz(75,75,105,105);
panel.brz(75,75,45,45);
panel.brz(75,75,105,45);
panel.brz(75,75,45,105);
panel.brz(75,75,85,45);
panel.brz(75,75,45,85);
panel.brz(75,75,95,85);
panel.brz(75,75,85,95);
panel.brz(75,75,45,55);
panel.brz(75,75,55,45);
panel.brz(75,75,125,45);
panel.brz(75,75,45,125);
*/
Random rand = new Random();
long time = 0;
for (int i = 0; i < N; i++) {
//generate random values for line endpoints
//since the window is 500 x 500 pixels, these are the bounds of the random numbers.
int x0 = rand.nextInt(500);
int y0 = rand.nextInt(500);
int x1 = rand.nextInt(500);
int y1 = rand.nextInt(500);
long start = System.nanoTime(); //get start time before the loop
panel.brz(x0, y0, x1, y1);
long end = System.nanoTime(); //get end time to calculate how long the algorithm took
long difference = end - start;
time += difference;
}
System.out.println("Time: " + time*0.000001 + " ms");
}
// algorithm was taken from class notes and adapted on my own for all other cases
public void brz( int x0, int y0, int x1, int y1) {
int delta_y = y1 - y0;
int delta_x = x1 - x0;
int y = y0;
int x = x0;
int color = pickColor();
//first case, delta_x > delta_y and both delta_x and delta_y >0
if(delta_x > delta_y && delta_x > 0 && delta_y > 0) {
int E = 2 * (delta_y - delta_x);
int inc1 = 2 * delta_y;
int inc2 = 2 * (delta_y - delta_x);
while(x <= x1) {
canvas.setRGB(x, y, color);
if(E < 0) {
E += inc1;
}else {
y += 1;
E += inc2;
}
x += 1;
}//while
} //if delta y is bigger, there will be one pixel y on the y axis, so switch delta_x and delta_y
else if (delta_y > delta_x && delta_x >0 && delta_y > 0) {
int E = 2 * (delta_x - delta_y);
int inc1 = 2 * delta_x;
int inc2 = 2 * (delta_x - delta_y);
while(y <= y1) {
canvas.setRGB(x, y, color);
if(E < 0) {
E += inc1;
}else {
x += 1;
E += inc2;
}
y += 1;
}//while
} // if delta x == delta y
else if (delta_x == delta_y && delta_x > 0 && delta_y > 0){
int E = 0;
int inc1 = 2 * delta_y;
int inc2 = 2 * (delta_y - delta_x);
while(x <= x1) {
canvas.setRGB(x, y, color);
if(E < 0) {
E += inc1;
}else {
y += 1;
E += inc2;
}
x += 1;
}//while
} //vertical line - delta x = 0 and delta y > 0
else if(delta_x == 0 && delta_y > 0) {
while(y <= y1) {
canvas.setRGB(x, y, color);
y += 1;
}//while
} //vertical line - delta x = 0 and delta y < 0
else if(delta_x == 0 && delta_y < 0) {
while(y >= y1) {
canvas.setRGB(x, y, color);
y -= 1;
}//while
} //horizontal line - delta y = 0 and delta x > 0
else if(delta_y == 0 && delta_x > 0) {
while(x <= x1) {
canvas.setRGB(x, y, color);
x += 1;
}//while
} //horizontal line - delta y = 0 and delta x < 0
else if(delta_y == 0 && delta_x < 0) {
while(x >= x1) {
canvas.setRGB(x, y, color);
x -= 1;
}//while
} //if delta y < 0 and delta x > 0 and delta x > the ablsolute value of delta y)
else if (delta_y < 0 && delta_x > 0 && delta_x > (delta_y * -1)) {
delta_y *= -1;
int E = 2 * (delta_y - delta_x);
int inc1 = 2 * delta_y;
int inc2 = 2 * (delta_y - delta_x);
while(x <= x1) {
canvas.setRGB(x, y, color);
if(E < 0) {
E += inc1;
}else {
y -= 1;
E += inc2;
}
x += 1;
}//while
} //if delta y < 0 and delta x > 0 and delta x = the ablsolute value of delta y)
else if(delta_y < 0 && delta_x > 0 && delta_x == (delta_y * -1)){
delta_y *= -1;
int E = 0;
int inc1 = 2 * delta_y;
int inc2 = 2 * (delta_y - delta_x);
while(x <= x1) {
canvas.setRGB(x, y, color);
if(E < 0) {
E += inc1;
}else {
y -= 1;
E += inc2;
}
x += 1;
}//while
} //if delta y < 0 and delta x > 0 and delta x < the ablsolute value of delta y
else if(delta_y < 0 && delta_x > 0 && delta_x < (delta_y * -1)){
delta_y *= -1;
int E = 2 * (delta_x - delta_y);
int inc1 = 2 * delta_x;
int inc2 = 2 * (delta_x - delta_y);
while(y >= y1) {
canvas.setRGB(x, y, color);
if(E < 0) {
E += inc1;
}else {
x += 1;
E += inc2;
}
y -= 1;
}//while
} //if delta x < 0 and delta y > 0 and delta y > the ablsolute value of delta x
else if((delta_x < 0 && delta_y > 0 && delta_y > (delta_x*-1))) {
delta_x *= -1;
int E = 2 * (delta_x - delta_y);
int inc1 = 2 * delta_x;
int inc2 = 2 * (delta_x - delta_y);
while(y <= y1) {
canvas.setRGB(x, y, color);
if(E < 0) {
E += inc1;
}else {
x -= 1;
E += inc2;
}
y += 1;
}//while
} //if delta x < 0 and delta y > 0 and delta x = the ablsolute value of delta y)
else if (delta_x < 0 && delta_y > 0 && delta_y == (delta_x*-1)) {
delta_x *= -1;
int E = 0;
int inc1 = 2 * delta_y;
int inc2 = 2 * (delta_y - delta_x);
while(x >= x1) {
canvas.setRGB(x, y, color);
if(E < 0) {
E += inc1;
}else {
y += 1;
E += inc2;
}
x -= 1;
}//while
} //if delta x < 0 and delta y > 0 and delta x < the ablsolute value of delta y)
else if (delta_x < 0 && delta_y > 0 && delta_y < (delta_x*-1)) {
delta_x *= -1;
int E = 2 * (delta_y - delta_x);
int inc1 = 2 * delta_y;
int inc2 = 2 * (delta_y - delta_x);
while(x >= x1) {
canvas.setRGB(x, y, color);
if(E < 0) {
E += inc1;
}else {
y += 1;
E += inc2;
}
x -= 1;
}//while
} //both delta x and delta y < 0 and delta x < delta y
else if(delta_x < 0 && delta_y < 0 && delta_x < delta_y) {
delta_x *= -1;
delta_y *= -1;
int E = 2 * (delta_y - delta_x);
int inc1 = 2 * delta_y;
int inc2 = 2 * (delta_y - delta_x);
while(x >= x1) {
canvas.setRGB(x, y, color);
if(E < 0) {
E += inc1;
}else {
y -= 1;
E += inc2;
}
x -= 1;
}//while
} // both delta x and delta y < 0 and delta x == delta y
else if (delta_x < 0 && delta_y < 0 && delta_x == delta_y) {
delta_x *= -1;
delta_y *= -1;
int E = 0;
int inc1 = 2 * delta_y;
int inc2 = 2 * (delta_y - delta_x);
while(x >= x1) {
canvas.setRGB(x, y, color);
if(E < 0) {
E += inc1;
}else {
y -= 1;
E += inc2;
}
x -= 1;
}//while
} // both delta x and delta y < 0 and delta x > delta y
else if (delta_x < 0 && delta_y < 0 && delta_x > delta_y) {
delta_x *= -1;
delta_y *= -1;
int E = 2 * (delta_x - delta_y);
int inc1 = 2 * delta_x;
int inc2 = 2 * (delta_x - delta_y);
while(y >= y1) {
canvas.setRGB(x, y, color);
if(E < 0) {
E += inc1;
}else {
x -= 1;
E += inc2;
}
y -= 1;
}//while
}
repaint();
}
//create a bufferedimage, fill with white background
public Bresenham() {
canvas = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
fillCanvas(Color.WHITE);
}
//set correct size of window
public Dimension getPreferredSize() {
return new Dimension(canvas.getWidth(), canvas.getHeight());
}
//allow canvas to be drawn
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(canvas, null, null);
}
//make the canvas white
public void fillCanvas(Color c) {
int color = c.getRGB();
for (int x = 0; x < canvas.getWidth(); x++) {
for (int y = 0; y < canvas.getHeight(); y++) {
canvas.setRGB(x, y, color);
}
}
repaint();
}
public static int pickColor() {
//pick random color for the line, just for fun
Random random = new Random();
int s = random.nextInt(7);
Color c;
switch(s) {
case 0:
c = Color.BLACK;
break;
case 1:
c = Color.BLUE;
break;
case 2:
c = Color.MAGENTA;
break;
case 3:
c = Color.GREEN;
break;
case 4:
c = Color.RED;
break;
case 5:
c = Color.PINK;
break;
default:
c = Color.ORANGE;
break;
}
int color = c.getRGB();
return color;
}
}