a missed IF statement

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • sanou
    New Member
    • Jul 2006
    • 19

    a missed IF statement

    Hi

    I have a loop that is iterating at approx 1000 times per second.

    There is an IF statement nested inside that instructs the program to stop (return) if a variable < 5. However, the program seems to always miss this condition. Even stranger, for any value > 5, the IF condition is properly followed. The variable in question is starting out from a very large value and with each iteration of the loop, being descreased a certain amount. The variable never goes below zero.

    Wondering if this is something wrong with my algorithm, or machine, or compiler..or all of the above =(

    Not sure if this makes sense. I can elaborate. Please help if you can.

    Thanks.
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    Most likely something wrong with your algorithm or code.

    Comment

    • apusateri
      New Member
      • Oct 2006
      • 27

      #3
      Can you include some of the code from the project so that we can see where there might be an error in the algorithm?

      Comment

      • sanou
        New Member
        • Jul 2006
        • 19

        #4
        Code:
        public: static double 
        
        // constants
        degrees = 45,
        radians = 0.0174532925 * degrees,
        
        // general time counters, i=1 means 1 tick per millisecond; 1000 ticks = 1 sec
        i = 0,
        time = 0,
        
        // unique time components for x and y
        x_i = 0,
        x_time = 0,
        y_i = 0,
        y_time = 0,
        
        // direction vector
        y_current_direction = -1,
        x_current_direction = 1,
        
        // gravity = 9.8 m/s^2
        gravity = y_current_direction * 50 ,  //default gravity is 9.8
        
        // velocity = some value with units m/s
        velocity = 137,
        
        // y values
        y_initial_position = 386,
        y_current_position = 0,
        
        y_velocity = sin(radians) * velocity,
        
        y_max = (0 - (y_velocity * y_velocity)) / (2 * gravity),
        
        // x values
        x_initial_position = 160,  
        x_current_position = 0,
        
        x_velocity = cos(radians) * velocity,
        
        // box dimensions
        top = 115,
        left = 160,
        right = 750,
        bottom = 386,
        
        // ball physical features
        mass = 1,
        friction = 0.8;
        
        private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
        
         if(timer1->Enabled == false){
        	 timer1->Enabled = true;
        	 button1->Text = L"Stop!";
         }
         else{
        	 timer1->Enabled = false;
        	 button1->Text = L"Start!";
         }
        }
        
        
        private: System::Void myTimer_Tick(System::Object^  sender, System::EventArgs^  e) {
        
        double	x = y_max,
        reset_x_time = 0,
        reset_y_time = 0;	
        
        time = i/10;
        x_time = x_i/10;
        y_time = y_i/10;
        
        x_current_position = ((x_initial_position) + (x_velocity * x_current_direction * x_time));
        y_current_position =  (2 * (y_initial_position)) + (direction_adjust * (y_initial_position + (y_velocity * y_time) + (0.5 * gravity * y_time * y_time)));
        
        if(y_current_position > bottom){
        	y_current_position = bottom;
        	reset_y_time = (2 * ((0 - y_velocity)/gravity)) - y_time;
        	y_time = abs(reset_y_time);
        	y_i = abs(reset_y_time * 10);
        // coefficient of restitution!
        	y_velocity *= 0.7;
        // friction coefficient!!
        	x_velocity *= friction;
        	x_initial_position = x_current_position;
        	x_time = x_i = reset_x_time;
        }
        
        if(x_current_position > right){
        	x_initial_position = x_current_position = right;
        	x_current_direction *= -1;
        	x_time = x_i = reset_x_time;
        }
        
        if(x_current_position < left){
        	x_initial_position = x_current_position = left;
        	x_current_direction *= -1;
        	x_time = x_i = reset_x_time;
        }
        
        pictureBox1->Location = System::Drawing::Point((int)x_current_position, (int)y_current_position);
        
        ///////////////////////////////////////////////////
        /* THIS CODE SEEMS TO BE MISSED?*/
        
        if(x_initial_velocity < 5){
           return;
        }
        
        ///////////////////////////////////////////////////
        
        x_i++;
        y_i++;
        
        }

        Comment

        • apusateri
          New Member
          • Oct 2006
          • 27

          #5
          Originally posted by sanou
          Code:
          public: static double 
          
          // constants
          degrees = 45,
          radians = 0.0174532925 * degrees,
          
          // general time counters, i=1 means 1 tick per millisecond; 1000 ticks = 1 sec
          i = 0,
          time = 0,
          
          // unique time components for x and y
          x_i = 0,
          x_time = 0,
          y_i = 0,
          y_time = 0,
          
          // direction vector
          y_current_direction = -1,
          x_current_direction = 1,
          
          // gravity = 9.8 m/s^2
          gravity = y_current_direction * 50 ,  //default gravity is 9.8
          
          // velocity = some value with units m/s
          velocity = 137,
          
          // y values
          y_initial_position = 386,
          y_current_position = 0,
          
          y_velocity = sin(radians) * velocity,
          
          y_max = (0 - (y_velocity * y_velocity)) / (2 * gravity),
          
          // x values
          x_initial_position = 160,  
          x_current_position = 0,
          
          x_velocity = cos(radians) * velocity,
          
          // box dimensions
          top = 115,
          left = 160,
          right = 750,
          bottom = 386,
          
          // ball physical features
          mass = 1,
          friction = 0.8;
          
          private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
          
           if(timer1->Enabled == false){
          	 timer1->Enabled = true;
          	 button1->Text = L"Stop!";
           }
           else{
          	 timer1->Enabled = false;
          	 button1->Text = L"Start!";
           }
          }
          
          
          private: System::Void myTimer_Tick(System::Object^  sender, System::EventArgs^  e) {
          
          double	x = y_max,
          reset_x_time = 0,
          reset_y_time = 0;	
          
          time = i/10;
          x_time = x_i/10;
          y_time = y_i/10;
          
          x_current_position = ((x_initial_position) + (x_velocity * x_current_direction * x_time));
          y_current_position =  (2 * (y_initial_position)) + (direction_adjust * (y_initial_position + (y_velocity * y_time) + (0.5 * gravity * y_time * y_time)));
          
          if(y_current_position > bottom){
          	y_current_position = bottom;
          	reset_y_time = (2 * ((0 - y_velocity)/gravity)) - y_time;
          	y_time = abs(reset_y_time);
          	y_i = abs(reset_y_time * 10);
          // coefficient of restitution!
          	y_velocity *= 0.7;
          // friction coefficient!!
          	x_velocity *= friction;
          	x_initial_position = x_current_position;
          	x_time = x_i = reset_x_time;
          }
          
          if(x_current_position > right){
          	x_initial_position = x_current_position = right;
          	x_current_direction *= -1;
          	x_time = x_i = reset_x_time;
          }
          
          if(x_current_position < left){
          	x_initial_position = x_current_position = left;
          	x_current_direction *= -1;
          	x_time = x_i = reset_x_time;
          }
          
          pictureBox1->Location = System::Drawing::Point((int)x_current_position, (int)y_current_position);
          
          ///////////////////////////////////////////////////
          /* THIS CODE SEEMS TO BE MISSED?*/
          
          if(x_initial_velocity < 5){
             return;
          }
          
          ///////////////////////////////////////////////////
          
          x_i++;
          y_i++;
          
          }

          Your condition is checking if x_initiial_velo city is less than 5, but I don't see that variable ever declared or assigned a value in the above code.

          Should it be x_velocity?

          Comment

          • sanou
            New Member
            • Jul 2006
            • 19

            #6
            yea it was a typo

            i changed it to x_initial_veloc ity but it still doesn't work. i'm really confused

            Comment

            • sanou
              New Member
              • Jul 2006
              • 19

              #7
              well this is weird, i tried moving the IF statement around. I nested it into another if statement looking like this,

              Code:
              if(y_current_position > bottom){
                 y_current_position = bottom;
                 reset_y_time = (2 * ((0 - y_initial_velocity)/gravity)) - y_time;
                 y_time = abs(reset_y_time);
                 y_i = abs(reset_y_time * 10);
                 y_initial_velocity *= 0.7;
              
                    if(x_initial_velocity < 1){
                       return;
                    }
              
                 x_initial_velocity *= friction;
                 x_initial_position = x_current_position;
                 x_time = x_i = reset_x_time;
              }
              now everything works fine. i'm still confused tho.

              Comment

              • Banfa
                Recognized Expert Expert
                • Feb 2006
                • 9067

                #8
                Originally posted by sanou
                Code:
                y_current_position =  (2 * (y_initial_position)) + ([b]direction_adjust[/b] * (y_initial_position + (y_velocity * y_time) + (0.5 * gravity * y_time * y_time)));
                direction_adjus t is not defined, if I change it to y_current_direc tion code seems to hit the if statement OK.

                Comment

                • sanou
                  New Member
                  • Jul 2006
                  • 19

                  #9
                  my apologies, i originally posted some outdated code

                  i double checked the direction_adjus t variable and it does not appear to play a role in the mistake

                  i think it maybe more of a problem with the windows form timer. like somehow the function that activates the timer loop is not properly synchronized with the rest of the program.

                  as you know, i'm using this program to simulate some simple physics. my current timer tick is set to 1 (approx 1 tick every millisecond). i've allowed for users to reset the ball location, along with the velocity and angle of trajectory. however, simply reseting the variables while the program is running does not seem to work. i have to stop the timer, replace the old variables with the new ones, then restart the timer. i find it hard to believe that a program will simply "miss" an IF statement, so i'm wondering if the reason behind it is improper synchronization of some sort. i'm not too familiar with the windows timer event so i dunno...

                  Comment

                  • Banfa
                    Recognized Expert Expert
                    • Feb 2006
                    • 9067

                    #10
                    No this should not really be a probem, a Windows GUI runs in a single thread (unless you have started another 1) so you can only be handling 1 message at a time.

                    I have to say I had no trouble with your code when I ran it as a console program.

                    I doubt Windows will ever be able to supply you with a tick every millisecond, I think about every 50 milliseconds or so is what it can manage (an old DOS limitation). It does have timers that go faster (in theory) but not message driven timers). Try slowing down the timer, if the program is single threaded the speed of the timer should have no effect of the calculation.

                    I refuse to believe that it is missing the if statement, if it can do that then there is a lot of code in a lot of trouble all over the world, try adding some debug, write a line to a file each time through the calculation to output all the different variables and what they are doing.

                    Comment

                    Working...