POV-Ray : Newsgroups : povray.advanced-users : Server Time30 Nov 2022 11:27:15 EST (-0500)
 (Message 1 to 10 of 18)
 From: Bald Eagle Subject: Date: 13 Sep 2018 19:35:00 Message:
```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#web.5b9af324c23a6d9458c7afe0%40news.povray.org",
"dateCreated": "2018-09-13T23:35:00+00:00",
"datePublished": "2018-09-13T23:35:00+00:00",
"author": {
"@type": "Person",
"name": "Bald Eagle"
}
}
[Floating-point] math is hard.

extra confounding factor that I had failed to consider. So, the lesson to
remember is that floating-point math is always more complex than you think it
is.

I may need something ... stronger than coffee, gin, bourbon, and Stephen's
proprietary family-secret Dried Frog Pills (TM) (R) (c)

I had ironed out some stupid errors and was homing in working out the wonkiness
of a function and, lo and behold, I'm getting an "...uninitialized array
element..." error - not because i was working outside the scope of my 2D array,
but because the comparison I was trying to perform - WAIT --- HAD been
performing for the last week - suddenly didn't like to successfully compare 0 to
.... "zero".

@#%\$^&**

So I have an array of vectors with .y and .z values ranging from 0 to tau, or
2*pi, or whatever the #version's parser allows...

And I just want to see "where" in that range I am....

#local Mult = 1000;

#local _Patch = array [6];

#for (U, 0, Usize)
#debug concat ("Testing Y = ", Scalar (YVal, 3, 0), " vs ", Vector
(UArray [U], 3, 0), " \n")

(commmence anti-floating point calisthenics...)

#if ( int(YVal*Mult) >= int(UArray [U].y*Mult) & int(YVal*Mult) <=
int(UArray [U].z*Mult) )

#local _Patch [0] = UArray [U].x;
#local _Patch [1] = UArray [U].y;
#local _Patch [2] = UArray [U].z;
#end
#end

And I mean, it's ZERO, so what do I multiply by and round it with?
Is f'ing  _***INT***_ (0) not ZERO?!

:|

I would like a kind soul to attempt, again, in a practical way, to suggest an
effective algorithm that will allow "easy" and accurate comparison of numbers
derived in some way shape or form from floating point calculations.

Apparently #for (N, 0, ....
doesn't give me a zero that's equal to 0 * N2....
```
 From: Bald Eagle Subject: Re: Date: 13 Sep 2018 19:40:01 Message:
```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#web.5b9af4d46f92e856458c7afe0%40news.povray.org",
"dateCreated": "2018-09-13T23:40:01+00:00",
"datePublished": "2018-09-13T23:40:01+00:00",
"author": {
"@type": "Person",
"name": "Bald Eagle"
}
}
"Bald Eagle" <cre### [at] netscapenet> wrote:
> [Floating-point] math is hard.

.....

> So, the lesson to
> remember is that floating-point math is always more complex than you think it
> is.

https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
```
 From: clipka Subject: Re: Date: 13 Sep 2018 23:17:25 Message: <5b9b2845\$1@news.povray.org>
```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#5b9b2845%241%40news.povray.org",
"dateCreated": "2018-09-14T03:17:25+00:00",
"datePublished": "2018-09-14T03:17:25+00:00",
"author": {
"@type": "Person",
"name": "clipka"
}
}
Am 14.09.2018 um 01:30 schrieb Bald Eagle:

> So I have an array of vectors with .y and .z values ranging from 0 to tau, or
> 2*pi, or whatever the #version's parser allows...
>
> And I just want to see "where" in that range I am....
>
>
>
>     #local Mult = 1000;
>
>     #local _Patch = array [6];
>
>     #for (U, 0, Usize)
>         #debug concat ("Testing Y = ", Scalar (YVal, 3, 0), " vs ", Vector
> (UArray [U], 3, 0), " \n")
>
> (commmence anti-floating point calisthenics...)
>
>         #if ( int(YVal*Mult) >= int(UArray [U].y*Mult) & int(YVal*Mult) <=
> int(UArray [U].z*Mult) )
>
>         #local _Patch [0] = UArray [U].x;
>         #local _Patch [1] = UArray [U].y;
>         #local _Patch [2] = UArray [U].z;
>         #end
>     #end
>
> And I mean, it's ZERO, so what do I multiply by and round it with?
> Is f'ing  _***INT***_ (0) not ZERO?!
...
> Apparently #for (N, 0, ....
> doesn't give me a zero that's equal to 0 * N2....

Wait.

What you're multiplying is YVal, not U.
What you're debug-outputting is YVal rounded to 0 decimals, not YVal
(nor U, for that matter).

And yes, that Random ASCII article is precise to the last digit:
Floating point arithmetics comes with 16 serious issues - and counting.
```
 From: Thomas de Groot Subject: Re: Date: 14 Sep 2018 02:43:15 Message: <5b9b5883\$1@news.povray.org>
```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#5b9b5883%241%40news.povray.org",
"dateCreated": "2018-09-14T06:43:15+00:00",
"datePublished": "2018-09-14T06:43:15+00:00",
"author": {
"@type": "Person",
"name": "Thomas de Groot"
}
}
On 14-9-2018 1:30, Bald Eagle wrote:
> I may need something ... stronger than coffee, gin, bourbon, and Stephen's
> proprietary family-secret Dried Frog Pills (TM) (R) (c)
>

Be careful about those pills, especially in combination with fire water.
Stephen certainly warned you about it (or he should have). They got me

--
Thomas
```
 From: Bald Eagle Subject: Re: Date: 14 Sep 2018 06:30:00 Message:
```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#web.5b9b8d556f92e856458c7afe0%40news.povray.org",
"dateCreated": "2018-09-14T10:30:00+00:00",
"datePublished": "2018-09-14T10:30:00+00:00",
"author": {
"@type": "Person",
"name": "Bald Eagle"
}
}
clipka <ano### [at] anonymousorg> wrote:

> Wait.
>
> What you're multiplying is YVal, not U.
> What you're debug-outputting is YVal rounded to 0 decimals, not YVal
> (nor U, for that matter).

Well what I'm comparing the loop integer to is max(0, U*Ustep) [see far below],
and it's crapping out right out of the gate.

element  low   high
_X = 0.00000, _Y = 0.00000
Testing Y = 0.000 vs <0.000, 0.000, 1.047> // totally skips this  :(
Testing Y = 0.000 vs <1.000, 1.047, 2.094>
Testing Y = 0.000 vs <2.000, 2.094, 3.142>
Testing Y = 0.000 vs <3.000, 3.142, 4.189>
Testing Y = 0.000 vs <4.000, 4.189, 5.236>
Testing Y = 0.000 vs <5.000, 5.236, 6.283>
Testing Y = 0.000 vs <6.000, 6.283, 6.283>

My #debug output - those are macros - it's rounding to 3 decimals (see above),
the 0 is a flag for +/- "\n".

#declare Ustep = (U2-U1)/(UU);
#declare Vstep = (V2-V1)/(VV);

#debug concat ("UStep = U2 (", Scalar (U2, 5, 0), ") - U1 (", Scalar (U1, 5, 0),
") / Usize (", Scalar (Usize, 5, 0), ") = ", Scalar (Ustep, 5, 1))
#debug concat ("VStep = V2 (", Scalar (V2, 5, 0), ") - V1 (", Scalar (V1, 5, 0),
") / Vsize (", Scalar (Vsize, 5, 0), ") = ", Scalar (Vstep, 5, 1))

#debug "\n\n"

#for (U, 0, UU)     // must be UU because SitchedArray is only that big
#declare UArray [U] = <U, max(0, U*Ustep), min((U+1)*Ustep, U2)>;
//#debug concat ("UArray [", Scalar (U, 0, 0), "] = ", Vector (UArray [U], 5,
1))
#end

#for (V, 0, VV) // must be VV because SitchedArray is only that big
#declare VArray [V] = <V, max(0, V*Vstep), min((V+1)*Vstep, V2)>;
//#debug concat ("VArray [", Scalar (V, 0, 0), "] = ", Vector (VArray [V], 5,
1))
#end
```
 From: Bald Eagle Subject: Re: Date: 14 Sep 2018 11:20:00 Message:
```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#web.5b9bd08a6f92e856c437ac910%40news.povray.org",
"dateCreated": "2018-09-14T15:20:00+00:00",
"datePublished": "2018-09-14T15:20:00+00:00",
"author": {
"@type": "Person",
"name": "Bald Eagle"
}
}
Thomas de Groot <tho### [at] degrootorg> wrote:
> On 14-9-2018 1:30, Bald Eagle wrote:
> > I may need something ... stronger than coffee, gin, bourbon, and Stephen's
> > proprietary family-secret Dried Frog Pills (TM) (R) (c)
> >
>
> Be careful about those pills, especially in combination with fire water.
> Stephen certainly warned you about it (or he should have). They got me
>
> --
> Thomas

Lightweight.  :P

Next thing, you'll be telling me that the hookah he and I have been building to
smoke some imported dried Conraua goliath is ... "ill advised".

Now, be a good lad and fetch me a Winchester bottle of ether.
```
 From: clipka Subject: Re: Date: 14 Sep 2018 13:13:08 Message: <5b9bec24\$1@news.povray.org>
```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#5b9bec24%241%40news.povray.org",
"dateCreated": "2018-09-14T17:13:08+00:00",
"datePublished": "2018-09-14T17:13:08+00:00",
"author": {
"@type": "Person",
"name": "clipka"
}
}
Am 14.09.2018 um 12:28 schrieb Bald Eagle:

>> What you're multiplying is YVal, not U.
>> What you're debug-outputting is YVal rounded to 0 decimals, not YVal
>> (nor U, for that matter).
>
> Well what I'm comparing the loop integer to is max(0, U*Ustep) [see far below],
> and it's crapping out right out of the gate.

Well, that's not the code you posted.

...

> My #debug output - those are macros - it's rounding to 3 decimals (see above),
> the 0 is a flag for +/- "\n".

Sorry, my bad. Skimming over the code, I had recognized the structure
typical for a `#debug` with invocations of `str()`, not realizing you
invoked something else entirely.

Still, 3 decimals is far below the precision of POV-Ray's float equality
tests.

Given your code, I'm pretty confident UArray[0].y will be 0, but from
the salami slices(*) of code you've posted so far, I can't say the same
for YVal; no post in this thread shows me how that value is computed, so
I don't trust it.

(* I hate to provide support for salami code, by the way. It means that
all I have to go by is "dry" code review, which for a meaningful answer
requires high attention to detail, and even then false assumptions or
misunderstandings may creep in and interfere. Give me a minimal complete
scene file to toy around with anytime, where I can easily verify my
assumptions and understandings by adding more `#debug` lines as I go
along. Providing such a scene may be more work on your side, but
probably saves as much work on mine, leaving more time for me to do
other POV-Ray related stuff.)
```
 From: Bald Eagle Subject: Re: Date: 14 Sep 2018 14:00:07 Message:
```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#web.5b9bf6c26f92e856c437ac910%40news.povray.org",
"dateCreated": "2018-09-14T18:00:07+00:00",
"datePublished": "2018-09-14T18:00:07+00:00",
"author": {
"@type": "Person",
"name": "Bald Eagle"
}
}
The wet and juicy version.

I prefer the bologna descriptor.

The offender is
#declare _Y = function (Angle, _M) {min(max(0, Angle * _M), _M)}

where "Angle" goes from 0 to 1.

#######################################################################

#version version;

// floating point comparison debug

#include "colors.inc"

light_source {
<5, 10, -20>
color White
}

camera {
location  <0, 2, -35>
look_at   <0, 0, -10>

right x*image_width/image_height
up y
}

//###############################################

#macro Scalar (_Value, _P, _N)
#local _Result = str(_Value, 0, _P);
#if(_N) #local _Result = concat (_Result, " \n") #end
_Result
#end

//###############################################

#macro Vector (_Value, _P, _N)
#local _Result = concat ("<", vstr(3, _Value, ", ", 0, _P), ">");
#if(_N) #local _Result = concat (_Result, " \n") #end
_Result
#end

//###############################################
//------------------------------------------------------------------------------
#declare Round = function (Value) {ceil(Value - 0.5)}
//------------------------------------------------------------------------------
// Fast NChooseM
#declare FastNCM = function (n, k) {prod(i, k+1, n, i) / prod(i, 1, n-k, i)}

#declare PowerFn = function(s, p) { select(p, pow(s, p), 1, pow(s, p)) }
//------------------------------------------------------------------------------
#declare Bernstein = function (Deg, K, S)
{FastNCM(Deg, K) * PowerFn(S, K) * PowerFn (1 - S, Deg - K)}

//------------------------------------------------------------------------------
#macro Point (VG, UG, Uc, Vc)   // called during interpolation loop due to using
Current [V][U] array
//#debug concat(Scalar(VG, 0, 0), ", ", Scalar(UG, 0, 1), "\n")
#local Degree = 3;
#local P =
#for (j, 0, 3)
#for (i, 0, 3)
//#debug concat(Scalar(VG, 0, 0), ", ", Scalar(UG, 0, 0), ", ", Scalar(i, 0,
0), ", ", Scalar(j, 0, 1), "\n")
Bernstein(Degree, i, Vc) * Bernstein(Degree, j, Uc) * StitchedArray
[VG][UG][i][j] +
#end
#end
0;
P
#end
//------------------------------------------------------------------------------

#declare Curve = true;

#declare R1 = 10;   //
#declare R2 = 4;   //
#declare Sum = R1+R2;  //

#declare U1 = 0;   // small radius
#declare U2 = 2*pi;   //
#declare V1 = 0;   // large radius
#declare V2 = 2*pi;   //
#declare r0 = R1;
#declare r1 = R2;
//#declare Phi = U1;
#declare   Phi_inc = (2*pi/360)*60;
#declare Theta_inc = (2*pi/360)*20;

#debug "Creating arrays... \n"

// Create an array to hold all of the Bezier patches to cover the surface
#declare Usize = Round ((U2-U1)/Phi_inc)+1;
#declare Vsize = Round((V2-V1)/Theta_inc);
#debug concat ("Usize = ", str(Usize, 0, 3), ",   Vsize = ", str(Vsize, 0, 3),
"\n")

#declare UU = Usize-1;
#declare VV = Vsize-1;

#debug concat ("UU = ", str(UU, 0, 3), ",   VV = ", str(VV, 0, 3), "\n")

#declare UArray = array [Usize+1];
#declare VArray = array [Vsize+1];

#debug concat ("UArray extends from 0 to ", str(dimension_size(UArray,1)-1, 0,
3), " \n")
#debug concat ("VArray extends from 0 to ", str(dimension_size(VArray,1)-1, 0,
3), " \n")

#declare StitchedArray = array[Vsize][Usize];

#for (U, 0, UU)
#for (V, 0, VV)
#local StitchedArray [V][U] = array[4][4];
#end

#end

#debug concat ("StitchedArray is ", str(dimension_size(StitchedArray, 1)-1, 0,
3), " x ", str(dimension_size(StitchedArray, 2)-1, 0, 3), " elements \n\n")

//----------------------------------------------------

#declare Ustep = (U2-U1)/(UU);
#declare Vstep = (V2-V1)/(VV);

#debug concat ("UStep = U2 (", Scalar (U2, 5, 0), ") - U1 (", Scalar (U1, 5, 0),
") / Usize (", Scalar (Usize, 5, 0), ") = ", Scalar (Ustep, 5, 1))
#debug concat ("VStep = V2 (", Scalar (V2, 5, 0), ") - V1 (", Scalar (V1, 5, 0),
") / Vsize (", Scalar (Vsize, 5, 0), ") = ", Scalar (Vstep, 5, 1))

#debug "\n\n"

#for (U, 0, UU)     // must be UU because SitchedArray is only that big
#declare UArray [U] = <U, max(0, U*Ustep), min((U+1)*Ustep, U2)>;
//#debug concat ("UArray [", Scalar (U, 0, 0), "] = ", Vector (UArray [U], 5,
1))
#end

#for (V, 0, VV) // must be VV because SitchedArray is only that big
#declare VArray [V] = <V, max(0, V*Vstep), min((V+1)*Vstep, V2)>;
//#debug concat ("VArray [", Scalar (V, 0, 0), "] = ", Vector (VArray [V], 5,
1))
#end

//----------------------------------------------------

// Determines the Bezier patch in the 2D array that the function coordinates
fall on
#macro ThisPatch (XVal, YVal)
#local Mult = 1000;

//#local _Patch = <0, 0>;
#local _Patch = array [6];

#for (U, 0, Usize)
#debug concat ("Testing Y = ", Scalar (YVal, 3, 0), " vs ", Vector
(UArray [U], 3, 0), " \n")
#if ( int(YVal*Mult) >= int(UArray [U].y*Mult) & int(YVal*Mult) <=
int(UArray [U].z*Mult) )

#local _Patch [0] = UArray [U].x;
#local _Patch [1] = UArray [U].y;
#local _Patch [2] = UArray [U].z;
#end
#end

#ifndef (_Patch [0]) #debug "_Patch [0] U not defined \n" #end

#for (V, 0, Vsize)
#debug concat ("Testing X = ", Scalar (XVal, 3, 0), " vs ", Vector (VArray
[V], 3, 0), " \n")
#if (XVal >= VArray [V].y & XVal <= VArray [V].z)

#local _Patch [3] = VArray [V].x;
#local _Patch [4] = VArray [V].y;
#local _Patch [5] = VArray [V].z;
#end
#end

#ifndef (_Patch [3]) #debug "_Patch [3] V not defined \n" #end

_Patch
#end

//-----------------------------------------------------------
#macro Vector4 (_Value, _P, _N)
#local _Result = concat ("<", vstr(4, _Value, ", ", 0, _P), ">");
#if(_N) #local _Result = concat (_Result, " \n") #end
_Result
#end
//-----------------------------------------------------------

// Determines where on individual Bezier patch function coordinates are
#macro PatchUV (XVal, YVal)
#local Range = ThisPatch (XVal, YVal);
#local ThisU = (YVal - Range [1]) / (Range [2]- Range [1]);
#local ThisV = (XVal - Range [4]) / (Range [5]- Range [4]);
#local _Result = <Range [3], Range [0], ThisV, ThisU>;
//#debug Vector4 (_Result, 3, 1)
_Result

#end

#if (Curve)

#declare N = 5;
#declare _X = function (_N, Angle, _M) {min (_N*mod(Angle, 1/_N) * _M, _M)}
#declare _Y = function (Angle, _M) {min(max(0, Angle * _M), _M)}

#declare F = 1.0000001; // LastPoint multiplier to avoid [most] degenerate
cylinders
#for (Theta, 0, 1, 0.001)

#debug concat ("_X = ", Scalar (_X(N, Theta, Vsize), 5, 0), ", _Y = ", Scalar
(_Y(Theta, Usize), 5, 1))

#local UV = PatchUV ( _X(N, Theta, Vsize), _Y(Theta, Usize) );
// this converts the points to 'flat' UV, but now they need to be converted to
the interpolated Bezier coordinates
#local CurrentPoint = Point (UV.x, UV.y, UV.z, UV.t);
//#debug Vector (Point, 3, 1)
//#debug Vector (UV, 3, 1)
#if (Theta > 0)
cylinder {LastPoint*F, CurrentPoint, Radius texture {CurveTex} }
#end
#local LastPoint = CurrentPoint;
#end

#end
```
 From: clipka Subject: Re: Date: 14 Sep 2018 15:55:45 Message: <5b9c1241\$1@news.povray.org>
```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#5b9c1241%241%40news.povray.org",
"dateCreated": "2018-09-14T19:55:45+00:00",
"datePublished": "2018-09-14T19:55:45+00:00",
"author": {
"@type": "Person",
"name": "clipka"
}
}
Am 14.09.2018 um 19:58 schrieb Bald Eagle:
> The wet and juicy version.
>
> I prefer the bologna descriptor.
>
> The offender is
> #declare _Y = function (Angle, _M) {min(max(0, Angle * _M), _M)}
>
> where "Angle" goes from 0 to 1.

That's not what i see.

What I see (after fixing some line-wrapped comments) is an error
encountering "srgb" before "assumed_gamma".

When that is fixed (by not including colors.inc and instead defining
"White" manually), I get an error in

#debug concat ("Testing Y = ", Scalar (YVal, 3, 0), " vs ", Vector
(UArray [U], 3, 0), " \n")

where U reaches 7.

Which is not surprising, since you have

#for (U, 0, Usize)

while the array is only Usize elements long, from 0 to Usize-1.
```
 From: clipka Subject: Re: Date: 14 Sep 2018 16:03:02 Message: <5b9c13f6\$1@news.povray.org>
```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#5b9c13f6%241%40news.povray.org",
"dateCreated": "2018-09-14T20:03:02+00:00",
"datePublished": "2018-09-14T20:03:02+00:00",
"author": {
"@type": "Person",
"name": "clipka"
}
}
Am 14.09.2018 um 21:55 schrieb clipka:

> Which is not surprising, since you have
>
>     #for (U, 0, Usize)
>
> while the array is only Usize elements long, from 0 to Usize-1.

Sorry, that's an imprecise observation; the array is Usize+1 elements
long, so it has space for elements from 0 to Usize. But you're only
initializing elements from 0 to UU, with UU = Usize-1, so element Usize
remains uninitialized.
```