Week 6 Assignment

Yasmin Elayat

 

Problem 1. Create a function called smoothPath that takes as input an array of points (Vec2d*), the number of points (int), and a smoothing parameter (float) between 0.0 and 1.0. Apply this function to a stroke that has been drawn. Optionally, try applying it to the stroke as it's being drawn. (dynamicSmoothPath)

void smoothPath(Vec2d unsmooth[], int numPoints, float smooth) {
     //S = A*w1 + B*w2  + C*w3
     // S = smoothed point
     // A = previous point, B = current pt, C = next pt
     // weights w1 + w2 + w3 = 1.0
     
     //leave both endpoints untouched
     //"get closer to your neighbors"
     
     glBegin(GL_LINE_STRIP );
     for(int i =0; i < numPoints - 1; i++) 
     {
               Vec2d currentPoint = unsmooth[i];
               glVertex2f(currentPoint.x, currentPoint.y);
     }
     glEnd();
     
     //make a duplicate array (copy line) and 
     //reference original when calculating the new array         
//     Vec2d copyPoints = points;   
     glBegin(GL_LINE_STRIP); 
     glColor3f(0.0, 1.0, 1.0);
     for(int i = 1; i < numPoints-1; i++) {
             Vec2d currentPoint = unsmooth[i];
             Vec2d prevPoint = unsmooth[i-1];
             Vec2d nextPoint = unsmooth[i+1];
             //glVertex2f(currentPoint.x, currentPoint.y);
             
             float w1 = 0.25;
             float w2 = 0.5;
             float w3 = 0.25;
             
             Vec2d smoothPoint = prevPoint*w1 + currentPoint*w2 + nextPoint*w3;
             glVertex2f(smoothPoint.x, smoothPoint.y); 
             //points[i] = smoothPoint;
     }
     glEnd();
}


void dynamicSmoothPath(float smooth = 1.0) {
     
     drawAStroke(1);
        
     for(int i = 1; i < numPoints-1; i++) {
             Vec2d currentPoint = pointList[i];
             Vec2d prevPoint = pointList[i-1];
             Vec2d nextPoint = pointList[i+1];
             //glVertex2f(currentPoint.x, currentPoint.y);
             
             float w1 = 0.25;
             float w2 = 0.5;
             float w3 = 0.25;
             
             Vec2d smoothPoint = prevPoint*w1 + currentPoint*w2 + nextPoint*w3;
             glVertex2f(smoothPoint.x, smoothPoint.y); 
             pointList[i] = smoothPoint;
     }
}
     
	  

 

Problem 2. Create a function called distortPath that distorts a shape by pushing its vertices radially away from 10 pre-set points on the screen, each of which should have a different distortion strength. Apply this function to a circle composed of 360 points. Optionally, allow the circle to be dragged about the screen.

void distortPath()
{
     //path of distortion. i.e. the points that will distort the shapes
     //each must have a distortion strenght whcih will be determined
     //by their vector length? or the decay function
     glBegin(GL_FILL); //STRIP);
     glPointSize(1);
     glColor3f(1.0,0,0);
     for(int i = 0; i < 10; i++) {            
             //drawCircle(5, 10, distorters[i]);
             //glVertex2f(distorters[i].x, distorters[i].y);       
             drawPearl(5, 10, distorters[i]);
     }
     glEnd();
     
   

     Vec2d P;
     Vec2d center(mouseX, mouseY);
     glBegin(GL_POINTS); 
     glPointSize(10);
     glColor3f(0,1.0,0);
     for(int i = 0; i < 360; i++) {
            // 360 = 2*PI radians
            float A = 2*PI / 360 * i;  //cos, sin takes radians
                       
            P.x = cos(A) * 100.0;
            P.y = sin(A) * 100.0; 
                        
            P = P + center; //vector math to perform a translation
            
            for(int i = 0; i < 10; i++) {            
                Vec2d V = P - distorters[i];
                float vLen = V.getLength();

                V.normalize();             
              
                //fall off function f(x) = 1/x
                float distort = 1/vLen * distorters[i].weight;
                //other option:
                //float amp = 20;
                //float radius; = 100.0;
                //vLen /= radius;
                //float distort = amp * pow(2.0, -1.0*vLen*vLen);
                //it wasn't working before because vLen was too small and we needed 0 - 2

                P = P + V * distort;     
            }       
            glVertex2f(P.x,P.y);            
    }
    glEnd();    
}
	  

 

Problem 3. Create a function that detects if a drawn stroke intersects itself. If it has, draw a finished shape that uses the intersection point as its start and end point, and is filled in solid red. Call this function continuously while drawing.

Vec2d intersectPts[10000];
int intersectCount =0;

bool intersects(Vec2d P0a, Vec2d P0b, Vec2d P1a, Vec2d P1b) {
         
     //compute intersection of 2 lines
     
     //calculate slopes
     //dy/dx, change of y of first line/change of x of second line
     float M0 = (P0b.y - P0a.y) / (P0b.x - P0a.x); 
     float M1 = (P1b.y - P1a.y) / (P1b.x - P1a.x); //slope
     
     //    x = y1 - y0 - x1*m1 + x0*m0
     float X = P1a.y - P0a.y - P1a.x*M1 + P0a.x*M0; 
     X /= (M0 - M1); //make sure m0 and m1 not equal to each other to avoid divide by zero
     
     //    y = y0 + (x - x0) * m0
     float Y = P0a.y + (X - P0a.x)*M0;
     
     //check intersection is within line segment boundaries
     //bounding box prob:
     //starting point might not be on the right hand side and the other on the left hand side
     //fix:
     float left0 = min(P0a.x, P0b.x);
     float right0 = max(P0a.x, P0b.x);

     float left1 = min(P1a.x, P1b.x);
     float right1 = max(P1a.x, P1b.x);
     
     //set color to green if line segments intersect
     if( X > left0 && X < right0 && X > left1 && X < right1) {
         intersectPts[intersectCount].x = X;
         intersectPts[intersectCount++].y = Y;
         return true; //&Vec2d(X,Y);//true;
     }
     else return false;
}        

int startPt;
int endPt;

void drawIntersectingShape()
{    
     drawAStroke(1);    
     for(int i =0; i < numPoints; i++) 
     {
          if(intersects(pointList[i], pointList[i+1], pointList[numPoints-1], pointList[numPoints-2])) {     
                startPt = i + 1;
                endPt=numPoints;
          }
     }
    
    glColor3f(1,0,0); //if it intersects line segment
    for(int i = 0; i