/**************************************************** Heart surface author : Mateusz Małczak mail : malczak@us.edu.pl ***************************************************** www.malczak.linuxpl.com www.malczak.info ***************************************************** feel free to distibute it and use it as you will *****************************************************/ //--------------------------------------------------------------------------- #define WIN32_LEAN_AND_MEAN // "odchudza" aplikację Windows //--------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #ifdef __BORLANDC__ #include #endif #define WIDTH 640 #define HEIGHT 540 const double PI = 4*atan(1); const double PI2 = 2*PI; const double PI_2 = PI/2; typedef struct __POS { double x,y,z; } POS; float lp[3]; float ambientLight[] = { 0.7f, 0.2, 0.2f, 1.0f }; float diffuseLight[] = { 0.9f, 0.6f, 0.6f, 1.0f }; float specularLight[] = { 1.0f, 0.1f, 0.1f, 1.0f }; float ambientLight2[] = { 0.8f, 0.3f, 0.3f, 1.0f }; float diffuseLight2[] = { 0.7f, 0.2f, 0.2f, 1.0f }; float specularLight2[] = { 1.0f, 0.8f, 0.8f, 1.0f }; //rotation angle int alfa = 0; //planes count and number of points in each layer #define LAYERS 40 #define POINTS_IN_LAYER 200 //heart surface constrains #define XMIN -3 #define XMAX 3 #define YMIN XMIN #define YMAX XMAX #define ZMIN XMIN #define ZMAX XMAX #define XSIZE 100 #define YSIZE XSIZE POS **heart; void set( POS &v, double x, double y, double z ) { v.x = x; v.y = y; v.z = z; }; POS cross( POS v1, POS v2 ) { POS v; v.x = v1.y * v2.z - v1.z * v2.y; v.y = v1.z * v2.x - v1.x * v2.z; v.z = v1.x * v2.y - v1.y * v2.x; return v; }; POS sub( POS v1, POS v2 ) { POS v; v.x = v1.x - v2.x; v.y = v1.y - v2.y; v.z = v1.z - v2.z; return v; } //heart function : ( 2x^2 + y^2 + z^2 - 1)^3 - 0.1x^2z^3 - y^2z^3 double f( double x,double y,double z ) { double xx = x*x; double yy = y*y; double zz = z*z; double a = 2*xx + yy +zz - 1; a = a*a*a; zz *= z; return a - 0.1*xx*zz - yy*zz; }; //generate points void initHeart2() { POS p1, p2, pn; double lX,lY,lZ, alfa, dalfa, f1,f2,fn; bool finished = false; int i,j,k; alfa = 0; dalfa = PI2/(double)POINTS_IN_LAYER; double X = -1.05; int hi = 0; double dx = ( 0.70 ) / (double)LAYERS; for ( X=-0.70, hi=0; hi<=LAYERS; X+=dx, hi++ ) // first loop { heart[ hi ] = (POS*)calloc( POINTS_IN_LAYER, sizeof(POS) ); POS* h = heart[ hi ]; for ( i=0; i0 ) ); while ( !finished ) { pn.y = (p1.y + p2.y) / 2; pn.z = (p1.z + p2.z) / 2; fn = f( X, pn.y, pn.z ); if ( fn<=0 ) { p1 = pn; f1 = fn; } else { p2 = pn; f2 = fn; }; finished = !( ( f1<=0 ) && ( f2>0 ) ); lY = p2.y - p1.y; lZ = p2.z - p1.z; if ( sqrt( lZ*lZ + lY*lY ) < 0.001 ) finished = true; }; lY = (p2.y + p1.y)/2; lZ = (p2.z + p1.z)/2; set( *h, X, lY, lZ ); h++; }; //second loop }; //first loop }; void renderScene() { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glPushMatrix(); glLoadIdentity(); glRotatef(alfa/10, 0, 1, 0 ); glScalef( 0.6, 0.6, 0.6 ); glRotatef( -90, 1, 0, 0); POS p[4], n, *h; int j,i; //draw heart for ( j=1; j<=LAYERS; j++ ) for ( h = heart[ j ], i=0; i