POV-Ray : Newsgroups : povray.binaries.images : Divide by negative zero Server Time
6 Nov 2024 14:25:15 EST (-0500)
  Divide by negative zero (Message 1 to 10 of 15)  
Goto Latest 10 Messages Next 5 Messages >>>
From: Anthony D  Baye
Subject: Divide by negative zero
Date: 25 Oct 2018 23:45:01
Message: <web.5bd28c9bc3066e9dfd6b6fe10@news.povray.org>
It seems to me that the engine used to throw an error when this happened...

Render attached. The last orange point is out of position. Why this happens at
-60 or 300 degrees and not on the other side, I don't know.
I found a possible workaround, but it's not pretty.

Watch the value of m1:
m1 = 0.500000 / -0.866025 = -0.577350
m2 = 0.327327 / -0.944911 = -0.346410
PC: <1.500000,0.866025,0.000000>
PD: <0.000000,1.732051,0.000000>
PE: <2.000000,1.732051,0.000000>
PF: <-0.500000,2.598076,0.000000>
m1 = -0.500000 / -0.866025 = 0.577350
m2 = -0.654654 / -0.755929 = 0.866025
PC: <0.000000,1.732051,0.000000>
PD: <-1.500000,0.866025,0.000000>
PE: <-0.500000,2.598076,0.000000>
PF: <-2.500000,0.866025,0.000000>
m1 = -1.000000 / -0.000000 = 3900231685776980.500000
m2 = -0.981981 / 0.188982 = -5.196152
PC: <-1.500000,0.866025,0.000000>
PD: <-1.500000,-0.866025,0.000000>
PE: <-2.500000,0.866025,0.000000>
PF: <-2.000000,-1.732051,0.000000>
m1 = -0.500000 / 0.866025 = -0.577350
m2 = -0.327327 / 0.944911 = -0.346410
PC: <-1.500000,-0.866025,0.000000>
PD: <-0.000000,-1.732051,0.000000>
PE: <-2.000000,-1.732051,0.000000>
PF: <0.500000,-2.598076,0.000000>
m1 = 0.500000 / 0.866025 = 0.577350
m2 = 0.654654 / 0.755929 = 0.866025
PC: <-0.000000,-1.732051,0.000000>
PD: <1.500000,-0.866025,0.000000>
PE: <0.500000,-2.598076,0.000000>
PF: <2.500000,-0.866025,0.000000>
m1 = 1.000000 / -0.000000 = -7800463371553961.000000
m2 = 0.981981 / -0.188982 = -5.196152
PC: <1.500000,-0.866025,0.000000>
PD: <1.500000,0.866025,0.000000>
PE: <2.500000,-0.866025,0.000000>
PF: <2.000000,1.732051,0.000000>
m1 = 1.000000 / -0.000000 = -7800463371553961.000000
m2 = 0.981981 / -0.188982 = -5.196152

Regards,

A.D.B.

Original Scene: Version 3.8.0-alpha.9606898.unofficial
/*
    Persistence of Vision Ray-Tracer Scene Description File
    Name: shm_2018-4.pov
    Vers: 3.6
    Desc: Spiral Honeycomb Mosaic
    Date: 10 - 24 - 18
    Auth: Anthony D. Baye
*/

#include "kolors.inc"
#include "math.inc"

#default { pigment { White }
  finish { diffuse 0.6 specular 0.3 roughness 0.01 fresnel on } }

light_source { <2.0, 3.0, -5.0> color rgb 1 }

camera {
    perspective
    location <0.0, 0.0, -15.0>
    up y
    right (image_width/image_height)*x
    look_at 0.0
}


#macro Arrow(S, D, L, C)
  union {
    cylinder { S, S+D*L 0.015625 }
    cone { S+D*L, 0.01325, S+D*L+0.125*D, 0.0 }
      pigment { C }
      finish { diffuse 0.6 specular 0.3 roughness 0.05 fresnel on }
  }
#end

#macro det2d(U,V)
  #local retval = U.x*V.y - U.y*V.x;
  retval
#end

#macro IPoint(UI1, UI2, VI1, VI2)
  #local Ud = vnormalize(UI2 - UI1);
  #local Vd = vnormalize(VI2 - VI1);

  // !! The problem is here !!
  #local m1 = Ud.y / Ud.x;
  #local m2 = Vd.y / Vd.x;
  // Workaround: ensure that x-coord is always slightly non-zero.
  // Problem: This introduces a slight error which grows larger with distance.
  // #local m1 = Ud.y / (Ud.x != 0 & Ud.x != -0 ? Ud.x : 0.00000000001 );
  // #local m2 = Vd.y / (Vd.x != 0 & Vd.x != -0 ? Vd.x : 0.00000000001 );
  #debug concat("m1 = " str(Ud.y,0,6) " / " str(Ud.x,0,6) " = " str(m1,0,6)
"\n")
  #debug concat("m2 = " str(Vd.y,0,6) " / " str(Vd.x,0,6) " = " str(m2,0,6)
"\n")
  #local rX = (m1*UI1.x - m2*VI1.x + VI1.y - UI1.y)/(m1 - m2);
  #local rY = m1*(rX - UI1.x) + UI1.y;
  #local retval = <rX,rY, 0.0>;
  retval
#end

#macro ShowPoints(RAD, ORDER, ADV)
  #local THETA = atand(sqrt(3)/2)*(ORDER - 1);
  #local BP = vrotate((RAD*<cosd(60), sind(60), 0.0> - <R, 0.0,
0.0>)*pow(sqrt(7),(ORDER - 1)),THETA*z);
  #local A = vrotate(RAD*<cosd(60), sind(60), 0.0>*pow(sqrt(7),(ORDER -
1)),THETA*z);
  #local B = vrotate((2*RAD*cosd(30))*<cosd(30), sind(30),
0.0>*pow(sqrt(7),(ORDER - 1)),THETA*z);
  #local G = vrotate((2*RAD*cosd(30))*<cosd(90), sind(90),
0.0>*pow(sqrt(7),(ORDER - 1)),THETA*z);
  #local D = B + RAD*sqrt(3)*<cosd(60), sind(60), 0.0>;
  #local E = G + RAD*sqrt(3)*<cosd(120), sind(120), 0.0>;

  union {
    sphere { A 0.09375 pigment { Red } }
    sphere { B 0.09375 pigment { Yellow } }
    sphere { G 0.09375 pigment { Yellow } }
    sphere { D 0.09375 pigment { Green } }
    sphere { E 0.09375 pigment { Green } }

    sphere { IPoint(B,G,D,E) 0.125
      pigment { Orange } finish { diffuse 0.6 specular 0.3 roughness 0.05
fresnel on } }
    }
#end

#declare R = 1.0;

#macro Hex(MajR)
union {
  #for(I,0,300,60)
    cylinder { MajR*<cosd(I), sind(I), 0.0> MajR*<cosd(I+60), sind(I+60), 0.0>
0.015625 }
  #end
  }
#end

#macro cMod(A, B)
  #local retval = A -  floor(A/B)*B;
  retval
#end

#local LV0 =
Hex(R)

#macro Flag(PIG, S)
  union {
    cylinder { <0.0,0.0,0.0> R*S*<cosd(0), sind(0), 0.0> 0.015625 }
    cylinder { <0.0,0.0,0.0> R*S*<cosd(60), sind(60), 0.0> 0.015625 }
    Arrow(R*S*<1.0, 0.0, 0.0>, <cosd(60),sind(60), 0.0> - <1, 0, 0.0>,
3*R*sqrt(7), PIG)
      pigment { PIG }
    }
#end

#macro Point(LOC, COL)
  sphere { LOC 0.0625 pigment {COL} }
#end

#declare LV1 =
union {
  object { LV0 }
  #for(A,0,5,1)
    object { LV0 translate R*sqrt(3)*<cosd(30 + 60*A), sind(30 + 60*A), 0.0> }
  #end
  }
LV1
// Point(<R, 0, 0>, Yellow)
// #for(A,0,5,1)
//   Point(R*sqrt(3)*<cosd(30 + 60*A), sind(30 + 60*A), 0.0>, Yellow)
//
// #end
// object { Point(R*sqrt(7)*<1.0, 0.0, 0.0>, Yellow) rotate atand(sqrt(3)/2)*z }
// object { Point(R*sqrt(7)*<1.0, 0.0, 0.0>, Yellow) rotate (atand(sqrt(3)/2) +
60)*z }

#declare PA = <R,0,0>;
#declare PB = R*<cosd(60), sind(60), 0.0>;
#declare PC = R*sqrt(3)*<cosd(30), sind(30), 0.0>;
#declare PD = R*sqrt(3)*<cosd(90), sind(90), 0.0>;
#declare PE = vrotate(PA*sqrt(7),atand(sqrt(3)/2)*z);
#declare PF = vrotate(PA*sqrt(7),(atand(sqrt(3)/2) + 60)*z);
Point(PA,Yellow)
Point(PB,Yellow)
Flag(Blue, R)
#for(A,0,5,1)
union {
    object { Flag(Red, R*sqrt(3)) rotate (30.0 + 60*A)*z }
    object { Flag(Green, R*sqrt(7)) rotate (atand(sqrt(3)/2) + 60*A)*z }
    }
#local ORIG = IPoint(
      vrotate(PC,60*A*z),
      vrotate(PD,60*A*z),
      vrotate(PE,60*A*z),
      vrotate(PF,60*A*z)
      );
#debug concat("PC: <" vstr(3,vrotate(PC,60*A*z),",",0,6) ">\n")
#debug concat("PD: <" vstr(3,vrotate(PD,60*A*z),",",0,6) ">\n")
#debug concat("PE: <" vstr(3,vrotate(PE,60*A*z),",",0,6) ">\n")
#debug concat("PF: <" vstr(3,vrotate(PF,60*A*z),",",0,6) ">\n")
Point(vrotate(PC,60*A*z),Green)
Point(vrotate(PD,60*A*z),Green)
Point(vrotate(PE,60*A*z),Yellow)
Point(vrotate(PF,60*A*z),Yellow)
Point(ORIG, Orange)
object { LV1 translate ORIG }
#end
Point(IPoint(vrotate(PC,300*z), vrotate(PD,300*z),  vrotate(PE,300*z),
vrotate(PF,300*z)),Red)


Post a reply to this message


Attachments:
Download 'shm_2018-4.png' (126 KB)

Preview of image 'shm_2018-4.png'
shm_2018-4.png


 

From: Anthony D  Baye
Subject: Re: Divide by negative zero
Date: 26 Oct 2018 00:25:01
Message: <web.5bd296ffa617eb51fd6b6fe10@news.povray.org>
What it should look like.

Regards,

A.D.B.


Post a reply to this message


Attachments:
Download 'shm_2018-4.png' (131 KB)

Preview of image 'shm_2018-4.png'
shm_2018-4.png


 

From: clipka
Subject: Re: Divide by negative zero
Date: 26 Oct 2018 02:02:46
Message: <5bd2ae06$1@news.povray.org>
Am 26.10.2018 um 05:41 schrieb Anthony D. Baye:
> It seems to me that the engine used to throw an error when this happened...
...
> Version 3.8.0-alpha.9606898.unofficial

That's on Linux, I presume?

POV-Ray does produce a warning if the second operand compares /equal to 
zero/.

Now as you've already noticed, there are two different zero values: A 
positive and a negative.

According to the C++ standard, /both/ values should compare equal to 
zero, so you /should/ get a warning when dividing by negative zero.

- BUT -

POV-Ray for Linux is usually compiled with `-ffast-math`. In this mode, 
the compiler does some smart floating-point optimizations - by cutting 
corners and /violating the standard/ for various special cases.

I don't know the details, but this sounds just like the kind of 
optimizations `-ffast-math` would do: Refuse to consider negative zero 
equal to (positive) zero just because hey, how can two values be equal 
if they have different binary representation.


There is no reliable way to work around this: Since this is all about 
the compiler violating the standard for the sake of optimization, there 
is no guarantee that a workaround would actually kick in, as it might 
also be subject to non-standard-compliant optimizations - or 
optimizations /based/ on the standard.

For example, if we chose to work around this by comparing the divisor 
with positive zero /and/ with negative zero, the compiler might decide 
that since positive and negative zeros are equivalent according to the 
standard, it can just as well drop one of the comparisons. Theoretically 
we might even end up making things worse, because the compiler might 
choose to keep the comparison with negative zero rather than the one 
with positive zero.

A compiler violating the C++ standard is free to contradict itself in 
the presumptions it uses for optimizations.


So if you want to be sure that you're not dividing by negative zero, 
either (a) explicitly test if the divisor is equal to zero in your scene 
code (this is reliable because POV-Ray's equality operator is 
implemented to use an error margin), or (b) re-compile POV-Ray without 
`-ffast-math`.


Post a reply to this message

From: Kenneth
Subject: Re: Divide by negative zero
Date: 26 Oct 2018 14:15:03
Message: <web.5bd35965a617eb5143b397d0@news.povray.org>
clipka <ano### [at] anonymousorg> wrote:
> Am 26.10.2018 um 05:41 schrieb Anthony D. Baye:
> > It seems to me that the engine used to throw an error when this happened...
> ...
> > Version 3.8.0-alpha.9606898.unofficial
>
> That's on Linux, I presume?
>
> POV-Ray does produce a warning if the second operand compares /equal to
> zero/.
> [etc]
>

For what it's worth, in POV-Ray for Windows v3.7.1 beta 9, I see the same
results as Anthony's original image-- the misplaced orange dot and the missing
hexagons at the top.

The only error messages I get are the expected ones: A missing assumed_gamma,
and the #version directive not being the first statement in the scene.

(By adding #version 3.71 , I get the same results, except for a quality
difference in the renders. But no *new* warning message.)


Post a reply to this message

From: Anthony D  Baye
Subject: Re: Divide by negative zero
Date: 26 Oct 2018 17:40:00
Message: <web.5bd3892fa617eb51fd6b6fe10@news.povray.org>
"Kenneth" <kdw### [at] gmailcom> wrote:
> clipka <ano### [at] anonymousorg> wrote:
> > Am 26.10.2018 um 05:41 schrieb Anthony D. Baye:
> > > It seems to me that the engine used to throw an error when this happened...
> > ...
> > > Version 3.8.0-alpha.9606898.unofficial
> >
> > That's on Linux, I presume?
> >
> > POV-Ray does produce a warning if the second operand compares /equal to
> > zero/.
> > [etc]
> >
>
> For what it's worth, in POV-Ray for Windows v3.7.1 beta 9, I see the same
> results as Anthony's original image-- the misplaced orange dot and the missing
> hexagons at the top.
>
> The only error messages I get are the expected ones: A missing assumed_gamma,
> and the #version directive not being the first statement in the scene.
>
> (By adding #version 3.71 , I get the same results, except for a quality
> difference in the renders. But no *new* warning message.)

I've got it working.  There are a couple lines in the IPoint macro that "Fix"
the problem (at least until offsets get really big) by ensuring that the slope
is never undefined.

I'm sure there's a method for finding intersections of two lines that isn't
vulnerable to this problem, but I haven't figured it out yet.

Regards,
A.D.B.


Post a reply to this message

From: clipka
Subject: Re: Divide by negative zero
Date: 28 Oct 2018 06:38:39
Message: <5bd591af$1@news.povray.org>
Am 26.10.2018 um 20:13 schrieb Kenneth:
> clipka <ano### [at] anonymousorg> wrote:
>> Am 26.10.2018 um 05:41 schrieb Anthony D. Baye:
>>> It seems to me that the engine used to throw an error when this happened...
>> ...
>>> Version 3.8.0-alpha.9606898.unofficial
>>
>> That's on Linux, I presume?
>>
>> POV-Ray does produce a warning if the second operand compares /equal to
>> zero/.
>> [etc]
>>
> 
> For what it's worth, in POV-Ray for Windows v3.7.1 beta 9, I see the same
> results as Anthony's original image-- the misplaced orange dot and the missing
> hexagons at the top.

Maybe the value isn't even exactly negative zero - I do get a "Division 
by zero" warning with all the POV-Ray for Windows binaries I've 
currently within close reach whenever I try to divide by exact negative 
zero.


Post a reply to this message

From: JimT
Subject: Re: Divide by negative zero
Date: 30 Oct 2018 05:55:01
Message: <web.5bd82976a617eb51be7517870@news.povray.org>
"Anthony D. Baye" <Sha### [at] spamnomorehotmailcom> wrote:
> What it should look like.
>
> Regards,
>
> A.D.B.

Anthony,

If you use the x(tVal1) = UI1 + Ud*tVal1 , y(tVal2) = VI1 + Vd*tVal2 formulation
for the lines then (x(tVal1)-y(tVal2)).Ud = 0 and
(x(tVal1)-y(tVal2)).Vd = 0 give 2 equations for tVal1 and tVal2. These would
give the nearest points of the pair of lines in 3D or the intersection point of
lines in 2D.

In the following, the only division is by detM, which will only be zero if the
lines are parallel. This will therefore not tread on the +-0 problem POV Ray
seems to have.

Thanks,

JimT

#macro IPoint(UI1, UI2, VI1, VI2)
  #local Ud      = vnormalize(UI2 - UI1);
  #local Vd      = vnormalize(VI2 - VI1);
  #local UddotVd = vdot(Ud,Vd);
  #if(UddotVd    = 1)
    #local rX    = 0;  // Parallel lines so no soln or infinite solns
    #local rY    = 0;
  #else
    #local UV1   = UI1 - VI1;
    #local b1    = vdot(-UV1,Ud);
    #local b2    = vdot( UV1,Vd);
    #local detM  = 1 - UddotVd*UddotVd;
    #local tVal  = (b1 + UddotVd*b2)/detM;
    #local Upt   = UI1 + Ud*tVal;
    #local rX    = Upt.x;
    #local rY    = Upt.y;
  #end
  #local retval  = <rX,rY, 0.0>;
  retval
#end


Post a reply to this message

From: dick balaska
Subject: Re: Divide by negative zero
Date: 1 Nov 2018 19:06:08
Message: <5bdb86e0$1@news.povray.org>
On 10/26/18 2:02 AM, clipka wrote:
> - BUT -
> 
> ...
>
> POV-Ray for Linux is usually compiled with `-ffast-math`.
> ...
> So if you want to be sure that you're not dividing by negative zero,
> either (a) explicitly test if the divisor is equal to zero in your scene
> code (this is reliable because POV-Ray's equality operator is
> implemented to use an error margin), or (b) re-compile POV-Ray without
> `-ffast-math`.

Most humbly, I would like to point out that the Debian POV-Ray 3.7.0.x
package does not use -ffast-math.  So, "usually" might be a bit strong.

From debian/rules:
  CXXFLAGS += -O3

  # This is rumoured to give wrong results with zero-thickness boxes, so
  # disabled
  # CXXFLAGS += -ffast-math


and a compile line:
g++ -DHAVE_CONFIG_H -I. -I..  -I.. -I../source/backend -I../source/base
-I../source/frontend -I../unix -I../vfe -I../vfe/unix -I/usr/include/SDL
-D_GNU_SOURCE=1 -D_REENTRANT -I/usr/include/OpenEXR -Wdate-time
-D_FORTIFY_SOURCE=2 -pthread -I/usr/include  -I/usr/include  -pipe
-Wno-multichar -Wno-write-strings -fno-enforce-eh-specs
-Wno-non-template-friend -g -O2
-fdebug-prefix-map=/home/dick/povray/debian/povray-3.7.0.7=.
-fstack-protector-strong -Wformat -Werror=format-security -O3 -pthread
-c -o lightgrp.o lightgrp.cpp

-- 
dik
Rendered 1024 of 921600 pixels (0%)


Post a reply to this message

From: clipka
Subject: Re: Divide by negative zero
Date: 1 Nov 2018 21:08:36
Message: <5bdba394$1@news.povray.org>
Am 02.11.2018 um 00:06 schrieb dick balaska:
> On 10/26/18 2:02 AM, clipka wrote:
>> - BUT -
>>
>> ...
>>
>> POV-Ray for Linux is usually compiled with `-ffast-math`.
>> ...
>> So if you want to be sure that you're not dividing by negative zero,
>> either (a) explicitly test if the divisor is equal to zero in your scene
>> code (this is reliable because POV-Ray's equality operator is
>> implemented to use an error margin), or (b) re-compile POV-Ray without
>> `-ffast-math`.
> 
> Most humbly, I would like to point out that the Debian POV-Ray 3.7.0.x
> package does not use -ffast-math.  So, "usually" might be a bit strong.

Given that "out of the box" from the official repository POV-Ray's Unix 
build process defaults to `-ffast-math`, I stick with "usually" and call 
Debian's package a - laudable - exception.

(Also, since distro packages are not compiled by each end user but only 
by the package manager, technically my statement remains true either way ;))


Post a reply to this message

From: William F Pokorny
Subject: Re: Divide by negative zero
Date: 2 Nov 2018 10:20:31
Message: <5bdc5d2f$1@news.povray.org>
On 11/1/18 7:06 PM, dick balaska wrote:
> On 10/26/18 2:02 AM, clipka wrote:
> 
> Most humbly, I would like to point out that the Debian POV-Ray 3.7.0.x
> package does not use -ffast-math.  So, "usually" might be a bit strong.
> 
>  From debian/rules:
>    CXXFLAGS += -O3
> 
>    # This is rumoured to give wrong results with zero-thickness boxes, so
>    # disabled
>    # CXXFLAGS += -ffast-math
> 
> 
> and a compile line:
> g++ -DHAVE_CONFIG_H -I. -I..  -I.. -I../source/backend -I../source/base
> -I../source/frontend -I../unix -I../vfe -I../vfe/unix -I/usr/include/SDL
> -D_GNU_SOURCE=1 -D_REENTRANT -I/usr/include/OpenEXR -Wdate-time
> -D_FORTIFY_SOURCE=2 -pthread -I/usr/include  -I/usr/include  -pipe
> -Wno-multichar -Wno-write-strings -fno-enforce-eh-specs
> -Wno-non-template-friend -g -O2
> -fdebug-prefix-map=/home/dick/povray/debian/povray-3.7.0.7=.
> -fstack-protector-strong -Wformat -Werror=format-security -O3 -pthread
> -c -o lightgrp.o lightgrp.cpp
> 

Interesting. I see too -fstack-protector-strong which off the top of my 
head the default compile does not use. Oh, and there is no -march=native 
so expect quite a few other optimizations not done. -D_FORTIFY_SOURCE=2 
added too.

Suppose compile differences like these something to keep in mind when 
someone reports a bug or performance concern where they might be using a 
pre-compiled package with different defaults than POV-Ray 'publishes.'

Aside: I've never done comparisons with and without -ffast_math. Wonder 
what the performance (result?) difference is...

Aside: Zero thickness boxes I'd think problematic in any case. Not 
opaque, differing inside/outside textures etc. Perhaps to the point the 
parser should complain on seeing such a box. Maybe something else 
meant...

Bill P.


Post a reply to this message

Goto Latest 10 Messages Next 5 Messages >>>

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