POV-Ray : Documentation : 1.3.9.5 What about loop types other than simple for-loops?
  POV-Ray 3.6 Documentation Online View  
1.3.9.4 What is a condition and how do I make one?   1.3.9.6 What about nested loops?

1.3.9.5 What about loop types other than simple for-loops?

As POV-Ray does not care what the condition is and what we are using to make that condition, we can use the while-loop in many other ways.

For example, this is a typical use of the while-loop which is not a simple for-loop:

#declare S = seed(0);
#declare Point = <2*rand(S)-1, 2*rand(S)-1, 2*rand(S)-1>;
#while(vlength(Point) > 1)
  #declare Point = <2*rand(S)-1, 2*rand(S)-1, 2*rand(S)-1>;
#end

What we are doing here is this: Take a random point between <-1, -1, -1> and <1, 1, 1> and if it is not inside the unit sphere take another random point in that range. Do this until we get a point inside the unit sphere.

This is not an unrealistic example since it is very handy.

As we see, this has nothing to do with an ordinary for-loop:

  • It does not have any "index" value which gets consecutive values during the loop.
  • We do not know how many times it will loop. In this case it loops a random number of times.
  • For-loops are usually used to get a series of things (eg. objects). At each loop another instance of that thing is created. Here, however, we are only interested in the value that results after the loop, not the values inside it.

As we can see, a while-loop can also be used for a task of type "calculate a value or some values until the result is inside a specified range" (among many other tasks).

By the way, there is a variant of this kind of loop where the task is: "Calculate a value until the result is inside a specified range, but make only a certain number of tries. If the value does not get inside that range after that number of tries, stop trying". This is used when there is a possibility for the loop for going on forever.

In the above example about the point inside the unit sphere we do not need this because the random point will surely hit the inside of the sphere at some time. In some other situations, however, we cannot be so sure.

In this case we need a regular index variable to count the number of loops. If we have made that amount of loops then we stop.

Suppose that we wanted to modify our point searching program to be completely safe and to try only up to 10 times. If the point does not hit the inside of the sphere after 10 tries, we just give up and take the point <0,0,0>.

#declare S = seed(0);
#declare Point = <2*rand(S)-1, 2*rand(S)-1, 2*rand(S)-1>;
#declare Index = 1;
#while(Index <= 10 & vlength(Point) > 1)
  #declare Point = <2*rand(S)-1, 2*rand(S)-1, 2*rand(S)-1>;
  #declare Index = Index + 1;
#end

#if(vlength(Point) > 1)
  #declare Point = <0,0,0>
#end

What did we do?

  • We added an 'Index' value which counts the amount of loops gone so far. It is quite similar to the index loop of a simple for-loop.
  • We added an extra condition to the while-loop: Besides testing that the point is outside the unit sphere it also tests that our index variable has not bailed out. So now there are two conditions for the loop to continue: The 'Index' value must be less or equal to 10 and the 'Point' has to be outside the unit sphere. If either one of them fails, the loop is ended.
  • Then we check if the point is still outside the unit sphere. If it is, we just take <0,0,0>.

Btw, sometimes it is not convenient to make the test again in the #if statement. There is another way of determining whether the loop bailed out without successful termination or not: Since the loop ends when the 'Index' gets the value 11, we can use this to test the successfulness of the loop:

#if(Index = 11)
  (loop was not successful)
#end
1.3.9.4 What is a condition and how do I make one?   1.3.9.6 What about nested loops?


Copyright 2003-2021 Persistence of Vision Raytracer Pty. Ltd.