Posted by Fourth on Mon 17 Nov 15:15
report abuse | download | new post
- /*
- * shape.cpp
- *
- * Tessellation algorithms by Nicholas Forysinski
- *
- * This file performs tessellations on 4 different shapes: cones, spheres,
- * cubes, and cylinders. It uses various iterative methods for creating
- * triangle tessellations in these 4 shapes.
- *
- */
- #include "shape.h"
- #include "draw_routines.h"
- #include <fstream>
- #include <math.h>
- // you must write this file
- const double PI = 3.14159265359;
- Shape::~Shape() {
- }
- void Shape::draw() {
- for (unsigned int i = 0; i < vertices.size(); i += 3)
- DrawRoutines::drawTriangle(vertices[i], vertices[i + 1], vertices[i + 2]);
- }
- Shape::Shape() : vertices() {
- }
- void Shape::addTriangle(const Point3& p1, const Point3& p2, const Point3& p3) {
- vertices.push_back(p1);
- vertices.push_back(p2);
- vertices.push_back(p3);
- }
- void Shape::addSquare(const Point3& p1, const Point3& p2,
- const Point3& p3, const Point3& p4) {
- addTriangle(p1,p2,p3);
- addTriangle(p3,p4,p1);
- }
- //container is the set of vertices that create the polygons
- void Shape::subdivide( vector<Point3>& container, const Point3& p0,
- const Point3& p1, const Point3& p2, const int level ) {
- vector<Point3> tempPoly = container; //holds the old sets of polygons
- //subdivide each original triangle by 'n' number of levels
- for( int l = 1; l < level; l++ ) {
- vector<Point3> newPoly = tempPoly;
- //split a single triangle into 4 new triangles
- for( int i = 0; i < tempPoly.size(); i++ ) {
- Point3 a,b,c;
- a = a;
- }
- }
- }
- Cube::Cube(int n) : Shape() {
- double x1,x2,y1,y2,z1,z2;
- x1 = -0.5;
- x2 = 0.5;
- y1 = -0.5;
- y2 = 0.5;
- z1 = .5; // front
- z2 = -.5; // back
- Point3 op3(x2,y2,z1);
- Point3 op2(x1,y2,z1);
- Point3 op1(x1,y1,z1);
- Point3 p3 = op3;
- Point3 p2 = op2;
- Point3 p1 = op1;
- float fx = n-1;
- float fy = n-1;
- float fz = n-1;
- Point3 temp = p3;
- //front and back
- //iterate through the square creating smaller squares made up of 2 triangles
- for( int x = 0; x < 2; x++ ) {
- for( int i = 0; i < n; i++ ) { //rows
- float facty = fy/n;
- float npy = (1-facty)*p1.y + facty*p2.y;
- for( int j = 0; j < n; j++ ) { //cols
- float factx = fx/n;
- float npx = (1-factx)*p2.x + factx*p3.x;
- Point3 topL( npx, temp.y, temp.z);
- Point3 lowR( temp.x, npy, temp.z);
- Point3 midP( npx, npy, temp.z);
- addSquare( temp, topL, midP, lowR );
- temp = topL;
- fx--;
- }
- fx = n-1;
- temp.x = p3.x;
- temp.z = p3.z;
- temp.y = npy;
- fy--;
- }
- fy = n-1;
- //reset for the back
- p2 = op3;
- p3 = op2;
- p1.x = p2.x;
- p3.z = z2;
- p2.z = z2;
- p1.z = z2;
- temp = p3;
- }
- //set up for the top
- p3 = op3;
- p2 = op2;
- p1 = op1;
- p3.z = z2;
- p2.z = z2;
- p1.y = p2.y;
- fx = n-1;
- temp = p3;
- //top and bottom
- for( int x = 0; x < 2; x++ ) {
- for( int i = 0; i < n; i++ ) { //rows
- float factz = fz/n;
- float npz = (1-factz)*p1.z + factz*p2.z;
- for( int j = 0; j < n; j++ ) { //cols
- float factx = fx/n;
- float npx = (1-factx)*p2.x + factx*p3.x;
- Point3 topL( npx, temp.y, temp.z);
- Point3 lowR( temp.x, temp.y, npz);
- Point3 midP( npx, temp.y, npz);
- addSquare( temp, topL, midP, lowR );
- temp = topL;
- fx--;
- }
- fx = n-1;
- temp.x = p3.x;
- temp.z = npz;
- temp.y = p3.y;
- fz--;
- }
- fz = n-1;
- //reset for the bottom
- p3 = op3;
- p2 = op1;
- p1 = op1;
- p1.z = z2;
- p3.y = p1.y;
- temp = p3;
- }
- //set up for the right
- p3 = op3;
- p2 = op3;
- p1.x = p2.x;
- p3.z = z2;
- fz = n-1;
- fy = n-1;
- temp = p3;
- //top and bottom
- for( int x = 0; x < 2; x++ ) {
- for( int i = 0; i < n; i++ ) { //rows
- float facty = fy/n;
- float npy = (1-facty)*p1.y + facty*p2.y;
- for( int j = 0; j < n; j++ ) { //cols
- float factz = fz/n;
- float npz = (1-factz)*p2.z + factz*p3.z;
- Point3 topL( temp.x, temp.y, npz);
- Point3 lowR( temp.x, npy, temp.z);
- Point3 midP( temp.x, npy, npz);
- addSquare( temp, topL, midP, lowR );
- temp = topL;
- fz--;
- }
- fz = n-1;
- temp.x = p3.x;
- temp.z = p3.z;
- temp.y = npy;
- fy--;
- }
- fy = n-1;
- //reset for the left
- p3 = op2;
- p2 = op2;
- p2.z = z2;
- p1 = op1;
- p1.z = z2;
- temp = p3;
- }
- }
- Cone::Cone(int n, int m) : Shape() {
- if (n < 3)
- n = 3;
- double x1,y1,z1,x2,y2,z2;
- x1 = -0.5;
- x2 = 0.5;
- y1 = -0.5;
- y2 = 0.5;
- z1 = .5;
- z2 = -.5;
- Point3 fixedPB( 0, y1, 0 ); //fixed point at the bottom
- Point3 fixedPT( 0, y2, 0 ); //fixed point at the top
- vector<Point3> circumPoints; //vector to hold circumference points
- //do the bottom first
- //begin by solving the circumference points
- float angle = 360/n; //get the angle interval
- for( double i = 0; i < 360; i+=angle ) {
- double px = .5*cos( i * (PI/180) );
- double pz = .5*sin( i * (PI/180) );
- Point3 circP( px, y2, pz );
- circumPoints.push_back(circP);
- }
- //iterate through to create the bottom of the cone
- for( int i = 0; i < n; i++ ) {
- int t = i;
- Point3 p1 = circumPoints.at(t);
- if( t+1 == n )
- t = -1;
- Point3 p2 = circumPoints.at(t+1);
- p1.y = y1;
- p2.y = y1;
- addTriangle( p1, p2, fixedPB );
- }
- /*
- * to make the cone part, we start from the fixed point at the top
- * and move down iterations of fy. the first iteration will not
- * make a square, but all others will.
- */
- float f = m-1;
- for( int i = 0; i < n; i++ ) {
- int t = i;
- //grab the first 2 circumference points
- Point3 p1 = circumPoints.at(t);
- if(t+1 == n) {
- t = -1; //go back to the beginning of the vector
- }
- Point3 p2 = circumPoints.at(t+1);
- p1.y = y1;
- p2.y = y1;
- Point3 tempr = p1;
- Point3 templ = p2;
- for( int i = 0; i < m; i++ ) {
- float fact = f/m;
- float npy = (1-fact)*p1.y + fact*fixedPT.y;
- float npzr = (1-fact)*p1.z + fact*fixedPT.z;
- float npzl = (1-fact)*p2.z + fact*fixedPT.z;
- float npxr = (1-fact)*p1.x + fact*fixedPT.x;
- float npxl = (1-fact)*p2.x + fact*fixedPT.x;
- Point3 uppR( npxr, npy, (-1)*npzr );
- Point3 uppL( npxl, npy, (-1)*npzl );
- if( i == 0 ) { //first iteration, so build a triangle at the top
- addTriangle( uppL, fixedPT, uppR );
- } else { //all other iterations make squares
- addSquare( uppR, uppL, templ, tempr );
- }
- tempr = uppR;
- templ = uppL;
- f--;
- }
- f = m-1;
- }
- }
- Cylinder::Cylinder(int n, int m) : Shape() {
- if (n < 3)
- n = 3;
- double x1,y1,z1,x2,y2,z2;
- x1 = -0.5;
- x2 = 0.5;
- y1 = -0.5;
- y2 = 0.5;
- z1 = .5;
- z2 = -.5;
- Point3 fixedPT( 0, y2, 0 );
- Point3 fixedPB( 0, y1, 0 );
- vector<Point3> circumPoints; //vector to hold circumference points
- //begin with the top and bottom
- //while n > 0, add points to the circumference and try triangles
- float angle = 360/n; //get the angle interval
- for( double i = 0; i < 360; i+=angle ) {
- double px = .5*cos( i * (PI/180) );
- double pz = .5*sin( i * (PI/180) );
- Point3 circP( px, y2, pz );
- circumPoints.push_back(circP);
- }
- //iterate through to make the top and the bottom
- for( int i = 0; i < n; i++ ) {
- int t = i;
- Point3 p1 = circumPoints.at(t);
- if( t+1 == n )
- t = -1;
- Point3 p2 = circumPoints.at(t+1);
- addTriangle( p2, p1, fixedPT );
- p1.y = y1;
- p2.y = y1;
- addTriangle( p1, p2, fixedPB );
- }
- //for each circumference point and the next circumference point
- //draw squares all the way down
- float fy = m-1;
- for( int x = 0; x < n; x++ ) { //number of faces
- int t = x;
- //grab the first 2 circumference points
- Point3 p1 = circumPoints.at(t);
- if(t+1 == n) {
- t = -1; //go back to the beginning of the vector
- }
- Point3 p2 = circumPoints.at(t+1);
- Point3 p3 = p2;
- Point3 temp = p2;
- p3.y = y1;
- for( int i = 0; i < m; i++ ) {
- float facty = fy/m;
- float npy = (1-facty)*p3.y + facty*p2.y;
- Point3 lowR( p1.x, npy, p1.z );
- Point3 midP( temp.x, npy, temp.z );
- addSquare( p1, temp, midP, lowR );
- p1 = lowR;
- temp = midP;
- fy--;
- }
- fy = m-1;
- }
- }
- Sphere::Sphere(int n) : Shape() {
- //your code for tessellating a sphere goes here
- if( n > 5 )
- n = 5;
- float five = 5.0;
- float a = 2.0 / ( 1.0 + sqrt(five) );
- Vector3 origin(0,0,0);
- //icosahedron vertices
- Vector3 tv0(0 , a, -1);
- Vector3 tv1(-a, 1, 0);
- Vector3 tv2(a, 1, 0);
- Vector3 tv3(0, a, 1);
- Vector3 tv4(-1, 0, a);
- Vector3 tv5(0, -a, 1);
- Vector3 tv6(1, 0, a);
- Vector3 tv7(1, 0, -a);
- Vector3 tv8(0, -a, -1);
- Vector3 tv9(-1, 0, -a);
- Vector3 tv10(-a, -1, 0);
- Vector3 tv11(a, -1, 0);
- //create the triangles in the original mesh
- vector< vector<Vector3> > triangles;
- //make triangle 0 and add it
- vector<Vector3> triangle0;
- triangle0.push_back(tv0);
- triangle0.push_back(tv1);
- triangle0.push_back(tv2);
- triangles.push_back(triangle0);
- //make triangle 1 and add it
- triangle0.clear();
- triangle0.push_back(tv3);
- triangle0.push_back(tv2);
- triangle0.push_back(tv1);
- triangles.push_back(triangle0);
- //make triangle 2 and add it
- triangle0.clear();
- triangle0.push_back(tv3);
- triangle0.push_back(tv4);
- triangle0.push_back(tv5);
- triangles.push_back(triangle0);
- //make triangle 3 and add it
- triangle0.clear();
- triangle0.push_back(tv3);
- triangle0.push_back(tv5);
- triangle0.push_back(tv6);
- triangles.push_back(triangle0);
- //make triangle 3 and add it
- triangle0.clear();
- triangle0.push_back(tv0);
- triangle0.push_back(tv7);
- triangle0.push_back(tv8);
- triangles.push_back(triangle0);
- //make triangle 4 and add it
- triangle0.clear();
- triangle0.push_back(tv0);
- triangle0.push_back(tv8);
- triangle0.push_back(tv9);
- triangles.push_back(triangle0);
- //make triangle 5 and add it
- triangle0.clear();
- triangle0.push_back(tv5);
- triangle0.push_back(tv10);
- triangle0.push_back(tv11);
- triangles.push_back(triangle0);
- //make triangle 6 and add it
- triangle0.clear();
- triangle0.push_back(tv8);
- triangle0.push_back(tv11);
- triangle0.push_back(tv10);
- triangles.push_back(triangle0);
- //make triangle 7 and add it
- triangle0.clear();
- triangle0.push_back(tv1);
- triangle0.push_back(tv9);
- triangle0.push_back(tv4);
- triangles.push_back(triangle0);
- //make triangle 8 and add it
- triangle0.clear();
- triangle0.push_back(tv10);
- triangle0.push_back(tv4);
- triangle0.push_back(tv9);
- triangles.push_back(triangle0);
- //make triangle 9 and add it
- triangle0.clear();
- triangle0.push_back(tv2);
- triangle0.push_back(tv6);
- triangle0.push_back(tv7);
- triangles.push_back(triangle0);
- //make triangle 10 and add it
- triangle0.clear();
- triangle0.push_back(tv11);
- triangle0.push_back(tv7);
- triangle0.push_back(tv6);
- triangles.push_back(triangle0);
- //make triangle 11 and add it
- triangle0.clear();
- triangle0.push_back(tv3);
- triangle0.push_back(tv1);
- triangle0.push_back(tv4);
- triangles.push_back(triangle0);
- //make triangle 12 and add it
- triangle0.clear();
- triangle0.push_back(tv3);
- triangle0.push_back(tv6);
- triangle0.push_back(tv2);
- triangles.push_back(triangle0);
- //make triangle 13 and add it
- triangle0.clear();
- triangle0.push_back(tv0);
- triangle0.push_back(tv9);
- triangle0.push_back(tv1);
- triangles.push_back(triangle0);
- //make triangle 14 and add it
- triangle0.clear();
- triangle0.push_back(tv0);
- triangle0.push_back(tv2);
- triangle0.push_back(tv7);
- triangles.push_back(triangle0);
- //make triangle 15 and add it
- triangle0.clear();
- triangle0.push_back(tv8);
- triangle0.push_back(tv10);
- triangle0.push_back(tv9);
- triangles.push_back(triangle0);
- //make triangle 16 and add it
- triangle0.clear();
- triangle0.push_back(tv8);
- triangle0.push_back(tv7);
- triangle0.push_back(tv11);
- triangles.push_back(triangle0);
- //make triangle 17 and add it
- triangle0.clear();
- triangle0.push_back(tv5);
- triangle0.push_back(tv4);
- triangle0.push_back(tv10);
- triangles.push_back(triangle0);
- //make triangle 18 and add it
- triangle0.clear();
- triangle0.push_back(tv5);
- triangle0.push_back(tv11);
- triangle0.push_back(tv6);
- triangles.push_back(triangle0);
- //so we have all of the vertices in there original coordinates
- //with that, we subdivide each polygon into 4 new ones and
- //do this n number of times
- for( int i = 1; i < n; i++ ) {
- vector< vector<Vector3> > tempTriangles;
- for( int j = 0; j < triangles.size(); j++ ) {
- //now we subdivide
- vector<Vector3> triangle = triangles.at(j);
- Vector3 two = triangle.at(2); //point 2 of the triangle
- Vector3 one = triangle.at(1); //point 1 of the triangle
- Vector3 zero = triangle.at(0); //point 0 of the triangle
- Vector3 a( ((two+zero)*.5) ); //intermediate point a
- Vector3 b( ((one+zero)*.5) ); //intermediate point b
- Vector3 c( ((two+one)*.5) ); //intermediate point c
- //add first new triangle
- triangle.clear();
- triangle.push_back( two );
- triangle.push_back( c );
- triangle.push_back( a );
- tempTriangles.push_back( triangle );
- //add second new triangle
- triangle.clear();
- triangle.push_back( c );
- triangle.push_back( one );
- triangle.push_back( b );
- tempTriangles.push_back( triangle );
- //add third new triangle
- triangle.clear();
- triangle.push_back( c );
- triangle.push_back( b );
- triangle.push_back( a );
- tempTriangles.push_back( triangle );
- //add fourth new triangle
- triangle.clear();
- triangle.push_back( a );
- triangle.push_back( b );
- triangle.push_back( zero );
- tempTriangles.push_back( triangle );
- }
- triangles = tempTriangles;
- }
- //loop to normalize each triangle vertex
- vector< vector<Vector3> > tempTriangles;
- for( int i = 0; i < triangles.size(); i++ ) {
- vector<Vector3> triangle = triangles.at(i);
- Vector3 two = triangle.at(0);
- Vector3 one = triangle.at(1);
- Vector3 zero = triangle.at(2);
- //now normalize
- two.normalize();
- one.normalize();
- zero.normalize();
- two*=.5;
- one*=.5;
- zero*=.5;
- Vector3 twoN = two;
- Vector3 oneN = one;
- Vector3 zeroN = zero;
- triangle.clear();
- triangle.push_back(twoN);
- triangle.push_back(oneN);
- triangle.push_back(zeroN);
- tempTriangles.push_back(triangle);
- }
- triangles = tempTriangles;
- /*//so we have now created all the proper triangles
- //now we must normalize, which requires all of the vertices
- int totalV = verts.size();
- for( int i = 0; i < totalV; i++ ) {
- //compute the vector that goes from the origin to the vertex and normalize it
- Vector3 temp = verts.at(i);
- temp.normalize();
- //multiply that normalized vector by .5 and add it to the origin to get the replacement vertex
- temp*=.5;
- Point3 np = origin+temp;
- normVerts.push_back(np);
- }*/
- //now iterate through, creating triangles in order
- for( int i = 0; i < triangles.size(); i++ ) {
- Point3 origin(0,0,0);
- vector<Vector3> triangle = triangles.at(i);
- Point3 a,b,c;
- a = origin+triangle.at(0);
- b = origin+triangle.at(1);
- c = origin+triangle.at(2);
- addTriangle(a,b,c);
- }
- }
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.