





 
 




 
 


"Chris R" <car### [at] comcastnet> wrote:
>
> So I've been playing around with shapes extruded along one of the axes, by
> changing the rounding parameter and the scaling parameters on the other two
> axes, as well as translating the center of the rounded box along those two other
> axes in various ways, including linear interpolation, spline interpolation, and
> various other functions.
>
> This is the one where the scale decreases linearly from bottom to top, the
> rounding factor decreases linearly from bottom to top, and the x and z centers
> of the box are translated using sin(y*2*pi/height) and cos(y*2*pi/height).
>
That's a nice result, and a clever use of functions. And gold colors! I assume
that this is just one functionobject, not a 'combination' of several function
shapes?
I experimented with functionbased isosurfaces years ago, but have forgotten
some of the finer points, like how to 'taper' an object (like you did in y.) But
I happened to be playing around with this same kind of technique this week! I
can make a nice sinewave shape, but what is the trick for getting the shape to
taper or scale so nicely? IIRC, it is something relatively simple but I
can't remember what :(
Post a reply to this message


 
 




 
 


"Kenneth" <kdw### [at] gmailcom> wrote:
> I experimented with functionbased isosurfaces years ago, but have forgotten
> some of the finer points, like how to 'taper' an object (like you did in y.) But
> I happened to be playing around with this same kind of technique this week! I
> can make a nice sinewave shape, but what is the trick for getting the shape to
> taper or scale so nicely? IIRC, it is something relatively simple but I
> can't remember what :(
IIRC, I emailed you a copy of Mike Williams' isosurface tutorial, which is no
longer on the internet. :( Not sure if I can post .odt or .pdf files to this
server anywhere...
I think what you're looking for is under "variable substitution" or something
similar.
We should have a section of the website for archiving these master reference
works  like Friedrich Lohmueller's site.
Post a reply to this message


 
 




 
 


William F Pokorny <ano### [at] anonymousorg> wrote:
> On 3/4/22 16:29, Chris R wrote:
> > One of the things I've noticed is how fast and clean isosurfaces based on built
> > in functions, like f_rounded_box are, and how bad any of my attempts at doing
> > extruded shapes end up being, so I thought about using an isosurface to extrude
> > f_rounded_box.
>
> Cool shape! :)
>
> Yep, isosufaces are sometimes more flexible and faster than other
> shape/surface options! However, as with most things in POVRay, where
> they work best depends greatly on particulars.
>
> Note. IIRC, the f_rounded_box() function has a changing gradient outside
> everywhere and into the rounded box only to the rounding radius  after
> which the returned values become fixed 'inside.' This makes the function
> difficult / impossible to use in many more complex situations. In other
> words. it's a function which can be difficult to use other than as a
> stand alone shape(1).
>
> Bill P.
>
> (1)  Why the povr fork added an explicit f_box() inbuilt.
Yes, I have noticed that, especially when attempting to add a wood pigment
function to the exterior with the grain pushing into the box with a very small
rounding radius. It seems fine for a grain extending out of the box.
 Chris R.
Post a reply to this message


 
 




 
 


"Kenneth" <kdw### [at] gmailcom> wrote:
> "Chris R" <car### [at] comcastnet> wrote:
> >
> > So I've been playing around with shapes extruded along one of the axes, by
> > changing the rounding parameter and the scaling parameters on the other two
> > axes, as well as translating the center of the rounded box along those two other
> > axes in various ways, including linear interpolation, spline interpolation, and
> > various other functions.
> >
> > This is the one where the scale decreases linearly from bottom to top, the
> > rounding factor decreases linearly from bottom to top, and the x and z centers
> > of the box are translated using sin(y*2*pi/height) and cos(y*2*pi/height).
> >
>
> That's a nice result, and a clever use of functions. And gold colors! I assume
> that this is just one functionobject, not a 'combination' of several function
> shapes?
>
> I experimented with functionbased isosurfaces years ago, but have forgotten
> some of the finer points, like how to 'taper' an object (like you did in y.) But
> I happened to be playing around with this same kind of technique this week! I
> can make a nice sinewave shape, but what is the trick for getting the shape to
> taper or scale so nicely? IIRC, it is something relatively simple but I
> can't remember what :(
Here's a pretty simple example with linear tapering. I did something similar
with the image above, but embedded the tapering in functions instead.
#macro TaperedBox(SizeBase,SizeTop,RoundingBase,RoundingTop,Height)
#local _xSlope = (SizeTop.x  SizeBase.x)/(2*Height);
#local _zSlope = (SizeTop.z  SizeBase.z)/(2*Height);
#local _rndSlope = (RoundingTop  RoundingBase)/Height;
#local _xScaleBase = SizeBase.x/2;
#local _zScaleBase = SizeBase.z/2;
#local _xScaleFn = function(l) {
_xScaleBase + _xSlope*l
}
#local _zScaleFn = function(l) {
_yScaleBase + _ySlope*l
}
#local _rndFn = function(l) {
RoundingBase + _rndSlope*l
}
#local _sy = Height/2;
#local _shapeFn = function(x,y,z) {
f_rounded_box(x, y, z, _rndFn(y+_sy), _xScaleFn(y+_sy), _sy,
_zScaleFn(y+_sy))
}
#local _maxx = max(SizeBase.x,SizeTop.x)/2;
#local _maxz = max(SizeBase.z,SizeTop.z)/2;
#local _lbounds = <_maxx, _sy, _maxz>;
#local _ubounds = <_maxx, _sy, _maxz>;
#local _shape = isosurface {
function {
_shapeFn(x,y,z)
}
threshold 0
contained_by { box { _lbounds, _ubounds } }
}
#undef _shapeFn
#undef _rndFn
#undef _zScaleFn
#undef _xScaleFn
_shape
#end
TaperedBox(<2,2>, <1,1>, 0.2, 0.1, 2)
I have purposefully, pedantically, broken things out, because it helps me
remember why I wrote the code when I go back to it months down the line.
This should give you a truncated pyramid with a rounded bottom, rounded edges,
with the rounding decreasing as you move up the pyramid.
I use the RC3 Metal macros to create the gold texture.
 Chris R.
Post a reply to this message


 
 




 
 


"Chris R" <car### [at] comcastnet> wrote:
> "Kenneth" <kdw### [at] gmailcom> wrote:
> > "Chris R" <car### [at] comcastnet> wrote:
> > >
> > > So I've been playing around with shapes extruded along one of the axes, by
> > > changing the rounding parameter and the scaling parameters on the other two
> > > axes, as well as translating the center of the rounded box along those two other
> > > axes in various ways, including linear interpolation, spline interpolation, and
> > > various other functions.
> > >
> > > This is the one where the scale decreases linearly from bottom to top, the
> > > rounding factor decreases linearly from bottom to top, and the x and z centers
> > > of the box are translated using sin(y*2*pi/height) and cos(y*2*pi/height).
> > >
> >
> > That's a nice result, and a clever use of functions. And gold colors! I assume
> > that this is just one functionobject, not a 'combination' of several function
> > shapes?
> >
> > I experimented with functionbased isosurfaces years ago, but have forgotten
> > some of the finer points, like how to 'taper' an object (like you did in y.) But
> > I happened to be playing around with this same kind of technique this week! I
> > can make a nice sinewave shape, but what is the trick for getting the shape to
> > taper or scale so nicely? IIRC, it is something relatively simple but I
> > can't remember what :(
>
> Here's a pretty simple example with linear tapering. I did something similar
> with the image above, but embedded the tapering in functions instead.
>
> #macro TaperedBox(SizeBase,SizeTop,RoundingBase,RoundingTop,Height)
> #local _xSlope = (SizeTop.x  SizeBase.x)/(2*Height);
> #local _zSlope = (SizeTop.z  SizeBase.z)/(2*Height);
> #local _rndSlope = (RoundingTop  RoundingBase)/Height;
> #local _xScaleBase = SizeBase.x/2;
> #local _zScaleBase = SizeBase.z/2;
> #local _xScaleFn = function(l) {
> _xScaleBase + _xSlope*l
> }
> #local _zScaleFn = function(l) {
> _zScaleBase + _ySlope*l
> }
> #local _rndFn = function(l) {
> RoundingBase + _rndSlope*l
> }
> #local _sy = Height/2;
> #local _shapeFn = function(x,y,z) {
> f_rounded_box(x, y, z, _rndFn(y+_sy), _xScaleFn(y+_sy), _sy,
> _zScaleFn(y+_sy))
> }
>
> #local _maxx = max(SizeBase.x,SizeTop.x)/2;
> #local _maxz = max(SizeBase.z,SizeTop.z)/2;
> #local _lbounds = <_maxx, _sy, _maxz>;
> #local _ubounds = <_maxx, _sy, _maxz>;
>
> #local _shape = isosurface {
> function {
> _shapeFn(x,y,z)
> }
> threshold 0
> contained_by { box { _lbounds, _ubounds } }
> }
>
> #undef _shapeFn
> #undef _rndFn
> #undef _zScaleFn
> #undef _xScaleFn
>
> _shape
>
> #end
>
> TaperedBox(<2,2>, <1,1>, 0.2, 0.1, 2)
>
> I have purposefully, pedantically, broken things out, because it helps me
> remember why I wrote the code when I go back to it months down the line.
>
> This should give you a truncated pyramid with a rounded bottom, rounded edges,
> with the rounding decreasing as you move up the pyramid.
>
> I use the RC3 Metal macros to create the gold texture.
>
>
>  Chris R.
Sorry, transcription error, yScaleBase should have been zScaleBase in _zScaleFn
 Chris R.
Post a reply to this message


 
 




 
 


"Bald Eagle" <cre### [at] netscapenet> wrote:
> "Kenneth" <kdw### [at] gmailcom> wrote:
>
> ...what is the trick for getting the shape to
> > taper or scale so nicely? IIRC, it is something relatively simple but I
> > can't remember what :(
>
> IIRC, I emailed you a copy of Mike Williams' isosurface tutorial, which is no
> longer on the internet. :( Not sure if I can post .odt or .pdf files to this
> server anywhere...
>
> I think what you're looking for is under "variable substitution" or something
> similar.
>
Yes, I remember reading part of that last year! So I reread our email
exchanges... but there's no attachment there(!) :( Damn. I've been looking all
over my Win10 computer today for that tutorial, but can't find it. I'm thinking
that *maybe* you posted it to a newsgroup thread instead(?), sometime prior to
April 2021. But I haven't had any luck searching the newsgroups either. Bummer!
I know I have it *somewhere*...
Post a reply to this message


 
 




 
 


"Kenneth" <kdw### [at] gmailcom> wrote:
> Yes, I remember reading part of that last year! So I reread our email
> exchanges... but there's no attachment there(!) :( Damn. I've been looking all
> over my Win10 computer today for that tutorial, but can't find it. I'm thinking
> that *maybe* you posted it to a newsgroup thread instead(?), sometime prior to
> April 2021. But I haven't had any luck searching the newsgroups either. Bummer!
> I know I have it *somewhere*...
Backup email and attachments incoming...
Post a reply to this message


 
 




 
 


"Chris R" <car### [at] comcastnet> wrote:
>
> Here's a pretty simple example with linear tapering. I did something similar
> with the image above, but embedded the tapering in functions instead.
> [code snip]
> Sorry, transcription error, yScaleBase should have been zScaleBase in _zScaleFn
Thanks! That's really interesting (and a bit more complex than I thought, ha.)
Now I can play around, to see what I can muck up! :O
I had to make some minor changes to your code to get it to run replacing some
z's with y's  probably because the macro call uses twopart vectors, like
<2,2> for the 'SizeBase' etc. So that would be like <x,y> (or even <u,v>)
instead of <x,z>... which POVray chokes on ;) At least in Windows.
I've attached my own trial image... just as a sanity check, to make sure I'm
seeing what you intended!
BTW, there are a few interesting pieces of your code that I'm clueless about, as
to what they mean and how they work. Example:
#local _xScaleFn = function(l)
_xScaleBase + _xSlope*l
}
That's a lowercase 'L'. I'm familiar with the typical x (or y or z) use in a
function which AFAIU usually represent spatial axes but I have never used
just a 'generic' letter as a substitute. Could you briefly explain what that
means, in the context of your code?
Anyway, thanks again for the example!

#include "functions.inc"
#macro TaperedBox(SizeBase,SizeTop,RoundingBase,RoundingTop,Height)
#local _xSlope = (SizeTop.x  SizeBase.x)/(2*Height);
// #local _zSlope = (SizeTop.z  SizeBase.z)/(2*Height); // [ORIGINAL]
#local _zSlope = (SizeTop.y  SizeBase.y)/(2*Height); // changed both to y
#local _rndSlope = (RoundingTop  RoundingBase)/Height;
#local _xScaleBase = SizeBase.x/2;
// #local _zScaleBase = SizeBase.z/2; // [ORIGINAL]
#local _zScaleBase = SizeBase.y/2; // changed to y
#local _xScaleFn = function(l) {
_xScaleBase + _xSlope*l
}
#local _zScaleFn = function(l) {
// _yScaleBase + _ySlope*l // [ORIGINAL]
_zScaleBase + _zSlope*l // [update]
}
#local _rndFn = function(l) {
RoundingBase + _rndSlope*l
}
#local _sy = Height/2;
#local _shapeFn = function(x,y,z) {
f_rounded_box(x, y, z, _rndFn(y+_sy), _xScaleFn(y+_sy), _sy,
_zScaleFn(y+_sy))
}
#local _maxx = max(SizeBase.x,SizeTop.x)/2;
// #local _maxz = max(SizeBase.z,SizeTop.z)/2; // [ORIGINAL]
#local _maxz = max(SizeBase.y,SizeTop.y)/2; // changed both to y
#local _lbounds = <_maxx, _sy, _maxz>;
#local _ubounds = <_maxx, _sy, _maxz>;
#local _shape = isosurface {
function {
_shapeFn(x,y,z)
}
threshold 0
contained_by { box { _lbounds, _ubounds } }
}
#undef _shapeFn
#undef _rndFn
#undef _zScaleFn
#undef _xScaleFn
_shape
#end
TaperedBox(<2,2>, <1,1>, 0.2, 0.1, 2)
Post a reply to this message
Attachments:
Download 'isosurface_tapering_example_1.jpg' (10 KB)
Preview of image 'isosurface_tapering_example_1.jpg'


 
 




 
 


Op 832022 om 02:15 schreef Kenneth:
> Thanks! That's really interesting (and a bit more complex than I thought, ha.)
> Now I can play around, to see what I can muck up! :O
>
> I had to make some minor changes to your code to get it to run replacing some
> z's with y's  probably because the macro call uses twopart vectors, like
> <2,2> for the 'SizeBase' etc. So that would be like <x,y> (or even <u,v>)
> instead of <x,z>... which POVray chokes on ;) At least in Windows.
>
Yep. Me too.
> BTW, there are a few interesting pieces of your code that I'm clueless about, as
> to what they mean and how they work. Example:
> #local _xScaleFn = function(l)
> _xScaleBase + _xSlope*l
> }
>
> That's a lowercase 'L'. I'm familiar with the typical x (or y or z) use in a
> function which AFAIU usually represent spatial axes but I have never used
> just a 'generic' letter as a substitute. Could you briefly explain what that
> means, in the context of your code?
>
> Anyway, thanks again for the example!
>
I second that!

Thomas
Post a reply to this message


 
 




 
 


"Kenneth" <kdw### [at] gmailcom> wrote:
> "Chris R" <car### [at] comcastnet> wrote:
> >
> > Here's a pretty simple example with linear tapering. I did something similar
> > with the image above, but embedded the tapering in functions instead.
> > [code snip]
> > Sorry, transcription error, yScaleBase should have been zScaleBase in _zScaleFn
>
> Thanks! That's really interesting (and a bit more complex than I thought, ha.)
> Now I can play around, to see what I can muck up! :O
>
> I had to make some minor changes to your code to get it to run replacing some
> z's with y's  probably because the macro call uses twopart vectors, like
> <2,2> for the 'SizeBase' etc. So that would be like <x,y> (or even <u,v>)
> instead of <x,z>... which POVray chokes on ;) At least in Windows.
>
> I've attached my own trial image... just as a sanity check, to make sure I'm
> seeing what you intended!
>
> BTW, there are a few interesting pieces of your code that I'm clueless about, as
> to what they mean and how they work. Example:
> #local _xScaleFn = function(l)
> _xScaleBase + _xSlope*l
> }
>
> That's a lowercase 'L'. I'm familiar with the typical x (or y or z) use in a
> function which AFAIU usually represent spatial axes but I have never used
> just a 'generic' letter as a substitute. Could you briefly explain what that
> means, in the context of your code?
>
> Anyway, thanks again for the example!
>
> 
> #include "functions.inc"
>
> #macro TaperedBox(SizeBase,SizeTop,RoundingBase,RoundingTop,Height)
> #local _xSlope = (SizeTop.x  SizeBase.x)/(2*Height);
> // #local _zSlope = (SizeTop.z  SizeBase.z)/(2*Height); // [ORIGINAL]
> #local _zSlope = (SizeTop.y  SizeBase.y)/(2*Height); // changed both to y
> #local _rndSlope = (RoundingTop  RoundingBase)/Height;
> #local _xScaleBase = SizeBase.x/2;
> // #local _zScaleBase = SizeBase.z/2; // [ORIGINAL]
> #local _zScaleBase = SizeBase.y/2; // changed to y
> #local _xScaleFn = function(l) {
> _xScaleBase + _xSlope*l
> }
> #local _zScaleFn = function(l) {
> // _yScaleBase + _ySlope*l // [ORIGINAL]
> _zScaleBase + _zSlope*l // [update]
> }
> #local _rndFn = function(l) {
> RoundingBase + _rndSlope*l
> }
> #local _sy = Height/2;
> #local _shapeFn = function(x,y,z) {
> f_rounded_box(x, y, z, _rndFn(y+_sy), _xScaleFn(y+_sy), _sy,
> _zScaleFn(y+_sy))
> }
>
> #local _maxx = max(SizeBase.x,SizeTop.x)/2;
> // #local _maxz = max(SizeBase.z,SizeTop.z)/2; // [ORIGINAL]
> #local _maxz = max(SizeBase.y,SizeTop.y)/2; // changed both to y
> #local _lbounds = <_maxx, _sy, _maxz>;
> #local _ubounds = <_maxx, _sy, _maxz>;
>
> #local _shape = isosurface {
> function {
> _shapeFn(x,y,z)
> }
> threshold 0
> contained_by { box { _lbounds, _ubounds } }
> }
>
> #undef _shapeFn
> #undef _rndFn
> #undef _zScaleFn
> #undef _xScaleFn
>
> _shape
>
> #end
>
> TaperedBox(<2,2>, <1,1>, 0.2, 0.1, 2)
Yes, that's exactly it. And I apologize for the x/y/z errors. I originally
wrote the macro to move along the Z axis and then rotated the object to stand it
upright for the image, and then didn't get all of the mental rotations right in
the text above.
By default, if you define a function, it takes three arguments (x,y,z).
However, you can declare it with any parameters you want; (hence
f_rounded_box(x,y,z,rnd,sx,sy,sz))
Since my scaling function only depends on the distance along the extrusion axis,
and I might want to reuse that function in some other object along a different
axis, I just declared it to be a function with one parameter, called "l". When
it is actually called, I can give it any axis I want.
I have a computer programming background, and the C compiler flags unused
parameters as wasteful and confusing, so I tend to define my functions just to
include the parameters I need in the body, and give them meaningful names.
 Chris R
Post a reply to this message


 
 




 

