Week 8 Assignment - Computational Forms

Lucas Longo

 

Problem 1. Create a function called Problem 1. Create a 30 x 30 mesh using a two-dimensional array of Vec3D's. Then create a function that draws your mesh as a wireframe. (Be sure to use "const int" variables represent the width and height of your mesh, instead of hard-coding it always to be 30 x 30.)

void drawMesh()
{
glPushMatrix();
glRotatef(mouseY,-1,0,0);
glRotatef(mouseX,0,-1,0);

for (int x = 0; x < meshW; x++){
for (int z = 0; z < meshH; z++){

float y = -100 + sin(x);

mesh[x][z].x = x*20;
mesh[x][z].y = 10*sin(x);
mesh[x][z].z = z*20;
}
}

glBegin(GL_LINES);
for (int x = 0; x < meshW-1; x++){
for (int z = 0; z < meshH-1; z++){

Vec3d A = mesh[x][z];
Vec3d B = mesh[x+1][z];
Vec3d C = mesh[x+1][z+1];
Vec3d D = mesh[x][z+1];

glColor3f(1,1,0);
glVertex3f(A.x,A.y,A.z);
glVertex3f(B.x,B.y,B.z);
glVertex3f(C.x,C.y,C.z);

glColor3f(0,1,0);
glVertex3f(A.x,A.y,A.z);
glVertex3f(D.x,D.y,D.z);
glVertex3f(C.x,C.y,C.z);

}
}
glEnd();
glPopMatrix();
}

Problem 2. Create a function that draws your mesh a solid surface and sets the color of each face according to the simple lighting model discussed in class.

void drawSolidMesh()
{
glPushMatrix();
glRotatef(30 ,1,0,0);
glRotatef(30 ,0,1,0);

for (int x = 0; x < meshW; x++){
for (int z = 0; z < meshH; z++){
mesh[x][z].x = x*20-200;
mesh[x][z].y = 10*sin(x);
mesh[x][z].z = z*20-200;
}
}

glBegin(GL_TRIANGLES);
for (int x = 0; x < meshW-1; x++){
for (int z = 0; z < meshH-1; z++){

Vec3d A = mesh[x][z];
Vec3d B = mesh[x+1][z];
Vec3d C = mesh[x+1][z+1];
Vec3d D = mesh[x][z+1];

Vec3d AB = B - A;
Vec3d AC = C - A;
Vec3d AD = D - A;

Vec3d N1 = AC.cross(AB);
Vec3d N2 = AD.cross(AC);
N1.normalize();
N2.normalize();

Vec3d L = Vec3d(mouseX,mouseY,300);
L.normalize();

float shade1 = L.dot(N1);
float shade2 = L.dot(N2);

if (shade1 < 0)
shade1 = 0;
if (shade2 < 0)
shade2 = 0;

glColor3f(shade1, shade1, 0);
glVertex3f(A.x,A.y,A.z);
glVertex3f(B.x,B.y,B.z);
glVertex3f(C.x,C.y,C.z);

glColor3f(shade2, shade2, 0);
glVertex3f(A.x,A.y,A.z);
glVertex3f(D.x,D.y,D.z);
glVertex3f(C.x,C.y,C.z);
}
}
glEnd();
glPopMatrix();
}

Problem 3. Create a function that makes a mountain out of your mesh.

void drawMountain()
{
float peaks = 30;

glPushMatrix();
glRotatef(30 ,1,0,0);
glRotatef(30 ,0,1,0);
glTranslatef(-trans,0,-trans);

for (int x = 0; x < meshW; x++){
for (int z = 0; z < meshH; z++){

if (x > meshW/4 && x < meshW/4*3){
peaks += 5*sin(z);
} else {
peaks = 30*sin(x);
}

mesh[x][z].x = x*20;
mesh[x][z].y = peaks*sin(x) + peaks*sin(z);
mesh[x][z].z = z*20;
}
}

glBegin(GL_TRIANGLES);
for (int x = 0; x < meshW-1; x++){
for (int z = 0; z < meshH-1; z++){

Vec3d A = mesh[x][z];
Vec3d B = mesh[x+1][z];
Vec3d C = mesh[x+1][z+1];
Vec3d D = mesh[x][z+1];

Vec3d AB = B - A;
Vec3d AC = C - A;
Vec3d AD = D - A;

Vec3d N1 = AC.cross(AB);
Vec3d N2 = AD.cross(AC);
N1.normalize();
N2.normalize();

Vec3d L = Vec3d(mouseX,300,300);
L.normalize();

float shade1 = L.dot(N1);
float shade2 = L.dot(N2);

if (shade1 < 0)
shade1 = 0;
if (shade2 < 0)
shade2 = 0;

glColor3f(shade1, 0.2, 0);
glVertex3f(A.x,A.y,A.z);
glVertex3f(B.x,B.y,B.z);
glVertex3f(C.x,C.y,C.z);

glColor3f(shade2, 0.2, 0);
glVertex3f(A.x,A.y,A.z);
glVertex3f(D.x,D.y,D.z);
glVertex3f(C.x,C.y,C.z);
}
}
glEnd();
glPopMatrix();
}

Problem 4. Create a function that produces waves in one direction (along x) in your mesh.

void drawWaves1(int animate)
{
glPushMatrix();
glRotatef(30 ,1,0,0);
glRotatef(30 ,0,1,0);
glTranslatef(-trans+20, 0, -trans-500);

for (int x = 0; x < meshW; x++){
for (int z = 0; z < meshH; z++){
mesh[x][z].x = x*40;
mesh[x][z].y = 10*sin(x+animate/10);
mesh[x][z].z = z*40;
}
}

glBegin(GL_TRIANGLES);
for (int x = 0; x < meshW-1; x++){
for (int z = 0; z < meshH-1; z++){

Vec3d A = mesh[x][z];
Vec3d B = mesh[x+1][z];
Vec3d C = mesh[x+1][z+1];
Vec3d D = mesh[x][z+1];

Vec3d AB = B - A;
Vec3d AC = C - A;
Vec3d AD = D - A;

Vec3d N1 = AC.cross(AB);
Vec3d N2 = AD.cross(AC);
N1.normalize();
N2.normalize();

Vec3d L = Vec3d(mouseX,300,300);
L.normalize();

float shade1 = L.dot(N1);
float shade2 = L.dot(N2);

if (shade1 < 0)
shade1 = 0;
if (shade2 < 0)
shade2 = 0;

glColor3f(0, 0, shade1);
glVertex3f(A.x,A.y,A.z);
glVertex3f(B.x,B.y,B.z);
glVertex3f(C.x,C.y,C.z);

glColor3f(0, 0, shade2);
glVertex3f(A.x,A.y,A.z);
glVertex3f(D.x,D.y,D.z);
glVertex3f(C.x,C.y,C.z);
}
}
glEnd();
glPopMatrix();
}

void drawProblem4()
{
drawWaves1(animate);
animate++;
}

Problem 5. Create a function that produces waves in two directions (along x and z ) in your mesh.

void drawWaves2(int animate)
{
glPushMatrix();
glRotatef(30 ,1,0,0);
glRotatef(30 ,0,1,0);
glTranslatef(-trans+20, 0, -trans-500);

for (int x = 0; x < meshW; x++){
for (int z = 0; z < meshH; z++){
mesh[x][z].x = x*40;
mesh[x][z].y = 10*sin(x+animate/10) + 2*sin(z+animate/10*2);
mesh[x][z].z = z*40;
}
}

glBegin(GL_TRIANGLES);
for (int x = 0; x < meshW-1; x++){
for (int z = 0; z < meshH-1; z++){

Vec3d A = mesh[x][z];
Vec3d B = mesh[x+1][z];
Vec3d C = mesh[x+1][z+1];
Vec3d D = mesh[x][z+1];

Vec3d AB = B - A;
Vec3d AC = C - A;
Vec3d AD = D - A;

Vec3d N1 = AC.cross(AB);
Vec3d N2 = AD.cross(AC);
N1.normalize();
N2.normalize();

Vec3d L = Vec3d(mouseX,300,300);
L.normalize();

float shade1 = L.dot(N1);
float shade2 = L.dot(N2);

if (shade1 < 0)
shade1 = 0;
if (shade2 < 0)
shade2 = 0;

glColor3f(0, 0, shade1);
glVertex3f(A.x,A.y,A.z);
glVertex3f(B.x,B.y,B.z);
glVertex3f(C.x,C.y,C.z);

glColor3f(0, 0, shade2);
glVertex3f(A.x,A.y,A.z);
glVertex3f(D.x,D.y,D.z);
glVertex3f(C.x,C.y,C.z);
}
}
glEnd();
glPopMatrix();
}

void drawProblem5()
{
drawWaves5(animate2);
animate2++;
}

Problem 6. Create a function that adds random variation to your mesh. Then using a two-dimensional smoothing function, smooth out the mesh. The smoothing function for each point should take into acount the four points directly connected to it. It may also include the other four points that are diagonally related to it. The inputs to this function should be the height of the random variation, and the level of smoothing.
void drawSmoothMesh(int distH, float smooth)
{
glPushMatrix();
glRotatef(mouseX ,0,1,0);
glRotatef(mouseY ,1,0,0);
glTranslatef(-trans,0,-trans);

if (notComplete2){
for (int x = 0; x < meshW; x++){
for (int z = 0; z < meshH; z++){
mesh[x][z].x = x*20;

if (x%10 <= 5)
mesh[x][z].y = 30*random()%distH;
else
mesh[x][z].y = 50*random()%distH;
if (z%10 <= 5)
mesh[x][z].y = 20*random()%distH;
else
mesh[x][z].y = 50*random()%distH;

mesh[x][z].z = z*20;
}
}

Vec3d newMesh[meshW][meshH];

for (int x = 0; x < meshW - 1; x++){
for (int z = 0; z < meshH - 1; z++){
Vec2d A(mesh[x][z].x, mesh[x][z].y);
Vec2d B(mesh[x][z+1].x, mesh[x][z+1].y);
Vec2d C(mesh[x][z-1].x, mesh[x][z-1].y);
Vec2d D(mesh[x+1][z].x, mesh[x+1][z].y);
Vec2d E(mesh[x-1][z].x, mesh[x-1][z].y);

Vec2d F(mesh[x-1][z-1].x, mesh[x-1][z-1].y);
Vec2d G(mesh[x-1][z+1].x, mesh[x][z+1].y);
Vec2d H(mesh[x+1][z-1].x, mesh[x+1][z-1].y);
Vec2d I(mesh[x+1][z+1].x, mesh[x+1][z+1].y);

float w1 = smooth;
float w2 = (1.0-smooth) / 8;
float w3 = (1.0-smooth) / 8;
float w4 = (1.0-smooth) / 8;
float w5 = (1.0-smooth) / 8;

float w6 = (1.0-smooth) / 8;
float w7 = (1.0-smooth) / 8;
float w8 = (1.0-smooth) / 8;
float w9 = (1.0-smooth) / 8;

Vec2d Z = A * w1 + B * w2 + C * w3 + D * w4 + E * w5 + F * w6 + G * w7 + H * w8 + I * w9;

newMesh[x][z] = Vec3d(mesh[x][z].x, Z.y, mesh[x][z].z);
}
}

for (int x = 0; x < meshW - 1; x++){
for (int z = 0; z < meshH - 1; z++){
mesh[x][z] = newMesh[x][z];
}
}
notComplete2 = false;
}

glBegin(GL_TRIANGLES);
for (int x = 0; x < meshW-1; x++){
for (int z = 0; z < meshH-1; z++){

Vec3d A = mesh[x][z];
Vec3d B = mesh[x+1][z];
Vec3d C = mesh[x+1][z+1];
Vec3d D = mesh[x][z+1];

Vec3d AB = B - A;
Vec3d AC = C - A;
Vec3d AD = D - A;
Vec3d DC = C - D;

Vec3d N1 = AC.cross(AB);
Vec3d N2 = AD.cross(AC);
N1.normalize();
N2.normalize();

Vec3d L = Vec3d(500,500,0);
L.normalize();

float shade1 = L.dot(N1);
float shade2 = L.dot(N2);

if (shade1 < 0)
shade1 = 0;
if (shade2 < 0)
shade2 = 0;

glColor3f(shade1, shade1, 0);
glVertex3f(A.x,A.y,A.z);
glVertex3f(B.x,B.y,B.z);
glVertex3f(C.x,C.y,C.z);

glColor3f(shade2, shade2, 0);
glVertex3f(A.x,A.y,A.z);
glVertex3f(D.x,D.y,D.z);
glVertex3f(C.x,C.y,C.z);
}
}
glEnd();
glPopMatrix();
}
Problem 7. Create a function that produces multiple vertical distortions in your mesh. Use the bell-curve function to distort the mesh about a series of points located around the mesh.

void drawMeshDistortion()
{
glPushMatrix();
glRotatef(30 , 0 , 1 , 0);
glRotatef(30 , 1 , 0 , 0);
glTranslatef(-trans,0,-trans);

for (int x = 0; x < meshW; x++){
for (int z = 0; z < meshH; z++){
mesh[x][z].x = x*40;
mesh[x][z].y = 10*sin(x) + 10*sin(z);
mesh[x][z].z = z*40;
}
}

for (int x = 0; x < meshW; x++){
for (int z = 0; z < meshH; z++){
Vec3d mousePos(mouseX, mouseY, mouseX+100);
Vec3d N = mesh[x][z] - mousePos;
float nLength = N.length();
N.normalize();

nLength /= 5000;

float offset = 100 * pow(2.0, -1.0 * (nLength * nLength));

mesh[x][z] = mesh[x][z] + N * offset;
}
}

glBegin(GL_TRIANGLES);
for (int x = 0; x < meshW-1; x++){
for (int z = 0; z < meshH-1; z++){

Vec3d A = mesh[x][z];
Vec3d B = mesh[x+1][z];
Vec3d C = mesh[x+1][z+1];
Vec3d D = mesh[x][z+1];

Vec3d AB = B - A;
Vec3d AC = C - A;
Vec3d AD = D - A;
Vec3d DC = C - D;

Vec3d N1 = AC.cross(AB);
Vec3d N2 = AD.cross(AC);
N1.normalize();
N2.normalize();

Vec3d L = Vec3d(500,500,0);
L.normalize();

float shade1 = L.dot(N1);
float shade2 = L.dot(N2);

if (shade1 < 0)
shade1 = 0;
if (shade2 < 0)
shade2 = 0;

glColor3f(shade1, shade1, 0);
glVertex3f(A.x,A.y,A.z);
glVertex3f(B.x,B.y,B.z);
glVertex3f(C.x,C.y,C.z);

glColor3f(shade2, shade2, 0);
glVertex3f(A.x,A.y,A.z);
glVertex3f(D.x,D.y,D.z);
glVertex3f(C.x,C.y,C.z);
}
}
glEnd();

glColor3f(1,0,0);
glPointSize(5);
glBegin(GL_POINTS);
glVertex3f(mouseX, mouseY, mouseX+100);
glEnd();

glPopMatrix();

}

Problem 8. This problem is optional. Create a function that uses a small grayscale image to distort the mesh. The image should be a 30 x 30 grayscale image saved in the RAW format in Photoshop. This requires some deft C programming, and will utilize the following functions: fopen, malloc, fread and fclose.