POV-Ray : Newsgroups : povray.binaries.images : Helical SDF for Isosurfaces Server Time
4 Jan 2025 18:23:32 EST (-0500)
  Helical SDF for Isosurfaces (Message 5 to 14 of 24)  
<<< Previous 4 Messages Goto Latest 10 Messages Next 10 Messages >>>
From: Bald Eagle
Subject: Re: Helical SDF for Isosurfaces
Date: 14 Dec 2024 09:55:00
Message: <web.675d9c254a98c6d61f9dae3025979125@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:

> Hopefully some time this weekend I will post a link to Mike Williams' isosurface
> tutorial, which also has a ton of good information.

Done.
https://wiki.povray.org/content/User:BillW


Post a reply to this message

From: Bald Eagle
Subject: Re: Helical SDF for Isosurfaces
Date: 20 Dec 2024 12:25:00
Message: <web.6765a7984a98c6d6327467e125979125@news.povray.org>
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.

Do you ever use Desmos to develop your isosurface functions?

- BE


Post a reply to this message

From: Bald Eagle
Subject: Re: Helical SDF for Isosurfaces
Date: 20 Dec 2024 19:55:00
Message: <web.6766113a4a98c6d61f9dae3025979125@news.povray.org>
"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}


Post a reply to this message


Attachments:
Download 'isosurfacerifle.png' (37 KB)

Preview of image 'isosurfacerifle.png'
isosurfacerifle.png


 

From: Kenneth
Subject: Re: Helical SDF for Isosurfaces
Date: 22 Dec 2024 10:20:00
Message: <web.67682a714a98c6d6e83955656e066e29@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:
>
> 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 spent hours going through you code line by line, changing this-that-and
the-other, and I still cannot solve the subtle problem with the 'rifling' itself
(see the top image in the attachment.) I think that the only recourse-- given
the equations as-is-- is to just translate the problem area far into -x so that
it's 'outside' of your rifle barrel! Sorry that I can't offer a better
suggestion:
#declare Rifling = function {dist (x, y, z) - Helix (x/12 + 50 , y, z)
// The +50 moves it way into -x

The only thing I succeeded in doing was slightly simplifying your equations, to
make them easier to work with (for me.) [See below.] I think they behave a
*little* bit better, but not much.

But that's just part of the problem: The isosurface itself is behaving oddly,
with parts that are showing up as 'inside' and 'outside.' (I used an ambient 1
finish in the interior_texture to see this, along with a few changes to your
equations to show the problem 'writ large'.) It's an odd camera/isosurface
interaction. Even though the functions are producing infinite gradients, that
doesn't explain such a problem, IMO (but I could be wrong.) And the camera
position doesn't matter-- it always sees the 'inside' portions as being on the
'back half' of the the spirals. I thought the culprit might be the atan2
function in your Theta, but negating it does not help, it just changes the
'chirality' of the spiral.

In any case, here is my own simplified set of equations. The various values
interplay.  I think that the same rifling/spiral effect as your's can be gotten
by leaving the first 'tau' here as tau/1 (or just tau), and only changing the
2nd tau (plus  one or two other changes elsewhere to change the frequency and/or
'stretching'.) In this case, the 2nd tau's divisor needs to be greater than 1.0:

#declare Helix = function {select (mod (Theta(x, y, z), tau/1)
- tau/6, 0.308, 0.35)

my code:
#declare Theta = function {atan2 (y, z) + 1*x}  // change multiplier of x
// to change frequency, but leave as-is; similar to changing the x multiplier
// in Rifling function's Helix below

#declare dist = function {sqrt (y*y + z*z)}

#declare Helix = function {select (mod (Theta(x, y, z), tau/1) - tau/2, 0.15,
0.35)}
// change 2nd tau between tau/6 and tau/( > 1.0) to see change in ratio of
// lands to  grooves.

#declare Rifling = function {dist (x, y, z) - Helix (x*1 + 50, y, z)}
// try x*8, or x, or x*.6 , to see the 'squashing' or 'stretching' of
// the frequency

isosurface{
function {Rifling(x,y,z)}
contained_by{...}
threshold 0
 accuracy .000001 // 0.0001
 max_gradient 150
// no 'open'
--- etc ---
}

-----
BTW: While trying the fixes, I also came up with an alternate form of your Theta
function:  two different 'mating' functions that produce the rifling effect in
both +x and -x, and without  the original rifling's 'glitch' (but they don't
solve the odd isosurface problems.) But I haven't had any success yet in
*combining* these two functions into one, to get the same effect as the
individual ones. (AND, they only work when Helix's two tau's are tau/1 and
tau/2-- i.e., the square-wave situation; otherwise their spirals slightly
overlap near the the x axis.) Anyway, here they are (for use in my set of
equations)...

#declare Theta_1 = function {atan2 (y, z) +x + pi} // pi simply moves
// the spiral one-half 'revolution' into -x
#declare Theta_2 = function {-atan2 (y, z) -x} // nicely mates up with Theta_1


Post a reply to this message


Attachments:
Download 'be_rifling_with_problems--kw_1.jpg' (169 KB)

Preview of image 'be_rifling_with_problems--kw_1.jpg'
be_rifling_with_problems--kw_1.jpg


 

From: Kenneth
Subject: Re: Helical SDF for Isosurfaces
Date: 22 Dec 2024 21:10:00
Message: <web.6768c60b4a98c6d6e83955656e066e29@news.povray.org>
"Kenneth" <kdw### [at] gmailcom> wrote:
>
> The only thing I succeeded in doing was slightly simplifying your
> equations, to make them easier to work with (for me.) I think they behave a
> *little* bit better, but not much.
> [snip]
> I think that the same rifling/spiral effect as your's can be gotten
> by leaving the first 'tau' here as tau/1 (or just tau), and only changing the
> 2nd tau.

Well, I was wrong :-/  In my own 'simplified' group of equations, leaving the
first tau as tau/1 produces only ONE groove down the length of the barrel, no
matter how I change the frequency.

#declare Helix = function {select (mod (Theta(x, y, z), tau/1) - tau/2, 0.15,
0.35)}

The rifling should have *many* grooves---which your code successfully produces.
Your own set of equations is definitely better-- even with the little 'glitch'
(which can be translated away.)

As usual, I didn't see this until after I posted. (**groan**)


Post a reply to this message

From: Bald Eagle
Subject: Re: Helical SDF for Isosurfaces
Date: 23 Dec 2024 09:10:00
Message: <web.67696edd4a98c6d6471fd7cd25979125@news.povray.org>
First - let me start off by saying that your annotated summary render is
absolutely beautiful.

I don't know if you have a standard scene all rigged up for that kind of thing -
but it's really nice.

> Well, I was wrong :-/  In my own 'simplified' group of equations, leaving the
> first tau as tau/1 produces only ONE groove down the length of the barrel, no
> matter how I change the frequency.
>
> #declare Helix = function {select (mod (Theta(x, y, z), tau/1) - tau/2, 0.15,
> 0.35)}

Right.  So basically all I'm doing is doing an if (one value) then this radius,
else if (another value) then another radius.

#declare Helix = function {select (mod (Theta(x, y, z), tau/3) - tau/6, 0.308,
0.35)} // modulates the radius to produce the rifling

Just using the dist () function would give you a cylinder.
Subtracting the Helix () function changes the radius of the cylinder according
to where around the cylinder you are.

#declare Rifling = function {dist (x, y, z) - Helix (x/12, y, z)}

Just using a simple atan2 function for Theta would give you a cylinder with
straight grooves down its length.

So I simply make the phase of Theta depend on x by adding it to the atan2
result.
#declare Theta = function {((atan2 (y, z)+pi)/pi)*tau + x*tau} // adds a
multiple of x to produce the helix

atan2 has a range of -pi/2 to pi/2, and the initial idea was to normalize all of
that so that I added pi/2 to go from 0 to pi, then divide by pi to get a range
from 0-1, and then multiply that by tau to get one full revolution.


I think the most useful thing to do at this point would be to ditch the
isosurface renderings and simply start graphing the equations to see where
things get out of joint.  Having the rifling just *disappear* doesn't seem to
make any sense, so graphing the Helix function would be my first line of attack.


Post a reply to this message

From: Bald Eagle
Subject: Re: Helical SDF for Isosurfaces
Date: 23 Dec 2024 10:00:00
Message: <web.67697a7d4a98c6d6471fd7cd25979125@news.povray.org>
> I think the most useful thing to do at this point would be to ditch the
> isosurface renderings and simply start graphing the equations to see where
> things get out of joint.

So, here's a Desmos graph of what I was striving to implement in SDL.

We're going around in a circle, but we want to graph things in rectangular
coordinates, so we pretend x is theta, and take the cos and sin of "theta" to
give our "x" and y coordinates.

then we take the atan y/x           (atan2(y, x) in SDL) to get the angle.
As you can see from the green lines, you go from -pi/2 to pi/2

Next, we add pi/2 to go from 0 to pi, and dive it all by pi to go from 0 to 1
(purple lines)

Multiplying by tau, we get a full 2*pi radians around the circle (red lines)

Applying the Helix function, we switch between radii of 0.5 and 1, based upon
using modulo to select () the number of grooves we want in our rifling (g)
(orange lines)

https://www.desmos.com/calculator/wa4avaopd1

- BW


Post a reply to this message

From: Chris R
Subject: Re: Helical SDF for Isosurfaces
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

From: Bald Eagle
Subject: Re: Helical SDF for Isosurfaces
Date: 23 Dec 2024 15:05:00
Message: <web.6769c1814a98c6d6471fd7cd25979125@news.povray.org>
"Chris R" <car### [at] comcastnet> wrote:

> 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

Most Excellent, fine Sir!
Some days I can see what needs to be done - other days it's more . . . opaque.

I'm officially voting that such be made an internal function, or at least
something available in functions.inc

This could save a lot of people a lot of trouble in the future.

Thank you,

- BW


Post a reply to this message

From: Kenneth
Subject: Re: Helical SDF for Isosurfaces
Date: 23 Dec 2024 23:30:00
Message: <web.676a37e44a98c6d6e83955656e066e29@news.povray.org>
"Chris R" <car### [at] comcastnet> wrote:
> "Bald Eagle" <cre### [at] netscapenet> wrote:

> First - let me start off by saying that your annotated summary render is
> absolutely beautiful.

> I don't know if you have a standard scene all rigged up for that kind of
> thing - but it's really nice.

Thanks! No, nothing special; I just set up a simple scene for your code (with
two lights in specific locations to see some particular details), made some
renders, then brought them into paint.net for assembly and annotation. A bit of
work, but fun.

Before seeing Chris R's comments, I had been going back over your code yet again
(for hours, ha). It's a really cool piece of work, that has a lot of uses
besides rifling.

> [Chris R:]
> 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}
>

Hey guys, what I'm seeing is that this and the original version of Theta look
the same in the isosurface-- or else I'm totally mistaken about what B.E.'s
original problem was?? I thought it was the truncated spirals in -x, where they
abruptly stop at y=0. Take a look at my comparison image.

Sorry if I totally misunderstood the problem(?)


Post a reply to this message


Attachments:
Download 'be_vs_chris_r_theta__by_kw.jpg' (134 KB)

Preview of image 'be_vs_chris_r_theta__by_kw.jpg'
be_vs_chris_r_theta__by_kw.jpg


 

<<< Previous 4 Messages Goto Latest 10 Messages Next 10 Messages >>>

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