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

As POV-Ray doesn't 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's 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's very handy and I have used this type of loops many times.

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

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's 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 doesn't get inside that range after that number of tries, stop trying". This is used when there's a possibility for the loop for going on forever.

In the above example about the point inside the unit sphere we don't need this because the random point will surely hit the inside of the sphere at some time. In some other situations, however, we can't 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 doesn't 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?

Btw, sometimes it's not convenient to make the test again in the #if statement. There's 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