PDA

View Full Version : Recursion program issues



hixidom
04-14-2012, 05:07 PM
Hello.

I have a program that makes a certain type of fractal using recursion to find where the next iteration's point go. I'm trying to rewrite the recursion parts of this program so that they use lists to make the job a bit easier. My idea of what the program should do is make a list of the inital points, then make a list using the previous list at each point, and again and again i times. The program below is a mucho simplified version of the full program that I have written so far.

In the simplified version, there are two reference points and one pattern point (or whatever you would call it) you only need to hit the space bar to toggle between 1 and 2 iterations. There are lines drawn to help see what's going on. The white line is the x-axis in the first display list, the blue line is the x-axis in the second display list, and the red lines connect the first reference point of the ith iteration to the [only] pattern point of the ith iteration.

The idea is that the blue line (in the second iteration) should fall on the red line of the first iteration. I can't imagine why this isn't happening, which is why I'm posting here. I've tried fanagling the code a hundred ways but have not found the solution.


#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(&amp;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;
}

Explaining, a little more, how I think the program should work:
storedmatrix0 and storedmatrix1 are vectors that store the MODELVIEW orientation for each point (the orientation that should make the next iteration's x-axis fall on the red line for each point in the current iteration). The recursion function makes a display list of the first setup, storing all of the previously described orientations (of which there is only one in this version of the program), then calls itself, which should display the first display list at every orientation stored in the previous iteration while also creating the display list to be used in the next iteration.

What actually happens is that the transformations caused by the reshape(0,2) command seem to not be stored in storedmatrix1, and thus are not enacted in the second iteration when glLoadMatrixf() is called. I've assumed that this is the case because the program does what I want it to do if I add in the commands glTranslatef(point[0].x[0],point[0].x[1],0);reshape(0,2); under the glLoadMatrixf() command. Anyways, the way I see it, I shouldn't have to do that since reshape(0,2); occurs in the first iteration just before the MODELVIEW matrix is stored in storedmatrix1

I'm using Ubuntu and have tested the above code, so you should be able to compile the program and observe what I'm talking about.

I'm at my wit's end with this code, so I really do have no idea why I'm not getting the result I expect. Thanks, in advance, for any help or insight that can be offerred.