POV-Ray : Newsgroups : povray.binaries.images : Helical SDF for Isosurfaces : Re: Helical SDF for Isosurfaces Server Time
4 Jan 2025 18:02:22 EST (-0500)
  Re: Helical SDF for Isosurfaces  
From: Chris R
Date: 23 Dec 2024 13:55:00
Message: <web.6769b1b34a98c6d6d30e597d5cc1b6e@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:
> "Bald Eagle" <cre### [at] netscapenet> wrote:
> > This is pretty nice, and I will definitely be using your library, as it's the
> > only nice/efficient way to make some good barrel rifling.
>
> POV-Ray absolutely drives me mad - on many occasions.
>
> I have a nice rifling cross section function, but for some reason - as of yet
> unknown to me, it behaves very badly when x is negative - as shown to the left
> of the origin.
>
> I could fix/hack it - but I'd like to know WHY it occurs.
> Even more baffling is when the twist rate is set very high - then the helix
> disappears completely.
>
>
>
> #version 3.8;
> global_settings {assumed_gamma 1.0 }
>
> #include "math.inc"
> #include "functions.inc"
> camera {
>  location <12, 0, -25>
>  right x*image_width/image_height
>  up y
>  look_at <12, 0, 0>
>  rotate -y*10
> }
>
> light_source {<10, 5, -10> rgb 1}
>
> sky_sphere {pigment {rgb 1}}
>
> #declare E = 0.00001;
>
> #declare Dia = 0.4;
>
> #declare Axis = 0.01;
> cylinder {<-30, 0, 0>, <30, 0, 0> Axis pigment {rgb x}}
> cylinder {<0, -Dia*2, 0>, <0, Dia*2, 0> Axis pigment {rgb y}}
> cylinder {<0, 0, -Dia*2>, <0, 0, Dia*2> Axis pigment {rgb z}}
>
> #declare fmod = function (Value, Modulo) {select (Value, 1 - mod (abs (Value),
> Modulo), mod (abs (Value), Modulo))}  // this gives a mod function that remains
> consistant across the origin
> //#declare Theta = function {atan2 (y, z)+tau + x*tau}
> #declare Theta = function {((atan2 (y, z)+pi)/pi)*tau + x*tau} // adds a
> multiple of x to produce the helix
>
> #declare dist = function {sqrt (y*y + z*z)}
>
> #declare Helix = function {select (mod (Theta(x, y, z), tau/3) - tau/6, 0.308,
> 0.35)} // modulates the radius to produce the rifling
>
> #declare Rifling = function {dist (x, y, z) - Helix (x/12, y, z)}
>
> #declare IS =
> isosurface {
>  function {Rifling(x,y,z)}
>  contained_by { box { <-12, -Dia, -Dia>, <24, Dia, Dia> } }
>  accuracy 0.0001
>  max_gradient 50
>  open
>
>  texture {
>   pigment {rgb 1}
>  } // end texture
>
>  interior_texture {
>   pigment {rgb <1, 0, 0>}
>  } // end texture
>
> } // end isosurface
>
> object {IS}

I got it to work by making the following change:

#declare natan2 = function(a,b) { select(a, 2*pi+atan2(a,b), atan2(a,b)) }
#declare Theta = function {((natan2 (y, z))/pi)*tau + x*tau}

The problem is that atan2 has that discontinuity where it jumps from pi/2 to
-pi/2, which happens along the edge you are looking at, and is made visible by
the switch in sign of the x value (x*tau).  The natan2 puts that discontinuity
at opposite ends of the value range, rather than in the middle and makes all of
the resulting angles positive (0-2*pi), and thus there is no abrupt switch when
x goes negative.

-- Chris R


Post a reply to this message

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