|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
Objectcommon:Generic
reb:InvertSphere
class
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
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 |
|---|
public InvertSphere(Generic pparent)
public InvertSphere()
| Method Detail |
|---|
public void InitSpheres()
public Sphere Inverse(Sphere target,
Sphere inverter,
int level,
int gen)
target - = sphere to be invertedinverter - = sphere used for the inversionlevel - = recursion levelgen - = index of generator (inverter) spherepublic void Recurse()
public void recurse2(int level,
int tarvalue)
level - = recursion leveltarvalue - = index of new sphere
public void findbound(SphereArray sa,
int count,
float xmin,
float ymin,
float zmin,
float xmax,
float ymax,
float zmax)
sa - = sphere array to be boundedcount - = index range to be boundedxmin - = min x boundaryymin - = min y boundaryzmin - = min z boundaryxmax - = max x boundaryymax - = max y boundaryzmax - = max z boundary
public void heapsort(SphereArray sa,
int count)
sa - = sphere array to be sortedcount - = index range to be sorted
public void heapsortz(SphereArray sa,
int count)
public void heapify(SphereArray sa,
int count)
sa - = sphere array to be sortedcount - = index range to be sorted
public void heapifyz(SphereArray sa,
int count)
public void siftdown(SphereArray sa,
int start,
int end)
sa - = sphere array to be sortedstart - = start of the index index rangeend - = end of the index index range
public void siftdownz(SphereArray sa,
int start,
int end)
public void swap(SphereArray sa,
int i,
int j)
i - = index of the first sphere to be swappedj - = index of the second sphere to be swapped
public void vanquish(SphereArray sa,
int count)
sa - = sphere array for duplicate element removalcount - = index range for duplicate removal
|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||