POV-Ray : Newsgroups : povray.advanced-users : It gets even weirder. : Re: It gets even weirder. Server Time
3 Feb 2023 14:00:04 EST (-0500)
  Re: It gets even weirder.  
From: clipka
Date: 27 Aug 2018 13:03:04
Message: <5b842ec8$1@news.povray.org>
Am 27.08.2018 um 16:04 schrieb Bald Eagle:
> clipka <ano### [at] anonymousorg> wrote:
> 
>> PEBCAK Error.

I guess I can do better. Sorry for that. It was intended purely humorously.

> If I'm missing something, then I still can't see it, and I'd like to know how a
> #for loop using (12-1)=11 as an endpoint, and yet it runs to 13, or (36-1)=35,
> and yet it runs to 36 - is possible.
> 
> Beyond the final #end statement, the counter should be final+step.  Within the
> loop, it should be start to end inclusive (according to the docs)
> 
> It would be most helpful if you could point to right where the error is, and
> say, "look - it's right HERE"  otherwise I'm just wasting a lot of time.

I thought my observations would already be pointing you in the right
direction. I need to have a closer look to provide more assistance.


> So the question is - what is YOUR mind seeing, and can you demonstrate to me
> that it's actually occurring - and WHY.
> 
> 
> =========================================================
> 
> 
> #version 3.7;
> global_settings {assumed_gamma 1.0}
> 
> #declare U1 = 0;
> #declare U2 = tau;
> #declare V1 = 0;
> #declare V2 = tau;
> #declare   Phi_inc = (tau/360)*30;
> #declare Theta_inc = (tau/360)*10;
> 
> #declare Usize = (U2-U1)/Phi_inc;
> #declare Vsize = (V2-V1)/Theta_inc;

One thing to note here is that, due to rounding issues, Usize and Vsize
may be non-integer, even though they should be according to mathematics.

Be that as it may - I'll assume Usize and Vsize are exact, in which case
they would be 12 and 36, respectively. The real problem lies elsewhere,
it's just that the computation of Usize and Vsize isn't perfectly kosher
either.

> // Run this as-is, and U goes to 11, and V goes to 35
> 
> // NOW
> 
> // change The line below to Usize+1, and U goes to 11, and V goes to 36 !!!  :O
> 
> // How can a variable NOT USED in defining the range of a #for loop change the
> behaviour of the loop!
> //  In BOTH variables!
> //  Usize is never redefined!   W   T   H
> 
>  #debug concat ("Usize = ", str(Usize, 0, 3), ",   Vsize = ", str(Vsize, 0, 3),
> "\n")
> 
> #declare StitchedArray = array[Usize+2][Vsize+2];  // <----- Try it!
> #for (U, 0, Usize-1)
>  #for (V, 0, Vsize-1)
>   #declare StitchedArray [U][V] = array[4][4];
>  #end
> 
> #end

The above loop should run from 0 to 11 and 0 to 35, respectively.
Note however that this only StitchedArray up to index 11 and 35,
respectively, whereas the next loop - even if running properly - seems
to be designed to access StitchedArray up to index 12 and 36, which may
bite you even after cleaning out the problem currently at hand.

> #declare PatchArray = array [4][4];
> 
> #for (Phi, U1, U2, Phi_inc) // 0 to 2pi
>  #declare U = ceil(Phi/Phi_inc);

This is dangerous, as you're using a non-integral loop variable with a
non-integral stepping, and it may not exactly end up at U2 even though
mathematically it should. The loop may run sort or long, i.e. Phi may
end up anywhere between U2-Phi_inc+epsilon to U2+Phi_inc-epsilon.

The resulting Phi/Phi_inc should nominally be 12, but may be anywhere
between 12-1+epsilon = 11+epsilon to 12+1-epsilon = 13-epsilon.

Taking the ceil of the value will bump your 11+epsilon to 12, but it
will also bump 13-epsilon to 13.

And indeed in practice the outer loop will happily run from 0 to 13, not
12 as you would expect. If the array is declared of size Usize+2 = 12+2
= 14, index 13 exists and therefore the loop runs without an obvious
hitch. If the array is instead declared of size Usize+1 = 12+1 = 13,
index 13 is out of bounds and you get a parse error (or even a crash)
trying to access it.


And that, I guess, is pretty much everything there is to it.

I recommend using `U = ceil(Phi/Phi_inc - 0.5)` or some such, i.e.
proper rounding.

Or maybe better still, use U and V as the loop variables, and from those
compute the angle, rather than vice versa.


The inner loop happens to be less of a problem, and it is running from
V=0 to V=36 as intended, but that is probably just coincidence. Change
Theta_inc, and you may get just as bad behaviour as with the outer loop.


> #for (U, 0, Usize-1)
>  #for (V, 0, Vsize-1)
>   #debug concat ("U2 = (", str(U, 2, 0), "/", str(Usize, 2, 0), "),   V2 = (",
> str(V, 2, 0), "/", str(Vsize, 2, 0), ")    ")
>   //#declare Test = StitchedArray [U][V][0][0];
>   //#declare Test1 = Test;
>   //#declare Test2 = Test[0][0];
>  #end
> 
> #end

This loop is better behaved, because Usize-1 seems to be a proper nut,
and you're using integer stepping. As a consequence, it runs from 0 to
11 and 0 to 35, respectively, as intended.


Post a reply to this message

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