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
|
|