Comp Form: Week 2

Vectors, ovals, stars, and a clock. . .

Problem 1. Complete the Vec2d class. Add the following methods to the class:
a. Subtract one vector from another and return the resulting vector.

Vec2d A(50,20);
Vec2d B(20,60);
Vec2d C;

C=A-B;

C.print();

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

in Vec2d.h:

Vec2d operator/(float D);

in Vec2d.cpp:

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

in main():

Vec2d A(50,20);
Vec2d D;

C=A/2;
D=A*.5;
C.print();
D.print();

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

in Vec2d.h:

Vec2d.h:float pythagorean(Vec2d B);

in Vec2d.cpp:

float Vec2d::pythagorean(Vec2d B)
{
float C=sqrt(B.x*B.x+B.y*B.y);
return C;
}

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:

void drawCircle(float radX, float radY, int centerX,int centerY, int numPoints){
//int numPoints=(radX+radY)/4;
Vec2d P;
Vec2d center(centerX,centerY);glBegin(GL_LINE_LOOP);for (int i=0;i<numPoints;i++){
float A=2*PI/numPoints*i;P.x=cos(A)*radX;
P.y=sin(A)*radY;P=P+center;glVertex2f(P.x,P.y);
}
glEnd();
}

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

int Rp=0;
int R=0;
int shift=0;
for (int i=1;i<6;i++){
shift=shift+Rp;
R=10*i;
Rp=R*2+10;
drawCircle(R, R, 100+shift, 200, 30);
}

screenshot_w22a.png

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.

int Rp=0;
int R=0;
int shift=0;
int n=3;
for (int i=1;i<6;i++){
shift=shift+Rp;
R=20*i;
Rp=R*2+20;
drawCircle(R, R, 100+shift, 200, n);
n++;
}

screenshot_2b.png

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 radX, float radY, int centerX,int centerY, int numPoints){
//int numPoints=(radX+radY)/4;
Vec2d P;
Vec2d center(centerX,centerY);

glBegin(GL_LINE_LOOP);

for (int i=0;i<numPoints;i++){
float A=2*PI/numPoints*i;

P.x=cos(A)*radX;
P.y=sin(A)*radY;

P=P+center;

glVertex2f(P.x,P.y);
}
glEnd();
} int Rp=0;
int xR=10;
int yR=100;

int shift=0;
int n=30;
for (int i=1;i<11;i++){

shift=shift+Rp;
xR=xR+10;
yR=yR-10;
Rp=xR*2+20;
drawOval(xR, yR, 10+shift, 200, n);
//n++;
}

w2_3.png

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 inRad, float outRad, int centerX,int centerY, int numPoints){
//int numPoints=(radX+radY)/4;
Vec2d P;
Vec2d center(centerX,centerY);
glBegin(GL_TRIANGLE_FAN);
for (int i=0;i<=numPoints;i++){
float A=2*PI/numPoints*i;
if(i%2==0){
P.x=cos(A)*inRad;
P.y=sin(A)*inRad;
}
else
{
P.x=cos(A)*outRad;
P.y=sin(A)*outRad;
}
P=P+center;
glVertex2f(P.x,P.y);
}
glEnd();
}

void background(){
glBegin(GL_POINTS);
for (int i=0;i<windowW;i++){
for (int j=0;j<windowH;j++){
if (j>windowH/2){
glColor3f( .5-float(j)/windowH*.2,.4-float(j)/windowH*2,.2+float(j)/windowH/6 ); //pen color (r,g,b)
}
if(j<windowH/2){
glColor3f( .2-float(j)/windowH,.1-float(j)/windowH,.1-float(j)/windowH); //pen color (r,g,b)
}
glVertex2f(i,j);
}
}
glEnd();
}

in displayFunc():

glColor3f( 1,1,1 );
int xR;
int yR;

for (int i=0;i<=100;i++){
xR=rand()%3;
yR=rand()%6+3;
drawStar(xR, yR, rand()%800, rand()%300+300, 10);
}

w2-4.png

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.

drawNecklace(200,250,150);

void drawNecklace(int width, int height, float numPoints){
for (float i=1;i<=numPoints;i++){
float rAA=-PI/2+PI*sinf((i-1)/numPoints*PI*2);//previous angle
float rA=-PI/2+PI*sinf(i/numPoints*PI*2)-rAA;//angle for radius of bead
float A=-PI/2+PI*sinf(i/numPoints*PI*2); //angle for center position

Vec2d o=ovalPoint(width, height, windowW/2,windowH/2, 30,A);
//float sizeShift=10;//sinf(i/numPoints*PI)*30;
Vec2d center(windowW/2,windowH/2);
Vec2d oo=o-center;

float h=oo.pythagorean();
//printf( “%fn”,h);
float r=sin(rA)*h;
glColor3f( 0,0,0 );
drawOval(r/2,r/2,o.x,o.y);
glColor3f( .9,.9,.9 );
Vec2d m(mouseX,mouseY);
Vec2d mouse=m-o;
float t=atan2(mouse.y,mouse.x);

if (i>numPoints/2) {
drawOval(r/6,r/6,o.x+r/3*cos(t),o.y+r/3*sin(t));
}else {
drawOval(r/8,r/8,o.x+r/3*cos(PI-t),o.y+r/3*sin(-t));
}
}
}

w2-necklacw.png

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.

Clock shows remaining time in a 12 hour sequence. Seconds on the inner ring, minutes in the middle, and hours in the outer ring.

/*
* main.cpp
* CompFormApp
*
*/

#include <OpenGL/gl.h> //openGL lib
#include <GLUT/glut.h> //glut lib

#include <stdio.h> //input output lib
#include <stdlib.h> //standard lib
#include <math.h> //math lib
#include <time.h>//time lib

#include “vec2d.h”

float windowW = 800; //window Width
float windowH = 600; //window Height

#define PI 3.14159265358979 //variable for pi

void drawMarkers(float total, float current, float r1, float r2){
for (float i=total;i>=current;i–){

float hx1=windowW/2-cos(i/total*PI*2+PI/2)*r1;
float hy1=windowH/2+sin(i/total*PI*2+PI/2)*r1;

float hx2=windowW/2-cos(i/total*PI*2+PI/2)*r2;
float hy2=windowH/2+sin(i/total*PI*2+PI/2)*r2;

float gradient=i/total-.02;
glColor3f(gradient, gradient, gradient);
//glLineWidth(2);
glBegin(GL_LINES);
glVertex2f(hx1,hy1);
glVertex2f(hx2,hy2);
glEnd();
}
}

void drawClock(float hour, float minute, float second){
//seconds
drawMarkers(60,second, 100, 160);
//minute
drawMarkers(60,minute, 150, 225);
//hour
drawMarkers(12, hour, 200, 250);
}

void displayFunc ( void )
{

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
time_t timeSince1970=time(NULL);
float seconds=timeSince1970%60;
float minutes=(timeSince1970%(60*60))/60.0;
float hours=timeSince1970%(12*60*60)/3600.0+8;
if (hours>12) {
hours=hours-12;
}
//printf(”%f “,hours);
drawClock(hours, minutes, seconds);

glutPostRedisplay(); //repeat, redraw
glutSwapBuffers(); //swaps offscreen buffer, offscreen to onscreen
}

clock_1.png

version 2:

void drawClock(float hour, float minute, float second){
//seconds
drawMarkers(60*5,second, 155, 160);
//minute
drawMarkers(60*12/2,minute*12/2, 161, 200);
//hour
drawMarkers(12, hour, 201, 250);
}

clock2.png