|
Como a POV-Ray no le importa cuál es la condición ni lo que usamos para hacer la condición, podemos usar el bucle while de muchas otras maneras.
Por ejemplo, este es un uso típico de un bucle que no es un blucle "for" sencillo:
#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
Lo que estamos haciendo aqui es: Tomar un punto al azar entre <-1, -1, -1> y <1, 1, 1> y si no está dentro de la unidad de la esfera, tomar otro punto al azar en ese rango. Hacer esto hasta que obtengamos un punto dentro de la unidad de la esfera.
Este no es un ejemplo irreal puesto que es muy útil y yo he usado muchas veces este tipo de bucles.
Como vemos, no tiene nada que ver con un bucle "for" ordinario:
Como vemos, un bucle "while" puede usarse también para una tarea del tipo "calcula un valor o varios valores hasta que el resultado se halle dentro de un rango específico" (entre muchas otras tareas).
Por cierto, hay una variante de esta clase de bucles donde la tarea es: "Calcula un valor hasta que el resultado se halle dentro de un rango específico, pero haz solamente cierto número de intentos. Si el valor no se obtiene dentro del rango después del nùmero de intentos, detienes los intentos. ". Esto se hace cuando existe la posibilidad de que el bucle se repita infinitamente.
En el ejemplo anterior acerca del punto dentro de la unidad de la esfera no necesitamos esto porque el punto al azar seguramente llegaría hasta dentro de la esfera en algun momento. En otras ocasiones, sin embargo, puede que no estemos tan seguros.
En este caso necesitamos una variable index regular para contar el número de repeticiones. Si hemos hecho esa cantidad de repeticiones, entonces paramos.
Suponga que queremos modificar nuestro programa de búsqueda de un punto para que sea completamente seguro, e intente solamente hasta 10 veces. Si el punto no llega hasta el interior de la esfera después de 10 intentos, abandonamos y tomamos el punto <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
¿Qué hicimos?
Por cierto, algunas veces no es conveniente hacer esta prueba otra vez en la declaración de #if. Hay otra manera de determinar si el bucle se excedió sin la terminación exitosa o no: puesto que el bucle termina cuando el valor de 'Index' llega a 11, podemos usar esto para verificar el éxito del loop:
#if(Index = 11)
(el bucle no acabo con éxito)
#end
|