POV-Ray : Newsgroups : povray.binaries.images : Helical SDF for Isosurfaces Server Time
30 Dec 2024 12:04:45 EST (-0500)
  Helical SDF for Isosurfaces (Message 1 to 10 of 24)  
Goto Latest 10 Messages Next 10 Messages >>>
From: Chris R
Subject: Helical SDF for Isosurfaces
Date: 13 Dec 2024 10:05:00
Message: <web.675c4cf3fffcf8c4239175245cc1b6e@news.povray.org>
My current WIP (Scrabble) had a need for a helix that I could texture, and I
could not find one in Inigo Quilez article on distance functions, so I decided
to create one myself using his basic principles.

I started just sing a circular cross section, but as you can see from the image,
I abstracted it so you can supply any 2D cross-section SDF, (this one is a
simple 2D square that I rotated 45 degrees).

Since it is an SDF, applying textures by adding noise works as expected.

The updated libisoshapes.inc is in GitHub now:
https://github.com/carath63/povlibrary

-- Chris R


Post a reply to this message


Attachments:
Download 'libisoshapes_test.png' (255 KB)

Preview of image 'libisoshapes_test.png'
libisoshapes_test.png


 

From: Bald Eagle
Subject: Re: Helical SDF for Isosurfaces
Date: 13 Dec 2024 10:20:00
Message: <web.675c4fc34a98c6d66563700825979125@news.povray.org>
"Chris R" <car### [at] comcastnet> wrote:
> My current WIP (Scrabble) had a need for a helix that I could texture, and I
> could not find one in Inigo Quilez article on distance functions, so I decided
> to create one myself using his basic principles.

An explanation of how you went about that would be a welcome tutorial.
I'll probably read that over 100 times when I get some free time in the future
to make some shapes myself.

> I started just sing a circular cross section, but as you can see from the image,
> I abstracted it so you can supply any 2D cross-section SDF, (this one is a
> simple 2D square that I rotated 45 degrees).

There are all of the inbuilt functions and their aliases in functions.inc,
including just such a spiral function with a cross-section parameter.

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


> Since it is an SDF, applying textures by adding noise works as expected.

And presumably you can make level-set ("coaxial") shells?

Very nice work.

- BW


Post a reply to this message

From: Alain Martel
Subject: Re: Helical SDF for Isosurfaces
Date: 13 Dec 2024 12:27:33
Message: <675c6e85$1@news.povray.org>
Le 2024-12-13 à 10:04, Chris R a écrit :
> My current WIP (Scrabble) had a need for a helix that I could texture, and I
> could not find one in Inigo Quilez article on distance functions, so I decided
> to create one myself using his basic principles.
> 
> I started just sing a circular cross section, but as you can see from the image,
> I abstracted it so you can supply any 2D cross-section SDF, (this one is a
> simple 2D square that I rotated 45 degrees).
> 
> Since it is an SDF, applying textures by adding noise works as expected.
> 
> The updated libisoshapes.inc is in GitHub now:
> https://github.com/carath63/povlibrary
> 
> -- Chris R

You should take a look at the f_helix1(x,y,z, Num_Helix, Period, 
Minor_radius, Major_radius, Shape, Cross_section, Section_Rotation) 
functions from functions.inc

Playing with the last three parameters affect the shape of the helix.
Shape : Not sure what it does
Cross_section determine how many sides the cross section have
Section_Rotation rotates the cross section.

f_helix2 works the same, but, the Num_Helix and Shape parameter are not 
used.


Post a reply to this message

From: Chris R
Subject: Re: Helical SDF for Isosurfaces
Date: 13 Dec 2024 13:00:00
Message: <web.675c75a64a98c6d6239175245cc1b6e@news.povray.org>
Alain Martel <kua### [at] videotronca> wrote:

> > My current WIP (Scrabble) had a need for a helix that I could texture, and I
> > could not find one in Inigo Quilez article on distance functions, so I decided
> > to create one myself using his basic principles.
> >
> > I started just sing a circular cross section, but as you can see from the image,
> > I abstracted it so you can supply any 2D cross-section SDF, (this one is a
> > simple 2D square that I rotated 45 degrees).
> >
> > Since it is an SDF, applying textures by adding noise works as expected.
> >
> > The updated libisoshapes.inc is in GitHub now:
> > https://github.com/carath63/povlibrary
> >
> > -- Chris R
>
> You should take a look at the f_helix1(x,y,z, Num_Helix, Period,
> Minor_radius, Major_radius, Shape, Cross_section, Section_Rotation)
> functions from functions.inc
>
> Playing with the last three parameters affect the shape of the helix.
> Shape : Not sure what it does
> Cross_section determine how many sides the cross section have
> Section_Rotation rotates the cross section.
>
> f_helix2 works the same, but, the Num_Helix and Shape parameter are not
> used.

I have used both of these in the past.  I always find it tricky to get the
parameters to work correctly at different scales.  I haven't looked at the
implementation of f_helix, but I know some of the other built-ins are not
implemented as exact SDF functions, which makes applying a surface texture to
the shape more difficult.  I'm also finding that exact SDF functions render as
isosurfaces more quickly than inexact methods I have used in the past.  These
functions also have limited shape options for the cross section, while mine can
take any function(x,y) that is also an exact 2D SDF.

Plus, it's always fun to go invent something on your own...

-- Chris R


Post a reply to this message

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

Goto Latest 10 Messages Next 10 Messages >>>

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