Week 5 Assignment (desc)

Younghyun Chung

 

Problem 1. Write a program that allows the user to draw a stroke of up to 1000 points. Optionally, implement a feature that prevents the addition of points that are closer than 5 pixels from the last point added.

// global variables
int       numPoints = 0;
Vec2d     pointList[1000];
Vec2d     lastPoint = Vec2d( 0,0 ); // store last point

// function
void drawStroke1() {
     glColor3f ( 0,0,0 );
     glLineWidth ( 5 );
     glBegin ( GL_LINE_STRIP );
     for ( int i=0; i<numPoints-1; i++ )
         glVertex2f( pointList[i].x, pointList[i].y );
     glEnd();
}

// in mouseDragFunc
    Vec2d currentPoint = Vec2d( mouseX, mouseY ); // for W5_1

    if ( numPoints < 1000 && ( lastPoint-currentPoint ).length() > 5  )  {
         pointList[ numPoints ].x = mouseX;
         pointList[ numPoints ].y = mouseY;
         lastPoint = currentPoint;
         numPoints++;
    }

// in keyboardFunc
     numPoints = 0; // initialize if change the problem set



: Klimt's painting

 

Problem 2. Create a function that draws the stroke (from Problem 1) using the special wide-stroke method. The function should take as input the desired with of the stroke as a float.

void drawStroke2( float strokeWidth ) {
     glColor4f ( 0,0,0,0.3 );       // alpha value
     glLineWidth ( 5 );           
     glBegin ( GL_TRIANGLE_STRIP );
     for ( int i=1; i<numPoints-1; i++ ) {
         Vec2d currentPoint = pointList[i]; // center point
         
         // calculating the point of stroke
         Vec2d A = pointList[i-1];        
         Vec2d B = pointList[i+1];
             
         Vec2d V = B - A;
         V.normalize();
         Vec2d Vp = Vec2d( -V.y, V.x );

         Vec2d C = currentPoint + Vp*strokeWidth/2;
         Vec2d D = currentPoint - Vp*strokeWidth/2;
         
         glVertex2f( C.x, C.y );
         glVertex2f( D.x, D.y );
         
     }
     glEnd();
}


// call in displayFunc
drawStroke2(5.0);


: alpha valued


:

 

Problem 3. Create a function that draws the stroke with a three-step stair-step pattern along it on just one side of the stroke.

void drawStroke3() {
     drawStroke1( 1 ); // draw a stroke
     float strokeWidth = 10; // width of stair
     glColor3f ( 0,0,0 );
     glLineWidth ( 1 );
     
     glBegin ( GL_LINES );
     for ( int i=1; i<numPoints-1; i++ ) {
         Vec2d currentPoint = pointList[i];
         Vec2d A = pointList[i-1];

         // calculate perpendicular vector and normalize             
         Vec2d V =  currentPoint - A;
         V.normalize();
         Vec2d Vp = Vec2d( -V.y, V.x );

         // get each point of step and draw
         Vec2d stairPoint = currentPoint;       
         for (int j=0; j<3; j++ ) {
             glVertex2f( stairPoint.x, stairPoint.y );
             stairPoint = stairPoint + Vp*strokeWidth;
             glVertex2f( stairPoint.x, stairPoint.y );

             glVertex2f( stairPoint.x, stairPoint.y );
             stairPoint = stairPoint - V*strokeWidth;
             glVertex2f( stairPoint.x, stairPoint.y );
         }
     }
     glEnd();
}



: three step stair step pattern along left side of the stroke

 

Problem 4. Create a function that the draws the stroke with a wave that runs perpendicular to the direction of the stroke. The wave should affect the path of the stroke, not its width. The function should take an amplitude and frequency as input

void drawStroke4( float Amplitude, float Frequency ) {
     drawStroke1(2);
     glColor4f ( 1,0,0,0.8 );
     glLineWidth ( 4 );
     
     glBegin( GL_LINE_STRIP );
     for ( int i=1; i<numPoints-1; i++ ) {
         Vec2d currentPoint = pointList[i];
         Vec2d A = pointList[i-1];

         Vec2d V =  currentPoint - A;
         V.normalize();
         Vec2d Vp = Vec2d( -V.y, V.x );
         
         float offset = Amplitude * sin_deg(i * Frequency);
         
         currentPoint = currentPoint + Vp * offset;
         glVertex2f( currentPoint.x, currentPoint.y );
         
     }
     glEnd();
}

// call in displayFunc
                drawStroke4( 30, 30);


:

 

Problem 5. Create a function that the draws the stroke with a giant arrowhead at its tip. The arrowhead should be in alignment the last stroke segment. Optionally, draw a series of similar but smaller arrows along the length of the whole stroke.

void drawStroke5() {
     float strokeWidth = 50;
     glColor4f ( 0,0,0,0.8 );
     glLineWidth ( 1 );
     glBegin ( GL_LINE_STRIP );
     for ( int i=1; i<numPoints-1; i++ ) {
         Vec2d currentPoint = pointList[i];
         
         Vec2d A = pointList[i-1];
         Vec2d B = pointList[i+1];
             
         Vec2d V = B - A;
         V.normalize();
         Vec2d Vp = Vec2d( -V.y, V.x );

         // perpendicular component, parellel component
         Vec2d C = currentPoint + Vp*strokeWidth - V*strokeWidth*2; 
         Vec2d D = currentPoint - Vp*strokeWidth - V*strokeWidth*2;
         
         // draw Giant arrowhead
         glVertex2f( C.x, C.y );
         glVertex2f( currentPoint.x, currentPoint.y );
         glVertex2f( D.x, D.y );
         glVertex2f( currentPoint.x, currentPoint.y );
     }
     glEnd();
}

:

 

Problem 6. Create a function that draws the stroke in a creative method of your choosing.

void drawStroke6( ) {
     glColor4f ( 0.2, 0.8, 0.3, 0.3);
     glLineWidth ( 5 );           
     
     for ( int i=10; i<numPoints-10; i++ ) {
         drawCubicBezierCurve( pointList[i-10], pointList[i-2], 
                               pointList[i+2], pointList[i+10] );        
     }
}

: green, alpha, bezier

 

Problem 7. Create a function that rotates a shape by a given angle. The function should take as input an array of points (Vec2d *), the number of points in the array (int), and an angle of rotation in degrees. You may want to calculate the center point and then rotate the points around the center, rather than about the window origin.

void drawShapeRotate ( Vec2d *Shape, int numberPoints, float rotateDegree ) {
     glLineWidth ( 1 );

     // draw regular shape
     glColor3f ( 0,0,0 );
     glBegin ( GL_LINE_LOOP );
     for ( int i=0; i<numberPoints; i++ ) {
         glVertex2f( Shape[i].x, Shape[i].y );
     }
     glEnd();
     
     // draw rotated shape
     Vec2d Xp, Yp;
     
     Xp.x = cos_deg( rotateDegree );
     Xp.y = sin_deg( rotateDegree );
     
     Yp.x = -sin_deg( rotateDegree );
     Yp.y = cos_deg( rotateDegree );
     
     Vec2d center( windowW/2, windowH/2 );
     
     glColor3f ( 1,0,0 );
     glBegin ( GL_LINE_LOOP );
     for ( int i=0; i<numberPoints; i++ ) {
             Vec2d currentPoint = Shape[i];
             currentPoint = currentPoint - center;
             Vec2d rotatedPoint = Xp*currentPoint.x + Yp*currentPoint.y;
             rotatedPoint = rotatedPoint + center;
             glVertex2f( rotatedPoint.x, rotatedPoint.y );
     }
     glEnd();
}

void drawRotate7 () {
       Vec2d Shape[5] = { Vec2d(500,200), Vec2d(600,200), Vec2d(600,300), 
                          Vec2d(500,300), Vec2d(450,250) };
       drawShapeRotate( Shape, 5, 30 );
}

: rotation

 

Problem 8. Create a function that twists a shape around its center. The further a point is from the center, the more it should be rotated.

void drawShapeRotate8 ( Vec2d *Shape, int numberPoints ) {
     float rotateDegree = 30;
     glLineWidth ( 1 );

     // draw regular shape
     glColor3f ( 0,0,0 );
     glBegin ( GL_LINE_LOOP );
     for ( int i=0; i<numberPoints; i++ ) {
         glVertex2f( Shape[i].x, Shape[i].y );
     }
     glEnd();
     
     // draw rotated shape
     
     Vec2d center( windowW/2, windowH/2 );
     
     glColor3f ( 1,0,0 );
     glBegin ( GL_LINE_LOOP );
     for ( int i=0; i<numberPoints; i++ ) {
         float distance = ( Shape[i] - center ).length();
         rotateDegree = 0.3*distance;
         
         Vec2d Xp, Yp;
         
         Xp.x = cos_deg( rotateDegree );
         Xp.y = sin_deg( rotateDegree );
         
         Yp.x = -sin_deg( rotateDegree );
         Yp.y = cos_deg( rotateDegree );

         Vec2d currentPoint = Shape[i];
         currentPoint = currentPoint - center;
         Vec2d rotatedPoint = Xp*currentPoint.x + Yp*currentPoint.y;
         rotatedPoint = rotatedPoint + center;
         glVertex2f( rotatedPoint.x, rotatedPoint.y );
     }
     glEnd();
}

: twisted rotation