Â¬â€  Â¬â€  Â¬â€  Â¬â€  Â¬â€

# Linux.com

## Few functions to draw lines, circles and ellipses in Java.

These days I'm working on few games which I'm writing in Java. I needed functions to draw lines and circles etc. Instead of using the Java libraries, I wrote my own functions. Thinking may be some day, some body else  use them too I'm putting the source code to these functions here, in my blog.

```////////////////////////////////////////////////////////////////////////////
// NibblesFunctions.java                                                            //
// Written by, Sohail Qayum Malik                                              //
////////////////////////////////////////////////////////////////////////////

package Nibbles;

import java.lang.Math;
import java.awt.Graphics;

public class NibblesFunctions {

//Bresenham circle
//Read the following book at page 29...
//http://books.google.com.pk/books?id=7gT1MhI1SbIC&pg=PP3&dq=+"Computer+Graphics++"SCHAUM's+outline+series"&cd=1#v=onepage&q= "Computer Graphics  "SCHAUM's outline series"&f=false
// a and b is an origin ordinate pair(a,b)
public static void drawCircle(Graphics graphics, int a, int b, int r) {

//We'll start at the right hand side of the circle
//First point is always on the circle so error is zero and we know that x is r and y is 0
//There are only two valid moves...
//Up = x^2 + (y + 1)^2 - r^2 and Left = (x - 1)^2 + (y + 1)^2 - r^2
//Our d = Up + Left
int x = r, y = 0, d = 3 - 2*r;

// x is initially r, x will be same as y at 45(degree) angle
while(y <= x) {

// Eight way symmetry of circle
graphics.drawString(".", x + b, y + a);
graphics.drawString(".", y + b, x + a);
graphics.drawString(".", (-1)*y + b, x + a);
graphics.drawString(".", (-1)*x + b, y + a);
graphics.drawString(".", (-1)*x + b, (-1)*y + a);
graphics.drawString(".", (-1)*y + b, (-1)*x + a);
graphics.drawString(".", y + b, (-1)*x + a);
graphics.drawString(".", x + b, (-1)*y + a);

if(d < 0) // move Up = d + Up + 2
d = d + 4*y + 6;
else { // move Left = d + Left + 2
d = d - 4*(x - y) + 10;
//Since we've started at the right hand side of the circle
x = x - 1;
}

// Since we have started at top of the circle
y = y + 1;
}
}

/*
//Bresenham circle
//Read the following book at page 29...
//http://books.google.com.pk/books?id=7gT1MhI1SbIC&pg=PP3&dq=+"Computer+Graphics++"SCHAUM's+outline+series"&cd=1#v=onepage&q= "Computer Graphics  "SCHAUM's outline series"&f=false
// a and b is an origin ordinate pair(a,b)
public static void drawCircle(Graphics graphics, int a, int b, int r) {

//We'll start at the top of the circle
//First point is always on the circle so error is zero and we know that x is zero and y is r
int x = 0, y = r, d = 3 - 2*r;

// x is initially zero, x will be same as y at 45(degree) angle
while(x <= y) {

// Eight way symmetry of circle
graphics.drawString(".", x + b, y + a);
graphics.drawString(".", y + b, x + a);
graphics.drawString(".", (-1)*y + b, x + a);
graphics.drawString(".", (-1)*x + b, y + a);
graphics.drawString(".", (-1)*x + b, (-1)*y + a);
graphics.drawString(".", (-1)*y + b, (-1)*x + a);
graphics.drawString(".", y + b, (-1)*x + a);
graphics.drawString(".", x + b, (-1)*y + a);

if(d < 0) // move right
d = d + 4*x + 6;
else { // move down
d = d + 4*(x - y) + 10;
//Since we've started at the top of the circle
y = y - 1;
}

// Since we have started at top of the circle
x = x + 1;
}
}
*/

//Bresenham line
//Read chapter 3 at page 28 of the following book
//http://books.google.com.pk/books?id=7gT1MhI1SbIC&pg=PP3&dq=+"Computer+Graphics++"SCHAUM's+outline+series"&cd=1#v=onepage&q= "Computer Graphics  "SCHAUM's outline series"&f=false
//I also went through following two documents
//http://cs.fit.edu/~wds/classes/graphics/Rasterize/rasterize/rasterize.html
//http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
public static void drawLine(Graphics graphics, int x1, int y1, int x2, int y2)  {

int x, y, dx, dy, d, ystep, tmp;

//This algorithm only deals with lines having shallow slopes. When a line has steep slope then we take the advantage of the fact that steep line can be reflected across the line y = x
boolean steep = Math.abs(y2 - y1) > Math.abs(x2 - x1);

//Yes line has steep slope make it shallow
if(steep) {

//swap(x1, y1)
//Because Java for scalar types is pass by value
tmp = y1;
y1 = x1;
x1 = tmp;

//swap(x2, y2)
//Because Java for scalar types is pass by value
tmp = y2;
y2 = x2;
x2 = tmp;
}

//We always move from left to right(that is x is always incremented)
if(x1 > x2) {

//swap(x1, x2);
//Because Java for scalar types is pass by value
tmp = x2;
x2 = x1;
x1 = tmp;

//swap(y1, y2)
//Because Java for scalar types is pass by value
tmp = y2;
y2 = y1;
y1 = tmp;
}

dx = x2 - x1;
dy = Math.abs(y2 - y1);
//Initial value, the first and the last points are always on the line, so error is zero(2e=2(0)=0)
//e = dyX - dxY + c
//eR = dy(X + 1) - dxY + c = e + dy
//eD = dy(X + 1) - dx(Y + 1) + c = e + dy - dx
//d = eR + eD
d = 2*dy - dx;

//Find out if we'll increment or decrement y
if(y1 < y2)
ystep = 1;
else
ystep = -1;

//Initial values(initial ordinate pair)
x = x1;
y = y1;

while(x <= x2) {

//x is reflected as y(transitive)
if(steep)
graphics.drawString(".", y, x);
else
graphics.drawString(".", x, y);

//We only allow two moves, move to the right, or move diagonally. when we move to the right we only increment x otherwise we increment both(sign of ystep)
if(d < 0)
d = d + 2*dy;
else {

d = d + 2*dy - 2*dx;
y = y + ystep;
}

x = x + 1;
}
}

// Trigonometric method
// a = length of major axis, b = length of minor axis
// h,k ordinate pair for the center of the ellipse
// x = a * cos(0 to PI/2 radians) + h
// y = b * sin(0 to PI/2 radians) + k
// Inorder to rotate on axis, make minor greater than major
public static void drawEllipse(Graphics graphics, int h, int k, int a, int b) {

int x = 0, y = 0;

//i is the magnitude of increment to radian at each step, this should not be fixed as it is now
double radian = 0, i = 0.01;

//Ellipses have 4 way symmetry
graphics.drawString(".", x + h, y + k);
graphics.drawString(".", (-1)*x + h, y + k);
graphics.drawString(".", (-1)*x + h, (-1)*y + k);
graphics.drawString(".", x + h, (-1)*y + k);

}
}

// It is easy, no special algorithm there, just draw four lines
public static void drawRectangle(Graphics graphics, int x1, int y1, int width, int height) {

drawLine(graphics, x1, y1, x1 + width, y1);
drawLine(graphics, x1, y1 + height, x1 + width, y1 + height);
drawLine(graphics, x1, y1, x1, y1 + height);
drawLine(graphics, x1 + width, y1, x1 + width, y1 + height);
}

public static void fillRectangle(Graphics graphics, int x1, int y1, int width, int height) {

int x, y;

if(width < 2 || height < 2) {

drawRectangle(graphics, x1, y1, width, height);
return;
}

for(y = 0; y < height + 1; y++)
for(x = 0; x < width + 1; x++)
graphics.drawString(".", x1 + x, y1 + y);
}

public static void fillCircle(Graphics graphics, int a, int b, int r) {

int r1;

for(r1 = r; r1 > 0; r1--)
drawCircle(graphics, a, b, r1);
}
};```

# Sohail Qayum Malik

### Upcoming Linux Foundation Courses

1. LFD320 Linux Kernel Internals and Debugging
04 Aug » 08 Aug - Virtual
2. LFD405 Embedded Linux Development with Yocto Project
04 Aug » 07 Aug - Santa Clara, CA
3. LFD312 Developing Applications For Linux
18 Aug » 22 Aug - Virtual

View All Upcoming Courses

### Who we are ?

The Linux Foundation is a non-profit consortium dedicated to the growth of Linux.