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