POV-Ray : Newsgroups : povray.binaries.images : Spiral Warps? : Re: Spiral Warps? Server Time
30 Apr 2024 15:59:33 EDT (-0400)
  Re: Spiral Warps?  
From: Bald Eagle
Date: 22 Jul 2018 16:35:00
Message: <web.5b54ea0aaab4365c458c7afe0@news.povray.org>
I think I found what looks to be some workable equations at:

https://people.sc.fsu.edu/~jburkardt/cpp_src/navier_stokes_2d_exact/navier_stokes_2d_exact.html


If you look at the png image, and then the source code for the vortex solution,
you'll notice that the code simply runs through an loop to evaluate the formula
over the <x, y> values of a unit square grid.
So, since POV-Ray "does the looping" when applying a pattern, that part of the
code is redundant, which just leave us with 3 equations.

The mental block is afflicting me with how to apply this, and how a warp is
different than a pattern.

(not having ever used gnuplot is a small problem as well)

Cue someone stepping in with the crayons and sock puppets to explain how I'd
make a spiral warp using functions, and how I'd visualize this.

Currently, my understanding is that a warp is akin to a translation or
phase-shift, where what's going on at the current point <x,y,z> is redefined as
what's going on at some other point, as defined by the code/function of the
warp.

I don't FULLY grasp the whole thing, so I'll try to describe it, and maybe
someone who sees the whole picture can correct me where I'm wrong.

I'll try to describe what I think happens in the following black hole warp code.
There's a "block" thing going on which I can only assume is for octants or
figuring out where in a repeat warp the black hole is being used.

Then in the actual application, you have a radius and a strength that are
specified.  So first, the distance of <x, y, z> from the center of the black
hole is determined.  Then that gets what I call "flipped" - if the distance is
1, it's now zero, and if it's 0, it's now 1.
That gets done in my illustrative function
#declare Limit = function {(Radius-Dist(x,y,z))...
and then it gets expressed as a proportion of the radius of the effect:
".../Radius}"
The result being that the black hole effect is strongest at the center, and
dropping off to zero near the radius.


#declare Radius = 0.2;
#declare Dist = function {sqrt(pow(x,2)+pow(y,2)+pow(z,2))}
#declare Limit = function {(Radius-Dist(x,y,z))/Radius}
#declare Warp = function {select( Limit(x,y,z), 0, 0, 1)}

that gets altered exponentially ...

.... and then the resulting scalar value gets used as a modifier of the <x, y,
z>, in Vector.h.

if we were physically moving points, this would be:

#declare Vector = <x, y, z>;
#declare NewVector = <x, y, z> + scalar * <a, b, c>;

Not really sure how vector <a, b, c> is defined, but let's keep that in the
black box for now.

But this is all mathematical, and the coordinates always stay the same, don't
they?  So what's really happening is that we're modifying the input of a pattern
or brightness or normal function so that it's behaving as if it were being
evaluated at another, point.  The FUNCTION is shifted by the warp.

If you look through Mike Williams' isosurface tutorial
http://www.econym.demon.co.uk/isotut/

the way to do this with a function is to "do the opposite"
to translate the effect in the +x direction, we subtract the translation from
the x term so that we are evaluating the function at (x-c).
Picture pulling a parabola, y=pow(x,2) to the right.
We grab the y value at (x-c) and pull it over to x, thus shifting it in the +x
direction.



I can only assume that if I want to model a warp, let's say as a density
function in a media (since that's been successful so far)
then I would use the warp to modify the effect of a pattern function.




The following is for a Black Hole Warp from warps.cpp:

case BLACK_HOLE_WARP:
Black_Hole = reinterpret_cast<BLACK_HOLE *>(Warp) ;
Assign_Vector (Center, Black_Hole->Center) ;

if (Black_Hole->Repeat)
{
/* first, get the block number we're in for each dimension  */
/* block numbers are (currently) calculated relative to 0   */
/* we use floor () since it correctly returns -1 for the
first block below 0 in each axis                         */
/* one final point - we could run into overflow problems if
the repeat vector was small and the scene very large.    */
if (Black_Hole->Repeat_Vector [X] >= EPSILON)
blockX = (int) floor (TPoint [X] / Black_Hole->Repeat_Vector [X]) ;

if (Black_Hole->Repeat_Vector [Y] >= EPSILON)
blockY = (int) floor (TPoint [Y] / Black_Hole->Repeat_Vector [Y]) ;

if (Black_Hole->Repeat_Vector [Z] >= EPSILON)
blockZ = (int) floor (TPoint [Z] / Black_Hole->Repeat_Vector [Z]) ;

if (Black_Hole->Uncertain)
{
/* if the position is uncertain calculate the new one first */
/* this will allow the same numbers to be returned by frand */

int seed = Hash3d (blockX, blockY, blockZ);
Center [X] += WarpRands(seed) * Black_Hole->Uncertainty_Vector [X] ;
Center [Y] += WarpRands(seed + 1) * Black_Hole->Uncertainty_Vector [Y] ;
Center [Z] += WarpRands(seed + 2) * Black_Hole->Uncertainty_Vector [Z] ;
}

Center [X] += Black_Hole->Repeat_Vector [X] * blockX ;
Center [Y] += Black_Hole->Repeat_Vector [Y] * blockY ;
Center [Z] += Black_Hole->Repeat_Vector [Z] * blockZ ;
}

VSub (Delta, TPoint, Center) ;
VLength (Length, Delta) ;

/* Length is the distance from the centre of the black hole */
if (Length >= Black_Hole->Radius) break ;

if (Black_Hole->Type == 0)
{
/* now convert the length to a proportion (0 to 1) that the point
is from the edge of the black hole. a point on the perimeter
of the black hole will be 0.0 ; a point at the centre will be
1.0 ; a point exactly halfway will be 0.5, and so forth. */
Length = (Black_Hole->Radius - Length) / Black_Hole->Radius ;

/* Strength is the magnitude of the transformation effect. firstly,
apply the Power variable to Length. this is meant to provide a
means of controlling how fast the power of the Black Hole falls
off from its centre. if Power is 2.0, then the effect is inverse
square. increasing power will cause the Black Hole to be a lot
weaker in its effect towards its perimeter.

finally we multiply Strength with the Black Hole's Strength
variable. if the resultant value exceeds 1.0 we clip it to 1.0.
this means a point will never be transformed by more than its
original distance from the centre. the result of this clipping
is that you will have an 'exclusion' area near the centre of
the black hole where all points whose final value exceeded or
equalled 1.0 were moved by a fixed amount. this only happens
if the Strength value of the Black Hole was greater than one. */

Strength = pow (Length, Black_Hole->Power) * Black_Hole->Strength ;
if (Strength > 1.0) Strength = 1.0 ;

/* if the Black Hole is inverted, it gives the impression of 'push-
ing' the pattern away from its centre. otherwise it sucks. */
VScaleEq (Delta, Black_Hole->Inverted ? -Strength : Strength) ;

/* add the scaled Delta to the input point to end up with TPoint. */
VAddEq (TPoint, Delta) ;
}
break;


Post a reply to this message

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