#include <math.h>
#include <GL\glut.h>
GLint ww=500, wh=500;
int gbtn, gstate;
static GLfloat theta[] = {0.0,0.0,0.0};
static GLfloat normals[4];
static GLfloat viewer[]= {0.0, 0.0, 10.0}; /* initial viewer location */
static GLdouble x[4000000], y[4000000], f[4000000];
static GLdouble mv[4][4];
static GLdouble trns[4][4]={{1.0,0.0,0.0,0.0},{0.0,1.0,0.0,0.0},{0.0,0.0,1.0,0.0},{0.0,0.0,0.0,1.0}};
static GLdouble rtx[4][4]={{1.0,0.0,0.0,0.0},{0.0,1.0,0.0,0.0},{0.0,0.0,1.0,0.0},{0.0,0.0,0.0,1.0}};
static GLdouble rty[4][4]={{1.0,0.0,0.0,0.0},{0.0,1.0,0.0,0.0},{0.0,0.0,1.0,0.0},{0.0,0.0,0.0,1.0}};
static GLdouble rtz[4][4]={{1.0,0.0,0.0,0.0},{0.0,1.0,0.0,0.0},{0.0,0.0,1.0,0.0},{0.0,0.0,0.0,1.0}};
//static GLdouble ac[4000000];
static int n=0;
void matmult (GLdouble m1[][4], GLdouble m2[][4], GLdouble m[][4]) {
GLdouble t=0.0;
for (int i=0; i<4; i++) {
for (int j=0; j<4; j++) {
t =0.0;
for (int k=0; k<4; k++) {
t += m1[i][k]*m2[k][j];
}
m[i][j] = t;
}
}
}
int inner (GLfloat v1[], GLfloat v2[]) {
GLfloat p = 0.0;
for (int i=0; i<3; i++)
p += v1[i]*v2[i];
if (p<0)
return -1;
else if (p>0)
return 1;
else
return 0;
}
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
n = 0;
for (GLdouble u=-1.0; u<=1.0; u+=0.001) {
for (GLdouble t=-1.0; t<=1.0; t+=0.001) {
/*x*/y[n] = t*(u*u - t*t);
/*y*/x[n] = u;
/*f*/f[n++] = u*u - t*t;
// ac[n] = (x[n]+y[n]+f[n])/3.0;
}
}
glEnable(GL_DEPTH_TEST);
}
void transform (GLfloat v[]) {
GLdouble t[4]={0.0, 0.0, 0.0, 0.0};
for (int i=0; i<4; i++) {
for (int j=0; j<4; j++) {
t[i] += mv[i][j]*v[j];
}
}
for (int i=0; i<4; i++) {
v[i] = t[i];
}
}
void surface()
{
glBegin(GL_POINTS);
for (int i=0; i<n; i++) {
//GLfloat c1 = (ac[n] + 1.0)*0.25;
//GLfloat c2 = (ac[n] + 3.0)*0.25;
GLfloat ray[4];
ray[0] = x[i];
ray[1] = y[i];
ray[2] = f[i];
ray[3] = 1.0;
//x^2 - y^2 * Z^2 + Z^3 = 0
normals[0] = 2.0 * x[i];
normals[1] = -2.0 * y[i] * f[i] * f[i];
normals[2] = -2.0 * y[i] * y[i] * f[i] + 3.0 * f[i] * f[i];
normals[3] = 1.0;
transform (ray);
transform (normals);
if (inner(ray, normals)>=0)
glColor3f((x[i]+1)*0.25, (y[i]+1)*0.25, (f[i]+1)*0.25);
//glColor3f(c1,c1,c1);
else
glColor3f((x[i]+3)*0.25, (y[i]+3)*0.25, (f[i]+3)*0.25);
//glColor3f(c2,c2,c2);
glVertex3d(x[i], y[i], f[i]);
}
glEnd();
}
void myDisplay(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
/* rotate surface */
GLdouble temp[4][4], temp1[4][4];
rtz[0][0] = rtz[1][1] = cos(theta[2]*3.14159265359/180.0);
rtz[1][0] = sin(theta[2]*3.14159265359/180.0);
rtz[0][1] = -rtz[1][0];
rtx[2][2] = rtx[1][1] = cos(theta[0]*3.14159265359/180.0);
rtx[2][1] = sin(theta[0]*3.14159265359/180.0);
rtx[1][2] = -rtx[2][1];
matmult(rtx, rtz, temp);
rty[2][2] = rtx[0][0] = cos(theta[1]*3.14159265359/180.0);
rty[0][2] = sin(theta[1]*3.14159265359/180.0);
rty[2][0] = -rty[0][2];
matmult(rty,temp, temp1);
trns[0][3] = -viewer[0];
trns[1][3] = -viewer[1];
trns[2][3] = -viewer[2];
matmult(trns, temp1, mv);
glTranslatef(-viewer[0],-viewer[1],-viewer[2]);
glRotatef(theta[1], 0.0, 1.0, 0.0);
glRotatef(theta[0], 1.0, 0.0, 0.0);
glRotatef(theta[2], 0.0, 0.0, 1.0);
surface();
glFlush();
glutSwapBuffers();
}
void
keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'X':theta[0]+=1;
if (theta[0]==360) theta[0]=0;
break;
case 'x': theta[0]-=1;
if (theta[0]<0) theta[0] = 359;
break;
case 'Y':theta[1]+=1;
if (theta[1]==360) theta[1]=0;
break;
case 'y': theta[1]-=1;
if (theta[1]<0) theta[1] = 359;
break;
case 'Z':theta[2]+=1;
if (theta[2]==360) theta[2]=0;
break;
case 'z': theta[2]-=1;
if (theta[2]<0) theta[2] = 359;
break;
}
glutPostRedisplay ();
}
void mouse(int x, int y)
{
static int t=0, xp, yp;
if(gbtn==GLUT_LEFT_BUTTON && gstate == GLUT_DOWN) {
if (t==0) {
xp=x;
yp=y;
t=1;
return;
}
else {
theta[0]+=(y-yp); while (theta[0]>=360) theta[0]-=360; while (theta[0]<0) theta[0]+=360;
theta[1]+=(x-xp); while (theta[1]>=360) theta[1]-=360; while (theta[1]<0) theta[1]+=360;
xp=x;
yp=y;
}
}
else if(gbtn==GLUT_LEFT_BUTTON && gstate == GLUT_UP) {
t = 0;
return;
}
glutPostRedisplay();
}
void mouseClick(int btn, int state, int x, int y){
gbtn=btn;
gstate=state;
mouse(x,y);
}
void myReshape(int w, int h)
{
glViewport(0, 0, w, h);
ww=w;wh=h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w<=h)
glOrtho(-2.4, 2.4, -2.4 * (GLfloat) h/ (GLfloat) w,
2.4* (GLfloat) h / (GLfloat) w, viewer[2]-1.8, viewer[2]+1.8);
else
glOrtho(-1.8* (GLfloat) w/ (GLfloat) h, 1.8* (GLfloat) w/ (GLfloat) h, -1.8, 1.8, viewer[2]-1.8, viewer[2]+1.8);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(ww,wh);
glutInitWindowPosition(100, 100);
glutCreateWindow("3D Function Plot");
init();
glutReshapeFunc(myReshape);
glutDisplayFunc(myDisplay);
glutMotionFunc(mouse);
glutMouseFunc(mouseClick);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}