Monday, May 4, 2009

Final Project

For my final project I made a simple game with OpenGL GLut. My original intention was to make a nice looking environment using my OBJ viewer as a starting point. The original camera movements using gluLookAt() proved adequate, and I attached an .obj shotgun to the camera. Due to technical difficulties getting textures uv mapped onto .obj files, I drew most of the environment manually, drawing several buildings into city blocks, which were then translated and rotated into 9 square blocks. I then added a ufo and a single bullet to make a quick gametype.
Use the W key and the mouse to move.
H toggles the hud
J activates player debug information, giving the player location and rotation
K activates ufo and bullet debug information, giving the ufo location, the bullet location, and the distance between them.
Although it still needs alot of work, it is not bad for only 1400 lines of code (many involved the creation of Open GL primatives.)
CLICK THE PICTURE TO DOWNLOAD AND PLAY.

Credits:
Shotgun .obj file:
http://www.turbosquid.com/FullPreview/Index.cfm/ID/308701

Mouse Movement:
http://www.lighthouse3d.com/opengl/glut/index.php?9

Loading Textures:
http://www.nullterminator.net/gltexture.html

Drawing to Viewscreen, Hud, Text to Screen:
http://www.songho.ca/opengl/gl_vbo.html

Obj file specs:
http://people.sc.fsu.edu/~burkardt/txt/obj_format.txt

Other reference:
Open GL SuperBible

Thursday, April 2, 2009

Project 2 Obj Viewer

Here are some screenshots of my .obj viewer. The first screenshot is of a skyscraper model. I included an algorithm to calculate the face normals. I just set them perpendicular to the face plane. My program only handles models that have been triangulated.

The second screenshot shows the teapot model, which I am sure everyone is tired of seeing. The shot on the left shows the teapot with normals turned on, and the shot on the right shows normals turned off.
The final screenshot shows the F22 model I did for CSC 220. Maya does not seem to "wind" all of the faces counterclockwise when it exports .obj files, so some of the normals are pointing in the wrong direction. The first shot shows the F22 with normals turned off. I also changed the colors using the R G and B keys.


Finally here is a link to my final version of the
OBJViewer. This version only works when you drag and drop a .obj file onto it. Models that are not triangulated will not look good.
The camera does not work perfectly, sometimes it will turn completely around.

Keyboard Instructions:
HOME: Resets camera to origin
Arrow UP/DOWN: moves the camera forwards and backwards in whatever direction you are facing
Arrow LEFT/RIGHT: Rotates left and right
INSERT/END: Pan left and right
R G B: change colors (reduces r g and b values)
M: toggle background black/white
N: toggle faces normals

Thanks to: lighthouse3D for this tutorial on using a vector for camera control with gluLookAt();
Thanks to: Richard Sabbarton for writing this article on Calculating normals

Saturday, March 28, 2009

Web Exercise 2

Here is the sample from the OpenGl redbook running, This screenshot was taken after I messed around with gluPerspective():


Here are some examples of my simple camera movement system. I was able to get the camera to pan left and right, up and down, and also tilt left and right and up and down. I used the home key to reset the camera to the origin. I made a simple model of an airplane to demonstrate my camera. Here are pictures of the plane after various camera movements:



// Camera4.cpp
// Demonstrates Camera Movement
// CSC 370 March 2009
// Michael Haizlip

#include
#include

// Rotation amounts
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;
static GLfloat zRot = 0.0f;
static GLfloat zMove= 0.0f;
static GLfloat yMove= 0.0f;
static GLfloat xMove= 0.0f;


// Change viewing volume and viewport. Called when window is resized
void ChangeSize(int w, int h)
{
GLfloat fAspect;
// Prevent a divide by zero
if(h == 0)
h = 1;

// Set Viewport to window dimensions
glViewport(0, 0, w, h);

fAspect = (GLfloat)w/(GLfloat)h;

// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Produce the perspective projection
gluPerspective(60.0f, fAspect, 1.0, 400.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}


// This function does any needed initialization on the rendering
// context. Here it sets up and initializes the lighting for
// the scene.
void SetupRC()
{
// Light values and coordinates
GLfloat whiteLight[] = { 0.45f, 0.45f, 0.45f, 1.0f };
GLfloat sourceLight[] = { 0.25f, 0.25f, 0.25f, 1.0f };
GLfloat lightPos[] = { -50.f, 25.0f, 250.0f, 0.0f };

glEnable(GL_DEPTH_TEST); // Hidden surface removal
glFrontFace(GL_CCW); // Counter clock-wise polygons face out
glDisable(GL_CULL_FACE); // Do not calculate inside of jet

// Enable lighting
glEnable(GL_LIGHTING);

// Setup and enable light 0
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,whiteLight);
glLightfv(GL_LIGHT0,GL_AMBIENT,sourceLight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,sourceLight);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
glEnable(GL_LIGHT0);

// Enable color tracking
glEnable(GL_COLOR_MATERIAL);

// Set Material properties to follow glColor values
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

// Black blue background
glClearColor(0.0f, 1.0f, 1.0f, 1.0f );
}

// Respond to arrow keys
void SpecialKeys(int key, int x, int y)
{
//Move Forwards and Backwards
if(key == GLUT_KEY_UP)
zMove += 5.0f;

if(key == GLUT_KEY_DOWN)
zMove -= 5.0f;

//Pan left and right
if(key == GLUT_KEY_RIGHT)
{
xMove -= 5.0f;
xRot -= 5.0f;
}
if(key == GLUT_KEY_LEFT)
{
xMove += 5.0f;
xRot += 5.0f;
}
//pan straight up and down
if(key == GLUT_KEY_PAGE_UP)
{
yRot += 5.0f;
yMove += 5.0f;
}
if(key == GLUT_KEY_PAGE_DOWN)
{
yRot -= 5.0f;
yMove -= 5.0f;
}
//reset to home
if(key == GLUT_KEY_HOME)
{
xRot = 0.0f;
yRot = 0.0f;
zRot = 0.0f;
zMove= 0.0f;
yMove= 0.0f;
xMove= 0.0f;
}
//rotate right
if(key == GLUT_KEY_INSERT)
xRot += 5.0f;
//rotate left
if(key == GLUT_KEY_END)
xRot -= 5.0f;

// Refresh the Window
glutPostRedisplay();
}


// Called to draw scene
void RenderScene(void)
{
float fZ,bZ;

// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

fZ = 100.0f;
bZ = -100.0f;

glLoadIdentity();

gluLookAt (xMove, yMove, zMove, xRot, yRot, zRot, 0.0, 1.0, 0.0);

glScalef (0.5,0.5,0.5);
// Set material color, Red
glColor3f(1.0f, 1.0f, 1.0f);

glBegin(GL_QUADS);

// Top Panel
glNormal3f(0.0f, 1.0f, 0.0f);
glVertex3f(-3.0f, 5.0f, fZ);
glVertex3f(3.0f, 5.0f, fZ);
glVertex3f(3.0f, 5.0f,bZ);
glVertex3f(-3.0f, 5.0f, bZ);

// Bottom Panel
glNormal3f(0.0f, -1.0f, 0.0f);
glVertex3f(-3.0f, -5.0f, fZ);
glVertex3f(-3.0f, -5.0f, bZ);
glVertex3f(3.0f, -5.0f,bZ);
glVertex3f(3.0f, -5.0f, fZ);

glNormal3f(1.0f, 1.0f, 0.0f);
glVertex3f(-6.0f, 0.0f, fZ);
glVertex3f(-3.0f, 5.0f, fZ);
glVertex3f(-3.0f, 5.0f, bZ);
glVertex3f(-6.0f, 0.0f,bZ);

glNormal3f(-1.0f, 1.0f, 0.0f);
glVertex3f(-3.0f, -5.0f, fZ);
glVertex3f(-6.0f, 0.0f, fZ);
glVertex3f(-6.0f, 0.0f,bZ);
glVertex3f(-3.0f, -5.0f, bZ);

glNormal3f(1.0f, -1.0f, 0.0f);
glVertex3f(3.0f, 5.0f, fZ);
glVertex3f(6.0f, 0.0f, fZ);
glVertex3f(6.0f, 0.0f,bZ);
glVertex3f(3.0f, 5.0f, bZ);

glNormal3f(-1.0f, -1.0f, 0.0f);
glVertex3f(6.0f, 0.0f, fZ);
glVertex3f(3.0f, -5.0f, fZ);
glVertex3f(3.0f, -5.0f, bZ);
glVertex3f(6.0f, 0.0f,bZ);

glEnd();

glBegin(GL_TRIANGLES);

glNormal3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, -120.0f);
glVertex3f(3.0f, 5.0f, bZ);
glVertex3f(6.0f, 0.0f, bZ);

glNormal3f(1.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 0.0f, -120.0f);
glVertex3f(-3.0f, 5.0f, bZ);
glVertex3f(3.0f, 5.0f, bZ);

glNormal3f(-1.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 0.0f, -120.0f);
glVertex3f(-6.0f, 0.0f, bZ);
glVertex3f(-3.0f, 5.0f, bZ);

glNormal3f(0.0f, -1.0f, 0.0f);
glVertex3f(0.0f, 0.0f, -120.0f);
glVertex3f(6.0f, 0.0f, bZ);
glVertex3f(3.0f, -5.0f, bZ);

glNormal3f(-1.0f, -1.0f, 0.0f);
glVertex3f(0.0f, 0.0f, -120.0f);
glVertex3f(3.0f, -5.0f, bZ);
glVertex3f(-3.0f, -5.0f, bZ);

glNormal3f(1.0f, -1.0f, 0.0f);
glVertex3f(0.0f, 0.0f, -120.0f);
glVertex3f(-3.0f, -5.0f, bZ);
glVertex3f(-6.0f, 0.0f, bZ);

glEnd();

glBegin(GL_QUADS);

glColor3f(0.0f, 0.0f, 0.0f);
glVertex3f(6.0f, 0.0f, fZ);
glVertex3f(60.0f, 0.0f, fZ);
glVertex3f(60.0f, 0.0f, 40.0f);
glVertex3f(6.0f, 0.0f,-40.0f);

glVertex3f(-6.0f, 0.0f,-40.0f);
glVertex3f(-60.0f, 0.0f, 40.0f);
glVertex3f(-60.0f, 0.0f, fZ);
glVertex3f(-6.0f, 0.0f, fZ);

glVertex3f(0.0f, 0.0f,fZ);
glVertex3f(0.0f, 50.0f, fZ);
glVertex3f(0.0f, 50.0f, 80.0f);
glVertex3f(0.0f, 0.0f, 50.0f);

glEnd();

// Buffer swap
glutSwapBuffers();
}

int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("Perspective Projection");
glutReshapeFunc(ChangeSize);
glutSpecialFunc(SpecialKeys);
glutDisplayFunc(RenderScene);
SetupRC();
glutMainLoop();

return 0;
}

Friday, March 27, 2009

Web Excersise

The most interesting thing I learned was in the PyOpenGL article. It was the breakdown of the hierarchy for drawing geometry. I think for my project I will try to use the Vertex Buffer Objects. It seems better to me to keep the objects in video card memory, then call them when you need them. The Unreal Engine uses this technique for rendering static meshes. If you store a model in video card memory, you can then draw it onscreen in many different places with a lot less overhead.
That OpenGL is available for Processing is also very interesting. I wish I had known this when I started working on my SuperShape Project.

Here is a screenshot of my Bezier curve program implemented in OpenGL:


For the perspective example, I first "cut" all of the 4 inside faces, and duplicated them, then added faces in the middle, creating a kind of wall in the center of the "hallway." Then I moved the 4 outside faces to make a diamond shape, and I added triangles to fill out the front and back faces. I also played with the colors. Here is a shot of the front, with red white and blue colors, and the back, with all 4 primary and secondary colors:



Finally here is a picture where I put in ridiculous values for the normals, just trying to figure out how they worked. I included this picture also because it shows how I added triangles to fill out those front and back faces:

Tuesday, March 3, 2009

Project 1: Supershape Monsters

Here are my processing monsters:

First I started off generating shape with the superformula:
Next I started generating many shapes and having them move around the screen, detect collision etc:
Then I added some color variation by varying the saturation from the center of each creature towards its outside radius:

Finally I added various random eyeball characteristics to give them personality:

Friday, February 27, 2009

How to get glut working in Dev C++

If you are having trouble getting this program working in Dev C++ in Windows

Step 1: Follow these instructions:
http://www.astahost.com/info.php/installing-glut-dev-c_t14192.html

Step2:
Click File>New>Project
In the tabs across the top click "Multimedia" then click on the icon with the words glut under it.
Save the project file.
This creates a new project called "main.cpp"
You can run it and check it out if you want but then:
Click "Save As" and save the file but rename it simple. cpp
Then copy all of the code from the original simple.cpp and paste it over all the code in this file.
Comment out this line:
#include "../../shared/gltools.h"

use these two lines instead (I stole them from that main.cpp it created earlier):

#include <GL/glut.h>
#include <stdlib.h>

Now compile and run it. No really. Do it.

Saturday, February 14, 2009

Transformations: Homework 4

Here is an image from the first part of Homework 4, rotating a triangle:


The Code:
int x1, x2, x3, y1, y2, y3;
Point p1, p2, p3, temp1, temp2, temp3, centroid;
float a,theta;

void setup()
{
size(720, 480);
background(0);
stroke(255);
p1=new Point(0, 0);
p2=new Point(0 ,0);
p3=new Point(0 ,0);
temp1=new Point(0, 0);
temp2=new Point(0 ,0);
temp3=new Point(0 ,0);
centroid=new Point(0 ,0);
a=90;
mousePressed();
}

void mousePressed()
{
background(0);
x1=int(random(720));
x2=int(random(720));
x3=int(random(720));
y1=int(random(480));
y2=int(random(480));
y3=int(random(480));

p1=new Point(x1,y1);
p2=new Point(x2 ,y2);
p3=new Point(x3 ,y3);

centroid = new Point((p1.x+p2.x+p3.x)/3,(p1.y+p2.y+p3.y)/3);

//move all points to the origin TEMPORARLILY
temp1=new Point(p1.x-centroid.x, p1.y-centroid.y);
temp2=new Point(p2.x-centroid.x, p2.y-centroid.y);
temp3=new Point(p3.x-centroid.x, p3.y-centroid.y);

}

void draw()
{
background(0);
frameRate(60);
stroke(255);
a = (mouseX / (float) width) * 360f;
// Convert it to radians
theta = radians(a);

//rotate the temporary points around the origin
p1=rotatePoint(temp1,theta);
p2=rotatePoint(temp2,theta);
p3=rotatePoint(temp3,theta);

//now move them back to OG location
p1=new Point(p1.x+centroid.x, p1.y+centroid.y);
p2=new Point(p2.x+centroid.x, p2.y+centroid.y);
p3=new Point(p3.x+centroid.x, p3.y+centroid.y);

//draw it
point(centroid.x, centroid.y);
myTri(p1,p2,p3);
}


void myTri(Point a, Point b, Point c)
{
line(a.x,a.y,b.x,b.y);
line(b.x,b.y,c.x,c.y);
line(c.x,c.y,a.x,a.y);
}


Point rotatePoint(Point p, float angle)
{
float[] coord = new float[3];
int[] newCoord= new int[3];
float[][] matrix= new float[3][3];
float c=cos(angle);
float s=sin(angle);
Point myPoint=new Point(0,0);

//setup the 3x1 matrix for the point
coord[0]=p.x;
coord[1]=p.y;
coord[2]=1;

//setup the 3x3 matrix for the rotation
matrix[0][0]=c;
matrix[0][1]=s;
matrix[0][2]=0;
matrix[1][0]=-s;
matrix[1][1]=c;
matrix[1][2]=0;
matrix[2][0]=0;
matrix[2][1]=0;
matrix[2][2]=1;

newCoord=matrixMult(matrix, coord);
myPoint.x=newCoord[0];
myPoint.y=newCoord[1];
return myPoint;

}

int[] matrixMult(float matA[][], float matB[])
{
float[] temp= new float[3];
int[] ntemp= new int[3];
temp[0]=0;
temp[1]=0;
temp[2]=0;
for(int i=0; i<3; j="0;" ntemp="int(temp);">

Here are some interesting images I made by rotating several randomly colored triangles, while changing the brightness each time the draw function ran:






The Code:
int x1, x2, x3, y1, y2, y3;
final int num=5;
Point[] p1=new Point[num];
Point[] p2=new Point[num];
Point[] p3=new Point[num];
Point[] temp1=new Point[num];
Point[] temp2=new Point[num];
Point[] temp3=new Point[num];
Point[] centroid=new Point[num];
int h=0;
int s=0;
int v=0;
color c=color(h, s, v);

float a,theta;

void setup()
{
size(720, 480);
background(0);
stroke(255);
colorMode(HSB, 255);
for(int i=0; i255)
v=0;
color c= color(h, s, v);
stroke(c);
point(centroid[i].x, centroid[i].y);
myTri(p1[i],p2[i],p3[i]);
}
}


void myTri(Point a, Point b, Point c)
{
line(a.x,a.y,b.x,b.y);
line(b.x,b.y,c.x,c.y);
line(c.x,c.y,a.x,a.y);
}


Point rotatePoint(Point p, float angle)
{
float[] coord = new float[3];
int[] newCoord= new int[3];
float[][] matrix= new float[3][3];
float c=cos(angle);
float s=sin(angle);
Point myPoint=new Point(0,0);

//setup the 3x1 matrix for the point
coord[0]=p.x;
coord[1]=p.y;
coord[2]=1;

//setup the 3x3 matrix for the rotation
matrix[0][0]=c;
matrix[0][1]=s;
matrix[0][2]=0;
matrix[1][0]=-s;
matrix[1][1]=c;
matrix[1][2]=0;
matrix[2][0]=0;
matrix[2][1]=0;
matrix[2][2]=1;

newCoord=matrixMult(matrix, coord);
myPoint.x=newCoord[0];
myPoint.y=newCoord[1];
return myPoint;

}

int[] matrixMult(float matA[][], float matB[])
{
float[] temp= new float[3];
int[] ntemp= new int[3];
temp[0]=0;
temp[1]=0;
temp[2]=0;
for(int i=0; i<3; j="0;" ntemp="int(temp);">


Finally here is another image I made using pushMatrix() and popMatrix();
They especially made it easy to return to the middle of the screen after each iteration of a loop:




The Code:

int h=0;
int s=0;
int v=0;
color c=color(h, s, v);
int scal=0;
int rot=0;

void setup(){
size(720, 480);
background(0,0,0);
colorMode(HSB, 255);
noLoop();
}

void draw(){
//just draw colored rectangles in each quadrant
randomColor();
rect(0,0,width/2, height/2);
randomColor();
rect(width/2, height/2,width/2, height/2);
randomColor();
rect(0,height/2,width/2, height/2);
randomColor();
rect(width/2,0,width/2, height/2);

//push Matrix, then move to middle of screen
pushMatrix();

translate(width/2, height/2);

for(int j=0; j<4; i="10;" j="0;" i="10;" h="int(random(200));" s="int(random(250));" v="int(random(255));" c="color(h,s,v);">

Sunday, February 1, 2009

Homework 3

Part 1:
For the interactive Bezier Curve program, check the previous post.
Instead of showing a picture of my first program that drew triangles without clipping, here is a picture of the nearly finished program which first drew the complete triangles in green, then drew the clipped sections in red. I used this for debugging.
Here is a pic of the final version with fully implemented Cohen-Sutherland clipping:
Here is the code:

int x1, x2, x3, y1, y2, y3;
int xmax=(720/4)*3;
int xmin=720/4;
int ymax=(480/4)*3;
int ymin=480/4;

void draw(){
}

void setup() {
size(720, 480);
background(255,255,255);
stroke(0,0,255);
rect(xmin, ymin, 360,240);
stroke(0,0,0);
fiveTriangles();
}

void fiveTriangles(){
for(int i=0; i<5; i++){
x1=int(random(720));
x2=int(random(720));
x3=int(random(720));
y1=int(random(480));
y2=int(random(480));
y3=int(random(480));

Point p1=new Point(x1, y1);
Point p2=new Point(x2 ,y2);
Point p3=new Point(x3 ,y3);

myTri(p1, p2,p3);
}
}

void myTri(Point a, Point b, Point c){
stroke(0,255,0);
line(a.x,a.y,b.x,b.y);
line(b.x,b.y,c.x,c.y);
line(c.x,c.y,a.x,a.y);
stroke(255,0,0);

myLine(a,b);
myLine(b,c);
myLine(c,a);

}

void myLine(Point p1, Point p2){
int pCode=verify(p1);
int qCode=verify(p2);
if( (pCode & qCode)!=0 ) {
println("1) outside screen DONT DRAW");
}
else if( (pCode | qCode) == 0 )
{
line(p1.x, p1.y, p2.x, p2.y);
println("2) inside screen DRAW IT");
}
else
{
println("3) Gotta CLIP IT....");
clipLine(p1,p2);

}

}

void clipLine(Point P0, Point P1){
int outCode0=verify(P0);
int outCode1=verify(P1);
int x=P0.x;
int y=P0.y;
int x0=P1.x;
int y0=P1.y;

while((outCode0 | outCode1)!=0)
{
println("outCode0 | outCode1 = "+(outCode0 | outCode1)+"while loop");
//outCode0 = verify(P0);
//outCode1 = verify(P1);

if(outCode0 == 0)
{
println("switching P and Q");
Point tempPt; int tempCode;
tempPt = P0;
P0= P1;
P1 = tempPt;
tempCode = outCode0;
outCode0 = outCode1;
outCode1 = tempCode;
tempCode=x;
x=x0;
x0=tempCode;
tempCode=y;
y=y0;
y0=tempCode;
}
if( (outCode0 & 1) != 0 )
{
println("outCode0 & 1 = "+(outCode0 & 1)+"clip at BOTTOM");
x = P0.x + (P1.x - P0.x)*(ymax - P0.y)/(P1.y - P0.y);
y = ymax;
outCode0=verify(x,y);
}
else
if( (outCode0 & 2) != 0 )
{
println("outCode0 & 2 = "+(outCode0 & 2)+"clip at TOP");
x=P0.x + (P1.x - P0.x)*(ymin - P0.y)/(P1.y - P0.y);
y = ymin;
outCode0=verify(x,y);
}
else
if( (outCode0 & 4) != 0 )
{
println("outCode0 & 4 = "+(outCode0 & 4)+"clip at RIGHT");
y =P0.y + (P1.y - P0.y)*(xmax - P0.x)/(P1.x - P0.x);
x = xmax;
outCode0=verify(x,y);
}
else
if( (outCode0 & 8) != 0 )
{
println("outCode0 & 8 = "+(outCode0 & 8)+"clip at LEFT");
y = P0.y + (P1.y - P0.y)*(xmin - P0.x)/(P1.x - P0.x);
x = xmin;
outCode0=verify(x,y);
}
//outCode0 = verify(P0);
//outCode1 = verify(P1);
}
println("FINALLY clipping done, drawing line!!!");
line(x, y, x0, y0);
}

int verify(Point p)
{
int bits=0;
if(p.x bits +=8;
if(p.x>xmax)
bits +=4;
if(p.y bits +=2;
if(p.y>ymax)
bits +=1;

String s=binary(bits,4);
println(s);
return bits;
}

int verify(int x, int y)
{
int bits=0;
if(x bits +=8;
if(x>xmax)
bits +=4;
if(y bits +=2;
if(y>ymax)
bits +=1;

String s=binary(bits,4);
println(s);
return bits;
}



Part 2

For my project I propose a program that will create creatures that have a recognizable structure, but are also created using some random values so that no two would be alike. This concept could be taken further by making the program interactive, so that if you click on two of the creatures you would get a third creature that "inherits" characteristics of both. The creatures would be drawn using primitive lines, circles, curves etc but would be detailed enough to look good. Here is a picture of a NodeBox project called Aquatics which inspired this idea. I would want to implement it in Processing rather than NodeBox because I don't have a Mac. Click on the link to view the original project page.

Tuesday, January 27, 2009

Bezier Curves

The following is from an interactive program I wrote to generate Bezier curves. The first click of the mouse draws a point. The second click draws a parametric line. The third click draws a Quadratic Bezier curve, the fourth click draws a Cubic Bezier curve, and the fifth click clears the screen and starts all over again.

Click the picture below open up the application in a new page:




Here is the code:

int pointNum=0;
int x0=0;
int y0=0;
int x1=0;
int y1=0;
int x2=0;
int y2=0;

void setup() {
size(400, 400);
stroke(255);
background(192, 64, 0);
}

void mouseReleased(){
if (pointNum==0){
x0=mouseX;
y0=mouseY;
point(x0,y0);
pointNum=1;
println("point0");

}
else if (pointNum==1){
paraLine(x0,y0,mouseX,mouseY);
x1=mouseX;
y1=mouseY;
pointNum=2;
println("point1");
}
else if (pointNum==2){
background(192, 64, 0);
quadBez(x0,y0,x1,y1,mouseX,mouseY);
x2=mouseX;
y2=mouseY;
pointNum=3;
}
else if(pointNum==3){
background(192, 64, 0);
cubBez(x0,y0,x1,y1,x2,y2,mouseX,mouseY);
pointNum=4;
}
else{
background(192, 64, 0);
pointNum=0;
}

}

void paraLine(int x0,int y0,int x1,int y1){
float x=0;
float y=0;
for(float t=0; t<=1; t=t+.001) { x=x0+(t*(x1-x0)); y=y0+(t*(y1-y0)); point(int(x),int(y)); } } void quadBez(int x0,int y0,int x1,int y1, int x2, int y2){ float x=0; float y=0; for(float t=0; t<=1; t=t+.001) { x=(pow((1-t),2)*x0)+(2*(1-t)*(t*x1))+(pow(t,2)*x2); y=(pow((1-t),2)*y0)+(2*(1-t)*(t*y1))+(pow(t,2)*y2); point(int(x),int(y)); } } void cubBez(int x0,int y0,int x1,int y1, int x2, int y2, int x3, int y3){ float x=0; float y=0; for(float t=0; t<=1; t=t+.001) { x=(pow((1-t),3)*x0)+(3*(pow((1-t), 2))*(t*x1))+(3*(1-t)*(pow(t,2)*x2))+(x3*pow(t,3)); y=(pow((1-t),3)*y0)+(3*(pow((1-t), 2))*(t*y1))+(3*(1-t)*(pow(t,2)*y2))+(y3*pow(t,3)); point(int(x),int(y)); } }

Thursday, January 15, 2009

Bresenham’s line algorithm


Here is a line created using Bresenham’s line algorithm.




Here is the code that drewdit:
void myLine(int x0, int y0, int x1, int y1){

//setup variables
int deltax=x1-x0;
int deltay=y1-y0;
float error;
int xstep, ystep;

//if y slopes down
if(deltay<0){ deltay="-deltay;" ystep="-1;" ystep="1;" deltax="-deltax;" xstep="-1;" xstep="1;">deltay){
error=deltay - (deltax>>1);
while (x0 != x1) {
if (error >= 0) {
y0 += ystep;
error -= deltax;
}
x0 += xstep;
error += deltay;
point( x0, y0);
}
} else {
error = deltax - (deltay >>1);
while (y0 != y1) {
if (error >= 0) {
x0 += xstep;
error -= deltay;
}
y0 += ystep;
error += deltax;
point( x0, y0);
}

}
}



Here is a web made using that same line algorithm followed by the code that generated the web:


void web(int num){
int size=500;
int skip=size/num;
int x1=0;
int y1=0;
int x2=0+skip;
int y2=size;

for(int i=0;i<=size; i=i+skip){ myLine(x1,y1,x2,y2); y1+=skip; x2+=skip; } }



Finally here is a circle based on the same algorithm:

and here is some code for your face to stare at:

void myCircle(int x, int y, int rad)
{

int invRad=1-rad;
int diax=1;
int diay=-2*rad;
int x1=0;
int y1=rad;

//draw n/s/e/w points
point(x,y+rad);
point(x,y-rad);
point(x+rad,y);
point(x-rad,y);

while(x1=0)
{
y1--;
diay += 2;
invRad += diay;
}
x1++;
diax+=2;
invRad+=diax;
point(x+x1, y+y1);
point(x-x1, y+y1);
point(x+x1, y-y1);
point(x-x1, y-y1);
point(x+y1, y+x1);
point(x-y1, y+x1);
point(x+y1, y-x1);
point(x-y1, y-x1);
}


}


Thursday, January 8, 2009

Homework 1....Doh!

Here is an image of Homer Simpson created using the Processing Graphics Environment.
And Here is the code:

size(200,200);
background(65,198,226);
noStroke();
fill(249, 200, 50);
rect(60,50,65,50);
ellipseMode(CORNER);
ellipse(60,25,65,50);
rect(75,100,50,50);
fill(178,138,16);
arc(50,90,60,50,PI,0);
arc(60,90,50,40,0,PI);
fill(255,255,255);
stroke(0);
ellipse(50,60,26,26);
noStroke();
fill(249, 200, 50);
ellipse(50,81,15,15);
rect(55,81,45,15);
ellipse(116,84,15,15);
fill(255,255,255);
stroke(0);
ellipse(70,60,26,26);
fill(0,0,0);
ellipse(57,72,3,3);
ellipse(83,72,3,3);
line(60,115,80,115);
noFill();
arc(80,18,25,20,PI,0);
arc(90,20,25,20,PI,0);
line(116,84,120,70);
line(120,70,124,84);
line(124,84,129,70);
line(129,70,132,84);