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 //
// Last modified on, Monday, 7th of March, 2010 @7:12AM //
////////////////////////////////////////////////////////////////////////////
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)
// r is the radius
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)
// r is the radius
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;
while(radian <= Math.PI/2) {
x = (int)(a*(Math.cos(radian)));
y = (int)(b*(Math.sin(radian)));
//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);
radian = radian + i;
}
}
// 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);
}
};




