Andrew Yenalavitch
Homework 1
CSE 420 - Fall 2014
1.) ( 20 points ) In the class, we have discussed how to draw a line given by y = m x + b using
Besenham's algorithm with |m| ≤ 1. Extend the algorithm to include the case |m| > 1. Implement the
algorithm for all the cases of |m| ≤ 1 and |m| > 1. Test your program by drawing the following lines
a.) from ( 20, 20 ) to ( 300, 60 )
b.) from ( 20, 20 ) to ( 60, 300 )
c.) from ( 20, 20 ) to ( 300, -60 )
d.) from ( 20, 20 ) to ( -300, 60 )
I used a series of if statements to swap values before plotting depending on the slope and direction of the
input. Here is the output for:
a) (20,20) to (300,60)
b) (20,20) to (60,300)
c) (20,20) to (300, -60)
d) (20,20) to (-300,60)
Source code:
#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
void init(void)
{
glClearColor(1.0,1.0,1.0,0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(-500.0,500.0,-500.0,500.0);
}
void setPixel(GLint x,GLint y)
{
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
}
void line()
{
int x0 = 20, y0 = 20, xn = -300, yn = 60, x, y;
int
dx, dy,
//deltas
pk,
//decision parameter
k;
//looping variable
glClear(GL_COLOR_BUFFER_BIT);
glColor3f( 0, 0, 0);
setPixel(x0, y0);
//plot first point
// difference between starting and ending points
dx = xn - x0;
dy = yn - y0;
double m = dy/dx;
x = x0;
y = y0;
pk = 2 * dy - dx;
if ( m < 0 ) {
dy = -dy;
for ( k = 0; k < dx+1; ++k ) {
if ( pk < 0 ) {
pk = pk + 2 * dy;
} else {
pk = pk + 2*dy - 2*dx;
--y;
}
++x;
setPixel( x, y );
}
}
if ( m > 1 ) {
dx = yn - y0;
dy = xn - x0;
x = y0;
y = x0;
for ( k = 0; k < dx-1; ++k ) {
if ( pk < 0 ) {
pk = pk + 2 * dy;
} else {
pk = pk + 2*dy - 2*dx;
++y;
}
++x;
setPixel( y, x );
}
}
if ( (m <= 1 && m >= 0) && (xn > 0)){
for ( k = 0; k < dx-1; ++k ) {
if ( pk < 0 ) {
pk = pk + 2 * dy;
} else {
pk = pk + 2*dy - 2*dx;
++y;
}
++x;
setPixel( x, y );
}
}
if ( (m <= 1 && m >= 0) && (xn < 0) ) {
dx = -dx;
pk = 2 * dy - dx;
for ( k = 0; k > -dx+1; --k ) {
if ( pk < 0 ) {
pk = pk + 2 * dy;
}
else {
pk = pk + 2*dy - 2*dx;
++y;
}
--x;
setPixel( x, y );
}
}
glFlush();
}
int main(int argc,char **argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(0,0);
glutInitWindowSize(500,500);
glutCreateWindow("BLineMod");
init();
glutDisplayFunc( line );
glutMainLoop();
return 0;
}
2.) ( 10 points ) Use OpenGL to draw a dot plot of the function f(x) = e-|x|sin ( 2πx ), where it is known
that as x varies from xlow to xhigh, f(x) takes on values between from ylow to yhigh. Find the appropriate
scaling and translation factors so that the dots will lie properly in a screen window with width W pixels
and height H pixels.
I used OpenGL to create a modified version of the plots program. It scales the function to fill the window
based on inputs xlow and xhigh. Here are screenshots of 3 different combinations of xlow and xhigh.
xlow = 0 and xhigh = 4
xlow = -4 and xhigh = 4
xlow = 0 and xhigh = 10
Source code:
#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
using namespace std;
const int screenWidth = 640;
const int screenHeight = 480;
// width of the screen window in pixels
// height of the screen window in pixels
void init(void) {
glClearColor(1.0,1.0,1.0,0.0);
// the background color is white
glColor3f(0.0f, 0.0f, 0.0f);
// the drawing color is black
glPointSize(2.0);
// a 'dot' is 2 by 2 pixels
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, screenWidth, 0.0, screenHeight);
}
double f ( double x ) {
double y = exp(-abs(x)) * sin(2 * 3.14159265 * x);
return y;
}
void mySine(void)
{
glClear(GL_COLOR_BUFFER_BIT);
double A, B, C, D, x, y, xlow, xhigh;
int sx, sy;
xlow = 0;
xhigh = 10;
A = screenWidth / (xhigh - xlow);
B = A * abs(xlow);
C = -screenHeight / 2;
D = screenHeight / 2;
glBegin(GL_POINTS);
for(x = xlow; x < xhigh ; x += 0.001)
{
y = f(x);
sx = (int) ( A * x + B );
sy = (int) ( C * y + D );
glVertex2i(sx, sy);
}
glEnd();
glFlush();
// send all output to display
}
int main(int argc,char **argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(0,0);
glutInitWindowSize(500,500);
glutCreateWindow("mySine");
init();
glutDisplayFunc( mySine );
glutMainLoop();
return 0;
}
3.) ( 10 points )Use SDL and the Surface class supplied in the web site to draw a line passing through the
center of the screen. Animate the rotation of the line about the center for several rounds. ( Note that a
user at any instance only sees a single line on the screen. )
I used SDL_Delay() and surf.clearScreen() to clear lines in set intervals, simulating a spinning line.
Source code:
// spinline.cpp
#include <SDL/SDL.h>
#include <stdlib.h>
#include <stdio.h>
#include "draw.h"
#include "surface.h"
//draw a spinning line
void spinLine ( Surface &surf, int x, int y )
{
surf.moveTo( x - 200, y );
surf.lineTo( x + 200, y );
surf.updateSurface();
SDL_Delay ( 1000 );
surf.clearScreen();
surf.moveTo( x - 175, y - 100);
surf.lineTo( x + 175, y + 100);
surf.updateSurface();
SDL_Delay ( 1000 );
surf.clearScreen();
surf.moveTo( x - 100, y - 175 );
surf.lineTo( x + 100, y + 175 );
surf.updateSurface();
SDL_Delay ( 1000 );
surf.clearScreen();
surf.moveTo( x , y - 200);
surf.lineTo( x , y + 200);
surf.updateSurface();
SDL_Delay ( 1000 );
surf.clearScreen();
surf.moveTo( x + 100, y - 175 );
surf.lineTo( x - 100, y + 175 );
surf.updateSurface();
SDL_Delay ( 1000 );
surf.clearScreen();
surf.moveTo( x + 175, y - 100 );
surf.lineTo( x - 175, y + 100);
surf.updateSurface();
SDL_Delay ( 1000 );
surf.clearScreen();
surf.moveTo( x + 200, y );
surf.lineTo( x - 200, y );
surf.updateSurface();
SDL_Delay ( 1000 );
surf.clearScreen();
}
int main()
{
const int VWIDTH = 640;
const int VHEIGHT = 480;
const Point center ( VWIDTH/2, VHEIGHT/2 );
//center of screen
Surface surf( VWIDTH, VHEIGHT, (char *) "Spinning Line" );
surf.setBackgroundColor ( 0xff, 0xff, 0xff );
surf.setColor ( 0, 0, 0 );
spinLine ( surf, center.x, center.y );
return 1;
//set background to white
//using black drawing color
}
4.) Use turtle graphics or/and other means to reproduce any five of the following images ( extra credit for
extra reproduction ).
The images on the homework page are really low resolution, which makes it hard see some shapes, but I
feel I made all 5 correctly.
Image 1) I did some research into the recursive Dragon curve algorithm and created this using turtle
graphics via the Canvas class:
Source code:
#include "canvas.h"
Canvas cvs ( 500, 500, "Dragon" );
void dragon( int n )
{
if (n == 0)
cvs.forward(.2,1);
else {
dragon (n-1);
cvs.turn(-90);
for (int i = n - 2; i >= 0; i--) {
dragon(i);
cvs.turn(90);
}
cvs.forward(.2,1);
}
}
void display(void)
{
cvs.clearScreen();
cvs.setBackgroundColor(0, 0, 0);
cvs.setColor(1.0, 0.5, 0);
cvs.moveTo(-2.0, 0.0);
cvs.turnTo ( 90.0 );
dragon ( 10 );
}
Image 2) I created the seven hexagon/six triangle image using OpenGl:
Source code:
#include <GL/glut.h>
//initialization
void init( void )
{
glClearColor( 1.0, 1.0, 1.0, 0.0 );
//get white background color
glColor3f( 0.0f, 1.0f, 0.0f );
//set drawing color
glPointSize( 4.0 );
//a dot is 4x4
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
//replace current matrix with identity matrix
gluOrtho2D( 0.0, 500.0, 0.0, 500.0 );
}
void display( void )
{
int x=200, y=200;
glClear( GL_COLOR_BUFFER_BIT );
glPolygonMode( GL_FRONT, GL_FILL );
//Here are the 7 hexagons
// Middle hexagon
glColor3f ( 0.0, 0.0, 1.0 );
// Blue
glBegin( GL_POLYGON );
glVertex2i( x + 50 , y + 100 );
glVertex2i( x
, y + 75 );
glVertex2i( x
, y + 25);
glVertex2i( x + 50 , y );
glVertex2i( x + 100, y + 25);
glVertex2i( x + 100, y + 75);
glEnd();
// Top middle hexagon
glColor3f ( 1.0, 1.0, 0.0 );
// Yellow
glBegin( GL_POLYGON );
glVertex2i( x + 50 , y + 200 );
glVertex2i( x
, y + 175 );
glVertex2i( x
, y + 125);
glVertex2i( x + 50 , y + 100);
glVertex2i( x + 100, y + 125);
glVertex2i( x + 100, y + 175);
glEnd();
// Bottom middle hexagon
glColor3f ( 1.0, 0.0, 0.0 );
// Red
glBegin( GL_POLYGON );
glVertex2i( x + 50 , y );
glVertex2i( x
, y - 25 );
glVertex2i( x
, y - 75);
glVertex2i( x + 50 , y - 100);
glVertex2i( x + 100, y - 75);
glVertex2i( x + 100, y - 25);
glEnd();
// Upper right hexagon
glColor3f ( 1.0, 0.0, 0.0 );
// Red
glBegin( GL_POLYGON );
glVertex2i( x + 100, y + 125);
glVertex2i( x + 100, y + 75);
glVertex2i( x + 150, y + 50);
// clear screen
glVertex2i( x + 150, y + 150);
glVertex2i( x + 200, y + 75);
glVertex2i( x + 200, y + 125);
glEnd();
// Lower right hexagon
glColor3f ( 1.0, 1.0, 0.0 );
// Yellow
glBegin( GL_POLYGON );
glVertex2i( x + 100, y + 25);
glVertex2i( x + 100, y - 25);
glVertex2i( x + 150, y - 50);
glVertex2i( x + 200, y - 25);
glVertex2i( x + 200, y + 25);
glVertex2i( x + 150, y + 50);
glEnd();
// Upper left hexagon
glColor3f ( 1.0, 0.0, 0.0 );
// Red
glBegin( GL_POLYGON );
glVertex2i( x
, y + 125);
glVertex2i( x
, y + 75);
glVertex2i( x - 50 , y + 50);
glVertex2i( x - 100, y + 75);
glVertex2i( x - 100, y + 125);
glVertex2i( x - 50 , y + 150);
glEnd();
// Lower left hexagon
glColor3f ( 1.0, 1.0, 0.0 );
// Yellow
glBegin( GL_POLYGON );
glVertex2i( x
, y + 25);
glVertex2i( x
, y - 25);
glVertex2i( x - 50 , y - 50);
glVertex2i( x - 100, y - 25);
glVertex2i( x - 100, y + 25);
glVertex2i( x - 50 , y + 50);
glEnd();
// Here are the six green triangles
glColor3f ( 0.0, 1.0, 0.0 );
// Green
glBegin( GL_TRIANGLES );
glVertex2i( x
, y + 25);
glVertex2i( x
, y - 25);
glVertex2i( x + 50 , y);
glEnd();
glBegin( GL_TRIANGLES );
glVertex2i( x
, y + 25);
glVertex2i( x
, y + 75);
glVertex2i( x - 50 , y + 50);
glEnd();
glBegin( GL_TRIANGLES );
glVertex2i( x
, y + 125);
glVertex2i( x
, y + 75);
glVertex2i( x + 50 , y + 100);
glEnd();
glBegin( GL_TRIANGLES );
glVertex2i( x + 50 , y + 100);
glVertex2i( x + 100, y + 75);
glVertex2i( x + 100, y + 125);
glEnd();
glBegin( GL_TRIANGLES );
glVertex2i( x + 100, y + 75);
glVertex2i( x + 100, y + 25);
glVertex2i( x + 150, y + 50);
glEnd();
glBegin( GL_TRIANGLES );
glVertex2i( x + 100, y + 25);
glVertex2i( x + 100, y - 25);
glVertex2i( x + 50 , y);
glEnd();
glFlush();
//send all output to screen
}
Image 3) I created the trispiral configuration using the Canvas class. There are 3 spirals and each spiral
has sides that increase in length with every turn:
#include "canvas.h"
Canvas cvs ( 500, 500, "trispiral" );
//draw a trispiral pattern
void drawTrispiral ( float sideLength ) {
for (int i = 0; i < 3; i++){ // Number of spirals
cvs.forward( sideLength * .5, 1 );
cvs.turn(300);
for (int j = 1; j < 10; j++){
cvs.forward( sideLength * j, 1 );
cvs.turn(300);
}
}
}
void display(void)
{
cvs.clearScreen();
cvs.setBackgroundColor(1, 1, 1);
cvs.setColor(0, 0, 0);
cvs.moveTo(0, 0);
cvs.turnTo ( 90 );
drawTrispiral( .5 );
}
Image 4)For this image I created the 5 figures using the Surface class
Source code:
#include <SDL/SDL.h>
#include <stdlib.h>
#include <stdio.h>
#include "draw.h"
#include "surface.h"
//draw a star pattern
void draw_star( Surface &surf, int L )
{
for ( int i = 0; i < 5; ++i ) {
surf.forward( L, 1 );
surf.turn( 144 );
}
}
//draw a wheel
void draw_wheel ( Surface &surf, int n, int radius, float rotAngle, Point wCenter)
{
if ( n < 5 ) return;
//bad number of sides
int cx = surf.getCP().x;
int cy = surf.getCP().y;
Point pointArray[n];
double angle = rotAngle * 3.14159265 / 180; //initial angle
double angleInc = 2 * 3.14159265 / n;
//angle increment
surf.moveTo ( ( int) (radius * cos( angle ) + cx),
( int ) ( radius * sin ( angle ) + cy ) );
for ( int k = 0; k < n; k++ ) {
//repeat n times
angle += angleInc;
Point temp (( int) (radius * cos( angle ) + cx),
( int ) ( radius * sin ( angle ) + cy ) );
surf.lineTo ( temp );
pointArray[k] = temp;
}
for (int i = 0; i < n; i++) {
surf.moveTo (wCenter);
surf.lineTo (pointArray[i]);
}
}
//draw an n-sided regular polygon
void draw_polygon ( Surface &surf, int n, int radius, float rotAngle )
{
if ( n < 3 ) return;
//bad number of sides
int cx = surf.getCP().x;
int cy = surf.getCP().y;
double angle = rotAngle * 3.14159265 / 180; //initial angle
double angleInc = 2 * 3.14159265 / n;
//angle increment
surf.moveTo ( ( int) (radius * cos( angle ) + cx),
( int ) ( radius * sin ( angle ) + cy ) );
for ( int k = 0; k < n; k++ ) {
//repeat n times
angle += angleInc;
surf.lineTo ( ( int) (radius * cos( angle ) + cx),
( int ) ( radius * sin ( angle ) + cy ) );
}
} //draw_polygon
//draw rosette with N-sided polygon
void rosette (Surface &surf, int N, int radius )
{
if ( N < 3 ) return;
Point pt[N+1];
int cx = surf.getCP().x;
int cy = surf.getCP().y;
double angle = 0;
//initial angle
double angleInc = 2 * 3.14159265 / N;
//angle increment
pt[0] = Point ( ( int) (radius * cos( angle ) + cx),
( int ) ( radius * sin ( angle ) + cy ) );
for ( int k = 1; k < N; k++ ) {
//repeat n times
angle += angleInc;
pt[k] = Point ( ( int) (radius * cos( angle ) + cx),
( int ) ( radius * sin ( angle ) + cy ) );
}
for ( int i = 0; i < N - 1; i++ ) {
for ( int j = i + 1; j < N; j++ ) {
surf.moveTo ( pt[i] ); //connect all vertices
surf.lineTo ( pt[j] );
}
}
} //rosette
int main()
{
#ifndef ARM
const int VWIDTH = 640;
const int VHEIGHT = 480;
#else
const int VWIDTH = 320;
const int VHEIGHT = 240;
#endif
const Point center ( VWIDTH/2, VHEIGHT/2 );
//center of screen
Surface surf( VWIDTH, VHEIGHT, (char *) "Draw_demo" );
surf.clearScreen();
surf.updateSurface();
SDL_Delay ( 1000 );
//clear screen
//dealy one second, just for demo
surf.setBackgroundColor ( 0xff, 0xff, 0xff ); //set background to white
surf.setColor ( 0, 0, 0 );
//black
//draw a star
surf.moveTo ( center.x - 100, center.y - 70 );
surf.turnTo ( 0 );
draw_star ( surf, 100 );
//draw nested stars
Point p1 ( center.x + 100, center.y - 60 );
surf.moveTo ( p1 );
surf.turnTo ( 0 );
for (int i = 99; i > 0; i-=33) {
int x = p1.x + 16;
int y = p1.y - 5;
p1.set(x,y);
surf.moveTo ( p1 );
draw_star ( surf, i );
}
//draw an pentagon
surf.moveTo ( center.x - 220, center.y - 70 );
draw_polygon ( surf, 5, 60, 55 );
//draw a wheel
Point wCenter ( center.x - 200, center.y + 100 );
surf.moveTo ( wCenter );
draw_wheel ( surf, 15, 100, 0, wCenter );
//draw an 20-sided rosette
surf.setColor ( 0, 0, 0 );
surf.moveTo ( center.x + 90, center.y + 100 );
rosette ( surf, 20, 100 );
surf.updateSurface();
SDL_Delay ( 5000 );
return 1;
}
Image 5) For this image I used the Surface class as in the above image:
Source code:
#include <SDL/SDL.h>
#include <stdlib.h>
#include <stdio.h>
#include "draw.h"
#include "surface.h"
void draw_fRect( Surface surf, int L) {
int temp = L;
for ( int i = 0; i < L; ++i ) {
surf.forward( temp, 1 );
surf.turn( 90 );
--temp;
}
}
void draw_rect( Surface surf, int W, int H) {
surf.forward( W, 1 );
surf.turn( 90 );
surf.forward( H, 1 );
surf.turn( 90 );
surf.forward( W, 1 );
surf.turn( 90 );
surf.forward( H, 1 );
surf.turn( 90 );
}
void draw_arc ( Surface &surf, int n, int radius, float rotAngle )
{
if ( n < 3 ) return;
//bad number of sides
int cx = surf.getCP().x;
int cy = surf.getCP().y;
double angle = rotAngle * 3.14159265 / 180; //initial angle
double angleInc = 2 * 3.14159265 / n;
//angle increment
surf.moveTo ( ( int) (radius * cos( angle ) + cx),
( int ) ( radius * sin ( angle ) + cy ) );
for ( int k = 0; k < 2 * n / 3; k++ ) {
//repeat n times
angle += angleInc;
surf.lineTo ( ( int) (radius * cos( angle ) + cx),
( int ) ( radius * sin ( angle ) + cy ) );
}
}
//draw rosette with N-sided polygon
void rosette (Surface &surf, int N, int radius )
{
if ( N < 3 ) return;
Point pt[N+1];
int cx = surf.getCP().x;
int cy = surf.getCP().y;
double angle = 0;
//initial angle
double angleInc = 2 * 3.14159265 / N;
//angle increment
pt[0] = Point ( ( int) (radius * cos( angle ) + cx),
( int ) ( radius * sin ( angle ) + cy ) );
for ( int k = 1; k < N; k++ ) {
//repeat n times
angle += angleInc;
pt[k] = Point ( ( int) (radius * cos( angle ) + cx),
( int ) ( radius * sin ( angle ) + cy ) );
}
for ( int i = 0; i < N - 1; i++ ) {
for ( int j = i + 1; j < N; j++ ) {
surf.moveTo ( pt[i] ); //connect all vertices
surf.lineTo ( pt[j] );
}
}
} //rosette
int main()
{
#ifndef ARM
const int VWIDTH = 640;
const int VHEIGHT = 480;
#else
const int VWIDTH = 320;
const int VHEIGHT = 240;
#endif
const Point center ( VWIDTH/2, VHEIGHT/2 );
//center of screen
Surface surf( VWIDTH, VHEIGHT, (char *) "Draw_demo" );
surf.clearScreen();
surf.updateSurface();
SDL_Delay ( 1000 );
//clear screen
//dealy one second, just for demo
surf.setBackgroundColor ( 0xff, 0xff, 0xff );
//draw a 17-sided rosette
surf.setColor ( 0xff, 0, 0 );
surf.moveTo ( center.x + 90, center.y );
rosette ( surf, 17, 100 );
//draw an arc (2/3 of a circle)
surf.setColor ( 0, 0, 0 );
surf.moveTo ( center.x + 40, center.y );
draw_arc ( surf, 40, 230, -85 );
//set background to white
//red
//black
//draw filled rectangle
surf.setColor ( 0, 0xff, 0 );
//green
surf.moveTo ( center.x - 270, center.y + 90 );
surf.turnTo(0);
draw_fRect ( surf, 170 );
//draw an empty square (overwrites lines of rectangle that overlap)
surf.setColor ( 0, 0xff, 0 );
//green
surf.moveTo ( center.x - 250, center.y - 60 );
draw_rect ( surf, 65, 75 );
surf.updateSurface();
SDL_Delay ( 3000 );
return 1;
}
Evaluation: This was one of the most time-consuming homework assignments I've ever done. I feel
5 images is too large a number. Having said that, I feel I successfully completed all parts of the
homework assignment and am giving myself 60 points.
© Copyright 2026 Paperzz