Chris Pollett > Old Classes >
CS116a

( Print View )

Student Corner:
  [Grades Sec1]

  [Submit Sec1]

  [Email List Sec1]

  [
Lecture Notes]

Course Info:
  [Texts & Links]
  [Topics]
  [Grading]
  [HW Info]
  [Exam Info]
  [Regrades]
  [Honesty]
  [Announcements]

HW Assignments:
  [Hw1]  [Hw2]  [Hw3]
  [Hw4]  [Hw5]

Practice Exams:
  [Mid1]  [Mid2]  [Final]

                           












HW3 Solutions Page

Return to homework page.

Book Problems

5.2

We want to show R(a)R(b) = R(a+b). The Book doesn't say if 2D or 3D rotation but since no axis given we assume it is 2D. We'll also use 2x2 matrices. (The homogeneous coordinates proof follows trivially from this case.) First, we compute R(a)R(b):

==            = =  ==             ==
| cos a   sin a |  | cos b   sin b |
| -sin a  cos a |  | -sin b  cos b |     =
==            = =  ==             ==

==                                                           ==
|  (cos a*cos b - sin a*sin b)   (cos a*sin b + sin b*cos a)  |
|  -(sin a* cos b + cos a*sin b) (cos a*cos b - sin a*sin b ) |  
==                                                           ==

Using the identities:

cos(a+b) = cos a*cos b - sin a*sin b

and

sin(a+b) = sin a*cos b + cos a*sin b

This shows the diagonala of this product matrix are cos(a+b) and the off diagonals are -sin(a+b) in the first column and sin(a+b) in the second. QED

5.5

We are asked to show uniform scalings and rotations commute with each other.

==     ==  ==             ==
| s  0  |  | cos b   sin b |
| 0  s  |  | -sin b  cos b |     =
==     ==  ==             ==

==                    ==      ==             ==  ==     ==
|  s*cos  b   s*sin b  |      |  cos b  sin b |  |  s  0 |
|  -s*sin b   s*cos b  |   =  | -sin b  cos b |  |  0  s |
==                    ==      ==             ==  ==     ==

So these operations commute with each other. We are then asked to show if the scaling is not uniform the two operations do not commute. To show this it suffices to come up with some non-uniform scaling and some rotation such that the two operations do not commute. Consider:

==     ==  ==               ==         ==    ==
| 1  0  |  | cos 90   sin 90 |         |  0 1 |
| 0  2  |  | -sin 90  cos 90 |     =   | -2 0 |
==     ==  ==               ==         ==    ==

We are using cos 90 = 0 and sin 90 = 1. On the other hand,

==               == ==     ==         ==    ==
| cos 90   sin 90 | | 1  0  |         |  0 2 |
| -sin 90  cos 90 | | 0  2  |     =   | -1 0 |
==               == ==     ==         ==    ==

aliastrans.cpp

/******************************************************
* Project:         CS116A Homework #3
* File:            aliastrans.cpp          
* Purpose:         Code to draw an anti-aliased, translated, rotated, scaled house using OpenGL
* Start date:      Nov 14, 2004
* Programmer:      Chris Pollett
*
* Remarks:
*          In real world word have separate .h and .cpp files
*
*******************************************************/

#ifdef WIN32
   #include<windows.h> //for windows
   #include <GL/glut.h>
   #include <GL/glu.h>
#endif

#ifdef __APPLE__ //for MAC
/*
        I created my project under xcode. I chose new C++ tool as the kind of project.
        Then under External frameworks and libraries I added the two frameworks:
        OpenGL.framework and GLUT.framework. (Frameworks are in /Library/Frameworks)

*/
   #include <OpenGL/gl.h> 
   #include <OpenGL/glu.h>
   #include <GLUT/glut.h>
#endif

#ifdef linux // for linux
 /*My compile line was:
        g++ -I /usr/X11R6/include -L /usr/X11R6/lib -lglut -lGL \
         -lGLU -lX11 -lXmu -lXi -lm name.cpp -o name
 */
      #include <GL/glut.h>
      #include <GL/glu.h>
#endif

#include <cstdlib>
#include <cmath>
#include <iostream>
#include <fstream>

using namespace std;


/*
   CONSTANTS
*/
const GLfloat PI = 3.14159265358979323846;

const int PIXELWIDTH = 10; //how many subpixels wide for super-sampling

//const GLfloat intensityInc = 1.0/(PIXELWIDTH*PIXELWIDTH); 
      /* This is how 
      much each subpixel will add to the intensity. As the PIXELWIDTH
	  in subpixels gets larger this will result in fainter and fainter
	  lines (as the line is getting thinner and thinner with respect the pixel). 
	  One can compensate for this by always drawing line with a certain 
	  fraction of a pixel thickness or trying to use pixel masks.
	   */
const GLfloat intensityInc = 1.0/PIXELWIDTH; // this looks better but isn't books algorithm

const int ZERO = 0; //Some constants used by out matrix constructor
const int IDENTITY = 1;
const int TRANSLATION = 2; 
const int ROTATION = 3;
const int SCALE = 4;


/*
   CLASS DEFINITIONS
*/


/*-----------------------------------------------*/
class Pt
/*
PURPOSE: Encapsulates the notions of a point (x,y) on the screen
         Has simple accessors and increment/decrement mutators which
         are useful for Bresenham-like algorithms
*/
{
   private:
      GLint x, y;

   public:
      Pt()
      {
         x= y =0;
      }
      Pt(GLint x0, GLint y0)
      {
		x = x0;
		y = y0;
	  }
      void setCoords(GLint x0, GLint y0)
      {
         x = x0;
         y = y0;
      }

      GLint getx() const
      {
         return x;
      }

      GLint gety() const
      {
         return y;
      }

      void incx()
      {
         x++;
      }

      void decy()
      {
         y--;
      }
};

class Matrix
/*
PURPOSE: Encapsulates the notions of a 2D homogeneous coordinate transformation matrix*/
{
	private:
		GLfloat entry[3][3];
		
		void clear()
		{
			for(int i = 0; i < 3; i++)
			{
				for(int j = 0; j < 3; j++)
				{
					entry[i][j] = 0;
				}
			}
		}

	public:
		Matrix(int type = ZERO, GLfloat param1 = 0, GLfloat param2 = 0);
		friend Matrix operator*(Matrix m1, Matrix m2);
		friend Pt operator*(Matrix m1, Pt p1);	
			
};

/*
   GLOBALS
*/

GLsizei winWidth = 600, winHeight = 300; // used for size of window
Matrix gTransformation; //Transformation matrix to apply to drawing

/*
   FUNCTIONS
*/

// Auxiliary functions
void setPixel(GLint x, GLint y);
inline GLfloat toDegrees(GLfloat radians);
inline GLint crossProduct(GLint x0, GLint y0, GLint x1, GLint y1);
void reflectOctant(Pt pt, Pt& presult, int octant);

void lineBres(int x0, int y0, int xEnd, int yEnd);

// Polyline functions
void polyLineBres(int x[], int y[], int len);

// Arc functions
void circleArcMidpoint(GLint xc, GLint yc, GLint r, GLfloat
startTheta = 0, GLfloat endTheta = 2*PI); //added some default values for angles

//Additional graphics functions that use our HW1 functions to draw things

void drawPolygon(Pt p[], int start, int end);
void drawCircle(Pt leftDiameter, Pt rightDiameter);



/*
   IMPLEMENTATIONS
*/


//Class Member Functions

/*-----------------------------------------------*/
Matrix::Matrix(int type, GLfloat param1, GLfloat param2)
/*
PURPOSE: Constructs a 2D coordinate transformation matrix (as a 3x3 homogeneous matrix)

RECEIVES: type - type of transformation to construct (IDENTITY, TRANSLATION, ROTATION, SCALE)
          param1, param2 -- parameters which depend on the type of transformation we are doing

RETURNS: constructed matrix

REMARKS:
*/
{
	int i;
	
	switch(type)
	{
		case TRANSLATION:
			clear();
			for(i = 0; i < 3 ; i++)
			{
				entry[i][i] = 1;
			}
			entry[0][2] = param1;
			entry[1][2] = param2;
			break;
		
		case ROTATION: //counter-clockwise
			clear();
			entry[0][0] = cos(param1);
			entry[0][1] = -sin(param1);
			entry[1][0] = -entry[0][1];
			entry[1][1] = entry[0][0];
			entry[2][2] = 1;
			break;
			
		case SCALE: //only do uniform scaling
			clear();
			entry[0][0] = param1;
			entry[1][1] = param1;
			entry[2][2] =1;
			break;
				
		case IDENTITY:
			clear();
			for(i = 0; i < 3 ; i++)
			{
				entry[i][i] = 1;
			}
			break;
			
		case ZERO:	
		default:
			clear();
	}
}

Matrix operator*(Matrix m1, Matrix m2)
{
	Matrix result(ZERO);
	
	for(int i = 0 ; i < 3; i++)
	{
		for(int j = 0; j < 3; j++)
		{
			for(int k = 0; k < 3; k++)
			{
				result.entry[i][j] += m1.entry[i][k]*m2.entry[k][j];
			}
		}
	}
	return result;
}

Pt operator*(Matrix m, Pt p)
{
	GLfloat homoPt[3] = {p.getx(), p.gety(), 1.0};
	GLfloat resultPt[3] = {0.0, 0.0, 0.0};
	Pt result;
	
	for(int i = 0 ; i < 2; i++)
	{
		for(int k = 0; k < 3; k++)
		{
			resultPt[i] += m.entry[i][k]*homoPt[k];
		}
	}
	
	result.setCoords((GLint)resultPt[0], (GLint)resultPt[1]);
	
	return result;
}

//Usual Functions

/*-----------------------------------------------*/
inline GLfloat toDegrees(GLfloat radians)
/*
PURPOSE: converts an angle in radians to degrees 

RECEIVES: radians -- the angle to convert

RETURNS:  the equivalent value in degrees

REMARKS: This is only used in the test angle drawing function
         since this is based on a GLU call in degrees
         Not used in the official angle drawing function

         inlined so don't have stack overhead in doing this small call    
*/
{
   return 180*radians/PI;

}

/*-----------------------------------------------*/
void setPixel(GLint x, GLint y)
/*
PURPOSE: Draw a pixel at desired location on screen
RECEIVES: x,y - coordinates of pixel to draw
RETURNS:  nothing
REMARKS:  side-effect is pixel drawn  
*/
{
   glBegin(GL_POINTS);
      glVertex2i(x, y);
   glEnd();
}

/*-----------------------------------------------*/
inline GLint crossProduct(Pt p0, Pt p1)
/*
PURPOSE: Takes the 2D cross-product of supplied points.
RECEIVES: p0, p1 - points to take cross product of
RETURNS:  p0 X p1
REMARKS:  inlined for speed  
*/
{
  return p0.getx()*p1.gety() - p1.getx()*p0.gety();
}

/*-----------------------------------------------*/
void reflectOctant(Pt pt, Pt& presult, int octant)
/*
PURPOSE: By using reflections to convert a point in the first octant
         to a point in the desired octant
RECEIVES: pt - a point assummed to be in the first quadrant
          presult - a reference to a point to store the result
          octant - desired octant to convert point to
RETURNS:  nothing
REMARKS:    
*/
{

   switch(octant%8)
   {
      case 0:
         presult.setCoords(pt.getx(), pt.gety());
         break;
      
      case 1:
         presult.setCoords(pt.gety(), pt.getx());
         break;

      case 2:
         presult.setCoords(pt.gety(), - pt.getx());
         break;

      case 3:
         presult.setCoords(pt.getx(), - pt.gety());
         break;

      case 4:
         presult.setCoords( - pt.getx(), - pt.gety());
         break;

      case 5:
         presult.setCoords( - pt.gety(),  - pt.getx());
         break;

      case 6:
         presult.setCoords( - pt.gety(),  pt.getx());
         break;

      case 7:
         presult.setCoords( - pt.getx(), pt.gety());
         break;

   }
}

/*-----------------------------------------------*/
void lineBres(int x0, int y0, int xEnd, int yEnd)
/*
PURPOSE: Draws a line segment from (x0, y0) to (xEnd, yEnd)
         using my implementation Bresenham's algorithm and anti-aliasing
RECEIVES: x0, y0 - start point of line segment
          xEnd, yENd - end point of line segment
RETURNS: nothing 
REMARKS: Side-effect is the line segment drawn
         Note basically hacked the books code to handle negative slopes
         and slopes with large magnitude. 
*/
{
   int dx = PIXELWIDTH*abs(xEnd - x0), dy = PIXELWIDTH*abs(yEnd - y0); 
		//PIXELWIDTH factors are for anti-aliasing
   int p;
   int twoD, twoDMinusD;
   int x,y, *a, *b, *a0, *aEnd;

   int slopeSign = ((xEnd - x0)*(yEnd - y0) > 0) ? 1 : -1;

   if(dx > dy)//added by me to books algorithm
   {
      a = &x;
          b = &y;
          a0 = &x0;
          aEnd = &xEnd;
          
      p = 2*dy -dx;
      twoD = 2*dy;
      twoDMinusD = 2*(dy-dx);
   }
   else
   {
      a = &y;
          b = &x;
          a0 = &y0;
          aEnd = &yEnd;
   
      p = 2*dx - dy;
      twoD = 2*dx;
      twoDMinusD = 2*(dx-dy);    
   }
   
  if(*a0 > *aEnd)
  {
         x = xEnd;
         y = yEnd;
         *aEnd = *a0;
  }
  else
  {
         x = x0;
         y = y0;
  }

                                                         
   GLfloat intensity = intensityInc;
   int subpixela = 0;
   int subpixelb = 0;
   int nextA = *a;
   int nextB = *b;
   
   bool plot = false;
   
   glEnable(GL_BLEND); //blending is being used for anti-aliasing
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   
   while(*a < *aEnd)
   {
      subpixela++;
      intensity += intensityInc;
	  
	  if(subpixela == PIXELWIDTH) // only draw when cross a pixel boundary
	  {
		 subpixela = 0;	 
         plot = true;
		 nextA++;
	  }
	  
      if(p < 0)
      {
         p += twoD;
      }
      else
      {
         subpixelb++;
         p += twoDMinusD;
		 
		 if(subpixelb == PIXELWIDTH)// only draw when cross a pixel boundary
		 {
			subpixelb = 0;
			plot = true;			
			nextB +=slopeSign;
		 }
      }
	  
	  if(plot)
	  {
		plot = false;
		glColor4f(0.0, 0.0, 0.0, intensity);
		setPixel(x, y);
		intensity = 0;
		*a = nextA;
		*b = nextB;		
	  }
   }
   glDisable(GL_BLEND);
}


/*-----------------------------------------------*/
void polyLineBres(int x[], int y[], int len)
/*
PURPOSE: Draws a polyline using my implmentation of Bresenham's algorithm

RECEIVES: x[], y[] - arrays of x and y values for points in the polyline
         len - number of points in the polyline

RETURNS: nothing

REMARKS: Has side-effect of drawing the poly-line to the screen   
*/
{
   for(int i = 0; i < len - 1; i++)
   {
      lineBres(x[i], y[i], x[i+1], y[i+1]);
   }
}



/*-----------------------------------------------*/
void circleArcMidpoint(GLint xc, GLint yc, GLint r, GLfloat startTheta, GLfloat
endTheta)
/*
PURPOSE: My implementation of a function to draw an arc  using circle midpoint algorithm
      centered at xc,yc of radius r from startTheta in radians to endTheta
      in radians. Arc drawing is down using anti-aliasing
RECEIVES: xc, yc - center of arc
          r - radius of arc
          startTheta - starting angle in radians
          endTheta - ending angle in radians
RETURNS:  nothing
REMARKS:  Side-effect is that arc drawn.
          Note I was a little sloppy about boundaries of octants
          O radians on our unit circle corresponds to the point (0, 1)
          and we take our angles clockwise around the circle
*/
{
   /*
      Variable initializations. Want to recalculate startTheta and endTheta so that
      startTheta + 2PI > endTheta >+ startTheta and 2PI > startTheta >= 0
      Also want to calculate which octants our angle is in and what are the endpoints
      of the arc. Although we do use sin and cos, we do this a total of 4 times,
      two of which can be eliminated, so incur at most a constant overhead to
      the midpoint algorithm.
   */
   Pt pt, oldPt, drawPt, nextDrawPt;
   Pt startPt, endPt; //start and end points of arc
   Pt endStartOctantPt, startEndOctantPt; /* corresponding end and start points
                                                   of these points octants */
   Pt tmpPt;


   GLint rsTheta = (int)(startTheta/(2*PI));
  
   int startOctant;
   int endOctant;

   startTheta -= rsTheta*(2*PI);
   endTheta -= rsTheta*(2*PI);

   startTheta = (startTheta > 0) ? startTheta : 2*PI - startTheta;
   endTheta = (endTheta > 0) ? endTheta : 2*PI - endTheta;
   endTheta = (endTheta > startTheta) ? endTheta : endTheta + (2*PI);

   startOctant = (int)(4*startTheta/PI);
   endOctant =  (int)(4*endTheta/PI);

   startPt.setCoords((long)(r*sin(startTheta)), (long)(r*cos(startTheta)));
   endPt.setCoords((long)(r*sin(endTheta)), (long)(r*cos(endTheta)));

   if(startOctant == endOctant)
   {
      endStartOctantPt = endPt;
      startEndOctantPt = startPt;
   }
   else
   {
      /* the use of sin and cosine here could be replaced by a lookup table
         as everything is a multiple of 4
      */
      endStartOctantPt.setCoords((int)(r*sin(PI*(startOctant+1)/4)), 
                (int)(r*cos(PI*(startOctant+1)/4)));
      startEndOctantPt.setCoords((int)(r*sin(PI*(endOctant)/4)), 
		(int)(r*cos(PI*(endOctant)/4)));

   }

   // initialize decision parameters and first octant point
   pt.setCoords(0, r*PIXELWIDTH); // PIXELWIDTH comes from doing anti-aliasing
   oldPt.setCoords(0, r*PIXELWIDTH);
   drawPt.setCoords(0, r);
   nextDrawPt.setCoords(0, r);
      
   GLint p = 1 - r*PIXELWIDTH;
   GLfloat intensity = intensityInc;

   bool plot = false;

   glEnable(GL_BLEND); //blending is being used for anti-aliasing
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   
   //Here is where the drawing is actually done
   while(drawPt.getx() < drawPt.gety())
   {
      pt.incx();
	  intensity += intensityInc;
	  if(pt.getx() == oldPt.getx() + PIXELWIDTH)
	  {
		oldPt.setCoords(pt.getx(), oldPt.gety());
		nextDrawPt.incx();
		plot = true;
	  }
      if(p < 0)
      {
         p += 2 * pt.getx() + 1;
      }
      else
      {
         pt.decy();
         p += 2 * (pt.getx() - pt.gety ()) + 1;
		 if(pt.gety() == oldPt.gety() - PIXELWIDTH)
		 {
		 	oldPt.setCoords(oldPt.getx(), pt.gety());
			nextDrawPt.decy();
			plot = true;
		 } 		 
      }

	  if(plot)
	  {
          glColor4f(0.0, 0.0, 0.0, intensity);//set draw color based on how filled pixel was		 
	  
		  plot = false; // reset plot mode and intensity
		  intensity = 0;
		  
		  //draw points, if applicable, in starting octant
		  reflectOctant(drawPt, tmpPt, startOctant);
		  if(crossProduct(startPt, tmpPt)* crossProduct(tmpPt, endStartOctantPt) > 0)
		  {
			 setPixel(xc + tmpPt.getx(), yc + tmpPt.gety());
		  }

		  //draw points, if applicable, in ending octant
		  reflectOctant(drawPt, tmpPt, endOctant);
		  if(crossProduct(startEndOctantPt, tmpPt)* crossProduct(tmpPt, endPt) > 0)
			 setPixel(xc + tmpPt.getx(), yc + tmpPt.gety());

		  /* ASIDE: notice if starting and ending octant were the same, then by
			 how we initialized things we would have plotted the same points twice
			 above.
		  */

		  //draw points in all the octants we know have to be completely drawn
		  for(int i = startOctant+1; i < endOctant; i++)
		  {
			 reflectOctant(drawPt, tmpPt,i);
			 setPixel(xc + tmpPt.getx(), yc + tmpPt.gety());

		  }
		  
		  drawPt = nextDrawPt;
	  }
   }
   glDisable(GL_BLEND);
}

/*-----------------------------------------------*/
void drawPolygon(Pt p[], int start, int end)
/*
PURPOSE: Draws a polygon using polyLineBres

RECEIVES: p - array of points in polygon
		  start -starting index in p of polygon
		  end -ending index in p of polygon

RETURNS: nothing

REMARKS: Has side-effect of drawing a polygon to the screen   
*/
{
   int len = end - start;
   int x[len + 2], y[len + 2];

   for(int i = 0; i<=len; i++)
   {
	  x[i] = p[start+i].getx();
	  y[i] = p[start+i].gety();	
   }
   
   x[len + 1] = x[0]; //connect back to start
   y[len + 1] = y[0];
   
   polyLineBres(x, y, len + 2);
}


/*-----------------------------------------------*/
void drawCircle(Pt leftDiameter, Pt rightDiameter)
/*
PURPOSE: Draws a circle using circleArcMidpoint such
  that the two points supplies are on a diameter of this
  circle 

RECEIVES: leftDiameter- left coordinates of the diameter of circle 
          rightDiameter- right coordinates of the diameter of circle 

RETURNS: nothing

REMARKS: Has side-effect of drawing a circle to the screen   
*/
{
   int x = (leftDiameter.getx() + rightDiameter.getx())/2;
   int y = (leftDiameter.gety() + rightDiameter.gety())/2;
   int diffX = rightDiameter.getx() - x;
   int diffY = rightDiameter.gety() - y;
   int radius = (int)sqrt((float)(diffX*diffX + diffY*diffY));

   circleArcMidpoint(x, y, radius); // using default values for angles;
}


/*
   GLUT AND DRIVER CODE
*/
/*-----------------------------------------------*/
void readParameters()
/*
PURPOSE: Reads Parameter file with initial window size and two points position
RECEIVES: nothing
RETURNS: nothing
REMARKS:    
*/
{
   ifstream fin;
   GLfloat transX, transY, angle, scale;
   
   try
   {
      fin.open("parameters.txt");
          if(fin.fail()) throw string("Failed to open parameters.txt");
          
          if(!(fin >> winWidth >> winHeight >> transX >> transY >> angle >> scale))
          {
            fin.close();
                throw string("parameters.txt format incorrect");
          }
		  gTransformation = Matrix(SCALE, scale)*
			Matrix(ROTATION, 2*PI*angle/360)*Matrix(TRANSLATION, transX, transY);
          
          fin.close();
   }
   catch(string error)
   {
	  cerr << error << endl;
      cerr << "Using default values" << endl;
      gTransformation = Matrix(IDENTITY);        
   }

}

/*-----------------------------------------------*/
void init(void)
/*
PURPOSE: Used to initializes our OpenGL window        
RECEIVES: Nothing
RETURNS:  Nothing
REMARKS:  Nothing  
*/
{
   glClearColor(1.0, 1.0, 1.0, 0.0);
   glMatrixMode(GL_PROJECTION);
   gluOrtho2D(0.0, winWidth, 0.0, winHeight);
}


/*-----------------------------------------------*/
void drawHouse(void)
/*
PURPOSE: GLUT display callback function for this program.
         Serves as the main driver for the program.
		 Draws transformed house 
RECEIVES: nothing, although uses global variables that have been
	set up with data from the parameters.txt file
RETURNS: nothing
REMARKS: Side-effect is to draw a house with anti-aliased line according
	to the transformations from the paremeter.txt file
*/
{


   glClear(GL_COLOR_BUFFER_BIT);
   glColor4f(0.0, 0.0, 0.0, 0.0); //
   
   //here's where we draw the strings to the screen

   Pt myHouse[] = { Pt(10, 10), Pt(10, 100), Pt(100, 100), Pt(100, 10), //square
                     Pt(10, 100), Pt(55, 150), Pt(100, 100), //triangle
					 Pt(200, 200), Pt(250, 200)}; //circle
   int myHouseLen = 9;
   
   for(int i = 0; i< myHouseLen; i++)
   {
	  myHouse[i] = gTransformation*myHouse[i];

   }
   
   drawPolygon(myHouse, 0, 3);
   drawPolygon(myHouse, 4, 6);
   drawCircle(myHouse[7], myHouse[8]);

   glFlush();
}


/*-----------------------------------------------*/
void winReshapeFn(int newWidth, int newHeight)
/*
PURPOSE: Resizes/redisplays the contents of the current window
RECEIVES: newWidth, newHeight -- the new dimensions
RETURNS: nothing
REMARKS:    
*/
{
   //glViewport(0, 0, newWidth, newHeight);
   glClearColor(1.0, 1.0, 1.0, 0.0);
   glClear(GL_COLOR_BUFFER_BIT); 
   glLoadIdentity();   
   gluOrtho2D(0.0, winWidth, 0.0, winHeight);
   drawHouse();
}


int main(int argc, char** argv)
{
   readParameters();
   
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
   glutInitWindowPosition(50, 100);

   glutInitWindowSize(winWidth, winHeight);
   glutCreateWindow("Anti-alias and Transformation Tester");

   init();
   glutDisplayFunc(drawHouse);
   glutReshapeFunc(winReshapeFn);
   glutMainLoop();
   return 0;
}
 

Return to homework page.