#include<iostream>
#include<math.h>
#include<vector>
#include<GL/glut.h>
using namespace std;
#define TWOPI 6.28318531
#define RENDER_LIST0 5
int itnum=1;
GLint winw=800,winh=800;
GLfloat plotradius[]={100,100},base;
struct coordtype
{
GLfloat x[2];
};
vector<coordtype> point;
coordtype plotval(GLint winx,GLint winy)
{
coordtype temp;
temp.x[0]=(((GLfloat)winx/(GLfloat)winw)-.5)*2.0*plotradius[0];
temp.x[1]=(((GLfloat)winy/(GLfloat)winh)-.5)*2.0*plotradius[1];
return temp;
}
void newpoint(GLfloat xval,GLfloat yval)
{
coordtype temp=plotval(xval,yval);
point.push_back(temp);
}
struct matrixtype
{
GLfloat m[16];
};
vector<matrixtype> storedmatrix0;
vector<matrixtype> storedmatrix1;
void reshape(short a,short b)
{
GLfloat scale,angle;
scale=sqrt(pow(point[B].x[1]-point[a].x[1],2)+pow(point[B].x[0]-point[a].x[0],2))/base;
if(b==1)angle=360.0*atan((point[B].x[1]-point[a].x[1])/(point[B].x[0]-point[a].x[0]))/TWOPI;
else angle=360.0*(atan((point[B].x[1]-point[a].x[1])/(point[B].x[0]-point[a].x[0]))-atan((point[1].x[1]-point[a].x[1])/(point[1].x[0]-point[a].x[0])))/TWOPI;
glRotatef(angle,0,0,1);
glScalef(scale,scale,scale);
}
float distv(float a[2],float b[2])
{
return sqrt(pow(b[0]-a[0],2)+pow(b[1]-a[1],2));
}
void getmatrix(bool mnum)
{
matrixtype matrix;
glGetFloatv(GL_MODELVIEW_MATRIX,matrix.m);
if(mnum)storedmatrix1.push_back(matrix);
else storedmatrix0.push_back(matrix);
}
void recur(short i)
{
short n,l;
storedmatrix0=storedmatrix1;
storedmatrix1.clear();
glDeleteLists(RENDER_LIST0+i,1);
glNewList(RENDER_LIST0+i,GL_COMPILE);
for(l=0;l<storedmatrix0.size();l++)
{
glPushMatrix();
glLoadMatrixf(storedmatrix0[l].m);
glColor3f(2-i,2-i,1);
glBegin(GL_LINES);
glVertex2f(0,0);
glVertex2f(base,0);
glEnd();
glColor3f(1,0,0);
glCallList(RENDER_LIST0+i-1);
glPushMatrix();
reshape(0,2);
getmatrix(1);
glBegin(GL_LINES);
glVertex2f(0,0);
glVertex2f(base,0);
glEnd();
glCallList(RENDER_LIST0);
glPopMatrix();
glPopMatrix();
}
glEndList();
if(i<itnum)recur(i+1);
}
void render(short num)
{
int i;
base=distv(point[0].x,point[1].x);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0,0,winw,winh);
gluOrtho2D(-plotradius[0],plotradius[0],plotradius[1],-plotradius[1]);
storedmatrix1.clear();
glPushMatrix();
glTranslatef(point[0].x[0],point[0].x[1],0);
reshape(0,1);
getmatrix(1);
glPopMatrix();
glPointSize(5);
glNewList(RENDER_LIST0,GL_COMPILE);
glPushMatrix();
glTranslatef(base,0,0);
glBegin(GL_POINTS);
glVertex2f(0,0);
glEnd();
glPopMatrix();
glEndList();
recur(1);
glNewList(num,GL_COMPILE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0,0,winw,winh);
gluOrtho2D(-plotradius[0],plotradius[0],plotradius[1],-plotradius[1]);
glColor3f(1,0,0);
glPointSize(10);
glBegin(GL_POINTS);
glVertex2fv(point[0].x);
glEnd();
glCallList(RENDER_LIST0+itnum);
glPointSize(5);
glColor3f(0,1,0);
glBegin(GL_POINTS);
for(i=0;i<point.size();i++)
{
glVertex2fv(point[i].x);
}
glEnd();
glEndList();
}
void controls(unsigned char key,int x,int y)
{
if(key==' ')
{
switch(itnum)
{
case 1:itnum=2;break;
case 2:itnum=1;break;
default:itnum=1;
}
render(1);
}
}
void resize (int w, int h)
{
winw=w;
winh=h;
render(2);
gluOrtho2D(0,winw,winh,0);
glViewport(0,0,winw,winh);
}
void init(void)
{
char temp[50];
glClearColor(0,0,0,0);
glShadeModel(GL_SMOOTH);
glPolygonMode (GL_FRONT_AND_BACK,GL_FILL);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_POINT_SMOOTH);
newpoint(winw/4,winh*4/7);
newpoint(3*winw/5,winh*4/7);
newpoint(1*winw/3,winh*3.5/7);
render(1);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glCallList(1);
glFlush();
}
int main(int argc,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(winw,winh);
glutInitWindowPosition(100,100);
glutCreateWindow("RecurTest");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(resize);
glutKeyboardFunc(controls);
glutMainLoop();
return 1;
}