POV-Ray : Newsgroups : povray.advanced-users : Help on isosurface - distances - other stuff... : Re: Help on isosurface - distances - other stuff... Server Time
29 Jul 2024 16:31:32 EDT (-0400)
  Re: Help on isosurface - distances - other stuff...  
From: Tor Olav Kristensen
Date: 12 Nov 2001 17:59:44
Message: <3BF0541A.62BC8C1F@hotmail.com>
Jan Walzer wrote:
> 
> Lets assume I have a function f(x,y,z) ...
> 
> this usually describes my isosurface ... The surface is all points, where
> f(x,y,z)=0...
> 
> How can I now describe another function g(x,y,z) that describes for g(...)=0
> all the
> points, that have a distance d to the the surface of f() ?
>...

Jan,
I have tried to put together some iso-code
below in order to try to solve your problem.

I hope it does what you need.

Be prepared for looooong redering times.


Tor Olav


// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Copyright 2001 by Tor Olav Kristensen
// Email: tor### [at] hotmailcom
// http://www.crosswinds.net/~tok
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#version 3.5;

#include "colors.inc"
#include "functions.inc"

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

// The "original" function. (f_torus() from functions.inc)
#declare Rmaj = 0.5;
#declare Rmin = 0.2;
#declare Fn = function { f_torus(x, y, z, Rmaj, Rmin) }

// Partial derivatives of function calculated numerically.
// (An analytical calculated partial derivatives of function
// would be better though.)
#declare H = 0.0001;
#declare DerxFn = function { (Fn(x + H, y, z) - Fn(x - H, y, z))/2/H }
#declare DeryFn = function { (Fn(x, y + H, z) - Fn(x, y - H, z))/2/H }
#declare DerzFn = function { (Fn(x, y, z + H) - Fn(x, y, z - H))/2/H }

/*
// As long as these functions are only used within the LDFn()
// function below, they can be simplified a bit:
#declare DerxFn = function { Fn(x + H, y, z) - Fn(x - H, y, z) }
#declare DeryFn = function { Fn(x, y + H, z) - Fn(x, y - H, z) }
#declare DerzFn = function { Fn(x, y, z + H) - Fn(x, y, z - H) }
*/

// Gradient vector at any point; <x, y, z> is:
// vGradient(x, y, z) =
// <DerxFn(x, y, z), DeryFn(x, y, z), DerzFn(x, y, z)>

// Length of gradient vector:
#declare LDFn =
function {
  sqrt(
    DerxFn(x, y, z)^2 +
    DeryFn(x, y, z)^2 +
    DerzFn(x, y, z)^2
  ) + 1e-8 // To avoid division by zero
}

// Normalized gradient vector for function at <x, y, z> is:
// vNormalizedGradient(x, y, z) = vGradient(x, y, z)/LDFn(x, y, z) =
// <DerxFn(x, y, z), DeryFn(x, y, z), DerzFn(x, y, z)>/LDFn(x, y, z)

#declare DerxFnNormalized = function { DerxFn(x, y, z)/LDFn(x, y, z) }
#declare DeryFnNormalized = function { DeryFn(x, y, z)/LDFn(x, y, z) }
#declare DerzFnNormalized = function { DerzFn(x, y, z)/LDFn(x, y, z) }

// Now assume that the surface of the "original" function lies in the
// opposite direction of the gradient vector.
// Also assume that it will be at:
// <x, y, z> - Dist*vNormalizedGradient(x, y, z)
// (Note that this may only be true for small Dist values.)

#declare Dist = 0.1;
// See note below
#declare xNew = function { x - Dist*DerxFnNormalized(x, y, z) }
#declare yNew = function { y - Dist*DeryFnNormalized(x, y, z) }
#declare zNew = function { z - Dist*DerzFnNormalized(x, y, z) }

#declare OutsideFn =
function { Fn(xNew(x, y, z), yNew(x, y, z), zNew(x, y, z)) }

isosurface {
//  function { Fn(x, y, z) }      // "Original" surface
  function { OutsideFn(x, y, z) } // Surface "outside" this
  contained_by {
    box {
      -<Rmaj + Rmin + Dist, Rmin + Dist, Rmaj + Rmin + Dist>,
       <Rmaj + Rmin + Dist, Rmin + Dist, Rmaj + Rmin + Dist>
    }
  }
  max_gradient 4
  pigment { color White }
}

// A little check
intersection {
  torus { Rmaj, (Rmin + Dist)*1.01 }
  plane { -z, 0 }
  pigment { color Cyan } 
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

background { color Blue/2 }

light_source { <0, 4, -3>*10 color White }

camera {
  location <1, 1, -1>
  look_at <0, 0, 0>
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

/*
// Note:
// Try to replace the 19 lines below the "See note below" line with
// these lines:

#declare Noise = 0.1;
#declare DD = function { Dist + Noise*f_noise3d(5*x, 5*y, 5*z) }
#declare xNew = function { x - DD(x, y, z)*DerxFnNormalized(x, y, z) }
#declare yNew = function { y - DD(x, y, z)*DeryFnNormalized(x, y, z) }
#declare zNew = function { z - DD(x, y, z)*DerzFnNormalized(x, y, z) }

#declare OutsideFn =
function { Fn(xNew(x, y, z), yNew(x, y, z), zNew(x, y, z)) }

#declare Rsmall = Rmin + Dist + Noise;

isosurface {
  function { OutsideFn(x, y, z) }
  contained_by {
    box {
      -<Rmaj + Rsmall, Rsmall, Rmaj + Rsmall>,
       <Rmaj + Rsmall, Rsmall, Rmaj + Rsmall>
    }
  }
  max_gradient 10
  pigment { color White }
}
*/

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7


Post a reply to this message

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