POV-Ray : Newsgroups : povray.beta-test : More To Test : Re: More To Test Server Time
29 Apr 2024 08:06:08 EDT (-0400)
  Re: More To Test  
From: clipka
Date: 26 Nov 2016 08:31:20
Message: <58398ea8@news.povray.org>
Am 26.11.2016 um 13:02 schrieb Jim Holsenback:

>>>> It's a bug in OTO_Get_Offset(), which had previously been lying
>>>> somewhat
>>>> dormant, but has now been exposed.
>>>
>>> come again ... are we looking at the same thing?
>>>
>>> in the include file i'm seeing:
>>>
>>> #macro OTO_Get_Offset(Cell)
>>>   #local CX = Cell.x;
>>>   #local CY = Cell.y;
>>>   (1-Bev*2)*<1,1,0>*(.5-OTO_FOffs(CX,CY,0))
>>> #end
>>
>> no help?!?
> 
> if it's /in/ the OTO_Get_Offset macro then why does commenting out the
> ..y and .x notation (after the call to macro) get rid of the error:
> 
> #if(OTO_Get_Mask(Vec)=1 )
>      #local Pt1 = Vec + y*(OTO_Get_Offset(Vec)/*.y*/) +
> x*(OTO_Get_Offset(Vec+y)/*.x*/);
>      #local Pt2 = Vec + y*(OTO_Get_Offset(Vec+x+y)/*.y*/) +
> x*(OTO_Get_Offset(Vec-y+x+y)/*.x*/) +x+y;
>     #else
>      #local Pt1 = Vec + x*(OTO_Get_Offset(Vec)/*.x*/) +
> (y*OTO_Get_Offset(Vec+x)/*.y*/);
>      #local Pt2 = Vec + x*(OTO_Get_Offset(Vec+x+y)/*.x*/) +
> y*(OTO_Get_Offset(Vec-x+x+y)/*.y*/) +x+y;
>     #end

The problem is rooted in how POV-Ray macros work: They're not
/functions/, but essentially "SDL code generators".

So if I have a macro

    #macro OTO_Get_Offset(Cell)
      #local CX = Cell.x;
      #local CY = Cell.y;
      (1-Bev*2)*<1,1,0>*(.5-OTO_FOffs(CX,CY,0))
    #end

then the macro invocation

    y*(OTO_Get_Offset(Vec).y)

does /not/ first compute the macro and then take the y component of the
result:

    // intended result
    y*((  (1-Bev*2)*<1,1,0>*(.5-OTO_FOffs(CX,CY,0))  ).y)

Instead, the body of the macro is essentially just pasted in:

    // actual result
    y*(  (1-Bev*2)*<1,1,0>*(.5-OTO_FOffs(CX,CY,0))  .y)

which -- obviously, once you format it a bit differently -- is something
entirely different:

    y*(  (1-Bev*2)  *  <1,1,0>  *  (.5-OTO_FOffs(CX,CY,0)).y  )


Now if you drop the `.y`, what you get is:

    y*(  (1-Bev*2)  *  <1,1,0>  *  (.5-OTO_FOffs(CX,CY,0))  )

which /happens/ to give exactly the same result as the intended
function, because given a vector V,

    y*(V.y)

aka

    <0,1,0>*(V.y)

scalar-to-vector promotion turns this into:

    <0,1,0>*<V.y,V.y,V.y>

which results in

    <0,V.y,0>

which happens to be the same as

    <0,1,0>*<V.x,V.y,V.z>

which is equivalent to

    <0,1,0>*V

aka

    y*V


The proper solution is to redefine the macro to include the intended
parentheses:

    #macro OTO_Get_Offset(Cell)
      #local CX = Cell.x;
      #local CY = Cell.y;
      (  (1-Bev*2)*<1,1,0>*(.5-OTO_FOffs(CX,CY,0))  )
    #end


Post a reply to this message

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