Week 2 Assignment (desc)

Younghyun Chung

 

Problem 1. Complete the Vec2d class. Add the following methods to the class:

a. Subtract one vector from another and return the resulting vector.

b. Divide a vector by a float and return the resulting vector.

c. Calculate the length of a vector using Pythagorean theorem and return the resulting float.

// in Vec2d.h
    Vec2d   operator-(Vec2d B);
    Vec2d   operator/(float M);
    float   length(); 

// in Vec2d.cpp
Vec2d Vec2d::operator-(Vec2d B)
{
      Vec2d C;
      C.x = x - B.x;
      C.y = y - B.y;
      return C;
}

Vec2d Vec2d::operator/(float M)
{
      Vec2d C;
      C.x = x / M;
      C.y = y / M;
      return C;     
}

float Vec2d::length()
{
      return sqrt(x*x+y*y);
}

 

Problem 2. Create a function called drawCircle that takes as arguments a radius (float), a number of points (int) and a center point (Vec2d) and draws a circle as specified. Demonstrate that this function works by using it in the following ways:

a. Draw 5 circles in a row, each with increasing radii (10, 20, 30...), just touching each other, each composed of 30 points.

b. Draw 5 regular polygons in a row, each with an increasing number of points (3, 4, 5...), each with a radius of 50 pixels.

		
float cos_deg( float A )
{
      return cos( A / 180.0 * PI );
}

float sin_deg( float A )
{
      return sin( A / 180.0 * PI );
}

void drawCircle( float radius, int numPoints, Vec2d Center ) {
     // for a.
     glPointSize(3);
     glBegin(GL_POINTS);

     // for b.
     // glBegin(GL_TRIANGLE_FAN);
     float angle;
     
     for(int i=0;i<numPoints;i++) {
             angle = 360.0 / numPoints * i; // angle of each point
             // calculate x, y position
             glVertex2f( radius*cos_deg(angle)+Center.x, 
                         radius*sin_deg(angle) + Center.y );
			 
     }        
     glEnd();
}

// a. call in displayFunc()
     Vec2d Center = Vec2d( 100,windowH/2 ); // set a start point
     for(int i=0;i<5;i++) { // draw 5 circles
             // reset a center of new circle
             Center = Center + Vec2d( (2*i+1)*10, 0 ); 
             drawCircle( (i+1)*10, 30, Center ); // draw the circle
     }

// b. call in displayFunc()
     Vec2d Center = Vec2d( 100,windowH/2 );
     for(int i=0;i<5;i++) {
             Center = Center + Vec2d( 100, 0 );
             drawCircle( 50, i+3, Center );
     }



: a.


: b.

 

Problem 3. Create a function called drawOval that takes as arguments a horizontal radius (float), a vertical radius, a number of points (int) and a center point (Vec2d) and draws an oval as specified. Demonstrate that this function works by drawing 10 ovals in a row, each with an increasing horizontal radius (10, 20, 30...) and decreasing vertical radius (100, 90, 80...).

		
void drawOval( float h_radius, float v_radius, int numPoints, Vec2d Center ) {
     glBegin(GL_TRIANGLE_FAN);
     float angle;
     
     for(int i=0;i<numPoints;i++) {
             angle = 360.0 / numPoints * i;
             glVertex2f( h_radius*cos_deg(angle) + Center.x, 
                         v_radius*sin_deg(angle) + Center.y );
     }
     
     glEnd();
}

// call in displayFunc()
     Vec2d Center = Vec2d( 10,windowH/2 );
     for(int i=0;i<10;i++) {
             Center = Center + Vec2d( (2*i+1)*10, 0 );
             drawOval( (i+1)*10, 100-i*10, 30, Center );
     }

: ovals in a row (resized 50%)

 

Problem 4. Create a function called drawStar that takes as arguments an inner radius (float), an outer radius (float), a number of points (int), and a center point (Vec2d) and draws a star as specified. Demonstrate that this function works by drawing 100 stars with a varying number of points placed randomly about the screen. Feel free to change the background color for a more dramatic effect.

		
void drawStar( float in_radius, float out_radius, int numPoints, Vec2d Center ) {
     float starColor = 1-rand()%10*0.05; // yellowish star
     float angle;
     if( numPoints%2 ) numPoints++; // make even number of points for better look

     glColor3f ( starColor,starColor,0 );
     glBegin( GL_TRIANGLE_FAN );
     glVertex2f( Center.x, Center.y );     

     for(int i=1;i<=numPoints;i++) {
             angle = 360.0 / numPoints * i;
             if(i%2) glVertex2f( in_radius*cos_deg(angle) + Center.x, 
                                 in_radius*sin_deg(angle) + Center.y );
             else glVertex2f( out_radius*cos_deg(angle) + Center.x, 
                              out_radius*sin_deg(angle) + Center.y );
     }

     // end at the beginning point
     glVertex2f( in_radius*cos_deg(360.0/numPoints) + Center.x, 
                 in_radius*sin_deg(360.0/numPoints) + Center.y );
     glEnd();
}

// call in displayFunc()
     glBegin ( GL_QUADS );
     glColor3f ( 0.5,0.5,0.3 ); // ground
     glVertex2f ( 0,0 ); glVertex2f ( 800,0 ); 
     glColor3f ( 0.1,0.1,0.0 );
     glVertex2f ( 800,200 ); glVertex2f ( 0, 200 );
     
     glColor3f ( 0.2,0.5,0.8 ); // sky
     glVertex2f ( 0,100 ); glVertex2f ( 800,100 ); 
     glColor3f ( 0.0,0.2,0.2 );
     glVertex2f ( 800,600 ); glVertex2f ( 0, 600 );
     glEnd ();

     Vec2d Center;
     srand ( time(NULL) ); // make a random 
     // put start above the horizon
     for(int i=0;i<100;i++ ){
             drawStar(3, 8, rand() % 13 + 8, 
             Center+Vec2d( rand()%windowW, rand()%(windowH-200)+150 ) );
     }

: stars. random number of vertex and position


: 100 stars in the sky

 

Problem 5. Create a function called drawNecklace that draws a pearl necklace. Feel free to shade the pearls or make them sparkle in the light of the moving mouse.

		
// drawCircle is modified to drawPearl
void drawPearl( float radius, int numPoints, Vec2d Center ) {
     float angle;
     
     glBegin(GL_TRIANGLE_FAN);
     glVertex2f( Center.x-3, Center.y+3 ); // adjust center for gradient effect
          
     for(int i=0;i<numPoints;i++) { 
             // give gradient effect and change color according to mouse movement
             glColor3f(0.03*i+mouseX/windowW/2,0.03*i+mouseX/windowW/2,0.025*i+mouseX/windowW/2); 
             angle = 360.0 / numPoints * i + 180; // angle
             glVertex2f( radius*cos_deg(angle) + Center.x, radius*sin_deg(angle) + Center.y);
     }        
     
     // end at the beginning point
     glVertex2f( radius*cos_deg(180) + Center.x, radius*sin_deg(180) + Center.y);
     glEnd();
     
}

void drawNecklace( void ) {
     glBegin ( GL_QUADS );
     glColor3f ( 0.3,0.3,0.3 );  // background color
     glVertex2f ( 0,0 ); glVertex2f ( 800,0 ); glVertex2f ( 800,600 ); 
     glColor3f ( 0,0,0 ); // gradient to background color
     glVertex2f ( 0, 600 );
     glEnd();
     
     float angle; // angle of each pearl on necklace
     float n_h_radius = 150;  // horizontal radius of necklace
     float n_v_radius = 100;  // vertical radius of necklace
     float p_radius = 10;     // radius of pearl
     int numPearls = 35;      // number of pearl
     int numPoints = 30;      // number of points of pearl
     
     for(int i=0;i<=numPearls;i++) {
             glColor3f ( 1,1,0.8 );
             angle = 360.0 / numPearls * i;
             drawPearl( p_radius,numPoints,
                        Vec2d(n_v_radius*cos_deg(angle)+windowW/2-270, 
                              n_h_radius*sin_deg(angle)+windowH/2+120) );
     }
}



: necklace


: sparkling with mouse movement

 

Problem 6. Create a function called drawClock that takes as arguments an hour (float), a minute (float) and a number of seconds (float), and draws an analog clock. Feel free to add a pendulum or any other fancy clock accoutrements.

		
// draw hand of clock, angle(degree) of hand from (0, 1), width of hand,
// length of hand, and Center
void drawHand( float angle, float width, float length, Vec2d Center ) {
     glLineWidth(width);
     glBegin( GL_LINES ); // draw line
     glVertex2f( 10*sin_deg(angle) + Center.x, 10*cos_deg(angle) + Center.y ); // start vertex
     glVertex2f( length*sin_deg(angle) + Center.x, length*cos_deg(angle) + Center.y ); // end vertex
     glEnd();
}

/* arguments an hour (float), a minute (float) and a number of seconds (float), 
and draws an analog clock. */
void drawClock(float hour, float minute, float second) {
     float angle;
     Vec2d Center = Vec2d( 400,300 ); // center point

     drawNecklace(); // brim
     drawStar( 5,10,10,Center ); // center star

     // star mark at every hour
     glColor3f( 1,1,0.85 );   
     for(int i=0;i<12;i++) {
             angle = 360.0 / 12 * i;
             drawStar( 2,5,10,Vec2d(125*cos_deg(angle) + Center.x,
                                    125*sin_deg(angle) + Center.y) );
                 
     }
     
     // hour hand
     // angle is sum of hour and minute passage
     glColor3f( 0.3,0.3,0.3 );
     drawHand( hour * 360/12 + minute * 360/12/60, 8, 80, Center );

     // minute hand
     glColor3f( 0.3,0.3,0.3 );
     drawHand( minute * 360/60 + second *360/60/60, 6, 120, Center );
     
     // second hand
     glColor3f( 0,0,0 );
     drawHand( second * 360/60, 1, 120, Center );
     
}

// call in displayFunc()
// for actual localtime, use reference
// struct tm: http://www.cplusplus.com/reference/clibrary/ctime/tm.html
// localtime http://www.cplusplus.com/reference/clibrary/ctime/localtime.html
     time_t rawtime;
     struct tm * timeinfo;

     time ( &rawtime );
     timeinfo = localtime ( &rawtime );

     mktime(timeinfo);

//     drawClock( 7.0, 23.0, 19.0 );
     drawClock( timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec );



: pearl decorated clock (time: 07:23:19 ), and it works on actual time too