reb
Class InvertSphere

Object
  extended by common:Generic
      extended by reb:InvertSphere
Direct Known Subclasses:
InvertCircles, InvertCube, InvertDodecahedron, InvertMobius, InvertOctahedron

class 
Generic:InvertSphere

sphere inversions starting with a tetrahedral geometery for the base set
this is the base class
it contains methods for
1. sphere initialization for base and generator sets
2. sphere inversion
3. recursion
4. heapsort and duplicate removal


Ultra Fractal Source

Toggle UF Source Code Display

 Class InvertSphere(common.ulb:Generic) {
 ; sphere inversions starting with a tetrahedral geometery for the base set <br>
 ; this is the base class  <br>
 ; it contains methods for <br>
 ;  1. sphere initialization for base and generator sets  <br>
 ;  2. sphere inversion <br>
 ;  3. recursion <br>
 ;  4. heapsort and duplicate removal <br>
 ;
 
 public:
   import "common.ulb"
 
 ;  constructor for sphere inversions with a tetrahedral geometry
   func InvertSphere(Generic pparent)
 ;
 ; dynamically allocate the maximum number of spheres
 ;
     s = new SphereArray(50000000)
 
     flength = 50000000, fscle = 3 + sqrt(6), fks = 4, fk = fks, fii = 5, fjj = 5
     rlevel = 5, fminsphere = @minsphere, mlevel = @MaxLevel, fbaserad = sqrt(2)
     thresh = fminsphere/1000, scale = 0.3, reflect = @reflect, xrot = (0,1)^(@xang/90),
     yrot = (0,1)^(@yang/90), zrot = (0,1)^(#angle*2/#pi), sflag = true
     crad = 0, circles = false, showc = true, lace = false, cir3 = false
     zsort = @zsort
     initSpheres()
   endfunc
 
 ;  Initializes base and generator spheres
   func InitSpheres()
     complex Fc[10]
     float Fz[10]
     float Fr[10]
     complex temp = 0
     int i = 0
 
     while i < 4
       Fc[i] = (1,1)*exp(flip(i)*#pi/2)*fscle
       Fr[i] = (fscle-1)*2
       if i%2 == 0
         Fz[i] = -fscle
       else
         Fz[i] = fscle
       endif
       i = i + 1
     endwhile
     Fc[i] = (0,0)
     Fr[i] = 1
     Fz[i] = 0
     i = i + 1
     while i < 9
       Fc[i] = (1,1)*exp(flip(i-5)*#pi/2)
       Fr[i] = fbaserad
       if i%2 == 0
         Fz[i] = -1
       else
         Fz[i] = 1
       endif
       i = i + 1
     endwhile
     Fc[i] = (0,0)
     Fr[i] = sqrt(2)+sqrt(3)
     Fz[i] = 0
 
     ; scale and translate the spheres to screen dimensions
     i = 0
     repeat
       if reflect
         Fc[i] = -conj(Fc[i])
       else
         Fc[i] = Fc[i]
       endif
       ; Z axis rotation
       Fc[i] = Fc[i]*zrot
 
       ; Y axis rotation
       temp = real(Fc[i]) + flip(Fz[i])
       temp = temp*yrot
       Fc[i] = real(temp) + flip(imag(Fc[i]))
       Fz[i] = imag(temp)
 
       ; X axis rotation
       temp = imag(Fc[i]) + flip(Fz[i])
       temp = temp*xrot
       Fc[i] = real(Fc[i]) + flip(real(temp))
       Fz[i] = imag(temp)
 
       ; scaling
       Fc[i] = Fc[i]*#magn*scale
       Fz[i] = Fz[i]*#magn*scale
       if i > 4
         Fr[i] = Fr[i]*#magn*scale*@bradadj
       else
         Fr[i] = Fr[i]*#magn*scale*@radadj
       endif
 
       i = i+1
     until i == 10
 ; declare the generator spheres
     ; tetrahedron
     i = 0
     while i <= 4
       fg[i] = new Sphere(Fc[i],Fz[i],Fr[i],0,i)
       i = i + 1
     endwhile
 ;
 ; declare the base Spheres
     ; tetrahedron
     while i <= 9
       fb[i-5] = new Sphere(Fc[i],Fz[i],Fr[i],0,i-5)
       i = i + 1
     endwhile
     bradius = fb[0].frad
 
     i = 0
     while i < 4
       s.sph[i] = fb[i]
       i = i + 1
     endwhile
   endfunc
 
 ; Inverts a sphere
 ; @param target = sphere to be inverted
 ; @param inverter = sphere used for the inversion
 ; @param level = recursion level
 ; @param gen = index of generator (inverter) sphere
    Sphere func Inverse(Sphere target, Sphere inverter, int level, int gen)
      rgen = gen
      float ar = inverter.frad
      float br = target.frad
      complex a = inverter.fcen
      complex b = target.fcen
      float ha = inverter.fz
      float hb = target.fz
      float temp = ar^2/(|a-b|+(ha-hb)^2-br^2)
      float rad = abs(temp*br)
      if lace && circles && cir3
        rad = temp*br
      endif
      complex cen = temp*(b-a) + a
      float z = temp*(hb-ha) + ha
      return new Sphere(cen,z,rad,level,rgen)
    endfunc
 
 ;  Top level recursion function - calls the function recurse2
    func Recurse()
      if mlevel > 0
        int level = 0
        level = level + 1
        int ii = 0
        int jj = 0
        fk = fks
        while ii < fii
          while jj < fjj && fk < flength
            if (|fb[jj].fcen-fg[ii].fcen|+ (fb[jj].fz-fg[ii].fz)^2)> \
               (fb[jj].frad+fg[ii].frad)^2
              s.sph[fk] = Inverse(fb[jj],fg[ii],level,jj)
              fk = fk + 1
            endif
            jj = jj + 1
          endwhile
          ii = ii + 1
          jj = 0
        endwhile
      ;
      ; The exeception to the rule of target and generator are external to each other
      ;
        s.sph[fk] = Inverse(fb[fjj-1],fg[fii-1],level,fjj-1)
        if circles
          crad = s.sph[fk].frad
        endif
        fk = fk + 1
        int j = fjj-1
        if level < mlevel
         while j < fjj-1 + rlevel
           recurse2(level,j)
           j = j + 1
         endwhile
        endif
        if sflag
          heapsort(s,fk)
          vanquish(s,fk)
        endif
      endif
      if @zsort
        heapsortz(s,fk)
      endif
    endfunc
 
 ; Function for recursive sphere inversion
 ; @param level = recursion level
 ; @param tarvalue = index of new sphere
   func recurse2(int level, int tarvalue)
     level = level + 1
     int k = 0
     while k < fii && fk < flength
       if lace && circles && cir3
         if (|s.sph[tarvalue].fcen-fg[k].fcen| + \
            (s.sph[tarvalue].fz-fg[k].fz)^2)> \
            (s.sph[tarvalue].frad+fg[k].frad)^2 && s.sph[tarvalue].frad > \
                fminSphere
           s.sph[fk] = Inverse(s.sph[tarvalue],fg[k],level,s.sph[tarvalue].fgen)
           fk = fk + 1
           if level < mlevel
             recurse2(level,fk-1)
           endif
         endif
       else
         if (|s.sph[tarvalue].fcen-fg[k].fcen| + \
            (s.sph[tarvalue].fz-fg[k].fz)^2)> \
            (s.sph[tarvalue].frad+fg[k].frad)^2 && abs(s.sph[tarvalue].frad) > \
                 fminSphere
           s.sph[fk] = Inverse(s.sph[tarvalue],fg[k],level,s.sph[tarvalue].fgen)
           fk = fk + 1
           if level < mlevel
             recurse2(level,fk-1)
           endif
         endif
       endif
       k = k + 1
     endwhile
   endfunc
 
 ; Find the overall bounding volume for a set of spheres
 ; @param sa = sphere array to be bounded
 ; @param count = index range to be bounded
 ; @param xmin = min x boundary
 ; @param ymin = min y boundary
 ; @param zmin = min z boundary
 ; @param xmax = max x boundary
 ; @param ymax = max y boundary
 ; @param zmax = max z boundary
    func findbound(SphereArray sa, int count, float &xmin, float &ymin, \
                   float &zmin, float &xmax, float &ymax, float &zmax)
      xmin = 1e10
      ymin = 1e10
      zmin = 1e10
      xmax = -1e10
      xmax = -1e10
      xmax = -1e10
      float temp = 0
      int i = 0
      while i < count
        temp =  real(sa.sph[i].fcen) - abs(sa.sph[i].frad)
        if temp < xmin
          xmin = temp
        endif
        temp =  real(sa.sph[i].fcen) + abs(sa.sph[i].frad)
        if temp > xmax
          xmax = temp
        endif
        temp =  imag(sa.sph[i].fcen) - abs(sa.sph[i].frad)
        if temp < ymin
          ymin = temp
        endif
        temp =  imag(sa.sph[i].fcen) + abs(sa.sph[i].frad)
        if temp > ymax
          ymax = temp
        endif
        temp =  sa.sph[i].fz - abs(sa.sph[i].frad)
        if temp < zmin
          zmin = temp
        endif
        temp =  sa.sph[i].fz + abs(sa.sph[i].frad)
        if temp > zmax
          zmax = temp
        endif
        i = i + 1
      endwhile
    endfunc
 
 
 ; Sort spheres in preparation for duplicate removal
 ; @param sa = sphere array to be sorted
 ; @param count = index range to be sorted
   func heapsort(SphereArray sa,int count)
      heapify(sa, count)
      int end = count-1
      while end > 0
        swap(sa,end,0)
        end = end-1
        siftDown(sa, 0, end)
      endwhile
   endfunc
 
 ; Sort spheres by z value.
   func heapsortz(SphereArray sa,int count)
      heapifyz(sa, count)
      int end = count-1
      while end > 0
        swap(sa,end,0)
        end = end-1
        siftDownz(sa, 0, end)
      endwhile
   endfunc
 
 ; A helper function for heapsort
 ; @param sa = sphere array to be sorted
 ; @param count = index range to be sorted
   func heapify(SphereArray sa,int count)
      int start = round((count-1)/2)
 
      while start >= 0
        siftDown(sa, start, count-1)
        start = start-1
      endwhile
   endfunc
 
 ; A helper function for heapsortz
   func heapifyz(SphereArray sa,int count)
      int start = round((count-1)/2)
 
      while start >= 0
        siftDownz(sa, start, count-1)
        start = start-1
      endwhile
   endfunc
 
 ; A helper function for heapsort
 ; @param sa = sphere array to be sorted
 ; @param start = start of the index index range
 ; @param end = end of the index index range
   func siftdown(SphereArray sa, int start,int end)
      int root = start, float dx = 0, float dy = 0, float dz = 0, float dr = 0
      int c = 0
 
      while (root*2+1) <= end
        int child = root*2+1
        dx = real(sa.sph[child].fcen) - real(sa.sph[child + 1].fcen)
        dy = imag(sa.sph[child].fcen) - imag(sa.sph[child + 1].fcen)
        dz = sa.sph[child].fz - sa.sph[child + 1].fz
        dr = sa.sph[child].frad - sa.sph[child + 1].frad
        if child < end
          if dr < -thresh
            c = -1
          elseif dr > thresh
            c = 1
          elseif dy < -thresh
            c = -1
          elseif dy > thresh
            c = 1
          elseif dz < -thresh
            c = -1
          elseif dz > thresh
            c = 1
          elseif dx < -thresh
            c = -1
          elseif dx > thresh
            c = 1
          else
            c = 0
          endif
          if c < 0
            child = child+1
          endif
        endif
        dx = real(sa.sph[root].fcen) - real(sa.sph[child].fcen)
        dy = imag(sa.sph[root].fcen) - imag(sa.sph[child].fcen)
        dz = sa.sph[root].fz - sa.sph[child].fz
        dr = sa.sph[root].frad - sa.sph[child].frad
        if dr < -thresh
          c = -1
        elseif dr > thresh
          c = 1
        elseif dy < -thresh
          c = -1
        elseif dy > thresh
          c = 1
        elseif dz < -thresh
          c = -1
        elseif dz > thresh
          c = 1
        elseif dx < -thresh
          c = -1
        elseif dx > thresh
          c = 1
        else
          c = 0
        endif
        if c < 0
          swap(s,root,child)
          root = child
        else
          return
        endif
      endwhile
   endfunc
 
 ; A helper function for heapsortz
   func siftdownz(SphereArray sa, int start,int end)
      int root = start, float dz = 0
      int c = 0
 
      while (root*2+1) < end
        int child = root*2+1
        dz = sa.sph[child].fz - sa.sph[child+1].fz
        if child < end
          if dz < -thresh
            c = -1
          elseif dz > thresh
            c = 1
          else
            c = 0
          endif
          if c > 0
            child = child+1
          endif
        endif
        dz = sa.sph[root].fz - sa.sph[child].fz
        if dz < -thresh
          c = -1
        elseif dz > thresh
          c = 1
        else
          c = 0
        endif
        if c > 0
          swap(s,root,child)
          root = child
        else
          return
        endif
      endwhile
   endfunc
 
 
 ; A helper function for heapsort
 ; @param i = index of the first sphere to be swapped
 ; @param j = index of the second sphere to be swapped
   func swap(SphereArray sa, int i, int j)
     Sphere temp = sa.sph[j]
     sa.sph[j] = sa.sph[i]
     sa.sph[i] = temp
   endfunc
 
 
 ; Removes duplicates from a sorted array
 ; @param sa = sphere array for duplicate element removal
 ; @param count = index range for duplicate removal
 ;------------------------------------------------
   func vanquish(SphereArray sa, int count)
     float dx = 0, float dy = 0, float dz = 0, float dr = 0, int c = 0
     int ir = 1, int l = 0
 
     while ir < count
       dx = real(sa.sph[ir].fcen) - real(sa.sph[ir-1].fcen)
       dy = imag(sa.sph[ir].fcen) - imag(sa.sph[ir-1].fcen)
       dz = sa.sph[ir].fz - sa.sph[ir-1].fz
       dr = sa.sph[ir].frad - sa.sph[ir-1].frad
       if dr < -thresh
         c = -1
       elseif dr > thresh
         c = 1
       elseif dy < -thresh
         c = -1
       elseif dy > thresh
         c = 1
       elseif dz < -thresh
         c = -1
       elseif dz > thresh
         c = 1
       elseif dx < -thresh
         c = -1
       elseif dx > thresh
         c = 1
       else
         c = 0
       endif
       if c == 0
         ir = ir + 1
       else
         sa.sph[l] = sa.sph[ir]
         ir = ir +1
         l = l + 1
       endif
     endwhile
     fk = l
   endfunc
 
   Sphere fg[14]
   float fscle
   int flength
   float fminSphere
   Sphere fb[22]
   int fk
   int rgen
   int mlevel
   int fks
   int fii
   int fjj
   int rlevel
   float fbaserad
   float fp
   float fip
   spherearray s
   float thresh
   float scale
   bool reflect
   complex xrot
   complex yrot
   complex zrot
   float bradius
   bool sflag
   float crad
   bool circles
   bool showc
   bool lace
   bool cir3
   bool zsort
   float rcen
 
 
 default:
   title = "Tetrahedron"
   int param v_tetrahedron
     caption = "Version (Tetrahedron)"
     default = 100
     hint = "This version parameter is used to detect when a change has been made to the formula that is incompatible with the previous version. When that happens, this field will reflect the old version number to alert you to the fact that an alternate rendering is being used."
     visible = @v_tetrahedron < 100
   endparam
 
   heading
     text  = "Do not use 'Sort by depth' with reflections, refractions or \
              transformations."
   endheading
   bool param zsort
     caption = "Sort by depth"
     default = false
     hint = "Allows intersection test for simple raytracing to terminate \
             at first hit."
   endparam
   float param minsphere
     caption = "Min sphere size"
     default = 0.01
     min = 0.00001
     hint = "Lower limit is 0.0005."
   endparam
   int param maxLevel
     caption = "Recursion level"
     default = 2
     min = 0
     max = 200
   endparam
   float param radadj
     caption = "Gen Rad adj"
     default = 1.0
   endparam
   float param bradadj
     caption = "Base Rad adj"
     default = 1.0
   endparam
   bool param reflect
     caption = "Reflect Object"
     default = false
   endparam
   float param xang
     caption = "X Axis Rotation"
     default = 0.0
   endparam
   float param yang
     caption = "Y Axis Rotation"
     default = 0.0
   endparam
 }
 


Constructor Summary
InvertSphere()
           
InvertSphere(Generic pparent)
          constructor for sphere inversions with a tetrahedral geometry
 
Method Summary
 void findbound(SphereArray sa, int count, float xmin, float ymin, float zmin, float xmax, float ymax, float zmax)
          Find the overall bounding volume for a set of spheres
 void heapify(SphereArray sa, int count)
          A helper function for heapsort
 void heapifyz(SphereArray sa, int count)
          A helper function for heapsortz
 void heapsort(SphereArray sa, int count)
          Sort spheres in preparation for duplicate removal
 void heapsortz(SphereArray sa, int count)
          Sort spheres by z value.
 void InitSpheres()
          Initializes base and generator spheres
 Sphere Inverse(Sphere target, Sphere inverter, int level, int gen)
          Inverts a sphere
 void Recurse()
          Top level recursion function - calls the function recurse2
 void recurse2(int level, int tarvalue)
          Function for recursive sphere inversion
 void siftdown(SphereArray sa, int start, int end)
          A helper function for heapsort
 void siftdownz(SphereArray sa, int start, int end)
          A helper function for heapsortz
 void swap(SphereArray sa, int i, int j)
          A helper function for heapsort
 void vanquish(SphereArray sa, int count)
          Removes duplicates from a sorted array
 
Methods inherited from class common:Generic
GetParent
 
Methods inherited from class Object
 

Constructor Detail

InvertSphere

public InvertSphere(Generic pparent)
constructor for sphere inversions with a tetrahedral geometry


InvertSphere

public InvertSphere()
Method Detail

InitSpheres

public void InitSpheres()
Initializes base and generator spheres


Inverse

public Sphere Inverse(Sphere target,
                      Sphere inverter,
                      int level,
                      int gen)
Inverts a sphere

Parameters:
target - = sphere to be inverted
inverter - = sphere used for the inversion
level - = recursion level
gen - = index of generator (inverter) sphere

Recurse

public void Recurse()
Top level recursion function - calls the function recurse2


recurse2

public void recurse2(int level,
                     int tarvalue)
Function for recursive sphere inversion

Parameters:
level - = recursion level
tarvalue - = index of new sphere

findbound

public void findbound(SphereArray sa,
                      int count,
                      float xmin,
                      float ymin,
                      float zmin,
                      float xmax,
                      float ymax,
                      float zmax)
Find the overall bounding volume for a set of spheres

Parameters:
sa - = sphere array to be bounded
count - = index range to be bounded
xmin - = min x boundary
ymin - = min y boundary
zmin - = min z boundary
xmax - = max x boundary
ymax - = max y boundary
zmax - = max z boundary

heapsort

public void heapsort(SphereArray sa,
                     int count)
Sort spheres in preparation for duplicate removal

Parameters:
sa - = sphere array to be sorted
count - = index range to be sorted

heapsortz

public void heapsortz(SphereArray sa,
                      int count)
Sort spheres by z value.


heapify

public void heapify(SphereArray sa,
                    int count)
A helper function for heapsort

Parameters:
sa - = sphere array to be sorted
count - = index range to be sorted

heapifyz

public void heapifyz(SphereArray sa,
                     int count)
A helper function for heapsortz


siftdown

public void siftdown(SphereArray sa,
                     int start,
                     int end)
A helper function for heapsort

Parameters:
sa - = sphere array to be sorted
start - = start of the index index range
end - = end of the index index range

siftdownz

public void siftdownz(SphereArray sa,
                      int start,
                      int end)
A helper function for heapsortz


swap

public void swap(SphereArray sa,
                 int i,
                 int j)
A helper function for heapsort

Parameters:
i - = index of the first sphere to be swapped
j - = index of the second sphere to be swapped

vanquish

public void vanquish(SphereArray sa,
                     int count)
Removes duplicates from a sorted array

Parameters:
sa - = sphere array for duplicate element removal
count - = index range for duplicate removal