Advertisement

For loop error in Display Function

Started by May 24, 2019 02:41 AM
4 comments, last by tamlam 5 years, 8 months ago

I have a vector saving 5 cube coordinates in oxy plan.

Task: 1st cube roll 90 degrees, then disappear then 2nd cube roll 90 dg … until the last cube in the vector.

Problem: whenever the program runs, all the cube will appear and roll the same time.

Q: How can I solve this problem?

  • I checked the value in for loop (temp), and value of (count) as below:
    angle 1 count 1
    temp0
    temp1
    temp2
    temp3
    temp4
    temp5
    temp6
    temp7

  • angle 2 count 2
    temp0
    temp1
    temp2
    temp3
    temp4
    temp5
    temp6
    temp7

=> I do not know why the for loop does not wait for for the “presskey” action to increase the angle value before move to the next temp value.


int Count(0);
void Display(void) {

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
SetLight();

glPushMatrix();

ConclusiveAxis();
DrawGrid();

for (int temp = 0; temp < cube.coordinates.size(); temp++) {
  cout<< "temp" << temp << endl;	
       if ((cube.coordinates[temp] == true)) {
		sDirection = true;

		if (Count <= 90) {

			glPushMatrix();
			glTranslatef(cube.coordinates[temp].x - 0.5, cube.coordinates[temp].y - 0.5, 0.0);
			glRotatef(angle, 0, 1, 0);
			glTranslatef(-0.5, 0.5, 0.5);
			glColor3f(0.5, 1.5, 1.0);
			glutSolidCube(1);
			glPopMatrix();
		}
		else if (Count > 90) {
			angle = 0;
			Count = 0;
		}
		else {
			sDirection = false;
		}
	}
	else {
	}
}

glPopMatrix();
glutSwapBuffers();
}

void SpecialKey(unsigned char key, int x, int y) {
switch (key) {
case 'r':
	//condition for next check	
	if (sDirection == true)
	{
		angle++;
		glutPostRedisplay();
		Count++;
		cout << "angle " << angle << " count " << Count << endl;
	}
	else
	{
		glutPostRedisplay(NULL);
	}
	break;
}
}

void OpenGLCallBackAnimation(void) {
	GLSettings0.PickObject = PickObject0;
	OpenGLInitialize(0, GLSettings0, 300, 150, 1000, 650, "window");

    glutDisplayFunc(Display);		   

	glutMouseFunc(MouseButton);
	glutMotionFunc(OnMouseMotion);
	glutPassiveMotionFunc(PassiveMotion);

	glutKeyboardFunc(SpecialKey);			//keyboard call
	
	glutMouseWheelFunc(OpenGLMouseWheel0);
	glutReshapeFunc(OpenGLReshape0);
	//glutTimerFunc(0, time_callback, 0); 
	OpenGLPostprocessor(GLSettings0);
}

 

Quote

Task: 1st cube roll 90 degrees, then disappear then 2nd cube roll 90 dg … until the last cube in the vector.


for (int temp = 0; temp < cube.coordinates.size(); temp++) {
  cout<< "temp" << temp << endl;	
       if ((cube.coordinates[temp] == true)) {
		sDirection = true;

		if (Count <= 90) {...

In the first line, you loop over all cubes. In the third line, you compare an array member to true.  Not sure what your intention is. If your coordinates array would store pointers, this would be a check for a nullptr but since you used 


cube.coordinates[temp].x

I guess it does not store pointers. Don't know how your class/struct that is stored in coordinates compares to true, but from the output, you described, it always yields true.

Then finally you compare to the count which yields always the same result for each loop iteration. So if the first branch is intended to check if a ball should start rotating, the reason why all are rotating at the same time must be that


(cube.coordinates[temp] == true)

always yields true. Find out why.

 

Quote

=> I do not know why the for loop does not wait for for the “presskey” action to increase the angle value before move to the next temp value.

2

 


		if (Count <= 90) {
...
		}
		else if (Count > 90) {
...
		}
		else {
			sDirection = false;
		}

Maybe I am suffering from a low caffeine level, but the last else statement can never be executed. The first else is only executed if Count is not less or equal than 90. In other words, if Count is greater than 90. In this case, your second if can only take the true direction since no value that would lead to the else condition passes the first branch.

So you never set sDirectionton to false.  The else statement for your keypress event is therefore also never called, once sDirection is set to true. This still does not explain why the switch always takes the path as if 'r' was pressed.

I guess you messed up the whole event handling system of glut. The best way to fix that is to set a breakpoint at some key locations and check the call stacks. Place them somewhere in the display function and also in the key callback. Check which function is calling them. For the display function, I guess that it is called directly after window creation and therefore the for loop is executed without any key being pressed. The question is, who calls the SpecialKey function and why is the 'r' key path always taken to increase the angle even if no key was pressed.

Check this and post the results.

 

Greetings

Advertisement

 

Looking at it more closely I am astounded that this compiles.

If cube.coordinates is an array of vectors (.x and .y components hint to that) the vector must have an overload for oporator==( bool ) or there must be an explicit conversion between bool and vector or cube.coordinates isn't an array of vectors with two components x and y.

Or am i wrong ?

 

5 minutes ago, Green_Baron said:

 

Looking at it more closely I am astounded that this compiles.

If cube.coordinates is an array of vectors (.x and .y components hint to that) the vector must have an overload for oporator==( bool ) or there must be an explicit conversion between bool and vector or cube.coordinates isn't an array of vectors with two components x and y in which case the translate function should refuse.

Or am i wrong ?

 

No, you are totally right. I was wondering about that too. Only thing I could imagine is that the vector elements are a custom type with operator=(bool) overload. Otherwise, the compiler should reject it for the reasons you mentioned. Thatswhy I told him to check what happens in this line.

 

Greetings

 
 
 
2
 
 
 
 
 
 
 
6
 
 
 
 
 
 
 
6
 
 
 
 
 
 
 
6
On 5/24/2019 at 4:41 PM, DerTroll said:

In the first line, you loop over all cubes. In the third line, you compare an array member to true.  Not sure what your intention is. If your coordinates array would store pointers, this would be a check for a nullptr but since you used 

I guess it does not store pointers. Don't know how your class/struct that is stored in coordinates compares to true, but from the output, you described, it always yields true.

Then finally you compare to the count which yields always the same result for each loop iteration. So if the first branch is intended to check if a ball should start rotating, the reason why all are rotating at the same time must be that always yields true. Find out why.

Thanks so much for great comments. Let me clarify more.

In the real code, I want to roll the cube in different direction within x_axis and y_axis.


//cube.cubeCenter[0] = (x0, y0, 0); and true for rolling aside with x_axis
//cube.cubeCenter[1] = (x1, y1, 0); and true for rolling aside with x_axis
//cube.cubeCenter[2] = (x2, y2, 0); and false for rolling aside with y_axis
//.....

for (int i = 0; i < cube.cubeCenter.size(); i++) {
    
  if(cube.cubeCenter[i]==true){  //means that it rolls along x_axis
    //SDirection = true; // in order to increase angle value;
  }
}

When I check boolean cube.cubeCenter, sometimes it is true, sometimes it's false due to rolling along x_axis or y_axis. I think it is the right boolean condition.

You are right with the error with a condition for Count. It should be:


//
if (cube.cubeCenter[i] == true){   //rolling along X_axis
  SDirection = true;           
  if (Count <= 90){
    
     ......  //do X_axis rolling
             // in order to increase angle value
  }else{
    angle = 0; 
    Count = 0;
  } 
}else{  // means: cube.cubeCenter[i] == false       //rolling along Y_axis
    
    SDirection = false; 
    if (Count <= 90){
    
     ......  //do Y_axis rolling
            
    }else{
    	angle = 0; 
    	Count = 0;
    } 
}
Quote

The question is, who calls the SpecialKey function and why is the 'r' key path always taken to increase the angle even if no key was pressed.

This is also my misunderstanding. 

Whenever the program runs, the Display() will run the same time with SpecialKey function. As a result, all cubes will appear without rolling. When pressing the 'r' key, it starts to roll for all cubes. 

Quote

The best way to fix that is to set a breakpoint at some key locations and check the call stacks. Place them somewhere in the display function and also in the key callback. Check which function is calling them.

Currently, I am trying to do that. But don't know why the program does not stop in if (cube.cubeCenter == true) condition to roll the cube before moving to the next cube. When I set a breakpoint like if (cube.cubeCenter == true) => print rolling x_axis, else {print rolling y_axis}, they are right with the condition. 

This topic is closed to new replies.

Advertisement