; comment { by Ron Barnett
July 3, 2008
revised Dec 12, 2012
Ron's Website

This is my public collection. As much as possible, I will try to keep these backwards-compatible, so that all of your parameters will always render correctly in the future.

Search Menu:
1. Quaternion/Hypercomplex math
2. Misc 3D 4D Methods including mandelbulb and Msltoe 3D
3. Mobius Transformations
4. 3D Rotations
5. 3D Object classes
6. 3D Inversion classes
7. Trap shape classes
8. Image TrapMode classes
9. Image Trap ColorMode classes
10. Trap Transfer classes
11. Image Traps class
12. Color Trap classes
13. Formula object classes
14. Formula Switch Classes 15. Direct Color Arrays
16. Direct Coloring Classes
17. Gradient Coloring Classes
18. Line Art Plugins
19. Transformation classes
20. 3D Mesh Classes
21. Raytrace Classes
22. Convolution filters
23. Generator classes
24. Formula classes for embossing
} ;------------------------------------------- ; Quaternion/Hypercomplex math ;------------------------------------------- Class QH { import "common.ulb" ; Functions for Quaternion and Hypercomplex operations.
;

; For quaternions, multiplication is not commutative and division is always ; defined. ;

; For hypercomplex, multiplication is commutative and division is not always ; defined. The inverses which are not defined lieon two orthogonal ; 4D hyperplanes. ;

; The hypercomplex code is based upon the complex number methods of Clyde ; Davenport using his complex/complex model. ;

; Davenport's Website
;

; H1 = [a1,a2]
;

; where a1 and a2 are both complex numbers. This is the method used in Fractint. ; a1 and a2 are converted to two new complex numbers: ;

; fa1 = a1 - conj(flip(a2))
; fa2 = a1 + conj(flip(a2))
;

; These new complex numbers (and correspondingly fb1 and fb2) can be used for ; ordinary complex math, including multiplication, division, trancendental ; functions, powers, etc. For example, sqrt: ;

; fa1 = sqrt(fa1)
; fa2 = sqrt(fa2)
;

; A second conversion is done at the end of the operation(s): ;

; c1 = 0.5*(fa1+fa2)
; c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
;

; H2 = [c1, c2]
; Operations for Spherical coordinates and 4D numbers added November 2009 ; public: ; Quaternian multiplication static func Qmul(Vector a, Vector b, Vector c) ; Q1*Q2 = [r1*r2 - V1.V2, r2*V1 + r1*V2 + V1xV2] ; calc V . V float dot = a.m_y*b.m_y + a.m_z*b.m_z + a.m_w*b.m_w ; calc V x V c.m_y = a.m_z*b.m_w - b.m_z*a.m_w c.m_z = -(a.m_y*b.m_w - b.m_y*a.m_w) c.m_w = a.m_y*b.m_z - b.m_y*a.m_z c.m_x = a.m_x*b.m_x-dot c.m_y = c.m_y + a.m_x*b.m_y + b.m_x*a.m_y c.m_z = c.m_z + a.m_x*b.m_z + b.m_x*a.m_z c.m_w = c.m_w + a.m_x*b.m_w + b.m_x*a.m_w endfunc ; Quaternian division calculated as Q2*(1/Q1) static func Qdiv(Vector a, Vector b, Vector c) ; 1/Q = [r, -V]/(r*r + V.V) ; then calculate Q2*(1/Q1) as for QMul float denom = 1/(b.m_x*b.m_x + b.m_y*b.m_y + b.m_z*b.m_z + b.m_w*b.m_w) ; calc V . V float dot = -(a.m_y*b.m_y + a.m_z*b.m_z + a.m_w*b.m_w) ; calc V x V c.m_y = -a.m_z*b.m_w + b.m_z*a.m_w c.m_z = a.m_y*b.m_w - b.m_y*a.m_w c.m_w = -a.m_y*b.m_z + b.m_y*a.m_z c.m_x = (a.m_x*b.m_x-dot)*denom c.m_y = (c.m_y - a.m_x*b.m_y + b.m_x*a.m_y)*denom c.m_z = (c.m_z - a.m_x*b.m_z + b.m_x*a.m_z)*denom c.m_w = (c.m_w - a.m_x*b.m_w + b.m_x*a.m_w)*denom endfunc ; Quaternian division calculated as 1/Q1)*Q2 static func Qdiv2(Vector a, Vector b, Vector c) ; 1/Q = [r, -V]/(r*r + V.V) ; then calculate (1/Q1)*Q2 as for QMul float denom = 1/(b.m_x*b.m_x + b.m_y*b.m_y + b.m_z*b.m_z + b.m_w*b.m_w) ; calc V . V float dot = -(a.m_y*b.m_y + a.m_z*b.m_z + a.m_w*b.m_w) ; calc V x V c.m_y = -b.m_z*a.m_w + a.m_z*b.m_w c.m_z = b.m_y*a.m_w - a.m_y*b.m_w c.m_w = -b.m_y*a.m_z + a.m_y*b.m_z c.m_x = (a.m_x*b.m_x-dot)*denom c.m_y = (c.m_y + b.m_x*a.m_y - a.m_x*b.m_y)*denom c.m_z = (c.m_z + b.m_x*a.m_z - a.m_x*b.m_z)*denom c.m_w = (c.m_w + b.m_x*a.m_w - a.m_x*b.m_w)*denom endfunc ; Quaternian square static func Qsqr(Vector a, Vector b) ; Q*Q = [r*r-V.V, 2*r*V] ; calc V . V float dot = a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w if dot == 0 dot = 1e-100 endif b.m_x = a.m_x*a.m_x-dot b.m_y = 2*a.m_x*a.m_y b.m_z = 2*a.m_x*a.m_z b.m_w = 2*a.m_x*a.m_w endfunc ; Quaternian square root static func Qsqrt(Vector a, Vector b) ; derived from the inverse of the equations for Qsqr ; PLEASE NOTE! ; There are infinitely many square roots of any negative real number, ; which are all purely imaginary and equidistant from the origin; and, ; also, that negative real numbers are the only quaternions that have ; this property. ; As a simplification for this case, the quaternion of a real negative ; number will be treated as a complex number. if a.m_x < 0 && a.m_y == 0 && a.m_z == 0 && a.m_w == 0 complex ir = a.m_x + flip(a.m_y) ir = sqrt(ir) b.init(real(ir),imag(ir),0,0) else float sdot = a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w if sdot == 0 sdot = 1e-100 endif b.m_x = sqrt((a.m_x + sqrt(a.m_x^2 + sdot))/2) float factor = 1/(2*b.m_x) b.m_y = a.m_y*factor b.m_z = a.m_z*factor b.m_w = a.m_w*factor endif endfunc ; Quaternian reciprocal or inverse static func Qrecip(Vector a, Vector b) ; 1/Q = [r, -V]/(r*r + V.V) float denom = 1/(a.m_x*a.m_x + a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) b.m_x = a.m_x*denom b.m_y = -a.m_y*denom b.m_z = -a.m_z*denom b.m_w = -a.m_w*denom endfunc ; Quaternian natural log static func Qlog(Vector a, Vector b) float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = log(z) float at = imag(z)/norm b.m_x = real(z) b.m_y = at*a.m_y b.m_z = at*a.m_z b.m_w = at*a.m_w endfunc ; Quaternian exponential static func Qexp(Vector a, Vector b) float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = exp(z) float at = imag(z)/norm b.m_x = real(z) b.m_y = at*a.m_y b.m_z = at*a.m_z b.m_w = at*a.m_w endfunc ; Quaternian power calculated as exp(ln(Q1)*Q2) static func Qpower(Vector a, Vector b, Vector c) ; Q1^Q2 = exp(ln(Q1)*Q2) ; Find the log of Q1 float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = log(z) float at = imag(z)/norm float x1 = real(z) float y1 = at*a.m_y float z1 = at*a.m_z float w1 = at*a.m_w ; Multiply log by Q2 float dot = y1*b.m_y + z1*b.m_z + w1*b.m_w ; calc V x V float y2 = z1*b.m_w - b.m_z*w1 float z2 = -(y1*b.m_w - b.m_y*w1) float w2 = y1*b.m_z - b.m_y*z1 float x2 = x1*b.m_x-dot y2 = y2 + x1*b.m_y + b.m_x*y1 z2 = z2 + x1*b.m_z + b.m_x*z1 w2 = w2 + x1*b.m_w + b.m_x*w1 ; Take the exponential norm = sqrt(y2*y2 + z2*z2 + w2*w2) if norm == 0 norm = 1e-100 endif z = x2 + flip(norm) z = exp(z) at = imag(z)/norm c.m_x = real(z) c.m_y = at*y2 c.m_z = at*z2 c.m_w = at*w2 endfunc ; Quaternian power calculated as exp(Q2*ln(Q1)) static func Qpower2(Vector a, Vector b, Vector c) ; Q1^Q2 = exp(Q2*ln(Q1)) ; Find the log of Q1 float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = log(z) float at = imag(z)/norm float x1 = real(z) float y1 = at*a.m_y float z1 = at*a.m_z float w1 = at*a.m_w ; Multiply log by Q2 float dot = y1*b.m_y + z1*b.m_z + w1*b.m_w ; calc V x V float y2 = -z1*b.m_w + b.m_z*w1 float z2 = (y1*b.m_w - b.m_y*w1) float w2 = -y1*b.m_z + b.m_y*z1 float x2 = x1*b.m_x-dot y2 = y2 + x1*b.m_y + b.m_x*y1 z2 = z2 + x1*b.m_z + b.m_x*z1 w2 = w2 + x1*b.m_w + b.m_x*w1 ; Take the exponential norm = sqrt(y2*y2 + z2*z2 + w2*w2) if norm == 0 norm = 1e-100 endif z = x2 + flip(norm) z = exp(z) at = imag(z)/norm c.m_x = real(z) c.m_y = at*y2 c.m_z = at*z2 c.m_w = at*w2 endfunc ; Quaternian sine static func Qsin(Vector a, Vector b) float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = sin(z) float at = imag(z)/norm b.m_x = real(z) b.m_y = at*a.m_y b.m_z = at*a.m_z b.m_w = at*a.m_w endfunc ; Quaternian arcsine static func Qasin(Vector a, Vector b) float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = asin(z) float at = imag(z)/norm b.m_x = real(z) b.m_y = at*a.m_y b.m_z = at*a.m_z b.m_w = at*a.m_w endfunc ; Quaternian cosine static func Qcos(Vector a, Vector b) float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = cos(z) float at = imag(z)/norm b.m_x = real(z) b.m_y = at*a.m_y b.m_z = at*a.m_z b.m_w = at*a.m_w endfunc ; Quaternian arccosine static func Qacos(Vector a, Vector b) float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = acos(z) float at = imag(z)/norm b.m_x = real(z) b.m_y = at*a.m_y b.m_z = at*a.m_z b.m_w = at*a.m_w endfunc ; Quaternian tangent static func Qtan(Vector a, Vector b) float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = tan(z) float at = imag(z)/norm b.m_x = real(z) b.m_y = at*a.m_y b.m_z = at*a.m_z b.m_w = at*a.m_w endfunc ; Quaternian hyperbolic tangent static func Qtanh(Vector a, Vector b) float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = tanh(z) float at = imag(z)/norm b.m_x = real(z) b.m_y = at*a.m_y b.m_z = at*a.m_z b.m_w = at*a.m_w endfunc ; Quaternian hyperbolic arctangent static func Qatanh(Vector a, Vector b) float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = atanh(z) float at = imag(z)/norm b.m_x = real(z) b.m_y = at*a.m_y b.m_z = at*a.m_z b.m_w = at*a.m_w endfunc ; Quaternian arctangent static func Qatan(Vector a, Vector b) float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = atan(z) float at = imag(z)/norm b.m_x = real(z) b.m_y = at*a.m_y b.m_z = at*a.m_z b.m_w = at*a.m_w endfunc ; Quaternian conjugate static func Qconj(Vector a, Vector b) ; conj(Q) = [r,-V] b.m_x = a.m_x b.m_y = -a.m_y b.m_z = -a.m_z b.m_w = -a.m_w endfunc ; Quaternian hyperbolic sine static func Qsinh(Vector a, Vector b) float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = sinh(z) float at = imag(z)/norm b.m_x = real(z) b.m_y = at*a.m_y b.m_z = at*a.m_z b.m_w = at*a.m_w endfunc ; Quaternian hyperbolic cosine static func Qcosh(Vector a, Vector b) float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = cosh(z) float at = imag(z)/norm b.m_x = real(z) b.m_y = at*a.m_y b.m_z = at*a.m_z b.m_w = at*a.m_w endfunc ; Quaternian hyperbolic arcsine static func Qasinh(Vector a, Vector b) float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = asinh(z) float at = imag(z)/norm b.m_x = real(z) b.m_y = at*a.m_y b.m_z = at*a.m_z b.m_w = at*a.m_w endfunc ; Quaternian hyperbolic arccosine static func Qacosh(Vector a, Vector b) float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = acosh(z) float at = imag(z)/norm b.m_x = real(z) b.m_y = at*a.m_y b.m_z = at*a.m_z b.m_w = at*a.m_w endfunc ; Quaternian cotangent static func Qcotan(Vector a, Vector b) float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = cotan(z) float at = imag(z)/norm b.m_x = real(z) b.m_y = at*a.m_y b.m_z = at*a.m_z b.m_w = at*a.m_w endfunc ; Quaternian hyperbolic cotangent static func Qcotanh(Vector a, Vector b) float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w) if norm == 0 norm = 1e-100 endif complex z = a.m_x + flip(norm) z = cotanh(z) float at = imag(z)/norm b.m_x = real(z) b.m_y = at*a.m_y b.m_z = at*a.m_z b.m_w = at*a.m_w endfunc ; Hypercomplex multiplication static func Hmul(Vector a, Vector b, Vector c) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex b1 = b.m_x + flip(b.m_y) complex b2 = b.m_z + flip(b.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) complex fb1 = b1 - conj(flip(b2)) complex fb2 = b1 + conj(flip(b2)) fa1 = fa1*fb1 fa2 = fa2*fb2 c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) c.m_x = real(c1) c.m_y = imag(c1) c.m_z = real(c2) c.m_w = imag(c2) endfunc ; Hypercomplex division static func Hdiv(Vector a, Vector b, Vector c) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex b1 = b.m_x + flip(b.m_y) complex b2 = b.m_z + flip(b.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) complex fb1 = b1 - conj(flip(b2)) complex fb2 = b1 + conj(flip(b2)) fa1 = fa1/fb1 fa2 = fa2/fb2 c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) c.m_x = real(c1) c.m_y = imag(c1) c.m_z = real(c2) c.m_w = imag(c2) endfunc ; Hypercomplex square static func Hsqr(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = fa1*fa1 fa2 = fa2*fa2 c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex square root static func Hsqrt(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = sqrt(fa1) fa2 = sqrt(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex reciprocal or inverse static func Hrecip(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = 1/fa1 fa2 = 1/fa2 c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex natural log static func Hlog(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = log(fa1) fa2 = log(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex exponential static func Hexp(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = exp(fa1) fa2 = exp(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex power static func Hpower(Vector a, Vector b, Vector c) ; Q1^Q2 = exp(ln(Q1)*Q2) ; ; Find the log of Q1 complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex b1 = b.m_x + flip(b.m_y) complex b2 = b.m_z + flip(b.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) complex fb1 = b1 - conj(flip(b2)) complex fb2 = b1 + conj(flip(b2)) fa1 = log(fa1) fa2 = log(fa2) ; ; Multiply log by Q2 fa1 = fa1*fb1 fa2 = fa2*fb2 ; ; Take exponential fa1 = exp(fa1) fa2 = exp(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) c.m_x = real(c1) c.m_y = imag(c1) c.m_z = real(c2) c.m_w = imag(c2) endfunc static func Hsin(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = sin(fa1) fa2 = sin(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex cosine static func Hcos(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = cos(fa1) fa2 = cos(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex hyperbolic sine static func Hsinh(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = sinh(fa1) fa2 = sinh(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex hyperbolic cosine static func Hcosh(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = cosh(fa1) fa2 = cosh(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex conjugate static func Hconj(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = conj(fa1) fa2 = conj(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex tangent static func Htan(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = tan(fa1) fa2 = tan(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex arcsine static func Hasin(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = asin(fa1) fa2 = asin(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex arccosine static func Hacos(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = acos(fa1) fa2 = acos(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex arctangent static func Hatan(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = atan(fa1) fa2 = atan(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex hyperbolic tangent static func Htanh(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = tanh(fa1) fa2 = tanh(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex hyperbolic arcsine static func Hasinh(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = asinh(fa1) fa2 = asinh(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex hyperbolic arccosine static func Hacosh(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = acosh(fa1) fa2 = acosh(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex hyperbolic arctangent static func Hatanh(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = atanh(fa1) fa2 = atanh(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex cotangent static func Hcotan(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = cotan(fa1) fa2 = cotan(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc ; Hypercomplex hyperbolic cotangent static func Hcotanh(Vector a, Vector b) complex a1 = a.m_x + flip(a.m_y) complex a2 = a.m_z + flip(a.m_w) complex fa1 = a1 - conj(flip(a2)) complex fa2 = a1 + conj(flip(a2)) fa1 = cotanh(fa1) fa2 = cotanh(fa2) c1 = 0.5*(fa1+fa2) c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2))) b.m_x = real(c1) b.m_y = imag(c1) b.m_z = real(c2) b.m_w = imag(c2) endfunc default: title = "Quat Hyper Methods" int param v_quathyper caption = "Version (Quat Hyper Methods)" 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_quathyper < 100 endparam } ;------------------------------------------- ; Misc 3D 4D Methods including mandelbulb and Msltoe 3D ;------------------------------------------- Class MD { $define debug import "common.ulb" ; Spherical power ; Spherical complex representation for s = x + iy + jz ; ; r = x^2 + y^2 +z^2 ; phi = atan2(x + iy) azimuth ; theta = atan2(cabs(x+iy) + iz) elevation ; ; x = r*cos(theta)*cos(phi) ; y = r*cos(theta)*sin(phi) ; z = r*sin(theta) ; static func Spower(bool quadcor, bool altel, float power, Vector a, Vector b, float pfactor, int flagtype) ; Power function for s = x + iy + jz expressed in spherical coordinates float r = 0 float phi = 0 float theta = 0 if flagtype == 6 if a.m_z* a.m_z < a.m_y* a.m_y r = a.m_x*a.m_x+a.m_y*a.m_y+a.m_z*a.m_z+4*a.m_y*a.m_y*a.m_z*a.m_z float r1 = sqrt(r)+1e-10 phi = atan2(a.m_x + flip(a.m_y)) theta = asin(a.m_z/r1) else r = a.m_x*a.m_x+a.m_y*a.m_y+a.m_z*a.m_z+4*a.m_y*a.m_y*a.m_z*a.m_z float r1 = sqrt(r)+1e-10 theta = atan2(a.m_x + flip(a.m_z)) phi = asin(a.m_y/r1) endif endif r = sqrt(a.m_x^2 + a.m_y^2 + a.m_z^2)+1e-10 if flagtype != 6 phi = atan2(a.m_x + flip(a.m_y)) ; azimuth theta = 0 endif float asa = 0 if flagtype ==0 || flagtype == 1 if altel theta = asin(a.m_z/r) else theta = asin(-a.m_z/r) endif elseif flagtype == 9 || flagtype == 10\ || flagtype == 11|| flagtype == 12|| flagtype == 13|| flagtype == 14\ || flagtype == 15|| flagtype == 16|| flagtype == 17|| flagtype == 18\ || flagtype == 19|| flagtype == 20|| flagtype == 21|| flagtype == 22\ || flagtype == 23|| flagtype == 24|| flagtype == 25|| flagtype == 26\ || flagtype == 27|| flagtype == 28|| flagtype == 29|| flagtype == 30\ || flagtype == 31|| flagtype == 32|| flagtype == 33|| flagtype == 34\ || flagtype == 35|| flagtype == 36|| flagtype == 37|| flagtype == 38\ || flagtype == 39|| flagtype == 40|| flagtype == 41 phi = atan2(a.m_x + flip(a.m_z)) theta = asin(a.m_y/r) elseif flagtype == 2 if altel theta = acos(-a.m_z/r) else theta = acos(a.m_z/r) endif elseif flagtype == 7 || flagtype == 8 if altel theta = acos(-a.m_y/r) else theta = acos(a.m_y/r) endif elseif flagtype == 3 if altel theta = atan2(-a.m_x + flip(a.m_z)) else theta = atan2(a.m_x + flip(a.m_z)) endif endif if flagtype == 42 || flagtype == 43 || flagtype == 44 || flagtype == 45\ || flagtype == 46 || flagtype == 47 || flagtype == 48 || flagtype == 49\ || flagtype == 50 || flagtype == 51 || (flagtype > 51 && flagtype <95) if altel theta = atan2(-a.m_x + flip(a.m_y)) else theta = atan2(a.m_x + flip(a.m_y)) endif phi = asin(a.m_z/r) endif if flagtype == 4 || flagtype == 5 phi = atan2(a.m_x + flip(a.m_y)) theta = asin(a.m_z/r) endif if flagtype == 7 || flagtype == 8 phi = atan2(a.m_x + flip(a.m_z)) theta = acos(a.m_y/r) endif r = r^power phi = power*phi theta = power*theta*pfactor if flagtype ==0 || flagtype == 1 if quadcor if theta > #pi/2 asa = sin(theta) theta = asin(asa) endif if theta < -#pi/2 asa = sin(theta) theta = asin(asa) endif endif elseif flagtype == 2 if quadcor if theta > #pi/2 asa = cos(theta) theta = acos(asa) endif if theta < -#pi/2 asa = cos(theta) theta = acos(asa) endif endif elseif flagtype == 7 || flagtype == 8 if quadcor if theta > #pi/2 asa = cos(theta) theta = acos(asa) endif if theta < -#pi/2 asa = cos(theta) theta = acos(asa) endif endif elseif flagtype == 3 if quadcor if theta > #pi/2 asa = tan(theta) theta = atan(asa) endif if theta < -#pi/2 asa = tan(theta) theta = atan(asa) endif endif endif if flagtype ==0 || flagtype == 1 b.m_x = r*cos(theta)*cos(phi) b.m_y = r*cos(theta)*sin(phi) if flagtype == 0 b.m_z = r*sin(theta) elseif flagtype == 1 b.m_z = -r*sin(theta) endif elseif flagtype == 2 b.m_x = r*sin(theta)*sin(phi) b.m_y = r*sin(theta)*cos(phi) b.m_z = r*cos(theta) elseif flagtype == 3 b.m_x = r*cos(theta)*cos(phi) b.m_y = r*cos(theta)*sin(phi) b.m_z = r*sin(theta) elseif flagtype == 4 || flagtype == 5 b.m_x = r*cos(phi)*cos(theta) b.m_z = r*cos(phi)*sin(theta) if flagtype == 4 b.m_y = -r*sin(phi) elseif flagtype == 5 b.m_y = r*sin(phi) endif elseif flagtype == 6 if a.m_z* a.m_z < a.m_y* a.m_y b.m_x = r*cos(theta)*cos(phi) b.m_y = r*sin(phi)*cos(theta) b.m_z = -r*sin(theta) else b.m_x = r*cos(theta)*cos(phi) b.m_y = -r*sin(theta) b.m_z = r*sin(phi)*cos(theta) endif elseif flagtype == 7 b.m_x = r*sin(theta)*sin(phi) b.m_y = r*cos(theta) b.m_z = r*sin(theta)*cos(phi) elseif flagtype == 8 b.m_x = r*sin(theta)*sin(phi) b.m_y = -r*cos(theta) b.m_z = r*sin(theta)*cos(phi) elseif flagtype == 9 b.m_x = r*sin(theta) b.m_y = -r*sin(phi)*cos(theta) b.m_z = r*cos(theta)*cos(phi) elseif flagtype == 10 b.m_x = -r*sin(theta) b.m_y = r*cos(phi)*cos(theta) b.m_z = r*cos(theta)*sin(phi) elseif flagtype == 11 b.m_x = r*cos(theta) b.m_y = -r*sin(phi)*sin(theta) b.m_z = r*cos(phi)*sin(theta ) elseif flagtype == 12 b.m_x = r*cos(theta) b.m_y = -r*sin(phi)*sin(theta) b.m_z = -r*cos(phi)*sin(theta ) elseif flagtype == 13 b.m_x = -r*sin(theta) b.m_y = -r*sin(phi)*cos(theta) b.m_z = r*cos(phi)*cos(theta) elseif flagtype == 14 b.m_x = r*sin(theta) b.m_y = r*sin(phi)*cos(theta) b.m_z = r*cos(phi)*cos(theta) elseif flagtype == 15 b.m_x = -r*sin(theta) b.m_y = r*sin(phi)*cos(theta) b.m_z = r*cos(phi)*cos(theta) elseif flagtype == 16 b.m_x = r*sin(phi)*cos(theta) b.m_y = -r*sin(theta) b.m_z = r*cos(phi)*cos(theta) elseif flagtype == 17 b.m_x = -r*sin(phi)*sin(theta) b.m_y = r*cos(theta) b.m_z = -r*cos(phi)*sin(theta) elseif flagtype == 18 b.m_x = -r*sin(phi)*sin(theta) b.m_y = r*cos(theta) b.m_z = r*cos(phi)*sin(theta) elseif flagtype == 19 b.m_x = r*sin(phi)*cos(theta) b.m_y = r*sin(theta) b.m_z = r*cos(phi)*cos(theta) elseif flagtype == 20 b.m_x = -r*sin(phi)*cos(theta) b.m_y = -r*sin(theta) b.m_z = r*cos(phi)*cos(theta) elseif flagtype == 21 b.m_x = -r*sin(phi)*cos(theta) b.m_y = r*sin(theta) b.m_z = r*cos(phi)*cos(theta) elseif flagtype == 22 b.m_x = r*sin(phi)*sin(theta) b.m_y = -r*cos(phi)*sin(theta) b.m_z = r*cos(theta) elseif flagtype == 23 b.m_x = -r*sin(phi)*cos(theta) b.m_y = r*cos(phi)*cos(theta) b.m_z = -r*sin(theta) elseif flagtype == 24 b.m_x = r*sin(phi)*cos(theta) b.m_y = r*cos(phi)*cos(theta) b.m_z = r*sin(theta) elseif flagtype == 25 b.m_x = -r*sin(phi)*sin(theta) b.m_y = r*cos(phi)*sin(theta) b.m_z = r*cos(theta) elseif flagtype == 26 b.m_x = -r*sin(phi)*sin(theta) b.m_y = -r*cos(phi)*sin(theta) b.m_z = r*cos(theta) elseif flagtype == 27 b.m_x = -r*sin(phi)*sin(theta) b.m_y = r*cos(phi)*sin(theta) b.m_z = r*cos(theta) elseif flagtype == 28 b.m_x = r*cos(theta) b.m_y = -r*cos(phi)*sin(theta) b.m_z = -r*sin(phi)*sin(theta) elseif flagtype == 29 b.m_x = r*cos(theta) b.m_y = r*cos(phi)*sin(theta) b.m_z = -r*sin(phi)*sin(theta) elseif flagtype == 30 b.m_x = r*sin(theta) b.m_y = r*cos(phi)*cos(theta) b.m_z = r*sin(phi)*cos(theta) elseif flagtype == 31 b.m_x = -r*sin(theta) b.m_y = r*cos(phi)*cos(theta) b.m_z = -r*sin(phi)*cos(theta) elseif flagtype == 32 b.m_x = r*sin(theta) b.m_y = r*cos(phi)*cos(theta) b.m_z = -r*sin(phi)*cos(theta) elseif flagtype == 33 b.m_x = -r*cos(phi)*sin(theta) b.m_y = r*cos(theta) b.m_z = r*sin(phi)*sin(theta) elseif flagtype == 34 b.m_x = r*cos(phi)*cos(theta) b.m_y = -r*sin(theta) b.m_z = -r*sin(phi)*cos(theta) elseif flagtype == 35 b.m_x = r*cos(phi)*cos(theta) b.m_y = r*sin(theta) b.m_z = r*sin(phi)*cos(theta) elseif flagtype == 36 b.m_x = r*cos(phi)*sin(theta) b.m_y = r*cos(theta) b.m_z = -r*sin(phi)*sin(theta) elseif flagtype == 37 b.m_x = -r*cos(phi)*sin(theta) b.m_y = r*cos(theta) b.m_z = -r*sin(phi)*sin(theta) elseif flagtype == 38 b.m_x = r*cos(phi)*sin(theta) b.m_y = r*cos(theta) b.m_z = r*sin(phi)*sin(theta) elseif flagtype == 39 b.m_x = r*cos(phi)*cos(theta) b.m_y = -r*sin(phi)*cos(theta) b.m_z = -r*sin(theta) elseif flagtype == 40 b.m_x = r*cos(phi)*cos(theta) b.m_y = -r*sin(phi)*cos(theta) b.m_z = r*sin(theta) elseif flagtype == 41 b.m_x = r*cos(phi)*sin(theta) b.m_y = -r*sin(phi)*sin(theta) b.m_z = r*cos(theta) elseif flagtype == 42 b.m_x = r*cos(theta) b.m_y = r*cos(phi) b.m_z = r*sin(theta) elseif flagtype == 43 b.m_x = r*cos(theta) b.m_y = -r*cos(phi) b.m_z = r*sin(theta) elseif flagtype == 44 b.m_x = r*cos(theta) b.m_y = -r*cos(phi) b.m_z = -r*sin(theta) elseif flagtype == 45 b.m_x = r*cos(theta) b.m_y = r*sin(theta) b.m_z = r*cos(phi) elseif flagtype == 46 b.m_x = r*cos(theta) b.m_y = r*sin(phi) b.m_z = r*cos(phi) elseif flagtype == 47 b.m_x = r*cos(theta) b.m_y = -r*sin(phi) b.m_z = -r*sin(theta) elseif flagtype == 48 b.m_x = -r*cos(theta) b.m_y = r*cos(phi) b.m_z = r*sin(theta) elseif flagtype == 49 b.m_x = -r*cos(theta) b.m_y = r*cos(phi) b.m_z = -r*sin(theta) elseif flagtype == 50 b.m_x = -r*cos(theta) b.m_y = r*cos(phi) b.m_z = r*sin(phi) elseif flagtype == 51 b.m_x = -r*cos(theta) b.m_y = r*cos(phi) b.m_z = -r*sin(phi) elseif flagtype == 52 b.m_x = r*cos(theta) b.m_y = r*sin(phi) b.m_z = r*sin(theta) elseif flagtype == 53 b.m_x = r*cos(theta) b.m_y = r*sin(phi) b.m_z = -r*sin(theta) elseif flagtype == 54 b.m_x = -r*cos(theta) b.m_y = -r*cos(phi) b.m_z = -r*sin(theta) elseif flagtype == 55 b.m_x = -r*cos(theta) b.m_y = -r*cos(phi) b.m_z = -r*sin(phi) elseif flagtype == 56 b.m_x = -r*cos(theta) b.m_y = r*sin(theta) b.m_z = r*cos(phi) elseif flagtype == 57 b.m_x = -r*cos(theta) b.m_y = r*sin(phi) b.m_z = r*cos(phi) elseif flagtype == 58 b.m_x = -r*cos(theta) b.m_y = r*sin(phi) b.m_z = r*sin(theta) elseif flagtype == 59 b.m_x = -r*cos(theta) b.m_y = r*sin(phi) b.m_z = -r*sin(theta) elseif flagtype == 60 b.m_x = -r*cos(theta) b.m_y = -r*sin(phi) b.m_z = r*cos(phi) elseif flagtype == 61 b.m_x = -r*cos(theta) b.m_y = -r*sin(phi) b.m_z = -r*cos(phi) elseif flagtype == 62 b.m_x = -r*cos(theta) b.m_y = -r*sin(phi) b.m_z = r*sin(theta) elseif flagtype == 63 b.m_x = -r*cos(theta) b.m_y = -r*sin(phi) b.m_z = -r*sin(theta) elseif flagtype == 64 b.m_x = r*cos(phi) b.m_y = r*sin(phi) b.m_z = r*cos(theta) elseif flagtype == 65 b.m_x = r*cos(phi) b.m_y = r*sin(phi) b.m_z = -r*cos(theta) elseif flagtype == 66 b.m_x = r*cos(phi) b.m_y = r*sin(phi) b.m_z = r*sin(theta) elseif flagtype == 67 b.m_x = r*cos(phi) b.m_y = -r*sin(phi) b.m_z = -r*cos(theta) elseif flagtype == 68 b.m_x = -r*cos(phi) b.m_y = r*sin(phi) b.m_z = r*cos(theta) elseif flagtype == 69 b.m_x = -r*cos(phi) b.m_y = r*sin(phi) b.m_z = -r*cos(theta) elseif flagtype == 70 b.m_x = -r*cos(phi) b.m_y = r*sin(phi) b.m_z = r*sin(theta) elseif flagtype == 71 b.m_x = -r*cos(phi) b.m_y = r*sin(phi) b.m_z = -r*sin(theta) elseif flagtype == 72 b.m_x = -r*cos(phi) b.m_y = -r*sin(phi) b.m_z = r*cos(theta) elseif flagtype == 73 b.m_x = -r*cos(phi) b.m_y = -r*sin(phi) b.m_z = -r*cos(theta) elseif flagtype == 74 b.m_x = -r*cos(phi) b.m_y = -r*sin(phi) b.m_z = r*sin(theta) elseif flagtype == 75 b.m_x = -r*cos(phi) b.m_y = -r*sin(phi) b.m_z = -r*sin(theta) elseif flagtype == 76 b.m_x = r*sin(theta) b.m_y = -r*cos(theta) b.m_z = r*sin(phi) elseif flagtype == 77 b.m_x = r*sin(theta) b.m_y = r*cos(phi) b.m_z = r*cos(theta) elseif flagtype == 78 b.m_x = r*sin(theta) b.m_y = r*sin(phi) b.m_z = r*cos(theta) elseif flagtype == 79 b.m_x = r*sin(theta) b.m_y = r*sin(phi) b.m_z = -r*cos(theta) elseif flagtype == 80 b.m_x = r*sin(theta) b.m_y = r*sin(phi) b.m_z = r*cos(phi) elseif flagtype == 81 b.m_x = -r*sin(theta) b.m_y = r*cos(theta) b.m_z = r*cos(phi) elseif flagtype == 82 b.m_x = -r*sin(theta) b.m_y = r*cos(phi) b.m_z = r*sin(phi) elseif flagtype == 83 b.m_x = -r*sin(theta) b.m_y = -r*cos(phi) b.m_z = -r*cos(theta) elseif flagtype == 84 b.m_x = -r*sin(theta) b.m_y = r*sin(phi) b.m_z = r*cos(theta) elseif flagtype == 85 b.m_x = -r*sin(theta) b.m_y = r*sin(phi) b.m_z = -r*cos(theta) elseif flagtype == 86 b.m_x = -r*sin(theta) b.m_y = -r*sin(phi) b.m_z = -r*cos(theta) elseif flagtype == 87 b.m_x = -r*sin(theta) b.m_y = -r*sin(phi) b.m_z = r*cos(phi) elseif flagtype == 88 b.m_x = r*sin(phi) b.m_y = -r*cos(phi) b.m_z = r*sin(theta) elseif flagtype == 89 b.m_x = r*sin(phi) b.m_y = -r*cos(phi) b.m_z = -r*sin(theta) elseif flagtype == 90 b.m_x = -r*sin(phi) b.m_y = r*cos(phi) b.m_z = r*cos(theta) elseif flagtype == 91 b.m_x = -r*sin(phi) b.m_y = r*cos(phi) b.m_z = -r*cos(theta) elseif flagtype == 92 b.m_x = r*sin(phi) b.m_y = r*cos(phi) b.m_z = r*sin(theta) elseif flagtype == 93 b.m_x = -r*sin(phi) b.m_y = r*cos(phi) b.m_z = -r*sin(theta) elseif flagtype == 94 b.m_x = -r*sin(phi) b.m_y = -r*cos(phi) b.m_z = -r*cos(theta) endif b.m_w = 0 endfunc ; r = x^2 + y^2 +z^2 ; theta = acos(a.m_z/r) elevation ; phi = atan2(x + iy) azimuth ; theta = theta*power; ; b.m_x = r*sin(theta)*cos(phi) ; b.m_y = r*sin(theta)*sin(phi) ; b.m_z = r*cos(theta) ; b.m_w = 0 ; theta = acos(b.m_z/r) elevation ; phi = atan2(b.m_x + ib.m_y) azimuth ; phi = phi*power; ; r = r^power ; b.m_x = r*sin(theta)*cos(phi) ; b.m_y = r*sin(theta)*sin(phi) ; b.m_z = r*cos(theta) ; b.m_w = 0 static func Spower2(float power, Vector a, Vector b) ; Alternate Power function for s = x + iy + jz expressed in spherical coordinates float r = sqrt(a.m_x^2 + a.m_y^2 + a.m_z^2)+1e-10 float phi = atan2(a.m_x + flip(a.m_y)) ; azimuth float theta = acos(a.m_z/r) theta = power*theta b.m_x = r*sin(theta)*cos(phi) b.m_y = r*sin(theta)*sin(phi) b.m_z = r*cos(theta) b.m_w = 0 theta = acos(b.m_z/r); elevation phi = atan2(b.m_x + flip(b.m_y)) ; azimuth phi = phi*power; r = r^power b.m_x = r*sin(theta)*cos(phi) b.m_y = r*sin(theta)*sin(phi) b.m_z = r*cos(theta) b.m_w = 0 endfunc static func SMult(bool quadcor,bool altel, Vector a, Vector b, Vector c, float pfactor, int flagtype) float ra = 0 float rb = 0 float r = 0 float phia = 0 float phib = 0 float thetaa = 0 float thetab = 0 if flagtype == 6 if a.m_z* a.m_z < a.m_y* a.m_y r = a.m_x*a.m_x+a.m_y*a.m_y+a.m_z*a.m_z+4*a.m_y*a.m_y*a.m_z*a.m_z float r1 = sqrt(r)+1e-10 phia = atan2(a.m_x + flip(a.m_y)) thetaa = asin(a.m_z/r1) else r = a.m_x*a.m_x+a.m_y*a.m_y+a.m_z*a.m_z+4*a.m_y*a.m_y*a.m_z*a.m_z float r1 = sqrt(r)+1e-10 thetaa = atan2(a.m_x + flip(a.m_z)) phia = asin(a.m_y/r1) endif if b.m_z* b.m_z < b.m_y* b.m_y r = b.m_x*b.m_x+b.m_y*b.m_y+b.m_z*b.m_z+4*b.m_y*b.m_y*b.m_z*b.m_z float r1 = sqrt(r)+1e-10 phib = atan2(b.m_x + flip(b.m_y)) thetab = asin(b.m_z/r1) else r = b.m_x*b.m_x+b.m_y*b.m_y+b.m_z*b.m_z+4*b.m_y*b.m_y*b.m_z*b.m_z float r1 = sqrt(r)+1e-10 thetab = atan2(b.m_x + flip(b.m_z)) phib = asin(b.m_y/r1) endif endif ra = sqrt(a.m_x^2 + a.m_y^2 + a.m_z^2)+1e-10 rb = sqrt(b.m_x^2 + b.m_y^2 + b.m_z^2)+1e-10 if flagtype != 6 float phia = atan2(a.m_x + flip(a.m_y)) ; azimuth float thetaa = 0 endif if flagtype == 7 || flagtype == 8 phia = atan2(a.m_x + flip(a.m_z)) thetaa = acos(a.m_y/ra) endif float asa = 0 if flagtype ==0 || flagtype == 1 if altel thetaa = asin(a.m_z/ra) else thetaa = asin(-a.m_z/ra) endif elseif flagtype == 9 || flagtype == 10\ || flagtype == 11|| flagtype == 12|| flagtype == 13|| flagtype == 14\ || flagtype == 15|| flagtype == 16|| flagtype == 17|| flagtype == 18\ || flagtype == 19|| flagtype == 20|| flagtype == 21|| flagtype == 22\ || flagtype == 23|| flagtype == 24|| flagtype == 25|| flagtype == 26\ || flagtype == 27|| flagtype == 28|| flagtype == 29|| flagtype == 30\ || flagtype == 31|| flagtype == 32|| flagtype == 33|| flagtype == 34\ || flagtype == 35|| flagtype == 36|| flagtype == 37|| flagtype == 38\ || flagtype == 39|| flagtype == 40|| flagtype == 41 phia = atan2(a.m_x + flip(a.m_z)) thetaa = asin(a.m_y/ra) elseif flagtype == 2 if altel thetaa = acos(-a.m_z/ra) else thetaa = acos(a.m_z/ra) endif elseif flagtype == 7 || flagtype == 8 if altel thetaa = acos(-a.m_y/ra) else thetaa = acos(a.m_y/ra) endif elseif flagtype == 3 if altel thetaa = atan2(-a.m_x + flip(a.m_z)) else thetaa = atan2(a.m_x + flip(a.m_z)) endif endif if flagtype == 42 || flagtype == 43 || flagtype == 44 || flagtype == 45\ || flagtype == 46 || flagtype == 47|| flagtype == 48 || flagtype == 49\ || flagtype == 50 || flagtype == 51 ||(flagtype > 51 && flagtype <95) if altel thetaa = atan2(-a.m_x + flip(a.m_y)) else thetaa = atan2(a.m_x + flip(a.m_y)) endif phia = asin(a.m_z/ra) endif if flagtype != 6 float phib = atan2(b.m_x + flip(b.m_y)) ; azimuth float thetab = 0 endif if flagtype == 7 || flagtype == 8 phib = atan2(b.m_x + flip(b.m_z)) thetab = acos(b.m_y/rb) endif if flagtype ==0 || flagtype == 1 if altel thetab = asin(b.m_z/rb) else thetab = asin(-b.m_z/rb) endif elseif flagtype == 9 || flagtype == 10\ || flagtype == 11|| flagtype == 12|| flagtype == 13|| flagtype == 14\ || flagtype == 15|| flagtype == 16|| flagtype == 17|| flagtype == 18\ || flagtype == 19|| flagtype == 20|| flagtype == 21|| flagtype == 22\ || flagtype == 23|| flagtype == 24|| flagtype == 25|| flagtype == 26\ || flagtype == 27|| flagtype == 28|| flagtype == 29|| flagtype == 30\ || flagtype == 31|| flagtype == 32|| flagtype == 33|| flagtype == 34\ || flagtype == 35|| flagtype == 36|| flagtype == 37|| flagtype == 38\ || flagtype == 39|| flagtype == 40|| flagtype == 41 phib = atan2(b.m_x + flip(b.m_z)) thetab = asin(b.m_y/rb) elseif flagtype == 2 if altel thetab = acos(-b.m_z/rb) else thetab = acos(b.m_z/rb) endif elseif flagtype == 7 || flagtype == 8 if altel thetab = acos(-b.m_y/rb) else thetab = acos(b.m_y/rb) endif elseif flagtype == 3 if altel thetab = atan2(-b.m_x + flip(b.m_z)) else thetab = atan2(b.m_x + flip(b.m_z)) endif endif if flagtype == 42 || flagtype == 43 || flagtype == 44 || flagtype == 45\ || flagtype == 46 || flagtype == 47|| flagtype == 48 || flagtype == 49\ || flagtype == 50 || flagtype == 51 ||(flagtype > 51 && flagtype <95) if altel thetab = atan2(-b.m_x + flip(b.m_y)) else thetab = atan2(b.m_x + flip(b.m_y)) endif phib = asin(b.m_z/rb) endif if flagtype == 4 || flagtype == 5 phia = atan2(a.m_x + flip(a.m_y)) phib = atan2(b.m_x + flip(b.m_y)) thetaa = asin(a.m_z/ra) thetab = asin(b.m_z/rb) endif float r = ra*rb float phi = phia + phib float theta = (thetaa + thetab)*pfactor if flagtype ==0 || flagtype == 1 if quadcor if theta > #pi/2 asa = sin(theta) theta = asin(asa) endif if theta < -#pi/2 asa = sin(theta) theta = asin(asa) endif endif elseif flagtype == 2 if quadcor if theta > #pi/2 asa = cos(theta) theta = acos(asa) endif if theta < -#pi/2 asa = cos(theta) theta = acos(asa) endif endif elseif flagtype == 3 if quadcor if theta > #pi/2 asa = tan(theta) theta = atan(asa) endif if theta < -#pi/2 asa = tan(theta) theta = atan(asa) endif endif elseif flagtype == 7 || flagtype == 8 if quadcor if theta > #pi/2 asa = tan(theta) theta = atan(asa) endif if theta < -#pi/2 asa = tan(theta) theta = atan(asa) endif endif endif if flagtype ==0 || flagtype == 1 c.m_x = r*cos(theta)*cos(phi) c.m_y = r*cos(theta)*sin(phi) if flagtype == 0 c.m_z = r*sin(theta) elseif flagtype == 1 c.m_z = -r*sin(theta) endif elseif flagtype == 2 c.m_x = r*sin(theta)*sin(phi) c.m_y = r*sin(theta)*cos(phi) c.m_z = r*cos(theta) elseif flagtype == 3 c.m_x = r*cos(theta)*cos(phi) c.m_y = r*cos(theta)*sin(phi) c.m_z = r*sin(theta) elseif flagtype == 4 || flagtype == 5 c.m_x = r*cos(phi)*cos(theta) c.m_z = r*cos(phi)*sin(theta) if flagtype == 4 c.m_y = -r*sin(phi) elseif flagtype == 5 c.m_y = r*sin(phi) endif elseif flagtype == 6 if a.m_z* a.m_z < a.m_y* a.m_y c.m_x = r*cos(theta)*cos(phi) c.m_y = r*sin(phi)*cos(theta) c.m_z = -r*sin(theta) else c.m_x = r*cos(theta)*cos(phi) c.m_y = -r*sin(theta) c.m_z = r*sin(phi)*cos(theta) endif elseif flagtype == 7 c.m_x = r*sin(theta)*sin(phi) c.m_y = r*cos(theta) c.m_z = r*sin(theta)*cos(phi) elseif flagtype == 8 c.m_x = r*sin(theta)*sin(phi) c.m_y = r*cos(theta) c.m_z = r*sin(theta)*cos(phi) elseif flagtype == 9 c.m_x = r*sin(theta) c.m_y = -r*sin(phi)*cos(theta) c.m_z = r*cos(theta)*cos(phi) elseif flagtype == 10 c.m_x = -r*sin(theta) c.m_y = r*cos(phi)*cos(theta) c.m_z = r*cos(theta)*sin(phi) elseif flagtype == 11 c.m_x = r*cos(theta) c.m_y = -r*sin(phi)*sin(theta) c.m_z = r*cos(phi)*sin(theta ) elseif flagtype == 12 c.m_x = r*cos(theta) c.m_y = -r*sin(phi)*sin(theta) c.m_z = -r*cos(phi)*sin(theta ) elseif flagtype == 13 c.m_x = -r*sin(theta) c.m_y = -r*sin(phi)*cos(theta) c.m_z = -r*cos(phi)*cos(theta) elseif flagtype == 14 c.m_x = r*sin(theta) c.m_y = r*sin(phi)*cos(theta) c.m_z = r*cos(phi)*cos(theta) elseif flagtype == 15 c.m_x = -r*sin(theta) c.m_y = r*sin(phi)*cos(theta) c.m_z = r*cos(phi)*cos(theta) elseif flagtype == 16 c.m_x = r*sin(phi)*cos(theta) c.m_y = -r*sin(theta) c.m_z = r*cos(phi)*cos(theta) elseif flagtype == 17 c.m_x = -r*sin(phi)*sin(theta) c.m_y = r*cos(theta) c.m_z = -r*cos(phi)*sin(theta) elseif flagtype == 18 c.m_x = -r*sin(phi)*sin(theta) c.m_y = r*cos(theta) c.m_z = r*cos(phi)*sin(theta) elseif flagtype == 19 c.m_x = r*sin(phi)*cos(theta) c.m_y = r*sin(theta) c.m_z = r*cos(phi)*cos(theta) elseif flagtype == 20 c.m_x = -r*sin(phi)*cos(theta) c.m_y = -r*sin(theta) c.m_z = r*cos(phi)*cos(theta) elseif flagtype == 21 c.m_x = -r*sin(phi)*cos(theta) c.m_y = r*sin(theta) c.m_z = r*cos(phi)*cos(theta) elseif flagtype == 22 c.m_x = r*sin(phi)*sin(theta) c.m_y = -r*cos(phi)*sin(theta) c.m_z = r*cos(theta) elseif flagtype == 23 c.m_x = -r*sin(phi)*cos(theta) c.m_y = r*cos(phi)*cos(theta) c.m_z = -r*sin(theta) elseif flagtype == 24 c.m_x = r*sin(phi)*cos(theta) c.m_y = r*cos(phi)*cos(theta) c.m_z = r*sin(theta) elseif flagtype == 25 c.m_x = -r*sin(phi)*sin(theta) c.m_y = r*cos(phi)*sin(theta) c.m_z = r*cos(theta) elseif flagtype == 26 c.m_x = -r*sin(phi)*sin(theta) c.m_y = -r*cos(phi)*sin(theta) c.m_z = r*cos(theta) elseif flagtype == 27 c.m_x = -r*sin(phi)*sin(theta) c.m_y = r*cos(phi)*sin(theta) c.m_z = r*cos(theta) elseif flagtype == 28 c.m_x = r*cos(theta) c.m_y = -r*cos(phi)*sin(theta) c.m_z = -r*sin(phi)*sin(theta) elseif flagtype == 29 c.m_x = r*cos(theta) c.m_y = r*cos(phi)*sin(theta) c.m_z = -r*sin(phi)*sin(theta) elseif flagtype == 30 c.m_x = r*sin(theta) c.m_y = r*cos(phi)*cos(theta) c.m_z = r*sin(phi)*cos(theta) elseif flagtype == 31 c.m_x = -r*sin(theta) c.m_y = r*cos(phi)*cos(theta) c.m_z = -r*sin(phi)*cos(theta) elseif flagtype == 32 c.m_x = r*sin(theta) c.m_y = r*cos(phi)*cos(theta) c.m_z = -r*sin(phi)*cos(theta) elseif flagtype == 33 c.m_x = -r*cos(phi)*sin(theta) c.m_y = r*cos(theta) c.m_z = r*sin(phi)*sin(theta) elseif flagtype == 34 c.m_x = r*cos(phi)*cos(theta) c.m_y = -r*sin(theta) c.m_z = -r*sin(phi)*cos(theta) elseif flagtype == 35 c.m_x = r*cos(phi)*cos(theta) c.m_y = r*sin(theta) c.m_z = r*sin(phi)*cos(theta) elseif flagtype == 36 c.m_x = r*cos(phi)*sin(theta) c.m_y = r*cos(theta) c.m_z = -r*sin(phi)*sin(theta) elseif flagtype == 37 c.m_x = -r*cos(phi)*sin(theta) c.m_y = r*cos(theta) c.m_z = -r*sin(phi)*sin(theta) elseif flagtype == 38 c.m_x = r*cos(phi)*sin(theta) c.m_y = r*cos(theta) c.m_z = r*sin(phi)*sin(theta) elseif flagtype == 39 c.m_x = r*cos(phi)*cos(theta) c.m_y = -r*sin(phi)*cos(theta) c.m_z = -r*sin(theta) elseif flagtype == 40 c.m_x = r*cos(phi)*cos(theta) c.m_y = -r*sin(phi)*cos(theta) c.m_z = r*sin(theta) elseif flagtype == 41 c.m_x = r*cos(phi)*sin(theta) c.m_y = -r*sin(phi)*sin(theta) c.m_z = r*cos(theta) elseif flagtype == 42 c.m_x = r*cos(theta) c.m_y = r*cos(phi) c.m_z = r*sin(theta) elseif flagtype == 43 c.m_x = r*cos(theta) c.m_y = -r*cos(phi) c.m_z = r*sin(theta) elseif flagtype == 44 c.m_x = r*cos(theta) c.m_y = -r*cos(phi) c.m_z = -r*sin(theta) elseif flagtype == 45 c.m_x = r*cos(theta) c.m_y = r*sin(theta) c.m_z = r*cos(phi) elseif flagtype == 46 c.m_x = r*cos(theta) c.m_y = r*sin(phi) c.m_z = r*cos(phi) elseif flagtype == 47 c.m_x = r*cos(theta) c.m_y = -r*sin(phi) c.m_z = -r*sin(theta) elseif flagtype == 48 c.m_x = -r*cos(theta) c.m_y = r*cos(phi) c.m_z = r*sin(theta) elseif flagtype == 49 c.m_x = -r*cos(theta) c.m_y = r*cos(phi) c.m_z = -r*sin(theta) elseif flagtype == 50 c.m_x = -r*cos(theta) c.m_y = r*cos(phi) c.m_z = r*sin(phi) elseif flagtype == 51 c.m_x = -r*cos(theta) c.m_y = r*cos(phi) c.m_z = -r*sin(phi) elseif flagtype == 52 c.m_x = r*cos(theta) c.m_y = r*sin(phi) c.m_z = r*sin(theta) elseif flagtype == 53 c.m_x = r*cos(theta) c.m_y = r*sin(phi) c.m_z = -r*sin(theta) elseif flagtype == 54 c.m_x = -r*cos(theta) c.m_y = -r*cos(phi) c.m_z = -r*sin(theta) elseif flagtype == 55 c.m_x = -r*cos(theta) c.m_y = -r*cos(phi) c.m_z = -r*sin(phi) elseif flagtype == 56 c.m_x = -r*cos(theta) c.m_y = r*sin(theta) c.m_z = r*cos(phi) elseif flagtype == 57 c.m_x = -r*cos(theta) c.m_y = r*sin(phi) c.m_z = r*cos(phi) elseif flagtype == 58 c.m_x = -r*cos(theta) c.m_y = r*sin(phi) c.m_z = r*sin(theta) elseif flagtype == 59 c.m_x = -r*cos(theta) c.m_y = r*sin(phi) c.m_z = -r*sin(theta) elseif flagtype == 60 c.m_x = -r*cos(theta) c.m_y = -r*sin(phi) c.m_z = r*cos(phi) elseif flagtype == 61 c.m_x = -r*cos(theta) c.m_y = -r*sin(phi) c.m_z = -r*cos(phi) elseif flagtype == 62 c.m_x = -r*cos(theta) c.m_y = -r*sin(phi) c.m_z = r*sin(theta) elseif flagtype == 63 c.m_x = -r*cos(theta) c.m_y = -r*sin(phi) c.m_z = -r*sin(theta) elseif flagtype == 64 c.m_x = r*cos(phi) c.m_y = r*sin(phi) c.m_z = r*cos(theta) elseif flagtype == 65 c.m_x = r*cos(phi) c.m_y = r*sin(phi) c.m_z = -r*cos(theta) elseif flagtype == 66 c.m_x = r*cos(phi) c.m_y = r*sin(phi) c.m_z = r*sin(theta) elseif flagtype == 67 c.m_x = r*cos(phi) c.m_y = -r*sin(phi) c.m_z = -r*cos(theta) elseif flagtype == 68 c.m_x = -r*cos(phi) c.m_y = r*sin(phi) c.m_z = r*cos(theta) elseif flagtype == 69 c.m_x = -r*cos(phi) c.m_y = r*sin(phi) c.m_z = -r*cos(theta) elseif flagtype == 70 c.m_x = -r*cos(phi) c.m_y = r*sin(phi) c.m_z = r*sin(theta) elseif flagtype == 71 c.m_x = -r*cos(phi) c.m_y = r*sin(phi) c.m_z = -r*sin(theta) elseif flagtype == 72 c.m_x = -r*cos(phi) c.m_y = -r*sin(phi) c.m_z = r*cos(theta) elseif flagtype == 73 c.m_x = -r*cos(phi) c.m_y = -r*sin(phi) c.m_z = -r*cos(theta) elseif flagtype == 74 c.m_x = -r*cos(phi) c.m_y = -r*sin(phi) c.m_z = r*sin(theta) elseif flagtype == 75 c.m_x = -r*cos(phi) c.m_y = -r*sin(phi) c.m_z = -r*sin(theta) elseif flagtype == 76 c.m_x = r*sin(theta) c.m_y = -r*cos(theta) c.m_z = r*sin(phi) elseif flagtype == 77 c.m_x = r*sin(theta) c.m_y = r*cos(phi) c.m_z = r*cos(theta) elseif flagtype == 78 c.m_x = r*sin(theta) c.m_y = r*sin(phi) c.m_z = r*cos(theta) elseif flagtype == 79 c.m_x = r*sin(theta) c.m_y = r*sin(phi) c.m_z = -r*cos(theta) elseif flagtype == 80 c.m_x = r*sin(theta) c.m_y = r*sin(phi) c.m_z = r*cos(phi) elseif flagtype == 81 c.m_x = -r*sin(theta) c.m_y = r*cos(theta) c.m_z = r*cos(phi) elseif flagtype == 82 c.m_x = -r*sin(theta) c.m_y = r*cos(phi) c.m_z = r*sin(phi) elseif flagtype == 83 c.m_x = -r*sin(theta) c.m_y = -r*cos(phi) c.m_z = -r*cos(theta) elseif flagtype == 84 c.m_x = -r*sin(theta) c.m_y = r*sin(phi) c.m_z = r*cos(theta) elseif flagtype == 85 c.m_x = -r*sin(theta) c.m_y = r*sin(phi) c.m_z = -r*cos(theta) elseif flagtype == 86 c.m_x = -r*sin(theta) c.m_y = -r*sin(phi) c.m_z = -r*cos(theta) elseif flagtype == 87 c.m_x = -r*sin(theta) c.m_y = -r*sin(phi) c.m_z = r*cos(phi) elseif flagtype == 88 c.m_x = r*sin(phi) c.m_y = -r*cos(phi) c.m_z = r*sin(theta) elseif flagtype == 89 c.m_x = r*sin(phi) c.m_y = -r*cos(phi) c.m_z = -r*sin(theta) elseif flagtype == 90 c.m_x = -r*sin(phi) c.m_y = r*cos(phi) c.m_z = r*cos(theta) elseif flagtype == 91 c.m_x = -r*sin(phi) c.m_y = r*cos(phi) c.m_z = -r*cos(theta) elseif flagtype == 92 c.m_x = r*sin(phi) c.m_y = r*cos(phi) c.m_z = r*sin(theta) elseif flagtype == 93 c.m_x = -r*sin(phi) c.m_y = r*cos(phi) c.m_z = -r*sin(theta) elseif flagtype == 94 c.m_x = -r*sin(phi) c.m_y = -r*cos(phi) c.m_z = -r*cos(theta) endif c.m_w = 0 endfunc static func SDiv(bool quadcor,bool altel, Vector a, Vector b, Vector c,float pfactor) ; Vector b is the divisor float ra = sqrt(a.m_x^2 + a.m_y^2 + a.m_z^2)+1e-10 float phia = atan2(a.m_x + flip(a.m_y)) ; azimuth float thetaa = 0 float asa = 0 if altel thetaa = asin(-a.m_z/ra) else thetaa = asin(a.m_z/ra) endif float rb = sqrt(b.m_x^2 + b.m_y^2 + b.m_z^2)+1e-10 float phib = atan2(b.m_x + flip(b.m_y)) ; azimuth float thetab = 0 if altel thetab = asin(-b.m_z/rb) else thetab = asin(b.m_z/rb) endif float r = ra/rb float phi = phia - phib float theta = (thetaa - thetab)*pfactor if quadcor if theta > #pi/2 asa = sin(theta) theta = asin(asa) endif if theta < -#pi/2 asa = sin(theta) theta = asin(asa) endif endif c.m_x = r*cos(theta)*cos(phi) c.m_y = r*cos(theta)*sin(phi) c.m_z = r^pfactor*sin(theta) c.m_w = 0 endfunc static func SExp(Vector a, Vector b) float t = a.m_z/sqrt(a.m_x^2+a.m_y^2) float p = t*a.m_x + a.m_y float m = t*a.m_x - a.m_y float m2 = a.m_x - t*a.m_y b.m_x = 0.5*exp(m2)*(cos(p) + exp(2*t*a.m_y)*cos(m)) b.m_y = 0.5*exp(m2)*(sin(p) - exp(2*t*a.m_y)*sin(m)) b.m_z = exp(sqrt(a.m_x^2+a.m_y^2))*sin(a.m_z) b.m_w = 0 endfunc static func SLn(Vector a, Vector b) float t = (a.m_x-1)^2 + a.m_y^2 b.m_x = 0.25*log((2*a.m_z^2*((a.m_x-1)*a.m_x+(a.m_y-1)*a.m_y)*((a.m_x-1)*a.m_x+a.m_y^2+a.m_y))/t \ + (a.m_x^2+a.m_y^2)^2 + a.m_z^4) b.m_y = 0.25*(-atan2(flip((a.m_x-1)*a.m_z-sqrt(t)*a.m_y)+sqrt(t)*a.m_x+a.m_y*a.m_z) \ +atan2(flip(sqrt(t)*a.m_y+(a.m_x-1)*a.m_z)+sqrt(t)*a.m_x-a.m_y*a.m_z) \ -atan2(flip(-sqrt(t)*a.m_y-a.m_x*a.m_z+a.m_z)+sqrt(t)*a.m_x-a.m_y*a.m_z) \ +atan2(flip(sqrt(t)*a.m_y-a.m_x*a.m_z+a.m_z)+sqrt(t)*a.m_x+a.m_y*a.m_z)) b.m_z = atan(a.m_z/(sqrt(t)+1)) b.m_w = 0 endfunc static func Tpower(Vector a, Vector b, Vector c, float pfactor, int flagtype) ; T1^T2 = exp(ln(T1)*T2) Vector d = new Vector(0,0,0,0) Vector f = new Vector(0,0,0,0) Sln(a,d) Smult(false,false,b,d,f,pfactor,flagtype) Sexp(f,c) c.m_w = 0 endfunc default: title = "Misc 3D 4D Methods" int param v_3D4D caption = "Version (Misc 3D 4D Methods)" 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_3D4D < 100 endparam } Class LKM { import "common.ulb" ; 3D Mandelbrot ; 3D representation for s = x + ij + jz ; ; Multiplication table for unit vectors: ; ; | r i j ; ------------------ ; r | r i j ; i | i -j -r ; j | j -r -i ; static func LKMsqr(Vector a, Vector b) b.m_x = a.m_x^2 - 2*a.m_y*a.m_z b.m_y = 2*a.m_x*a.m_y - a.m_z^2 b.m_z = 2*a.m_x*a.m_z - a.m_y^2 b.m_w = 0 endfunc static func LKMmult(Vector a, Vector b, Vector c) c.m_x = a.m_x*b.m_x - a.m_y*b.m_z - a.m_z*b.m_y c.m_y = a.m_x*b.m_y + a.m_y*b.m_x - a.m_z*b.m_z c.m_z = a.m_x*b.m_z - a.m_y*b.m_y + a.m_z*b.m_x c.m_w = 0 endfunc ; 3D Mandelbrot2 ; 3D representation for s = x + ij + jz ; ; Multiplication table for unit vectors: ; ; | r i j ; ------------------ ; r | r i j ; i | i -r -j ; j | j -i -r ; static func REBsqr(Vector a, Vector b) b.m_x = a.m_x^2 - a.m_y^2 - a.m_z^2 b.m_y = 2*a.m_x*a.m_y - a.m_y*a.m_z b.m_z = 2*a.m_x*a.m_z - a.m_y*a.m_z b.m_w = 0 endfunc static func REBmult(Vector a, Vector b, Vector c) c.m_x = a.m_x*b.m_x - a.m_y*b.m_z - a.m_z*b.m_y c.m_y = a.m_x*b.m_y + a.m_y*b.m_x - a.m_z*b.m_z c.m_z = a.m_x*b.m_z - a.m_y*b.m_y + a.m_z*b.m_x c.m_w = 0 endfunc default: title = "3D Vector Methods" int param v_3D caption = "Version (3D Vector Methods)" 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_3D < 100 endparam } ;------------------------------------------- ; Mobius Transforms ;------------------------------------------- class Mobius { $define debug ; Creates Mobius transformations in a matrix format.
;

; T(z) = (az+b)/(cz+d)
;

; T is a Mobius Transformation were z, a, b, c and d are complex ; numbers. T is typically represented in normalized matrix form: ;

; T = | a b |
; | c d |
;

; T is normalized if the determinant of ad-bc = 1
;

; A Mobius Transformation can be viewed as a composition of translation, ; scaling and inversion. ;

; The Trace of T is TrT = a+ d public: ; Mobius constructor for T(a, b, c, d) ; @param a = a value ; @param b = b value ; @param c = c value ; @param d = d value func Mobius(complex a, complex b, complex c, complex d) m_a = a m_b = b m_c = c m_d = d m_TrT = m_a + m_d endfunc ; Circle to Mobius func CircToMob(Sphere s) ; Lines and Circles can be represented as Mobius Transforms. Lines and ; Circles are equivalent in Riemann space. For convenience circles are ; represented as sphere objects ; method from Curtis McMullen complex unit = 0 complex im = (0,1) if s.frad <= 0 ; matrix of line unit = cos(-#pi*s.frad) + flip(sin(-#pi*s.frad)) m_a = im*unit m_b = im*(conj(unit)*s.fcen-unit*conj(s.fcen)) m_c = 0 m_d = im*conj(unit) else ; matrix of circle m_a = s.fcen/s.frad m_b = s.frad-|s.fcen|/s.frad m_c = 1/s.frad m_d = -conj(s.fcen)/s.frad endif endfunc ; Mobius to Circle func MobToCirc(int level, int rgen, Sphere s) ; A Mobius Transform can be represented as a Line or Circle. In ; Reimann space a line is a circle with a negative radius. The ; 'level' and 'rgen' arguments are for the Kleinian inversion algorithms ; method from Curtis McMullen float LINEFUZZ = 1e-5 if real(m_c) < LINEFUZZ && real(m_c) > - LINEFUZZ ; matrix to line s.frad = -atan2(m_a)/#pi-1.5 s.fcen = -m_b*m_a/2 else ; matrix to circle s.fcen = m_a/m_c s.frad = cabs(1/real(m_c)) endif s.flevel = level s.fgen = rgen endfunc ; Hermitian to Circle func HermitToCirc(Circle C) ; A Hermitian matrix can be converted to a circle format. ; The method is from David Wright. In Riemann space both circles and ; lines are equivalent. The code handles both. im = (0,1) if m_a != 0 ;Hermitian is for a circle C.fcen = -m_b/m_a C.frad = sqrt(|m_b|-real(m_a)*real(m_d)) \ /cabs(m_a) else ;Hermitian is for a line C.fcen = -m_d/(2*m_c) C.frad = -atan2(im*m_b)/#pi while C.frad > 0 C.frad = C.frad-1 endwhile endif endfunc ; Circle to Hermitian func CircToHermit(Mobius H, Circle C) ; A circle can be converted to a Hermitian matrix. ; The method is from David Wright. In Riemann space both circles and ; lines are equivalent. The code handles both. float vector = tan(-#pi*C.frad) complex im = (0,1) if C.frad > 0 ;calculation for circle H.m_a = 1 H.m_b = -C.fcen H.m_c = conj(H.m_b) H.m_d = |C.fcen|-C.frad^2 else ;calculation for line H.m_a = 0 H.m_b = vector+im H.m_c = conj(H.m_b) H.m_d = -2*imag(C.fcen)*(1+vector^2) endif endfunc ; Mobius on Circle func MobOnCirc(Circle C) ; Applies a Mobius transform to a circle ; The method is from David Wright. In Riemann space both circles and ; lines are equivalent. The code handles both. Mobius I = new Mobius(m_d, -m_b, -m_c, m_a) Mobius CT = new Mobius(conj(I.m_a),conj(I.m_c),conj(I.m_b),conj(I.m_d)) Mobius H = new Mobius(0,0,0,0) this.CircToHermit(H,C) complex temp1 = H.m_a, complex temp2 = H.m_b complex temp3 = H.m_c, complex temp4 = H.m_d H.m_a = temp1*I.m_a+temp2*I.m_c, H.m_b = temp1*I.m_b+temp2*I.m_d H.m_c = temp3*I.m_a+temp4*I.m_c, H.m_d = temp3*I.m_b+temp4*I.m_d temp1 = H.m_a, temp2 = H.m_b temp3 = H.m_c, temp4 = H.m_d H.m_a = CT.m_a*temp1+CT.m_b*temp3, H.m_b = CT.m_a*temp2+CT.m_b*temp4 H.m_c = CT.m_c*temp1+CT.m_d*temp3, H.m_d = CT.m_c*temp2+CT.m_d*temp4 H.HermitToCirc(C) endfunc ; Normalize Mobius func Normalize(Mobius T) complex det = T.m_a*T.m_d-T.m_b*T.m_c det = 1/sqrt(det) T.m_a = m_a*det T.m_b = m_b*det T.m_c = m_c*det T.m_d = m_d*det endfunc ; Invert Mobius func Invert(Mobius T) complex det = m_a*m_d-m_b*m_c T.m_a = m_d T.m_b = -m_b T.m_c = -m_c T.m_d = m_a if real(det) <= 0 T.m_a = -conj(T.m_a) T.m_b = -conj(T.m_b) T.m_c = -conj(T.m_c) T.m_d = -conj(T.m_d) endif endfunc ; Multiplication func Mult(Mobius T1, Mobius T2) ; T2 = T * T1 This does not commute. ; complex det = m_a*m_d-m_b*m_c if real(det) <= 0 T2.m_a = m_a*conj(T1.m_a)+m_b*conj(T1.m_c) T2.m_b = m_a*conj(T1.m_b)+m_b*conj(T1.m_d) T2.m_c = m_c*conj(T1.m_a)+m_d*conj(T1.m_c) T2.m_d = m_c*conj(T1.m_b)+m_d*conj(T1.m_d) else T2.m_a = m_a*T1.m_a+m_b*T1.m_c T2.m_b = m_a*T1.m_b+m_b*T1.m_d T2.m_c = m_c*T1.m_a+m_d*T1.m_c T2.m_d = m_c*T1.m_b+m_d*T1.m_d endif endfunc ; Conjugate func MConj(Mobius T1,Mobius T2) ; T2 = T * T1 * inverse(T) Mobius igen = new Mobius(0,0,0,0) ; Inverse of T this.Invert(igen) Mobius prod1 = new Mobius(0,0,0,0) this.Mult(T1,prod1) prod1.Mult(igen,T2) endfunc ; Mobius Trace complex func Trace() return m_a + m_d endfunc complex m_a complex m_b complex m_c complex m_d complex m_TrT default: title = "Mobius Methods" int param v_mobius caption = "Version (Mobius Methods)" default = 101 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_mobius < 101 endparam } class MobiusArray(Array) { ; class for Mobius Transformation arrays public: import "common.ulb" ; Constructor for Mobius arrays ; @param plength = sets the size of the array func MobiusArray(int plength) setLength(m_T, plength) endfunc ; Get array length int func GetArrayLength() return length(m_T) endfunc ; Set array length func SetArrayLength(int plength) setLength(m_T, plength) endfunc ; Copy array func Copy(MobiusArray &dest) int l = this.GetArrayLength() if (dest == 0) dest = new MobiusArray(l) else dest.SetArrayLength(l) endif int j = 0 while (j < l) dest.m_T[j] = m_T[j] j = j + 1 endwhile endfunc Mobius m_T[] default: title = "Mobius Array" int param v_mobiusarray caption = "Version (Mobius Array)" 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_mobiusarray < 100 endparam } ;------------------------------------------- ; 3D Rotations ;------------------------------------------- Class Rot { import "common.ulb" static func Rotate(float &x, float &y, float &z, float angle, Vector a) float rmatrix[3,3] float cangle = cos(angle*#pi/180) float sangle = sin(angle*#pi/180) rmatrix[0,0] = cangle+a.m_x^2*(1-cangle) rmatrix[1,0] = a.m_x*a.m_y*(1-cangle)-a.m_z*sangle rmatrix[2,0] = a.m_x*a.m_z*(1-cangle)+a.m_y*sangle rmatrix[0,1] = a.m_x*a.m_y*(1-cangle)+a.m_z*sangle rmatrix[1,1] = cangle+a.m_y^2*(1-cangle) rmatrix[2,1] = a.m_y*a.m_z*(1-cangle)-a.m_x*sangle rmatrix[0,2] = a.m_x*a.m_z*(1-cangle)-a.m_y*sangle rmatrix[1,2] = a.m_y*a.m_z*(1-cangle)+a.m_x*sangle rmatrix[2,2] = cangle+a.m_z^2*(1-cangle) float tempx = x float tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endfunc static func RotateX(float &x, float &y, float &z, float angle) float rmatrix[3,3] float cangle = cos(angle*#pi/180) float sangle = sin(angle*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle float tempx = x float tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endfunc static func RotateY(float &x, float &y, float &z, float angle) float rmatrix[3,3] float cangle = cos(angle*#pi/180) float sangle = sin(angle*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle float tempx = x float tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endfunc static func RotateZ(float &x, float &y, float &z, float angle) float rmatrix[3,3] float cangle = cos(angle*#pi/180) float sangle = sin(angle*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 float tempx = x float tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endfunc ; rotations for Turtle orientation using the the Abelson diSessa paradigm. ; The turtle is oriented using three vectors H (heading), L (left) and U (up). ; H x L = U static func RotateH(float &x, float &y, float &z, float angle) float rmatrix[3,3] float cangle = cos(angle*#pi/180) float sangle = sin(angle*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle float tempx = x float tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endfunc static func RotateL(float &x, float &y, float &z, float angle) float rmatrix[3,3] float cangle = cos(angle*#pi/180) float sangle = sin(angle*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = -sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle float tempx = x float tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endfunc static func RotateU(float &x, float &y, float &z, float angle) float rmatrix[3,3] float cangle = cos(angle*#pi/180) float sangle = sin(angle*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = sangle rmatrix[2,0] = 0 rmatrix[0,1] = -sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 float tempx = x float tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endfunc } ;------------------------------------------- ; 5. 3D Object classes ;------------------------------------------- class Point { ; class for creating 3D point objects public: ; Point constructor for (x, y, z) ; @param x = x value ; @param y = y value ; @param z = z value func Point(float x, float y, float z) fx = x fy = y fz = z endfunc float fx float fy float fz default: title = "Point" int param v_point caption = "Version (Point)" 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_point < 100 endparam } class PointArray(Array) { ; class for creating 3D point object arrays public: import "common.ulb" ; Constructor for plane arrays ; @param plength = sets the size of the array func PointArray(int plength) setLength(pt, plength) endfunc ; Get array length int func GetArrayLength() return length(pt) endfunc ; Set array length func SetArrayLength(int plength) setLength(pt, plength) endfunc ; Copy array func Copy(PointArray &dest) int l = this.GetArrayLength() if (dest == 0) dest = new PointArray(l) else dest.SetArrayLength(l) endif int j = 0 while (j < l) dest.pt[j] = pt[j] j = j + 1 endwhile endfunc Point pt[] default: title = "Point Array" int param v_pointarray caption = "Version (Point Array)" 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_pointarray < 100 endparam } class Line { ; class for creating line objects public: import "common.ulb" ; Line constructor for a line defined by 2 points (x1, y1, z1, x2, y2, z2) ; @param x1 = x1 value ; @param y1 = y1 value ; @param z1 = z1 value ; @param x2 = x2 value ; @param y2 = y2 value ; @param z2 = z2 value ; @param vis = line visibility ; @param lcol = line color gradient ; @param dcol = line color direct color ; @param depth = recursion depth ; @param poly = is polygon ; @param lwidth = line width ; @param brratio = branching thickness ratio func Line(float x1, float y1, float z1, float x2, float y2, float z2) fx1 = x1 fy1 = y1 fz1 = z1 fx2 = x2 fy2 = y2 fz2 = z2 llength = sqrt((fx2-fx1)^2 + (fy2-fy1)^2 + (fz2-fz1)^2) vis = true lcol = 0.5 depth = 0 lwidth = 1 dcol = rgba(1,1,1,1) poly = false brratio = 1 sign = 1 jump = false endfunc func SetLength() llength = sqrt((fx2-fx1)^2 + (fy2-fy1)^2 + (fz2-fz1)^2) endfunc func SetVis(bool svis) vis = svis endfunc func SetJump(bool sjump) jump = sjump endfunc func SetGradCol(float gradcol) lcol = gradcol endfunc func SetWidth(float width) lwidth = width endfunc func SetDirectColor(color dcolor) dcol = dcolor endfunc func SetDepth(int j) depth = j endfunc func SetPoly(bool ispoly) poly = ispoly endfunc func SetBranchRatio(float branchratio) brratio = branchratio endfunc func SetSign(float sign) sign = sign/abs(sign) endfunc func GetVector(Vector &vec) float x2 = fx2-fx1 float y2 = fy2-fy1 float z2 = fz2-fz1 vec = new Vector(x2,y2,z2,0) vec.Normalize(vec) endfunc func Resize(float setsize) fx1 = setsize*fx1 fy1 = setsize*fy1 fz1 = setsize*fz1 fx2 = setsize*fx2 fy2 = setsize*fy2 fz2 = setsize*fz2 llength = sqrt((fx2-fx1)^2 + (fy2-fy1)^2 + (fz2-fz1)^2) endfunc ; rotate around the point x1, y1, z1 func Rotate(float theta) float x1 = fx1-x1 float y1 = fy1-y1 float z1 = fz1-z1 float x2 = fx2-x1 float y2 = fy2-y1 float z2 = fz2-z1 vector vec = new Vector(x2,y2,z2,0) rot.rotate(x2,y2,z2,theta,vec) fx2 = x2+x1 fy2 = y2+y1 fz2 = z2+z1 endfunc float llength float lwidth float fx1 float fy1 float fz1 float fx2 float fy2 float fz2 bool vis float lcol color dcol int depth bool poly float brratio float sign bool jump default: title = "Line" int param v_line caption = "Version (Line)" 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_line < 100 endparam } class LineArray(Array) { ; class for creating 3D point object arrays public: import "common.ulb" ; Constructor for line arrays ; @param plength = sets the size of the array func LineArray(int plength) setLength(line, plength) endfunc ; Get array length int func GetArrayLength() return length(line) endfunc ; Set array length func SetArrayLength(int plength) setLength(line, plength) endfunc ; Copy array func Copy(LineArray &dest) int l = this.GetArrayLength() if (dest == 0) dest = new LineArray(l) else dest.SetArrayLength(l) endif int j = 0 while (j < l) dest.line[j] = line[j] j = j + 1 endwhile endfunc Line line[] default: title = "LineArray" int param v_linearray caption = "Version (Line Array)" 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_linearray < 100 endparam } class Plane { ; class for creating plane objects public: ; Plane constructor for Ax + By + C = 0 ; @param A = A value ; @param B = B value ; @param C = C value ; @param D = D value func Plane(float A, float B, float C, float D) float norm = sqrt(A^2+B^2+C^2) pnx = A/norm pny = B/norm pnz = C/norm pspot = D/norm pa = A pb = B pc = C pd = D endfunc ; Is a point on the plane bool func OnPlane(float x, float y, float z, float tol) bool opl = false if (pa*x+pb*y+pc*z+pd < tol) && (pa*x+pb*y+pc*z+pd > -tol) opl = true endif return opl endfunc float pnx float pny float pnz float pspot float pa float pb float pc float pd default: title = "Plane" int param v_plane caption = "Version (Plane)" 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_plane < 100 endparam } class PlaneArray(Array) { ; class for creating plane object arrays public: import "common.ulb" ; Constructor for plane arrays. func PlaneArray(int plength) setLength(pl, plength) endfunc ; Get array length int func GetArrayLength() return length(pl) endfunc ; Set array length func SetArrayLength(int plength) setLength(pl, plength) endfunc ; Copy array func Copy(PlaneArray &dest) int l = this.GetArrayLength() if (dest == 0) dest = new PlaneArray(l) else dest.SetArrayLength(l) endif int j = 0 while (j < l) dest.pl[j] = pl[j] j = j + 1 endwhile endfunc Plane pl[] default: title = "Plane Array" int param v_planearray caption = "Version (Plane Array)" 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_planearray < 100 endparam } class Triangle { ; class for creating triangle objects public: import "Common.ulb" ; Triangle constructor for (x1, y1, z1, x2, y2, z2, x3, y3, z3) ; @param x1 = x1 value ; @param y1 = y1 value ; @param z1 = z1 value ; @param x2 = x2 value ; @param y2 = y2 value ; @param z2 = z2 value ; @param x2 = x3 value ; @param y2 = y3 value ; @param z2 = z3 value func Triangle(float x1, float y1, float z1, float x2, float y2, float z2, \ float x3, float y3, float z3) fx1 = x1 fy1 = y1 fz1 = z1 fx2 = x2 fy2 = y2 fz2 = z2 fx3 = x3 fy3 = y3 fz3 = z3 r_fz1 = z1 r_fz2 = z2 r_fz3 = z3 t_norm = new Vector(0,0,0,0) Norm() t_norm.Normalize(t_norm) ; P*N + pspot = 0 this is the equation for the plane of the triangle pspot = -(t_norm.m_x*fx1+t_norm.m_y*fy1+t_norm.m_z*fz1) endfunc ; used to re-initialize the triangle parameters func Init(float x1, float y1, float z1, float x2, float y2, float z2, \ float x3, float y3, float z3) fx1 = x1 fy1 = y1 fz1 = z1 fx2 = x2 fy2 = y2 fz2 = z2 fx3 = x3 fy3 = y3 fz3 = z3 Norm() t_norm.Normalize(t_norm) ; P*N + pspot = 0 this is the equation for the plane of the triangle pspot = -(t_norm.m_x*fx1+t_norm.m_y*fy1+t_norm.m_z*fz1) xy_ave = (fx1+fx2+fx3)/3 + flip((fy1+fy2+fy3)/3) z_ave = (fz1+fz2+fz3)/3 endfunc ; 1 -> 2 ->3 must be counterclockwise func Norm() Vector V1 = new Vector(fx1-fx2, fy1-fy2, fz1-fz2, 0) Vector V2 = new Vector(fx3-fx2, fy3-fy2, fz3-fz2, 0) V1.Cross(V2, t_norm) t_norm.m_w = 0 endfunc ; determine vector from camera to center of triangle float fx1 float fy1 float fz1 float fx2 float fy2 float fz2 float fx3 float fy3 float fz3 float r_fz1 float r_fz2 float r_fz3 Vector t_norm float pspot complex xy_ave float z_ave default: title = "Triangle" int param v_triangle caption = "Version (Triangle)" 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_triangle < 100 endparam } class TriangleArray(Array) { ; class for creating 3D Triangle object arrays public: import "common.ulb" ; Constructor for triangle arrays ; @param plength = sets the size of the array func TriangleArray(int plength) setLength(tr, plength) endfunc ; Get array length int func GetArrayLength() return length(tr) endfunc ; Set array length func SetArrayLength(int plength) setLength(tr, plength) endfunc ; Copy array func Copy(TriangleArray &dest) int l = this.GetArrayLength() if (dest == 0) dest = new TriangleArray(l) else dest.SetArrayLength(l) endif int j = 0 while (j < l) dest.tr[j] = tr[j] j = j + 1 endwhile endfunc Triangle tr[] default: title = "Triangle Array" int param v_Trianglearray caption = "Version (Triangle Array)" 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_Trianglearray < 100 endparam } class Sphere { ; class for creating sphere objects
;

; The sphere object contains arguments for recursion level and ; generator sphere identifier for facilitate use with Sphere ; Inversions public: ; Sphere constructor ; @param center = (x,y) coordinates of the sphere center ; @param height = z coordinate of sphere center ; @param radius = sphere radius ; @param level = recursion level of the sphere ; @param generator = index of generator sphere func Sphere(complex center, float height, float radius, int level, int generator) fCen = center fRad = radius fZ = height fLevel = level fGen = generator endfunc int fLevel complex fCen float fRad float fZ int fGen default: title = "Sphere" int param v_sphere caption = "Version (Sphere)" 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_sphere < 100 endparam } class SphereArray(Array) { ; class for sphere arrays public: import "common.ulb" ; Sphere array constructor ; @param plength = size of the sphere array func SphereArray(int plength) setLength(sph, plength) endfunc ; Get array length int func GetArrayLength() return length(sph) endfunc ; Set array length func SetArrayLength(int plength) setLength(sph, plength) endfunc ; Copy Array ; @param dest = SphereArray object to copy all values into ; previous contents of dest will be discarded. func Copy(SphereArray &dest) int l = this.GetArrayLength() if (dest == 0) dest = new SphereArray(l) else dest.SetArrayLength(l) endif int j = 0 while (j < l) dest.sph[j] = sph[j] j = j + 1 endwhile endfunc Sphere sph[] default: title = "Sphere Array" int param v_spherearray caption = "Version (Sphere Array)" 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_spherearray < 100 endparam } class Circle { ; class for creating circle objects
;

public: ; Circle constructor ; @param center = (x,y) coordinates of the sphere center ; @param radius = sphere radius func Circle(complex center, float radius) fCen = center fRad = radius endfunc complex fCen float fRad default: title = "Circle" int param v_circle caption = "Version (Circle)" 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_circle < 100 endparam } class CircleArray(Array) { ; class for circle arrays public: import "common.ulb" ; Circle array constructor ; @param plength = size of the circle array func CircleArray(int plength) setLength(cir, plength) endfunc ; Get array length int func GetArrayLength() return length(cir) endfunc ; Set array length func SetArrayLength(int plength) setLength(cir, plength) endfunc ; Copy Array ; @param dest = CircleArray object to copy all values into ; previous contents of dest will be discarded. func Copy(CircleArray &dest) int l = this.GetArrayLength() if (dest == 0) dest = new CircleArray(l) else dest.SetArrayLength(l) endif int j = 0 while (j < l) dest.cir[j] = cir[j] j = j + 1 endwhile endfunc Circle cir[] default: title = "Circle Array" int param v_circlearray caption = "Version (Circle Array)" 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_circlearray < 100 endparam } ;-------------------------------------------- ; 3D Inversion Classes ;-------------------------------------------- Class InvertSphere(common.ulb:Generic) { ; 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
; $define debug 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 if target != 0 && inverter != 0 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) else return new Sphere((0,0),0,0,0,0) endif 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 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 if sa.sph[child] != 0 && sa.sph[child+1] != 0 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 else dx = 0 dy = 0 dz = 0 dr = 0 endif 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 if sa.sph[child] != 0 && sa.sph[root] != 0 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 else dx = 0 dy = 0 dz = 0 dr = 0 endif 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 if sa.sph[ir] != 0 && sa.sph[ir-1] != 0 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 else dx = 0 dy = 0 dz = 0 dr = 0 endif 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 endparam int param maxLevel caption = "Recursion level" default = 2 min = 0 max = 1000 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 } Class InvertCube(InvertSphere) { ; sphere inversions starting with a cubic geometery
; this is a child of InvertSphere public: import "common.ulb" ; constructor for sphere inversions with a cubic geometry func InvertCube(Generic pparent) InvertSphere.InvertSphere(0) fscle = 3 + sqrt(3), fbaserad = sqrt(6)+sqrt(2) scale = 0.34, fii = 7, fjj = 9, fks = 8, fk = fks, rlevel = 25 initSpheres() endfunc ; Initializes base and generator spheres func InitSpheres() complex Fc[16] float Fz[16] float Fr[16] int i = 0 complex grot = exp(flip(1)*#pi/2) while i < 4 Fc[i] = (1,0)*grot^i*fscle Fz[i] = 0 Fr[i] = fbaserad i = i + 1 endwhile Fc[4] = Fc[5] = Fc[6] = (0,0) Fz[4] = fscle Fz[5] = -fscle Fz[6] = 0 Fr[4] = Fr[5] = fbaserad Fr[6] = sqrt(2) i = 7 while i < 15 Fc[i] = (1,1)*grot^(i-7) if i < 11 Fz[i] = 1 else Fz[i] = -1 endif Fr[i] = 1 i = i + 1 endwhile Fc[i] = (0,0) Fz[i] = 0 Fr[i] = 1+sqrt(3) ; 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 > 6 Fr[i] = Fr[i]*#magn*scale*@bradadj else Fr[i] = Fr[i]*#magn*scale*@radadj endif i = i+1 until i == 16 ; declare the generator spheres ; ; cube i = 0 while i < 7 fg[i] = new Sphere(Fc[i],Fz[i],Fr[i],0,i) i = i + 1 endwhile ; ; declare the base Spheres ; ; cube while i < 16 fb[i-7] = new Sphere(Fc[i],Fz[i],Fr[i],0,i-7) i = i + 1 endwhile bradius = fb[0].frad i = 0 while i < 8 s.sph[i] = fb[i] i = i + 1 endwhile endfunc default: title = "Cube" int param v_cube caption = "Version (Cube)" 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_cube < 100 endparam } Class InvertOctahedron(InvertSphere) { ; sphere inversions starting with a octahedral geometery
; this is a child of InvertSphere public: import "common.ulb" ; constructor for sphere inversions with an octahedral geometry func InvertOctahedron(Generic pparent) InvertSphere.InvertSphere(0) fscle = 1+sqrt(2)/2, fbaserad = 1+sqrt(2), scale = 0.5, fii = 9, fjj = 7 fks = 6, fk = fks, rlevel = 25 initSpheres() endfunc ; Initializes base and generator spheres func InitSpheres() complex Fc[22] float Fz[22] float Fr[22] Fc[0] = (1,1)*fscle, Fc[1] = (-1,1)*fscle, Fc[2] = (1,-1)*fscle, Fc[3] = (1,1)*fscle Fc[4] = (-1,-1)*fscle, Fc[5] = (-1,1)*fscle, Fc[6] = (1,-1)*fscle, Fc[7] = (-1,-1)*fscle Fc[8] = (0,0), Fc[9] = (1,0), Fc[10] = (0,-1), Fc[11] = (0,0), Fc[12] = (-1,0) Fc[13] = (0,1), Fc[14] = (0,0), Fc[15] = (0,0), Fc[16] = (1,0), Fc[17] = (0,-1) Fc[18] = (0,0), Fc[19] = (-1,0), Fc[20] = (0,1), Fc[21] = (0,0) Fz[0] = fscle, Fz[1] = fscle, Fz[2] = fscle, Fz[3] = -fscle, Fz[4] = fscle Fz[5] = -fscle, Fz[6] = -fscle, Fz[7] = -fscle, Fz[8] = 0, Fz[9] = 0, Fz[10] = 0 Fz[11] = 1, Fz[12] = 0, Fz[13] = 0, Fz[14] = -1, Fz[15] = 0, Fz[16] = 0 Fz[17] = 0, Fz[18] = 1, Fz[19] = 0, Fz[20] = 0, Fz[21] = -1 Fr[0] = fbaserad, Fr[1] = fbaserad, Fr[2] = fbaserad, Fr[3] = fbaserad, Fr[4] = fbaserad Fr[5] = fbaserad, Fr[6] = fbaserad, Fr[7] = fbaserad, Fr[8] = sqrt(2)/2, Fr[9] = sqrt(2)/2 Fr[10] = sqrt(2)/2, Fr[11] = sqrt(2)/2, Fr[12] = sqrt(2)/2, Fr[13] = sqrt(2)/2 Fr[14] = sqrt(2)/2, Fr[15] = 1+sqrt(2)/2, Fr[16] = sqrt(2)/2, Fr[17] = sqrt(2)/2 Fr[18] = sqrt(2)/2, Fr[19] = sqrt(2)/2, Fr[20] = sqrt(2)/2, Fr[21] = sqrt(2)/2 int i = 0 ; scale and translate the spheres to screen dimensions ; 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 > 8 Fr[i] = Fr[i]*#magn*scale*@bradadj else Fr[i] = Fr[i]*#magn*scale*@radadj endif i = i+1 until i == 22 ; declare the generator spheres ; ; octahedron fg[0] = new Sphere(Fc[0],Fz[0],Fr[0],0,0), fg[1] = new Sphere(Fc[1],Fz[1],Fr[1],0,1) fg[2] = new Sphere(Fc[2],Fz[2],Fr[2],0,2), fg[3] = new Sphere(Fc[3],Fz[3],Fr[3],0,3) fg[4] = new Sphere(Fc[4],Fz[4],Fr[4],0,4), fg[5] = new Sphere(Fc[5],Fz[5],Fr[5],0,5) fg[6] = new Sphere(Fc[6],Fz[6],Fr[6],0,6), fg[7] = new Sphere(Fc[7],Fz[7],Fr[7],0,7) fg[8] = new Sphere(Fc[8],Fz[8],Fr[8],0,8) ; ; declare the base Spheres ; ; octahedron fb[0] = new Sphere(Fc[9],Fz[9],Fr[9],0,0), fb[1] = new Sphere(Fc[10],Fz[10],Fr[10],0,1) fb[2] = new Sphere(Fc[11],Fz[11],Fr[11],0,2), fb[3] = new Sphere(Fc[12],Fz[12],Fr[12],0,3) fb[4] = new Sphere(Fc[13],Fz[13],Fr[13],0,4), fb[5] = new Sphere(Fc[14],Fz[14],Fr[14],0,5) fb[6] = new Sphere(Fc[15],Fz[15],Fr[15],0,6) bradius = fb[0].frad s.sph[0] = new Sphere(Fc[16],Fz[16],Fr[16],0,0), s.sph[1] = new Sphere(Fc[17],Fz[17],Fr[17],0,1) s.sph[2] = new Sphere(Fc[18],Fz[18],Fr[18],0,2), s.sph[3] = new Sphere(Fc[19],Fz[19],Fr[19],0,3) s.sph[4] = new Sphere(Fc[20],Fz[20],Fr[20],0,4), s.sph[5] = new Sphere(Fc[21],Fz[21],Fr[21],0,5) endfunc default: title = "Octahedron" int param v_octahedron caption = "Version (Octahedron)" 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_octahedron < 100 endparam } Class InvertDodecahedron(InvertSphere) { ; sphere inversions starting with a dodecahedral geometery
; this is a child of InvertSphere public: import "common.ulb" ; constructor for sphere inversions with a dodecahedral geometry func InvertDodecahedron(Generic pparent) InvertSphere.InvertSphere(0) p = (1+sqrt(5))/2, ip = 1/p, fscle = (3+sqrt(3)*(p-1))/(p+1), fbaserad = fscle*2*sqrt(3)/3 scale = 0.4, fii = 13, fjj = 21, fks = 20, fk = fks, rlevel = 181 initSpheres() endfunc ; Initializes base and generator spheres func InitSpheres() complex Fc[54] float Fz[54] float Fr[54] Fc[0] = (1,0)*fscle, Fc[1] = (1,0)*fscle, Fc[2] = (-1,0)*fscle, Fc[3] = (-1,0)*fscle Fc[4] = flip(p)*fscle, Fc[5] = flip(p)*fscle, Fc[6] = -flip(p)*fscle, Fc[7] = -flip(p)*fscle Fc[8] = (p+flip(1))*fscle, Fc[9] = (p-flip(1))*fscle, Fc[10] = (-p+flip(1))*fscle Fc[11] = (-p-flip(1))*fscle, Fc[12] = (0,0), Fc[13] = (1,1), Fc[14] = (-1,1) Fc[15] = (1,-1), Fc[16] = (1,1), Fc[17] = (-1,-1), Fc[18] = (-1,1), Fc[19] = (1,-1) Fc[20] = (-1,-1), Fc[21] = flip(ip), Fc[22] = -flip(ip), Fc[23] = flip(ip) Fc[24] = -flip(ip), Fc[25] = ip+flip(p), Fc[26] = -ip+flip(p), Fc[27] = ip-flip(p) Fc[28] = -ip-flip(p), Fc[29] = p, Fc[30] = -p, Fc[31] = p, Fc[32] = -p, Fc[33] = (0,0) Fc[34] = (1,1), Fc[35] = (-1,1), Fc[36] = (1,-1), Fc[37] = (1,1), Fc[38] = (-1,-1) Fc[39] = (-1,1), Fc[40] = (1,-1), Fc[41] = (-1,-1), Fc[42] = flip(ip), Fc[43] = -flip(ip) Fc[44] = flip(ip), Fc[45] = -flip(ip), Fc[46] = ip+flip(p), Fc[47] = -ip+flip(p) Fc[48] = ip-flip(p), Fc[49] = -ip-flip(p), Fc[50] = p, Fc[51] = -p, Fc[52] = p, Fc[53] = -p Fz[0] = p*fscle, Fz[1] = -p*fscle, Fz[2] = p*fscle, Fz[3] = -p*fscle, Fz[4] = fscle Fz[5] = -fscle, Fz[6] = fscle, Fz[7] = -fscle, Fz[8] = 0, Fz[9] = 0, Fz[10] = 0 Fz[11] = 0, Fz[12] = 0, Fz[13] = 1, Fz[14] = 1, Fz[15] = 1, Fz[16] = -1, Fz[17] = 1 Fz[18] = -1, Fz[19] = -1, Fz[20] = -1, Fz[21] = p, Fz[22] = p, Fz[23] = -p,, Fz[24] = -p Fz[25] = 0, Fz[26] = 0, Fz[27] = 0, Fz[28] = 0, Fz[29] = ip, Fz[30] = ip, Fz[31] = -ip Fz[32] = -ip, Fz[33] = 0, Fz[34] = 1, Fz[35] = 1, Fz[36] = 1, Fz[37] = -1, Fz[38] = 1 Fz[39] = -1, Fz[40] = -1, Fz[41] = -1, Fz[42] = p, Fz[43] = p, Fz[44] = -p Fz[45] = -p, Fz[46] = 0, Fz[47] = 0, Fz[48] = 0, Fz[49] = 0, Fz[50] = ip, Fz[51] = ip Fz[52] = -ip, Fz[53] = -ip Fr[0] = fbaserad, Fr[1] = fbaserad, Fr[2] = fbaserad, Fr[3] = fbaserad, Fr[4] = fbaserad Fr[5] = fbaserad, Fr[6] = fbaserad, Fr[7] = fbaserad, Fr[8] = fbaserad, Fr[9] = fbaserad Fr[10] = fbaserad, Fr[11] = fbaserad, Fr[12] = p, Fr[13] = p-1, Fr[14] = p-1 Fr[15] = p-1, Fr[16] = p-1, Fr[17] = p-1, Fr[18] = p-1, Fr[19] = p-1, Fr[20] = p-1 Fr[21] = p-1, Fr[22] = p-1, Fr[23] = p-1, Fr[24] = p-1, Fr[25] = p-1, Fr[26] = p-1 Fr[27] = p-1, Fr[28] = p-1, Fr[29] = p-1, Fr[30] = p-1, Fr[31] = p-1, Fr[32] = p-1 Fr[33] = sqrt(3)+p-1, Fr[34] = p-1, Fr[35] = p-1, Fr[36] = p-1, Fr[37] = p-1 Fr[38] = p-1, Fr[39] = p-1, Fr[40] = p-1, Fr[41] = p-1, Fr[42] = p-1, Fr[43] = p-1 Fr[44] = p-1, Fr[45] = p-1, Fr[46] = p-1, Fr[47] = p-1, Fr[48] = p-1, Fr[49] = p-1 Fr[50] = p-1, Fr[51] = p-1, Fr[52] = p-1, Fr[53] = p-1 int i = 0 ; scale and translate the spheres to screen dimensions ; 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 > 12 Fr[i] = Fr[i]*#magn*scale*@bradadj else Fr[i] = Fr[i]*#magn*scale*@radadj endif i = i+1 until i == 54 ; declare the generator spheres ; ; dodecahedron fg[0] = new Sphere(Fc[0],Fz[0],Fr[0],0,0), fg[1] = new Sphere(Fc[1],Fz[1],Fr[1],0,1) fg[2] = new Sphere(Fc[2],Fz[2],Fr[2],0,2), fg[3] = new Sphere(Fc[3],Fz[3],Fr[3],0,3) fg[4] = new Sphere(Fc[4],Fz[4],Fr[4],0,4), fg[5] = new Sphere(Fc[5],Fz[5],Fr[5],0,5) fg[6] = new Sphere(Fc[6],Fz[6],Fr[6],0,6), fg[7] = new Sphere(Fc[7],Fz[7],Fr[7],0,7) fg[8] = new Sphere(Fc[8],Fz[8],Fr[8],0,8), fg[9] = new Sphere(Fc[9],Fz[9],Fr[9],0,9) fg[10] = new Sphere(Fc[10],Fz[10],Fr[10],0,10), fg[11] = new Sphere(Fc[11],Fz[11],Fr[11],0,11) fg[12] = new Sphere(Fc[12],Fz[12],Fr[12],0,12) ; ; declare the base Spheres ; ; dodecahedron fb[0] = new Sphere(Fc[13],Fz[13],Fr[13],0,0), fb[1] = new Sphere(Fc[14],Fz[14],Fr[14],0,1) fb[2] = new Sphere(Fc[15],Fz[15],Fr[15],0,2), fb[3] = new Sphere(Fc[16],Fz[16],Fr[16],0,3) fb[4] = new Sphere(Fc[17],Fz[17],Fr[17],0,4), fb[5] = new Sphere(Fc[18],Fz[18],Fr[18],0,5) fb[6] = new Sphere(Fc[19],Fz[19],Fr[19],0,6), fb[7] = new Sphere(Fc[20],Fz[20],Fr[20],0,7) fb[8] = new Sphere(Fc[21],Fz[21],Fr[21],0,8), fb[9] = new Sphere(Fc[22],Fz[22],Fr[22],0,9) fb[10] = new Sphere(Fc[23],Fz[23],Fr[23],0,10), fb[11] = new Sphere(Fc[24],Fz[24],Fr[24],0,11) fb[12] = new Sphere(Fc[25],Fz[25],Fr[25],0,12), fb[13] = new Sphere(Fc[26],Fz[26],Fr[26],0,13) fb[14] = new Sphere(Fc[27],Fz[27],Fr[27],0,14), fb[15] = new Sphere(Fc[28],Fz[28],Fr[28],0,15) fb[16] = new Sphere(Fc[29],Fz[29],Fr[29],0,16), fb[17] = new Sphere(Fc[30],Fz[30],Fr[30],0,17) fb[18] = new Sphere(Fc[31],Fz[31],Fr[31],0,18), fb[19] = new Sphere(Fc[32],Fz[32],Fr[32],0,19) fb[20] = new Sphere(Fc[33],Fz[33],Fr[33],0,20) bradius = fb[0].frad s.sph[0] = new Sphere(Fc[34],Fz[34],Fr[34],0,0), s.sph[1] = new Sphere(Fc[35],Fz[35],Fr[35],0,1) s.sph[2] = new Sphere(Fc[36],Fz[36],Fr[36],0,2), s.sph[3] = new Sphere(Fc[37],Fz[37],Fr[37],0,3) s.sph[4] = new Sphere(Fc[38],Fz[38],Fr[38],0,4), s.sph[5] = new Sphere(Fc[39],Fz[39],Fr[39],0,5) s.sph[6] = new Sphere(Fc[40],Fz[40],Fr[40],0,6), s.sph[7] = new Sphere(Fc[41],Fz[41],Fr[41],0,7) s.sph[8] = new Sphere(Fc[42],Fz[42],Fr[42],0,8), s.sph[9] = new Sphere(Fc[43],Fz[43],Fr[43],0,9) s.sph[10] = new Sphere(Fc[44],Fz[44],Fr[44],0,10), s.sph[11] = new Sphere(Fc[45],Fz[45],Fr[45],0,11) s.sph[12] = new Sphere(Fc[46],Fz[46],Fr[46],0,12), s.sph[13] = new Sphere(Fc[47],Fz[47],Fr[47],0,13) s.sph[14] = new Sphere(Fc[48],Fz[48],Fr[48],0,14), s.sph[15] = new Sphere(Fc[49],Fz[49],Fr[49],0,15) s.sph[16] = new Sphere(Fc[50],Fz[50],Fr[50],0,16), s.sph[17] = new Sphere(Fc[51],Fz[51],Fr[51],0,17) s.sph[18] = new Sphere(Fc[52],Fz[52],Fr[52],0,18), s.sph[19] = new Sphere(Fc[53],Fz[53],Fr[53],0,19) endfunc float p float ip default: title = "Dodecahedron" int param v_dodecahedron caption = "Version (Dodecahedron)" 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_dodecahedron < 100 endparam } Class InvertCircles(InvertSphere) { ; ; circle inversions
;

; This is a child of InvertSphere. For the case of 3 base circles ; (Apollonian Gasket) methods for perturbation of the initiating circles ; are available. ;

$define debug public: import "common.ulb" ; constructor for circle inversions using spheres func InvertCircles(Generic pparent) InvertSphere.InvertSphere(0) ang = 2*#pi/@ncircle ipi = flip(#pi) cpi = flip(#pi/@ncircle) complex cr1 = exp((0,0)*ang+ipi) complex cr2 = exp((0,1)*ang+ipi) float rdd = cabs(cr1-cr2)/2 dd = cabs(cr1) float dtan = sqrt(dd*dd-rdd*rdd) fscle = (dd+rdd)/dtan pert = @pert pert = 11 - pert fscle2 = 1 fbaserad = fscle*2*sqrt(3)/3 fii = @ncircle+1 fjj = @ncircle+1 fks = @ncircle fk = fks g = 0 b = 0 circles = true showc = @showc lace = @lace if @ncircle == 3 rlevel = 4 scale = 0.5 if @ptype == "Inner Circle" && pert <= 2 cir3 = true endif if @ptype == "None" fscle = 2 + sqrt(3) fscle2 = 1 elseif @ptype == "Outer Circles" fscle = (2 + sqrt(3))*cos(#pi/(pert+6)) fscle2 = (fscle-sqrt(3)-1.5)/0.5 else if pert == 10 fscle2 = 1.0041268407 elseif pert == 9 fscle2 = 1.0049465720 elseif pert == 8 fscle2 = 1.0060422243 elseif pert == 7 fscle2 = 1.0075560883 elseif pert == 6 fscle2 = 1.0097381547 elseif pert == 5 fscle2 = 1.0130643119 elseif pert == 4 fscle2 = 1.0185254 elseif pert == 3 fscle2 = 1.0286754 elseif pert == 2 fscle2 = 1.0515254 elseif pert == 1 fscle2 = 1.1277437913 endif endif elseif @ncircle == 4 rlevel = 9 scale = 0.55 elseif @ncircle == 5 rlevel = 16 scale = 0.6 elseif @ncircle == 6 rlevel = 25 scale = 0.65 elseif @ncircle == 7 rlevel = 36 scale = 0.65 elseif @ncircle == 8 rlevel = 49 scale = 0.7 elseif @ncircle == 9 rlevel = 64 scale = 0.7 elseif @ncircle == 10 rlevel = 81 scale = 0.7 elseif @ncircle == 11 rlevel = 100 scale = 0.7 elseif @ncircle == 12 rlevel = 121 scale = 0.7 endif initSpheres() endfunc ; Initializes base and generator spheres func InitSpheres() complex Fc[26] float Fz[26] float Fr[26] ; generator set int i = 0 while i < @ncircle Fc[i] = exp(flip(i)*ang+ipi)*fscle Fz[i] = 0 i = i + 1 endwhile Fc[i] = 0 if @ncircle == 3 Fr[0] = sqrt(3)+1.5 else Fr[0] = cabs(Fc[0]-Fc[1])/2 endif i = 1 while i < @ncircle Fr[i] = Fr[0] i = i + 1 endwhile if @ncircle == 3 if @ptype == "None" Fr[3] = 0.5 elseif @ptype == "Outer Circles" Fr[3] = fscle-sqrt(3)-1.5 elseif @ptype == "Inner Circle" if pert == 10 Fr[3] = 0.5151714074 elseif pert == 9 Fr[3] = 0.5181320854 elseif pert == 8 Fr[3] = 0.5220631074 elseif pert == 7 Fr[3] = 0.5274464005 elseif pert == 6 Fr[3] = 0.5351105381 elseif pert == 5 Fr[3] = 0.5465863845 elseif pert == 4 Fr[3] = 0.564987 elseif pert == 3 Fr[3] = 0.597588 elseif pert == 2 Fr[3] = 0.665053 elseif pert == 1 Fr[3] = 0.8524941755 endif endif else Fr[i] = cabs(Fc[0])-Fr[0] endif g = i ; Base set i = i + 1 if @ncircle%2 == 0 while i < 2*@ncircle+1 Fc[i] = exp(flip(i-4)*ang+cpi)*fscle2 Fz[i] = 0 i = i + 1 endwhile else sflag = false while i < 2*@ncircle+1 Fc[i] = exp(flip(i-3)*ang)*fscle2 Fz[i] = 0 i = i + 1 endwhile endif Fc[i] = 0 if @ncircle == 3 if @ptype == "Outer Circles" || @ptype == "None" Fr[4] = sqrt(3)/2*fscle2 Fr[7] = Fr[4]+fscle2 elseif @ptype == "Inner Circle" if pert == 10 Fr[4] = 0.8618985631 elseif pert == 9 Fr[4] = 0.8610788318 elseif pert == 8 Fr[4] = 0.8599831795 elseif pert == 7 Fr[4] = 0.8584693155 elseif pert == 6 Fr[4] = 0.8562872491 elseif pert == 5 Fr[4] = 0.8529610919 elseif pert == 4 Fr[4] = 0.8475 elseif pert == 3 Fr[4] = 0.83735 elseif pert == 2 Fr[4] = 0.8145 elseif pert == 1 Fr[4] = 0.7382816125 endif Fr[7] = Fr[4] + 1 endif else Fr[@ncircle+1] = cabs(Fc[@ncircle+1]-Fc[@ncircle+2])/2 endif i = @ncircle+2 while i < 2*@ncircle+1 Fr[i] = Fr[@ncircle+1] i = i + 1 endwhile if @ncircle != 3 dd = cabs(Fc[0]) Fr[i] = sqrt(dd*dd-Fr[0]*Fr[0]) endif b = i i = 0 ; scale and translate the spheres to screen dimensions ; 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 > 12 Fr[i] = Fr[i]*#magn*scale*@bradadj else Fr[i] = Fr[i]*#magn*scale*@radadj endif i = i+1 until i == 2*@ncircle+2 ; ; declare the generator spheres i = 0 while i <= g fg[i] = new Sphere(Fc[i],Fz[i],Fr[i],0,i) i = i + 1 endwhile ; declare the base Spheres i = 0 while i <= g fb[i] = new Sphere(Fc[i+g+1],Fz[i+g+1],Fr[i+g+1],0,i) i = i + 1 endwhile bradius = fb[0].frad i = 0 while i <= g s.sph[i] = fb[i] i = i + 1 endwhile endfunc int g int b float ang complex ipi complex cpi float dd int pert float fscle2 bool showc default: title = "Circle Inversions" int param v_invcircle caption = "Version (Circle Inversions)" 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_invcircle < 100 endparam int param ncircle caption = "# of Circles (3-12)" default = 3 min = 3 max = 12 endparam int param maxLevel caption = "Recursion level" default = 20 min = 0 max = 200 endparam bool param showc caption = "Show Center Circle" default = true endparam bool param lace caption = "Display as Lace" default = false visible = @ptype == "Inner Circle" && (@pert >=8) && @ncircle == 3 endparam heading text = "Perturbation of Inversion Circles \ by overlap." visible = @ncircle == 3 endheading param ptype caption = "Perturb Type" default = 0 enum = "None" "Outer Circles" "Inner Circle" visible = @ncircle == 3 endparam param pert caption = "Perturb Level (1-10)" default = 1 min = 1 max = 10 visible = @ptype != "None" && @ncircle == 3 endparam float param xang caption = "X Axis Rotation" default = 0.0 endparam float param yang caption = "Y Axis Rotation" default = 0.0 endparam } class InvertMobius(InvertSphere) { ;

; Derived from the public C code of Curtis McMullen and ; material from Indra's Pearls by Mumford, Series and Wright ; A new method for InitSpheres is needed, as both spheres ; and Kleinian Group matricies must be initalized. ; public: import "common.ulb" $define debug ; constructor for Mobius (Kleinian) sphere inversions func InvertMobius(Generic pparent) invertSphere.Invertsphere(0) PARAFUZZ = 1e-3, LINEFUZZ = 1e-5, im = (0,1),gi = 0 fii = 4, fks = 1, fk = fks, scale = 0.7, sscale = 1, iend = 4 ss = new SphereArray(50000000) InitSpheresK() endfunc ; Initialize spheres, inversion matricies and trace values func InitSpheresK() ; This function initializes the base sphere(s), the Kleinian group ; inversion matrices and the trace values complex Fc[4] float Fz[4] float Fr[4] int i = 0 complex ta = @ta complex tb = @tb float cir = @cir complex cira = @cira Complex cirs = @cirs float rada = @rada float rads = @rads float radam = @radam complex m = @m complex tab = 0 complex gz0 = 0 complex gz = 0 complex gQ = 0 complex gR = 0 complex tabAB = @tabAB Fz[0] = 0 Fz[1] = 0 Fz[2] = 0 Fz[3] = 0 if @cusptype == "Nearby group" ta = (1.91,-0.05) tb = (2,0) cir = 0.297 elseif @cusptype == "Accident" ta = (1.9021130325903071442328786667588,0) tb = (1.9021130325903071442328786667588,0) elseif @cusptype == "Troel's Point" ta = (1.6168866453,-0.7056734968) tb = (2,0) cir = 0.13091 elseif @cusptype == "Degenerate Spiral" ta = (1.9264340533,-0.0273817919) tb = (2,0) cir = 0.2419 elseif @cusptype == "Double Cusp" tb = (2,0) if @cusp == "0/1" ta = (2,0) cir = 0.5 elseif @cusp == "1/100" ta = (1.99599050389291,-0.000302826761310194) cir = 0.3091 elseif @cusp == "2/99" ta = (1.99599050389291,-0.000302826761310194) cir = 0.2676 elseif @cusp == "3/100" ta = (1.99118310579765,-0.000982081178197968) cir = 0.2427 elseif @cusp == "4/99" ta = (1.98427416931522,-0.00237401043014847) cir = 0.2351 elseif @cusp == "1/15" ta = (1.95859103011179,-0.0112785606117653) cir = 0.32870768 elseif @cusp == "1/10" ta = (1.91342329586682,-0.0362880775225429) cir = 0.32365169 elseif @cusp == "2/19" ta = (1.90377999779718,-0.0395799512688805) cir = 0.2604321 elseif @cusp == "1/9" ta = (1.89640725094921,-0.0487530128986506) cir = 0.32176507 elseif @cusp == "7/43" ta = (1.80785523999043,-0.136998687907137) cir = 0.229796 elseif @cusp == "3/10" ta = (1.65831239517773,-0.5) cir = 0.2316625 elseif @cusp == "2/5" ta = (1.64213876865348,-0.766588417465459) cir = 0.2665884 elseif @cusp == "1/2" ta = (1.73205080756888,-1) cir = 0.36602539 elseif @cusp == "21/34" ta = (1.6179907967521,-1.29170028664218) cir = 0.166461 endif endif ; Grandma's Special algorithm if !(@cusptype == "Grandma's Special #2" || @cusptype == "Maskit") if @showcusp == "Both" Fc[0] = 1-cir Fr[0] = cir Fc[1] = -(1-cir) Fr[1] = cir Fc[2] = (0,0) Fr[2] = 1 s.sph[0] = new Sphere(Fc[0],Fz[0],Fr[0],0,0) s.sph[1] = new Sphere(Fc[1],Fz[1],Fr[1],0,0) s.sph[2] = new Sphere(Fc[2],Fz[2],Fr[2],0,0) ss.sph[0] = s.sph[0] ss.sph[1] = s.sph[1] ss.sph[2] = s.sph[2] elseif @showcusp == "Alternate" Fc[0] = (1-cir) Fr[0] = cir Fc[1] = -(1-cir) Fr[1] = cir s.sph[0] = new Sphere(Fc[0],Fz[0],Fr[0],0,0) s.sph[1] = new Sphere(Fc[1],Fz[1],Fr[1],0,0) ss.sph[0] = s.sph[0] ss.sph[1] = s.sph[1] elseif @showcusp == "Standard" Fc[0] = (0,0) Fr[0] = 1 s.sph[0] = new Sphere(Fc[0],Fz[0],Fr[0],0,0) ss.sph[0] = s.sph[0] endif complex tab = (ta*tb+sqrt(ta*ta*tb*tb-4*(ta*ta+tb*tb)))/2 if @alttab tab = (ta*tb-sqrt(ta*ta*tb*tb-4*(ta*ta+tb*tb)))/2 endif complex gz0 = (tab-2)*tb/(tb*tab-2*ta+2*(0,1)*tab) mob[0] = new Mobius((tb-(0,2))/2, tb/2, tb/2, conj((tb-(0,2))/2)) mob[1] = new Mobius(mob[0].m_d, -mob[0].m_b, -mob[0].m_c, mob[0].m_a) mob[2] = new Mobius(ta/2, (ta*tab-2*tb-(0,4))*gz0/(2*tab-4), \ (ta*tab-2*tb+(0,4))/((2*tab+4)*gz0), ta/2) if @trans temp1 = mob[2].m_b mob[2].m_b = mob[2].m_c mob[2].m_c = temp1 endif mob[3] = new Mobius(mob[2].m_d, -mob[2].m_b, -mob[2].m_c, mob[2].m_a) endif ; Figure 11.1 from the Indra's Pearls book if @cusptype == "Indra 11.1" tabAB = (0,0) tb = (2,0) sscale = 2.4 ta = (1.924781, 0.047529) rads = 0.41421381 cirs = (0, 0.272591599) cira = (0.168208, 0) rada = 0.2211131 endif ; Grandma's Special #2 algorithm if !(@cusptype == "Grandma's Special" || @cusptype == "Maskit" ||\ @cusptype == "Double Cusp" || @cusptype == "Nearby Group" ||\ @cusptype == "Troel's Point"|| @cusptype == "Degenerate Spiral") if @showcusp == "Both" Fc[0] = cirs Fr[0] = rads-cabs(cirs) if @lines Fr[0] = -Fr[0] endif Fc[1] = -cirs Fr[1] = Fr[0] Fc[2] = cira Fr[2] = rada-cabs(cira) if @linea Fr[2] = -Fr[2] endif Fc[3] = -cira Fr[3] = Fr[2] s.sph[0] = new Sphere(Fc[0],Fz[0],Fr[0],0,0) s.sph[1] = new Sphere(Fc[1],Fz[1],Fr[1],0,0) s.sph[2] = new Sphere(Fc[2],Fz[2],Fr[2],0,0) s.sph[3] = new Sphere(Fc[3],Fz[3],Fr[3],0,0) ss.sph[0] = s.sph[0] ss.sph[1] = s.sph[1] ss.sph[2] = s.sph[2] ss.sph[3] = s.sph[3] elseif @showcusp == "Alternate" Fc[0] = cira Fr[0] = rada-cabs(cira) if @linea Fr[0] = -Fr[0] endif Fc[1] = -cira Fr[1] = Fr[0] s.sph[0] = new Sphere(Fc[0],Fz[0],Fr[0],0,0) s.sph[1] = new Sphere(Fc[1],Fz[1],Fr[1],0,0) ss.sph[0] = s.sph[0] ss.sph[1] = s.sph[1] else Fc[0] = cirs Fr[0] = rads-cabs(cirs) if @lines Fr[0] = -Fr[0] endif Fc[1] = -cirs Fr[1] = Fr[0] s.sph[0] = new Sphere(Fc[0],Fz[0],Fr[0],0,0) s.sph[1] = new Sphere(Fc[1],Fz[1],Fr[1],0,0) ss.sph[0] = s.sph[0] ss.sph[1] = s.sph[1] endif gz = 0.5*sqrt(ta^2*tb^2-4*ta^2-4*tb^2+4*tabAB+8) tab = 0.5*ta*tb-gz if @alttab tab = 0.5*ta*tb+gz endif gQ = sqrt(2-tabAB) gR = sqrt(2+tabAB) if cabs(tabAB+im*gQ*gR)<2 gR = -gR endif gz0 = (tab-2)*(tb+gR)/(tb*tab-2*ta+im*gQ*tab) mob[0] = new Mobius((tb-im*gQ)/2, (tb*tab-2*ta-im*gQ*tab)/((2*tab+4)*gz0),\ (tb*tab-2*ta+im*gQ*tab)*gz0/(2*tab-4), (tb+im*gQ)/2) mob[1] = new Mobius(mob[0].m_d, -mob[0].m_b, -mob[0].m_c, mob[0].m_a) mob[2] = new Mobius(ta/2, (ta*tab-2*tb+2*im*gQ)/((2*tab+4)*gz0), \ (ta*tab-2*tb-2*im*gQ)*gz0/(2*tab-4), ta/2) if @trans temp1 = mob[2].m_b mob[2].m_b = mob[2].m_c mob[2].m_c = temp1 endif mob[3] = new Mobius(mob[2].m_d, -mob[2].m_b, -mob[2].m_c, mob[2].m_a) endif if @cusptype == "Maskit" if @showcuspm == "Predefined" if @cuspm == "0/1" m = (0,2) radam = 0.5 elseif @cuspm == "1/15" m = (-0.0112785606117653, 1.95859103011179) radam = 0.489661311 elseif @cuspm == "1/10" m = (-0.0362880775225429,1.91342329586682) radam = 0.47852888 elseif @cuspm == "2/19" m = (-0.0395799512688805,1.90377999779718) radam = 0.35214005 elseif @cuspm == "1/9" m = (-0.0487530128986506,1.89640725094921) radam = 0.4744165 elseif @cuspm == "7/43" m = (-0.136998687907137,1.80785523999043) radam = 0.2983515 elseif @cuspm == "3/10" m = (-0.5,1.65831239517773) radam = 0.3015111 elseif @cuspm == "2/5" m = (-0.766588417465459,1.64213876865348) radam = 0.363491 elseif @cuspm == "1/2" m = (-1,1.73205080756888) radam = 0.57735015 elseif @cuspm == "21/34" m = (1.29170028664218,1.6179907967521) radam = 0.1997052 endif endif if @showcuspm == "Both" || (@showcuspm == "Predefined" \ && @showcuspm2 == "Both") Fc[0] = 1 + flip(radam) Fr[0] = radam Fc[1] = (1,0) Fr[1] = 0 s.sph[0] = new Sphere(Fc[0],Fz[0],Fr[0],0,0) s.sph[1] = new Sphere(Fc[1],Fz[1],Fr[1],0,0) ss.sph[0] = s.sph[0] ss.sph[1] = s.sph[1] elseif @showcuspm == "Alternate" || (@showcuspm == "Predefined" \ && @showcuspm2 == "Alternate") Fc[0] = 1 + flip(radam) Fr[0] = radam s.sph[0] = new Sphere(Fc[0],Fz[0],Fr[0],0,0) ss.sph[0] = s.sph[0] else Fc[0] = (1,0) Fr[0] = 0 s.sph[0] = new Sphere(Fc[0],Fz[0],Fr[0],0,0) ss.sph[0] = s.sph[0] endif mob[0] = new Mobius(m, 1, 1, 0) mob[1] = new Mobius(mob[0].m_d, -mob[0].m_b, -mob[0].m_c, mob[0].m_a) mob[2] = new Mobius(1, 0, 2, 1) mob[3] = new Mobius(mob[2].m_d, -mob[2].m_b, -mob[2].m_c, mob[2].m_a) endif ; normalize the matrices i = 0 while i < 4 mob[i].Normalize(mob[i]) i = i + 1 endwhile endfunc ; Inverts a sphere - Mobius inversion The return value may be a sphere or a plane.
; @param target = sphere to be inverted ; @param inverter = not used. ; @param level = recursion level ; @param gen = index of generator matrix ;------------------------------------------------ Sphere func Inverse(Sphere target, Sphere inverter, int level, int gen) mob[5] = new Mobius(0,0,0,0) mob[5].CircToMob(target) mob[gen].MConj(mob[5],mob[5]) Sphere ns = new Sphere(0,0,0,0,0) mob[5].MobToCirc(level,gen,ns) return ns endfunc ; Top level recursion function func Recurse() int l = 0 int ir = 0 int si = 0 int sj = 0 int j = 0 bool done = false int c = 0 float ddx = 0 float ddy = 0 float ddr = 0 sphere rra bool continue = false int ifinal = 0 int istack = 0 int nold = 0 int nfinal = 1 int iii = 0 int k = 0 int lev = 0 if @showcusp == "Both" j = 3 iii = 2 elseif @showcusp == "Standard" j = 1 iii = 0 else j = 2 iii = 1 endif if @cusptype == "Grandma's Special #2" if @showcusp == "Both" j = 4 iii = 3 else j = 2 iii = 1 endif endif if @cusptype == "Maskit" if @showcuspm == "Both" || (@showcuspm == "Predefined" && \ @showcuspm2 == "Both") j = 2 iii = 1 else j = 1 iii = 0 endif endif iii = iii + 1 lev = 1 while lev <= mlevel && j < flength gi = 0 while gi < iend && j < flength k = 0 while k <= iii && j < flength ss.sph[j] = Inverse(ss.sph[k],ss.sph[0],lev,gi) if ss.sph[j].frad >= 0 && abs(ss.sph[j].frad) < fminsphere j = j - 1 endif if j > flength lev = mlevel + 1 k = iii + 1 endif j = j+1 k = k + 1 endwhile if j > flength gi = 5 endif gi = gi + 1 endwhile ; sort array by circle identity l = round(j/2)+1 ir = j continue = true repeat if l > 1 l = l-1 rra = ss.sph[l-1] else rra = ss.sph[ir-1] ss.sph[ir-1] = ss.sph[0] ir = ir-1 if ir == 0 ss.sph[0] = rra continue = false endif endif if continue == true si = l sj = 2*l endif while (sj <= ir) && (continue == true) if sj < ir ddx = real(ss.sph[sj-1].fcen)-real(ss.sph[sj].fcen) ddy = imag(ss.sph[sj-1].fcen)-imag(ss.sph[sj].fcen) ddr = ss.sph[sj-1].frad-ss.sph[sj].frad c = 0 done = false ; Lines precede circles if ss.sph[sj-1].frad <= 0 && ss.sph[sj].frad > 0 c = -1 done = true elseif ss.sph[sj].frad <= 0 && ss.sph[sj-1].frad > 0 c = 1 done = true elseif ddx < -thresh c = -1 done = true elseif ddx > thresh && !done c = 1 done = true elseif ddy < -thresh && !done c = -1 done = true elseif ddy > thresh && !done c = 1 done = true elseif ss.sph[sj-1].frad <= 0 && !done ; Lines if ddr < -PARAFUZZ && !done c = -1 done = true elseif ddr > PARAFUZZ && !done c = 1 done = true endif elseif !done ; Circles if ddr < -thresh && !done c = -1 done = true elseif ddr > thresh && !done c = 1 done = true endif endif if c < 0 sj = sj + 1 endif endif ddx = real(rra.fcen)-real(ss.sph[sj-1].fcen) ddy = imag(rra.fcen)-imag(ss.sph[sj-1].fcen) ddr = rra.frad-ss.sph[sj-1].frad c = 0 done = false ; ; Lines precede circles if rra.frad <= 0 && ss.sph[sj-1].frad > 0 c = -1 done = true elseif ss.sph[sj-1].frad <= 0 && rra.frad > 0 c = 1 done = true elseif ddx < -thresh c = -1 done = true elseif ddx > thresh && !done c = 1 done = true elseif ddy < -thresh && !done c = -1 done = true elseif ddy > thresh && !done c = 1 done = true elseif rra.frad <= 0 && !done ; Lines if ddr < -PARAFUZZ && !done c = -1 done = true elseif ddr > PARAFUZZ && !done c = 1 done = true endif elseif !done ; Circles if ddr < -thresh && !done c = -1 done = true elseif ddr > thresh && !done c = 1 done = true endif endif if c < 0 ss.sph[si-1] = ss.sph[sj-1] si = sj sj = sj + sj else sj = ir + 1 endif endwhile if (continue == true) ss.sph[si-1] = rra endif until continue == false ; eliminate duplicates in place ; ir = oldj-iii+1 ; l = oldj-iii ir = j+1 l = j while ir < j ddx = real(ss.sph[ir].fcen)-real(ss.sph[ir-1].fcen) ddy = imag(ss.sph[ir].fcen)-imag(ss.sph[ir-1].fcen) ddr = ss.sph[ir].frad-ss.sph[ir-1].frad c = 0 done = false ; Lines precede circles if ss.sph[ir].frad <= 0 && ss.sph[ir-1].frad > 0 c = -1 done = true elseif ss.sph[ir-1].frad <= 0 && ss.sph[ir].frad > 0 c = 1 done = true elseif ddx < -thresh && !done c = -1 done = true elseif ddx > thresh && !done c = 1 done = true elseif ddy < -thresh && !done c = -1 done = true elseif ddy > thresh && !done c = 1 done = true elseif ss.sph[ir].frad <= 0 && !done ; Lines if ddr < -PARAFUZZ && !done c = -1 done = true elseif ddr > PARAFUZZ && !done c = 1 done = true endif elseif !done ; Circles if ddr < -thresh && !done c = -1 done = true elseif ddr > thresh && !done c = 1 done = true endif endif if c == 0 ir = ir + 1 else ss.sph[l] = ss.sph[ir] ir = ir +1 l = l + 1 endif endwhile j = j-(ir-l)+1 ; move to final array, skipping dups ifinal = 0 istack = 0 nold = nfinal while ifinal < nold && istack < j && nfinal < flength ddx = real(s.sph[ifinal].fcen)-real(ss.sph[istack].fcen) ddy = imag(s.sph[ifinal].fcen)-imag(ss.sph[istack].fcen) ddr = s.sph[ifinal].frad-ss.sph[istack].frad c = 0 done = false ; Lines precede circles if s.sph[ifinal].frad <= 0 && ss.sph[istack].frad > 0 c = -1 done = true elseif ss.sph[istack].frad <= 0 && s.sph[ifinal].frad > 0 c = 1 done = true elseif ddx < -thresh c = -1 done = true elseif ddx > thresh && !done c = 1 done = true elseif ddy < -thresh && !done c = -1 done = true elseif ddy > thresh && !done c = 1 done = true elseif s.sph[ifinal].frad <= 0 && !done ; Lines if ddr < -PARAFUZZ && !done c = -1 done = true elseif ddr > PARAFUZZ && !done c = 1 done = true endif elseif !done ; Circles if ddr < -thresh && !done c = -1 done = true elseif ddr > thresh && !done c = 1 done = true endif endif if c < 0 ifinal = ifinal + 1 endif if c == 0 istack = istack + 1 endif if c > 0 s.sph[nfinal] = ss.sph[istack] nfinal = nfinal + 1 istack = istack + 1 endif endwhile while istack < j && nfinal < flength s.sph[nfinal] = ss.sph[istack] nfinal = nfinal + 1 istack = istack + 1 endwhile ir = nold while ir 1 l = l-1 rra = s.sph[l-1] else rra = s.sph[ir-1] s.sph[ir-1] = s.sph[0] ir = ir-1 if ir == 0 s.sph[0] = rra continue = false endif endif if continue == true si = l sj = 2*l endif while (sj <= ir) && (continue == true) if sj < ir ddx = real(s.sph[sj-1].fcen)-real(s.sph[sj].fcen) ddy = imag(s.sph[sj-1].fcen)-imag(s.sph[sj].fcen) ddr = s.sph[sj-1].frad-s.sph[sj].frad c = 0 done = false ; Lines precede circles if s.sph[sj-1].frad <= 0 && s.sph[sj].frad > 0 c = -1 done = true elseif s.sph[sj].frad <= 0 && s.sph[sj-1].frad > 0 c = 1 done = true elseif ddx < -thresh c = -1 done = true elseif ddx > thresh && !done c = 1 done = true elseif ddy < -thresh && !done c = -1 done = true elseif ddy > thresh && !done c = 1 done = true elseif s.sph[sj-1].frad <= 0 && !done ; Lines if ddr < -PARAFUZZ && !done c = -1 done = true elseif ddr > PARAFUZZ && !done c = 1 done = true endif elseif !done ; Circles if ddr < -thresh && !done c = -1 done = true elseif ddr > thresh && !done c = 1 done = true endif endif if c < 0 sj = sj + 1 endif endif ddx = real(rra.fcen)-real(s.sph[sj-1].fcen) ddy = imag(rra.fcen)-imag(s.sph[sj-1].fcen) ddr = rra.frad-s.sph[sj-1].frad c = 0 done = false ; Lines precede circles if rra.frad <= 0 && s.sph[sj-1].frad > 0 c = -1 done = true elseif s.sph[sj-1].frad <= 0 && rra.frad > 0 c = 1 done = true elseif ddx < -thresh c = -1 done = true elseif ddx > thresh && !done c = 1 done = true elseif ddy < -thresh && !done c = -1 done = true elseif ddy > thresh && !done c = 1 done = true elseif rra.frad <= 0 && !done ; Lines if ddr < -PARAFUZZ && !done c = -1 done = true elseif ddr > PARAFUZZ && !done c = 1 done = true endif elseif !done ; Circles if ddr < -thresh && !done c = -1 done = true elseif ddr > thresh && !done c = 1 done = true endif endif if c < 0 s.sph[si-1] = s.sph[sj-1] si = sj sj = sj + sj else sj = ir + 1 endif endwhile if (continue == true) s.sph[si-1] = rra endif until continue == false iii = j-1 if j == 0 lev = mlevel+1 else lev = lev+1 endif endwhile fk = nfinal-1 ss = 0 heapsort(s,fk) vanquish(s,fk) SizeAndRot() if @zsort heapsortz(s, fk) endif endfunc ; Size and rotate spheres func SizeAndRot() if @cusptype == "Nearby group" && @trans sscale = 0.05 elseif @cusptype == "Double Cusp" && @trans if @cusp == "1/15" sscale = 0.015 elseif @cusp == "0/1" sscale = 0.5 elseif @cusp == "2/19" sscale = 0.025 elseif @cusp == "1/9" sscale = 0.04 elseif @cusp == "7/43" sscale = 0.035 elseif @cusp == "2/5" sscale = 0.2 endif endif int i = 0 while i < fk if s.sph[i].frad > 0 ; size routines if s.sph[i].frad > @maxsphere s.sph[i].frad = 0 endif if @cusptype == "Maskit" s.sph[i].fcen = (s.sph[i].fcen+(0,-1))*#magn*scale*sscale else s.sph[i].fcen = s.sph[i].fcen*#magn*scale*sscale endif s.sph[i].fz = s.sph[i].fz*#magn*scale*sscale s.sph[i].frad = s.sph[i].frad*#magn*scale*sscale ; rotation around the z axis ; float fx = real(s.sph[i].fcen) float fy = imag(s.sph[i].fcen) float fz = s.sph[i].fz float xx = real(s.sph[i].fcen) fx = fx*cos(#angle) - fy*sin(#angle) fy = fy*cos(#angle) + xx*sin(#angle) s.sph[i].fcen = fx + flip(fy) ; rotation around the y axis ; xx = fx fx = fz*sin(@yang*#pi/180) + fx*cos(@yang*#pi/180) fz = fz*cos(@yang*#pi/180) - xx*sin(@yang*#pi/180) s.sph[i].fcen = fx + flip(fy) s.sph[i].fz = fz ; rotation around the x axis ; float yy = fy fy = fy*cos(@xang*#pi/180) - fz*sin(@xang*#pi/180) fz = yy*sin(@xang*#pi/180) + fz*cos(@xang*#pi/180) s.sph[i].fcen = fx + flip(fy) s.sph[i].fz = fz endif i = i + 1 endwhile endfunc float PARAFUZZ float LINEFUZZ complex im Mobius mob[6] int gi int iend float sscale spherearray ss default: title = "Mobius Inversions" int param v_mobinvert caption = "Version (Mobius Inversions)" default = 101 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_mobinvert < 101 endparam float param minsphere caption = "Min sphere size" default = 0.001 min = 0.000001 endparam float param maxsphere caption = "Max sphere size" default = 0.7 endparam int param maxLevel caption = "Recursion level" default = 100 min = 0 max = 1000 endparam float param radadj caption = "Gen Rad adj" default = 1.0 visible = false endparam float param bradadj caption = "Base Rad adj" default = 1.0 visible = false 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 heading text = "For rotation around the Z Axis use the rotation angle on the Location Tab." endheading heading text = "Use these methods with care, as only certain combinations of \ parameters will give satisfactory results. Use of the help file \ is essential. Use of the 'Explore' feature is not recommended." visible = @cusptype == "Grandma's Special" || @cusptype == "Grandma's Special #2" \ || @cusptype == "Maskit" endheading heading text = "The Grandma algorithms come from 'Indra's Pearls' by Mumford, \ Series and Wright. Consult the book for use of the trace parameters." visible = @cusptype == "Grandma's Special" || @cusptype == "Grandma's Special #2" endheading heading text = "The Maskit algorithm comes from 'Indra's Pearls' by Mumford, \ Series and Wright. Consult the book for use of the Maskit parameters." visible = @cusptype == "Maskit" endheading param cusptype caption = "Group" default = 7 enum = "Accident" "Indra 11.1" "Degenerate Spiral" "Double Cusp" \ "Grandma's Special" "Grandma's Special #2" "Maskit" "Nearby Group" \ "Troel's Point" endparam param cusp caption = "Cusp" default = 5 enum = "0/1" "1/100" "2/99" "3/100" "4/99" "1/15" "1/10" "2/19" "1/9" \ "7/43" "3/10" "2/5" "1/2" "21/34" visible = @cusptype == "Double Cusp" endparam param showcusp caption = "Cusp view" default = 1 enum = "Both" "Standard" "Alternate" visible = !(@cusptype == "Maskit" || @cusptype == "Accident") endparam param showcuspm caption = "Cusp view" default = 1 enum = "Both" "Standard" "Alternate" "Predefined" visible = @cusptype == "Maskit" endparam param showcuspm2 caption = "Cusp view" default = 1 enum = "Both" "Standard" "Alternate" visible = @cusptype == "Maskit" && @showcuspm == "Predefined" endparam heading text = "Slowly increase 'gen circle' until good circle packing is observed." visible = @cusptype == "Grandma's special"&& @showcusp != "Standard" endheading param @cir caption ="Gen circle" default = 0.01 hint = "Slowly increase until good circle packing is observed." visible = @cusptype == "Grandma's special"&& @showcusp != "Standard" endparam heading text = "These parameters set the size and position of the 'Standard' \ generator circles." visible = @cusptype == "Grandma's special #2"&& @showcusp != "Alternate" endheading param @cirs caption ="Gen circle std" default = (0,0) visible = (@cusptype == "Grandma's special #2"&& @showcusp != "Alternate") endparam param @rads caption ="Rad ref std" default = 1.0 visible = (@cusptype == "Grandma's special #2"&& @showcusp != "Alternate") endparam bool param @lines caption ="Generate as line" default = false visible = (@cusptype == "Grandma's special #2"&& @showcusp != "Alternate") endparam heading text = "These parameters set the size and position of the 'Alternate' \ generator circles." visible = @cusptype == "Grandma's special #2"&& @showcusp != "Standard" endheading param @cira caption ="Gen circle alt" default = (0,0) visible = (@cusptype == "Grandma's special #2"&& @showcusp != "Standard") endparam param @rada caption ="Rad ref alt" default = 1.0 visible = (@cusptype == "Grandma's special #2"&& @showcusp != "Standard") endparam heading text = "This parameter set the size and position of the 'Alternate' \ generator circle." visible = @cusptype == "Maskit"&& @showcusp != "Standard" endheading param @radam caption ="Rad ref" default = 0.5 visible = @cusptype == "Maskit"&& @showcuspm != "Standard" && \ @showcuspm != "Predefined" endparam bool param @linea caption ="Generate as line" default = false visible = (@cusptype == "Grandma's special #2"&& @showcusp != "Standard") endparam complex param m caption = "Maskit param" default = (0.0112785606117653,1.95859103011179) visible = @cusptype == "Maskit" && @showcuspm != "Predefined" endparam param cuspm caption = "Cusp" default = 1 enum = "0/1" "1/15" "1/10" "2/19" "1/9" "7/43" "3/10" "2/5" "1/2" "21/34" visible = @cusptype == "Maskit" && @showcuspm == "Predefined" endparam complex param ta caption = "Trace a" default = (1.95,0.02) visible = @cusptype == "Grandma's Special" || @cusptype == "Grandma's Special #2" endparam complex param tb caption = "Trace b" default = 3 visible = @cusptype == "Grandma's Special" || @cusptype == "Grandma's Special #2" endparam bool param alttab caption ="Alternate trace ab" default = false visible = @cusptype == "Grandma's Special" || @cusptype == "Grandma's Special #2" endparam complex param tabAB caption = "Trace abAB" default = -2 visible = @cusptype == "Grandma's Special #2" endparam bool param trans caption = "Transpose transform" default = false visible = @cusptype != "Maskit" endparam } ;------------------------------------------- ; Trap shape classes ;--------------------------------------------- ; general references to 2D curves:
; Mathematical Curves
;
;

class REB_TrapShapeIkenaga(common.ulb:TrapShape) { ; Uses the Ikenaga fractal function as the trap public: import "common.ulb" ; Constructor func REB_TrapShapeIkenaga(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) complex p = pz*@scale p = @fn1(p) int ike_iter = 0 complex c = #pixel while ike_iter < @max_iterations p = p*p*p +(c-1)*p - c ike_iter = ike_iter + 1 endwhile m_LastZ = @fn2(p) float d = abs(|pz| - |m_LastZ|) return d endfunc default: title = "Ikenaga" int param v_trapshapeikenaga caption = "Version (Trap Shape Ikenaga)" default = 101 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_trapshapeikenaga < 101 endparam float param scale caption = "Scale" default = 1.0 endparam param max_iterations caption = "Ikenaga iterations" hint = "This is the number of iterations for the Ikenaga formula." default = 1 endparam func fn1 caption = "Pre Function" default = atan() endfunc func fn2 caption = "Post Function" default = sinh() endfunc } class REB_TrapShapePlatonicSolids(common.ulb:TrapShape) { public: import "common.ulb" import "reb.ulb" $define debug ; Constructor func REB_TrapShapePlatonicSolids(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; call before each iteration func Init(complex pz) TrapShape.Init(pz) twopi = 2*#pi mx = 0 my = 0 i = 0 x = 0.0 y = 0.0 out = false rotx = @rotx+1e-10 roty = @roty+1e-10 rotz = @rotz+1e-10 if @polygontype == "Tetrahedron" vertex = 4 side = 6 i = 0 vx[0] = 0.5 vy[0] = 0.5 vz[0] = 0.5 vx[1] = -0.5 vy[1] = -0.5 vz[1] = 0.5 vx[2] = 0.5 vy[2] = -0.5 vz[2] = 0.5 vx[3] = -0.5 vy[3] = 0.5 vz[3] = -0.5 repeat rot.rotatex(vx[i],vy[i],vz[i],rotx) rot.rotatey(vx[i],vy[i],vz[i],roty) rot.rotatez(vx[i],vy[i],vz[i],rotz) i = i + 1 until i == vertex i = 0 repeat v[i] = vx[i] + flip(vy[i]) i = i+1 until i == vertex elseif @polygontype == "Cube" vertex = 8 side = 12 i = 0 vx[0] = 0.5 vy[0] = 0.5 vz[0] = 0.5 vx[1] = 0.5 vy[1] = -0.5 vz[1] = 0.5 vx[2] = -0.5 vy[2] = -0.5 vz[2] = 0.5 vx[3] = -0.5 vy[3] = 0.5 vz[3] = 0.5 vx[4] = -0.5 vy[4] = 0.5 vz[4] = -0.5 vx[5] = 0.5 vy[5] = 0.5 vz[5] = -0.5 vx[6] = 0.5 vy[6] = -0.5 vz[6] = -0.5 vx[7] = -0.5 vy[7] = -0.5 vz[7] = -0.5 repeat rot.rotatex(vx[i],vy[i],vz[i],rotx) rot.rotatey(vx[i],vy[i],vz[i],roty) rot.rotatez(vx[i],vy[i],vz[i],rotz) i = i + 1 until i == vertex i = 0 repeat v[i] = vx[i] + flip(vy[i]) i = i+1 until i == vertex elseif @polygontype == "Octahedron" vertex = 6 side = 12 i = 0 vx[0] = 0.7071 vy[0] = 0 vz[0] = 0 vx[1] = 0 vy[1] = -0.7071 vz[1] = 0 vx[2] = 0 vy[2] = 0 vz[2] = 0.7071 vx[3] = 0 vy[3] = 1 vz[3] = 0 vx[4] = -0.7071 vy[4] = 0 vz[4] = 0 vx[5] = 0 vy[5] = 0 vz[5] = -0.7071 repeat rot.rotatex(vx[i],vy[i],vz[i],rotx) rot.rotatey(vx[i],vy[i],vz[i],roty) rot.rotatez(vx[i],vy[i],vz[i],rotz) i = i + 1 until i == vertex i = 0 repeat v[i] = vx[i] + flip(vy[i]) i = i+1 until i == vertex elseif @polygontype == "Icosahedron" vertex = 12 side = 30 i = 0 vx[0] = 0 vy[0] = 0 vz[0] = 1 vx[1] = 0.894 vy[1] = 0 vz[1] = 0.447 vx[2] = 0.276 vy[2] = 0.851 vz[2] = 0.447 vx[3] = -0.724 vy[3] = 0.526 vz[3] = 0.447 vx[4] = -0.724 vy[4] = -0.526 vz[4] = 0.447 vx[5] = 0.276 vy[5] = -0.851 vz[5] = 0.447 vx[6] = 0.724 vy[6] = 0.526 vz[6] = -0.447 vx[7] = -0.276 vy[7] = 0.851 vz[7] = -0.447 vx[8] = -0.894 vy[8] = 0 vz[8] = -0.447 vx[9] = -0.276 vy[9] = -0.851 vz[9] = -0.447 vx[10] = 0.724 vy[10] = -0.526 vz[10] = -0.447 vx[11] = 0 vy[11] = 0 vz[11] = -1 repeat rot.rotatex(vx[i],vy[i],vz[i],rotx) rot.rotatey(vx[i],vy[i],vz[i],roty) rot.rotatez(vx[i],vy[i],vz[i],rotz) i = i + 1 until i == vertex i = 0 repeat v[i] = vx[i] + flip(vy[i]) i = i+1 until i == vertex elseif @polygontype == "Dodecahedron" vertex = 20 side = 30 i = 0 vx[0] = 0.607 vy[0] = 0 vz[0] = 0.795 vx[1] = 0.188 vy[1] = 0.577 vz[1] = 0.795 vx[2] = -0.491 vy[2] = 0.357 vz[2] = 0.795 vx[3] = -0.491 vy[3] = -0.357 vz[3] = 0.795 vx[4] = 0.188 vy[4] = -0.577 vz[4] = 0.795 vx[5] = 0.982 vy[5] = 0 vz[5] = 0.188 vx[6] = 0.304 vy[6] = 0.934 vz[6] = 0.188 vx[7] = -0.795 vy[7] = 0.577 vz[7] = 0.188 vx[8] = -0.894 vy[8] = -0.577 vz[8] = 0.188 vx[9] = 0.304 vy[9] = -0.934 vz[9] = 0.188 vx[10] = 0.795 vy[10] = 0.577 vz[10] = -0.188 vx[11] = -0.304 vy[11] = 0.934 vz[11] = -0.188 vx[12] = -0.982 vy[12] = 0.000 vz[12] = -0.188 vx[13] = -0.304 vy[13] = -0.934 vz[13] = -0.188 vx[14] = 0.795 vy[14] = -0.577 vz[14] = -0.188 vx[15] = 0.491 vy[15] = 0.357 vz[15] = -0.795 vx[16] = -0.188 vy[16] = 0.577 vz[16] = -0.795 vx[17] = -0.607 vy[17] = 0 vz[17] = -0.795 vx[18] = -0.188 vy[18] = -0.577 vz[18] = -0.795 vx[19] = 0.491 vy[19] = -0.357 vz[19] = -0.795 repeat rot.rotatex(vx[i],vy[i],vz[i],rotx) rot.rotatey(vx[i],vy[i],vz[i],roty) rot.rotatez(vx[i],vy[i],vz[i],rotz) i = i + 1 until i == vertex i = 0 repeat v[i] = (vx[i] + flip(vy[i]))/0.713644 i = i+1 until i == vertex endif endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) d = 1e10 size = @size complex pzs = pz/size i = 0 ; ; calculate r[i] and t[i] for first n-1 sides ; if @polygontype == "Tetrahedron" ; ; front face repeat t[i]=(pzs-v[i])/(v[i+1]-v[i]) x=real(t[i]) y=imag(t[i]) if y > 0 out = false endif if(x<0.0) r[i]=sqr(x)+sqr(y) elseif(x>1.0) r[i]=sqr(x-1.0)+sqr(y) else r[i]=sqr(y) endif r[i]=sqrt(r[i])*cabs(v[i+1]-v[i]) i = i + 1 until i == 3 ; ; calculate r[i] and t[i] for the last side of front face ; t[2]=(pzs-v[2])/(v[0]-v[2]) x=real(t[2]) y=imag(t[2]) if y > 0 out = false endif if(x<0.0) r[2]=sqr(x)+sqr(y) elseif(x>1.0) r[2]=sqr(x-1.0)+sqr(y) else r[2]=sqr(y) endif r[2]=sqrt(r[2])*cabs(v[0]-v[2]) ; ; right side ; t[3]=(pzs-v[3])/(v[0]-v[3]) x=real(t[3]) y=imag(t[3]) if y > 0 out = false endif if(x<0.0) r[3]=sqr(x)+sqr(y) elseif(x>1.0) r[3]=sqr(x-1.0)+sqr(y) else r[3]=sqr(y) endif r[3]=sqrt(r[3])*cabs(v[0]-v[3]) t[4]=(pzs-v[3])/(v[1]-v[3]) x=real(t[4]) y=imag(t[4]) if y > 0 out = false endif if(x<0.0) r[4]=sqr(x)+sqr(y) elseif(x>1.0) r[4]=sqr(x-1.0)+sqr(y) else r[4]=sqr(y) endif r[4]=sqrt(r[4])*cabs(v[1]-v[3]) ; ; left side ; t[5]=(pzs-v[3])/(v[2]-v[3]) x=real(t[5]) y=imag(t[5]) if y > 0 out = false endif if(x<0.0) r[5]=sqr(x)+sqr(y) elseif(x>1.0) r[5]=sqr(x-1.0)+sqr(y) else r[5]=sqr(y) endif r[5]=sqrt(r[5])*cabs(v[2]-v[3]) elseif @polygontype == "Cube" ; ; front face repeat t[i]=(pzs-v[i])/(v[i+1]-v[i]) x=real(t[i]) y=imag(t[i]) if y > 0 out = false endif if(x<0.0) r[i]=sqr(x)+sqr(y) elseif(x>1.0) r[i]=sqr(x-1.0)+sqr(y) else r[i]=sqr(y) endif r[i]=sqrt(r[i])*cabs(v[i+1]-v[i]) i = i + 1 until i == (vertex-5) ; ; calculate r[i] and t[i] for the last side of front face ; t[vertex-5]=(pzs-v[vertex-5])/(v[0]-v[vertex-5]) x=real(t[vertex-5]) y=imag(t[vertex-5]) if y > 0 out = false endif if(x<0.0) r[vertex-5]=sqr(x)+sqr(y) elseif(x>1.0) r[vertex-5]=sqr(x-1.0)+sqr(y) else r[vertex-5]=sqr(y) endif r[vertex-5]=sqrt(r[vertex-5])*cabs(v[0]-v[vertex-5]) ; ; top face ; t[4]=(pzs-v[4])/(v[3]-v[4]) x=real(t[4]) y=imag(t[4]) if y > 0 out = false endif if(x<0.0) r[4]=sqr(x)+sqr(y) elseif(x>1.0) r[4]=sqr(x-1.0)+sqr(y) else r[4]=sqr(y) endif r[4]=sqrt(r[4])*cabs(v[3]-v[4]) t[5]=(pzs-v[5])/(v[4]-v[5]) x=real(t[5]) y=imag(t[5]) if y > 0 out = false endif if(x<0.0) r[5]=sqr(x)+sqr(y) elseif(x>1.0) r[5]=sqr(x-1.0)+sqr(y) else r[5]=sqr(y) endif r[5]=sqrt(r[5])*cabs(v[4]-v[5]) t[6]=(pzs-v[5])/(v[0]-v[5]) x=real(t[6]) y=imag(t[6]) if y > 0 out = false endif if(x<0.0) r[6]=sqr(x)+sqr(y) elseif(x>1.0) r[6]=sqr(x-1.0)+sqr(y) else r[6]=sqr(y) endif r[6]=sqrt(r[6])*cabs(v[0]-v[5]) ; ; right face ; t[7]=(pzs-v[6])/(v[1]-v[6]) x=real(t[7]) y=imag(t[7]) if y > 0 out = false endif if(x<0.0) r[7]=sqr(x)+sqr(y) elseif(x>1.0) r[7]=sqr(x-1.0)+sqr(y) else r[7]=sqr(y) endif r[7]=sqrt(r[7])*cabs(v[1]-v[6]) t[8]=(pzs-v[6])/(v[5]-v[6]) x=real(t[8]) y=imag(t[8]) if y > 0 out = false endif if(x<0.0) r[8]=sqr(x)+sqr(y) elseif(x>1.0) r[8]=sqr(x-1.0)+sqr(y) else r[8]=sqr(y) endif r[8]=sqrt(r[8])*cabs(v[5]-v[6]) ; ; bottom face ; t[9]=(pzs-v[7])/(v[2]-v[7]) x=real(t[9]) y=imag(t[9]) if y > 0 out = false endif if(x<0.0) r[9]=sqr(x)+sqr(y) elseif(x>1.0) r[9]=sqr(x-1.0)+sqr(y) else r[9]=sqr(y) endif r[9]=sqrt(r[9])*cabs(v[2]-v[7]) t[10]=(pzs-v[7])/(v[6]-v[7]) x=real(t[10]) y=imag(t[10]) if y > 0 out = false endif if(x<0.0) r[10]=sqr(x)+sqr(y) elseif(x>1.0) r[10]=sqr(x-1.0)+sqr(y) else r[10]=sqr(y) endif r[10]=sqrt(r[10])*cabs(v[6]-v[7]) ; ; back face ; t[11]=(pzs-v[7])/(v[4]-v[7]) x=real(t[11]) y=imag(t[11]) if y > 0 out = false endif if(x<0.0) r[11]=sqr(x)+sqr(y) elseif(x>1.0) r[11]=sqr(x-1.0)+sqr(y) else r[11]=sqr(y) endif r[11]=sqrt(r[11])*cabs(v[4]-v[7]) elseif @polygontype == "Octahedron" ; ; lower right face ; repeat t[i]=(pzs-v[i])/(v[i+1]-v[i]) x=real(t[i]) y=imag(t[i]) if y > 0 out = false endif if(x<0.0) r[i]=sqr(x)+sqr(y) elseif(x>1.0) r[i]=sqr(x-1.0)+sqr(y) else r[i]=sqr(y) endif r[i]=sqrt(r[i])*cabs(v[i+1]-v[i]) i = i + 1 until i == 3 ; endif t[2]=(pzs-v[2])/(v[0]-v[2]) x=real(t[2]) y=imag(t[2]) if y > 0 out = false endif if(x<0.0) r[2]=sqr(x)+sqr(y) elseif(x>1.0) r[2]=sqr(x-1.0)+sqr(y) else r[2]=sqr(y) endif r[2]=sqrt(r[2])*cabs(v[0]-v[2]) ; ; upper right face ; t[3]=(pzs-v[3])/(v[0]-v[3]) x=real(t[3]) y=imag(t[3]) if y > 0 out = false endif if(x<0.0) r[3]=sqr(x)+sqr(y) elseif(x>1.0) r[3]=sqr(x-1.0)+sqr(y) else r[3]=sqr(y) endif r[3]=sqrt(r[3])*cabs(v[0]-v[3]) t[7]=(pzs-v[3])/(v[2]-v[3]) x=real(t[7]) y=imag(t[7]) if y > 0 out = false endif if(x<0.0) r[7]=sqr(x)+sqr(y) elseif(x>1.0) r[7]=sqr(x-1.0)+sqr(y) else r[7]=sqr(y) endif r[7]=sqrt(r[7])*cabs(v[2]-v[3]) ; ; lower left face ; t[4]=(pzs-v[4])/(v[1]-v[4]) x=real(t[4]) y=imag(t[4]) if y > 0 out = false endif if(x<0.0) r[4]=sqr(x)+sqr(y) elseif(x>1.0) r[4]=sqr(x-1.0)+sqr(y) else r[4]=sqr(y) endif r[4]=sqrt(r[4])*cabs(v[1]-v[4]) t[6]=(pzs-v[4])/(v[2]-v[4]) x=real(t[6]) y=imag(t[6]) if y > 0 out = false endif if(x<0.0) r[6]=sqr(x)+sqr(y) elseif(x>1.0) r[6]=sqr(x-1.0)+sqr(y) else r[6]=sqr(y) endif r[6]=sqrt(r[6])*cabs(v[2]-v[4]) ; ; upper left face ; t[7]=(pzs-v[3])/(v[2]-v[3]) x=real(t[7]) y=imag(t[7]) if y > 0 out = false endif if(x<0.0) r[7]=sqr(x)+sqr(y) elseif(x>1.0) r[7]=sqr(x-1.0)+sqr(y) else r[7]=sqr(y) endif r[7]=sqrt(r[7])*cabs(v[2]-v[3]) t[5]=(pzs-v[4])/(v[3]-v[4]) x=real(t[5]) y=imag(t[5]) if y > 0 out = false endif if(x<0.0) r[5]=sqr(x)+sqr(y) elseif(x>1.0) r[5]=sqr(x-1.0)+sqr(y) else r[5]=sqr(y) endif r[5]=sqrt(r[5])*cabs(v[3]-v[4]) ; ; lower right face back ; t[8]=(pzs-v[5])/(v[0]-v[5]) x=real(t[8]) y=imag(t[8]) if y > 0 out = false endif if(x<0.0) r[8]=sqr(x)+sqr(y) elseif(x>1.0) r[8]=sqr(x-1.0)+sqr(y) else r[8]=sqr(y) endif r[8]=sqrt(r[8])*cabs(v[0]-v[5]) t[9]=(pzs-v[5])/(v[1]-v[5]) x=real(t[9]) y=imag(t[9]) if y > 0 out = false endif if(x<0.0) r[9]=sqr(x)+sqr(y) elseif(x>1.0) r[9]=sqr(x-1.0)+sqr(y) else r[9]=sqr(y) endif r[9]=sqrt(r[9])*cabs(v[1]-v[5]) ; ; upper right face back ; t[10]=(pzs-v[5])/(v[3]-v[5]) x=real(t[10]) y=imag(t[10]) if y > 0 out = false endif if(x<0.0) r[10]=sqr(x)+sqr(y) elseif(x>1.0) r[10]=sqr(x-1.0)+sqr(y) else r[10]=sqr(y) endif r[10]=sqrt(r[10])*cabs(v[3]-v[5]) ; ; upper left face back ; t[11]=(pzs-v[5])/(v[4]-v[5]) x=real(t[11]) y=imag(t[11]) if y > 0 out = false endif if(x<0.0) r[11]=sqr(x)+sqr(y) elseif(x>1.0) r[11]=sqr(x-1.0)+sqr(y) else r[11]=sqr(y) endif r[11]=sqrt(r[11])*cabs(v[4]-v[5]) elseif @polygontype == "Icosahedron" ; ; 0,1,2 ; repeat t[i]=(pzs-v[i])/(v[i+1]-v[i]) x=real(t[i]) y=imag(t[i]) if y > 0 out = false endif if(x<0.0) r[i]=sqr(x)+sqr(y) elseif(x>1.0) r[i]=sqr(x-1.0)+sqr(y) else r[i]=sqr(y) endif r[i]=sqrt(r[i])*cabs(v[i+1]-v[i]) i = i + 1 until i == 3 ; endif t[2]=(pzs-v[2])/(v[0]-v[2]) x=real(t[2]) y=imag(t[2]) if y > 0 out = false endif if(x<0.0) r[2]=sqr(x)+sqr(y) elseif(x>1.0) r[2]=sqr(x-1.0)+sqr(y) else r[2]=sqr(y) endif r[2]=sqrt(r[2])*cabs(v[0]-v[2]) ; ; 0,2,3 ; t[3]=(pzs-v[3])/(v[0]-v[3]) x=real(t[3]) y=imag(t[3]) if y > 0 out = false endif if(x<0.0) r[3]=sqr(x)+sqr(y) elseif(x>1.0) r[3]=sqr(x-1.0)+sqr(y) else r[3]=sqr(y) endif r[3]=sqrt(r[3])*cabs(v[0]-v[3]) t[4]=(pzs-v[3])/(v[2]-v[3]) x=real(t[4]) y=imag(t[4]) if y > 0 out = false endif if(x<0.0) r[4]=sqr(x)+sqr(y) elseif(x>1.0) r[4]=sqr(x-1.0)+sqr(y) else r[4]=sqr(y) endif r[4]=sqrt(r[4])*cabs(v[2]-v[3]) ; ; 0,3,4 ; t[5]=(pzs-v[3])/(v[4]-v[3]) x=real(t[5]) y=imag(t[5]) if y > 0 out = false endif if(x<0.0) r[5]=sqr(x)+sqr(y) elseif(x>1.0) r[5]=sqr(x-1.0)+sqr(y) else r[5]=sqr(y) endif r[5]=sqrt(r[5])*cabs(v[4]-v[3]) t[6]=(pzs-v[4])/(v[0]-v[4]) x=real(t[6]) y=imag(t[6]) if y > 0 out = false endif if(x<0.0) r[6]=sqr(x)+sqr(y) elseif(x>1.0) r[6]=sqr(x-1.0)+sqr(y) else r[6]=sqr(y) endif r[6]=sqrt(r[6])*cabs(v[0]-v[4]) ; ; 0,4,5 ; t[7]=(pzs-v[5])/(v[4]-v[5]) x=real(t[7]) y=imag(t[7]) if y > 0 out = false endif if(x<0.0) r[7]=sqr(x)+sqr(y) elseif(x>1.0) r[7]=sqr(x-1.0)+sqr(y) else r[7]=sqr(y) endif r[7]=sqrt(r[7])*cabs(v[4]-v[5]) t[8]=(pzs-v[0])/(v[5]-v[0]) x=real(t[8]) y=imag(t[8]) if y > 0 out = false endif if(x<0.0) r[8]=sqr(x)+sqr(y) elseif(x>1.0) r[8]=sqr(x-1.0)+sqr(y) else r[8]=sqr(y) endif r[8]=sqrt(r[8])*cabs(v[5]-v[0]) ; ; 0,5,1 ; t[9]=(pzs-v[5])/(v[1]-v[5]) x=real(t[9]) y=imag(t[9]) if y > 0 out = false endif if(x<0.0) r[9]=sqr(x)+sqr(y) elseif(x>1.0) r[9]=sqr(x-1.0)+sqr(y) else r[9]=sqr(y) endif r[9]=sqrt(r[9])*cabs(v[1]-v[5]) ; ; 1,2,6 ; t[10]=(pzs-v[6])/(v[1]-v[6]) x=real(t[10]) y=imag(t[10]) if y > 0 out = false endif if(x<0.0) r[10]=sqr(x)+sqr(y) elseif(x>1.0) r[10]=sqr(x-1.0)+sqr(y) else r[10]=sqr(y) endif r[10]=sqrt(r[10])*cabs(v[1]-v[6]) t[11]=(pzs-v[6])/(v[2]-v[6]) x=real(t[11]) y=imag(t[11]) if y > 0 out = false endif if(x<0.0) r[11]=sqr(x)+sqr(y) elseif(x>1.0) r[11]=sqr(x-1.0)+sqr(y) else r[11]=sqr(y) endif r[11]=sqrt(r[11])*cabs(v[2]-v[6]) ; ; 2,3,7 ; t[12]=(pzs-v[7])/(v[2]-v[7]) x=real(t[12]) y=imag(t[12]) if y > 0 out = false endif if(x<0.0) r[12]=sqr(x)+sqr(y) elseif(x>1.0) r[12]=sqr(x-1.0)+sqr(y) else r[12]=sqr(y) endif r[12]=sqrt(r[12])*cabs(v[2]-v[7]) t[13]=(pzs-v[7])/(v[3]-v[7]) x=real(t[13]) y=imag(t[13]) if y > 0 out = false endif if(x<0.0) r[13]=sqr(x)+sqr(y) elseif(x>1.0) r[13]=sqr(x-1.0)+sqr(y) else r[13]=sqr(y) endif r[13]=sqrt(r[13])*cabs(v[3]-v[7]) ; ; 3,4,8 ; t[14]=(pzs-v[8])/(v[3]-v[8]) x=real(t[14]) y=imag(t[14]) if y > 0 out = false endif if(x<0.0) r[14]=sqr(x)+sqr(y) elseif(x>1.0) r[14]=sqr(x-1.0)+sqr(y) else r[14]=sqr(y) endif r[14]=sqrt(r[14])*cabs(v[3]-v[8]) t[15]=(pzs-v[8])/(v[4]-v[8]) x=real(t[15]) y=imag(t[15]) if y > 0 out = false endif if(x<0.0) r[15]=sqr(x)+sqr(y) elseif(x>1.0) r[15]=sqr(x-1.0)+sqr(y) else r[15]=sqr(y) endif r[15]=sqrt(r[15])*cabs(v[4]-v[8]) ; ; 4,5,9 ; t[16]=(pzs-v[9])/(v[4]-v[9]) x=real(t[16]) y=imag(t[16]) if y > 0 out = false endif if(x<0.0) r[16]=sqr(x)+sqr(y) elseif(x>1.0) r[16]=sqr(x-1.0)+sqr(y) else r[16]=sqr(y) endif r[16]=sqrt(r[16])*cabs(v[4]-v[9]) t[17]=(pzs-v[9])/(v[5]-v[9]) x=real(t[17]) y=imag(t[17]) if y > 0 out = false endif if(x<0.0) r[17]=sqr(x)+sqr(y) elseif(x>1.0) r[17]=sqr(x-1.0)+sqr(y) else r[17]=sqr(y) endif r[17]=sqrt(r[17])*cabs(v[5]-v[9]) ; ; 5,1,10 ; t[18]=(pzs-v[10])/(v[1]-v[10]) x=real(t[18]) y=imag(t[18]) if y > 0 out = false endif if(x<0.0) r[18]=sqr(x)+sqr(y) elseif(x>1.0) r[18]=sqr(x-1.0)+sqr(y) else r[18]=sqr(y) endif r[18]=sqrt(r[18])*cabs(v[1]-v[10]) t[19]=(pzs-v[10])/(v[5]-v[10]) x=real(t[19]) y=imag(t[19]) if y > 0 out = false endif if(x<0.0) r[19]=sqr(x)+sqr(y) elseif(x>1.0) r[19]=sqr(x-1.0)+sqr(y) else r[19]=sqr(y) endif r[19]=sqrt(r[19])*cabs(v[5]-v[10]) ; ; 6,7,2 ; t[20]=(pzs-v[7])/(v[6]-v[7]) x=real(t[20]) y=imag(t[20]) if y > 0 out = false endif if(x<0.0) r[20]=sqr(x)+sqr(y) elseif(x>1.0) r[20]=sqr(x-1.0)+sqr(y) else r[20]=sqr(y) endif r[20]=sqrt(r[20])*cabs(v[6]-v[7]) ; ; 7,8,3 ; t[21]=(pzs-v[8])/(v[7]-v[8]) x=real(t[21]) y=imag(t[21]) if y > 0 out = false endif if(x<0.0) r[21]=sqr(x)+sqr(y) elseif(x>1.0) r[21]=sqr(x-1.0)+sqr(y) else r[21]=sqr(y) endif r[21]=sqrt(r[21])*cabs(v[7]-v[8]) ; ; 8,9,4 ; t[22]=(pzs-v[9])/(v[8]-v[9]) x=real(t[22]) y=imag(t[22]) if y > 0 out = false endif if(x<0.0) r[22]=sqr(x)+sqr(y) elseif(x>1.0) r[22]=sqr(x-1.0)+sqr(y) else r[22]=sqr(y) endif r[22]=sqrt(r[22])*cabs(v[8]-v[9]) ; ; 9,10,5 ; t[23]=(pzs-v[9])/(v[10]-v[9]) x=real(t[23]) y=imag(t[23]) if y > 0 out = false endif if(x<0.0) r[23]=sqr(x)+sqr(y) elseif(x>1.0) r[23]=sqr(x-1.0)+sqr(y) else r[23]=sqr(y) endif r[23]=sqrt(r[23])*cabs(v[10]-v[9]) ; ; 10,6,1 ; t[24]=(pzs-v[6])/(v[10]-v[6]) x=real(t[24]) y=imag(t[24]) if y > 0 out = false endif if(x<0.0) r[24]=sqr(x)+sqr(y) elseif(x>1.0) r[24]=sqr(x-1.0)+sqr(y) else r[24]=sqr(y) endif r[24]=sqrt(r[24])*cabs(v[10]-v[6]) ; ; 11,6,7 ; t[25]=(pzs-v[11])/(v[6]-v[11]) x=real(t[25]) y=imag(t[25]) if y > 0 out = false endif if(x<0.0) r[25]=sqr(x)+sqr(y) elseif(x>1.0) r[25]=sqr(x-1.0)+sqr(y) else r[25]=sqr(y) endif r[25]=sqrt(r[25])*cabs(v[6]-v[11]) t[26]=(pzs-v[11])/(v[7]-v[11]) x=real(t[26]) y=imag(t[26]) if y > 0 out = false endif if(x<0.0) r[26]=sqr(x)+sqr(y) elseif(x>1.0) r[26]=sqr(x-1.0)+sqr(y) else r[26]=sqr(y) endif r[26]=sqrt(r[26])*cabs(v[7]-v[11]) ; ; 11,7,8 ; t[27]=(pzs-v[11])/(v[8]-v[11]) x=real(t[27]) y=imag(t[27]) if y > 0 out = false endif if(x<0.0) r[27]=sqr(x)+sqr(y) elseif(x>1.0) r[27]=sqr(x-1.0)+sqr(y) else r[27]=sqr(y) endif r[27]=sqrt(r[27])*cabs(v[8]-v[11]) ; ; 11,8,9 ; t[28]=(pzs-v[11])/(v[9]-v[11]) x=real(t[28]) y=imag(t[28]) if y > 0 out = false endif if(x<0.0) r[28]=sqr(x)+sqr(y) elseif(x>1.0) r[28]=sqr(x-1.0)+sqr(y) else r[28]=sqr(y) endif r[28]=sqrt(r[28])*cabs(v[9]-v[11]) ; ; 11,9,10 ; t[29]=(pzs-v[11])/(v[10]-v[11]) x=real(t[29]) y=imag(t[29]) if y > 0 out = false endif if(x<0.0) r[29]=sqr(x)+sqr(y) elseif(x>1.0) r[29]=sqr(x-1.0)+sqr(y) else r[29]=sqr(y) endif r[29]=sqrt(r[29])*cabs(v[10]-v[11]) elseif @polygontype == "Dodecahedron" ; ; 0,1,2,3,4 ; repeat t[i]=(pzs-v[i])/(v[i+1]-v[i]) x=real(t[i]) y=imag(t[i]) if y > 0 out = false endif if(x<0.0) r[i]=sqr(x)+sqr(y) elseif(x>1.0) r[i]=sqr(x-1.0)+sqr(y) else r[i]=sqr(y) endif r[i]=sqrt(r[i])*cabs(v[i+1]-v[i]) i = i + 1 until i == 5 t[4]=(pzs-v[4])/(v[0]-v[4]) x=real(t[4]) y=imag(t[4]) if y > 0 out = false endif if(x<0.0) r[4]=sqr(x)+sqr(y) elseif(x>1.0) r[4]=sqr(x-1.0)+sqr(y) else r[4]=sqr(y) endif r[4]=sqrt(r[4])*cabs(v[0]-v[4]) ; ; 0,1,6,10,5 ; t[5]=(pzs-v[5])/(v[0]-v[5]) x=real(t[5]) y=imag(t[5]) if y > 0 out = false endif if(x<0.0) r[5]=sqr(x)+sqr(y) elseif(x>1.0) r[5]=sqr(x-1.0)+sqr(y) else r[5]=sqr(y) endif r[5]=sqrt(r[5])*cabs(v[0]-v[5]) t[6]=(pzs-v[5])/(v[10]-v[5]) x=real(t[6]) y=imag(t[6]) if y > 0 out = false endif if(x<0.0) r[6]=sqr(x)+sqr(y) elseif(x>1.0) r[6]=sqr(x-1.0)+sqr(y) else r[6]=sqr(y) endif r[6]=sqrt(r[6])*cabs(v[10]-v[5]) t[7]=(pzs-v[6])/(v[10]-v[6]) x=real(t[7]) y=imag(t[7]) if y > 0 out = false endif if(x<0.0) r[7]=sqr(x)+sqr(y) elseif(x>1.0) r[7]=sqr(x-1.0)+sqr(y) else r[7]=sqr(y) endif r[7]=sqrt(r[7])*cabs(v[10]-v[6]) t[8]=(pzs-v[6])/(v[1]-v[6]) x=real(t[8]) y=imag(t[8]) if y > 0 out = false endif if(x<0.0) r[8]=sqr(x)+sqr(y) elseif(x>1.0) r[8]=sqr(x-1.0)+sqr(y) else r[8]=sqr(y) endif r[8]=sqrt(r[8])*cabs(v[1]-v[6]) ; ; 1,2,7,11,6 ; t[9]=(pzs-v[7])/(v[2]-v[7]) x=real(t[9]) y=imag(t[9]) if y > 0 out = false endif if(x<0.0) r[9]=sqr(x)+sqr(y) elseif(x>1.0) r[9]=sqr(x-1.0)+sqr(y) else r[9]=sqr(y) endif r[9]=sqrt(r[9])*cabs(v[2]-v[7]) ; t[10]=(pzs-v[11])/(v[7]-v[11]) x=real(t[10]) y=imag(t[10]) if y > 0 out = false endif if(x<0.0) r[10]=sqr(x)+sqr(y) elseif(x>1.0) r[10]=sqr(x-1.0)+sqr(y) else r[10]=sqr(y) endif r[10]=sqrt(r[10])*cabs(v[7]-v[11]) t[11]=(pzs-v[11])/(v[6]-v[11]) x=real(t[11]) y=imag(t[11]) if y > 0 out = false endif if(x<0.0) r[11]=sqr(x)+sqr(y) elseif(x>1.0) r[11]=sqr(x-1.0)+sqr(y) else r[11]=sqr(y) endif r[11]=sqrt(r[11])*cabs(v[6]-v[11]) ; ; 2,3,8,12,7 ; t[12]=(pzs-v[8])/(v[3]-v[8]) x=real(t[12]) y=imag(t[12]) if y > 0 out = false endif if(x<0.0) r[12]=sqr(x)+sqr(y) elseif(x>1.0) r[12]=sqr(x-1.0)+sqr(y) else r[12]=sqr(y) endif r[12]=sqrt(r[12])*cabs(v[3]-v[8]) t[13]=(pzs-v[12])/(v[8]-v[12]) x=real(t[13]) y=imag(t[13]) if y > 0 out = false endif if(x<0.0) r[13]=sqr(x)+sqr(y) elseif(x>1.0) r[13]=sqr(x-1.0)+sqr(y) else r[13]=sqr(y) endif r[13]=sqrt(r[13])*cabs(v[8]-v[12]) t[14]=(pzs-v[12])/(v[7]-v[12]) x=real(t[14]) y=imag(t[14]) if y > 0 out = false endif if(x<0.0) r[14]=sqr(x)+sqr(y) elseif(x>1.0) r[14]=sqr(x-1.0)+sqr(y) else r[14]=sqr(y) endif r[14]=sqrt(r[14])*cabs(v[7]-v[12]) ; ; 3,4,9,13,8 ; t[15]=(pzs-v[9])/(v[4]-v[9]) x=real(t[15]) y=imag(t[15]) if y > 0 out = false endif if(x<0.0) r[15]=sqr(x)+sqr(y) elseif(x>1.0) r[15]=sqr(x-1.0)+sqr(y) else r[15]=sqr(y) endif r[15]=sqrt(r[15])*cabs(v[4]-v[9]) t[16]=(pzs-v[13])/(v[9]-v[13]) x=real(t[16]) y=imag(t[16]) if y > 0 out = false endif if(x<0.0) r[16]=sqr(x)+sqr(y) elseif(x>1.0) r[16]=sqr(x-1.0)+sqr(y) else r[16]=sqr(y) endif r[16]=sqrt(r[16])*cabs(v[9]-v[13]) t[17]=(pzs-v[8])/(v[13]-v[8]) x=real(t[17]) y=imag(t[17]) if y > 0 out = false endif if(x<0.0) r[17]=sqr(x)+sqr(y) elseif(x>1.0) r[17]=sqr(x-1.0)+sqr(y) else r[17]=sqr(y) endif r[17]=sqrt(r[17])*cabs(v[13]-v[8]) ; ; 4,0,5,14,9 ; t[18]=(pzs-v[5])/(v[14]-v[5]) x=real(t[18]) y=imag(t[18]) if y > 0 out = false endif if(x<0.0) r[18]=sqr(x)+sqr(y) elseif(x>1.0) r[18]=sqr(x-1.0)+sqr(y) else r[18]=sqr(y) endif r[18]=sqrt(r[18])*cabs(v[14]-v[5]) t[19]=(pzs-v[9])/(v[14]-v[9]) x=real(t[19]) y=imag(t[19]) if y > 0 out = false endif if(x<0.0) r[19]=sqr(x)+sqr(y) elseif(x>1.0) r[19]=sqr(x-1.0)+sqr(y) else r[19]=sqr(y) endif r[19]=sqrt(r[19])*cabs(v[14]-v[9]) ; ; 15,16,11,6,10 ; t[20]=(pzs-v[16])/(v[11]-v[16]) x=real(t[20]) y=imag(t[20]) if y > 0 out = false endif if(x<0.0) r[20]=sqr(x)+sqr(y) elseif(x>1.0) r[20]=sqr(x-1.0)+sqr(y) else r[20]=sqr(y) endif r[20]=sqrt(r[20])*cabs(v[11]-v[16]) t[21]=(pzs-v[15])/(v[16]-v[15]) x=real(t[21]) y=imag(t[21]) if y > 0 out = false endif if(x<0.0) r[21]=sqr(x)+sqr(y) elseif(x>1.0) r[21]=sqr(x-1.0)+sqr(y) else r[21]=sqr(y) endif r[21]=sqrt(r[21])*cabs(v[16]-v[15]) t[22]=(pzs-v[10])/(v[15]-v[10]) x=real(t[22]) y=imag(t[22]) if y > 0 out = false endif if(x<0.0) r[22]=sqr(x)+sqr(y) elseif(x>1.0) r[22]=sqr(x-1.0)+sqr(y) else r[22]=sqr(y) endif r[22]=sqrt(r[22])*cabs(v[15]-v[10]) ; ; 16,17,12,7,11 ; t[23]=(pzs-v[17])/(v[12]-v[17]) x=real(t[23]) y=imag(t[23]) if y > 0 out = false endif if(x<0.0) r[23]=sqr(x)+sqr(y) elseif(x>1.0) r[23]=sqr(x-1.0)+sqr(y) else r[23]=sqr(y) endif r[23]=sqrt(r[23])*cabs(v[12]-v[17]) t[24]=(pzs-v[16])/(v[17]-v[16]) x=real(t[24]) y=imag(t[24]) if y > 0 out = false endif if(x<0.0) r[24]=sqr(x)+sqr(y) elseif(x>1.0) r[24]=sqr(x-1.0)+sqr(y) else r[24]=sqr(y) endif r[24]=sqrt(r[24])*cabs(v[17]-v[16]) ; ; 17,18,13,8,12 ; t[25]=(pzs-v[18])/(v[13]-v[18]) x=real(t[25]) y=imag(t[25]) if y > 0 out = false endif if(x<0.0) r[25]=sqr(x)+sqr(y) elseif(x>1.0) r[25]=sqr(x-1.0)+sqr(y) else r[25]=sqr(y) endif r[25]=sqrt(r[25])*cabs(v[13]-v[18]) t[26]=(pzs-v[17])/(v[18]-v[17]) x=real(t[26]) y=imag(t[26]) if y > 0 out = false endif if(x<0.0) r[26]=sqr(x)+sqr(y) elseif(x>1.0) r[26]=sqr(x-1.0)+sqr(y) else r[26]=sqr(y) endif r[26]=sqrt(r[26])*cabs(v[18]-v[17]) ; ; 18,19,14,9,13 ; t[27]=(pzs-v[19])/(v[14]-v[19]) x=real(t[27]) y=imag(t[27]) if y > 0 out = false endif if(x<0.0) r[27]=sqr(x)+sqr(y) elseif(x>1.0) r[27]=sqr(x-1.0)+sqr(y) else r[27]=sqr(y) endif r[27]=sqrt(r[27])*cabs(v[14]-v[19]) t[28]=(pzs-v[18])/(v[19]-v[18]) x=real(t[28]) y=imag(t[28]) if y > 0 out = false endif if(x<0.0) r[28]=sqr(x)+sqr(y) elseif(x>1.0) r[28]=sqr(x-1.0)+sqr(y) else r[28]=sqr(y) endif r[28]=sqrt(r[28])*cabs(v[19]-v[18]) ; ; 19,15,10,5,14 ; t[29]=(pzs-v[15])/(v[19]-v[15]) x=real(t[29]) y=imag(t[29]) if y > 0 out = false endif if(x<0.0) r[29]=sqr(x)+sqr(y) elseif(x>1.0) r[29]=sqr(x-1.0)+sqr(y) else r[29]=sqr(y) endif r[29]=sqrt(r[29])*cabs(v[19]-v[15]) endif i = 0 repeat if r[i] < @thick if r[i] != 0 d = r[i] endif m_LastZ = m_LastZ + t[i] endif i = i + 1 until i == side m_lastZ = m_lastZ/(side)^2 return d endfunc protected: float r[30] float vx[20] float vy[20] float vz[20] complex v[30] complex t[30] float twopi int seed float mx float my int i float x float y bool out int vertex int side float d float rotx float roty float rotz default: title = "Platonic Solids" int param v_trapshapeplatonicsolids caption = "Version (Trap Shape Platonic Solids)" 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_trapshapeplatonicsolids < 100 endparam heading text = "This is a TrapShape that is still under development. I will try to \ maintain backwards compatibility, but I cannot guarantee it. The \ Trapshape creates solid and outline regular polygons from 3 sides \ to 10 sides." endheading param polygontype caption = "Polygon Type" default = 1 enum = "Tetrahedron" "Cube" "Octahedron" "Icosahedron" "Dodecahedron" endparam heading text = "Rotations around the X, Y and Z axes." endheading float param rotx caption = "X axis" default = 20 endparam float param roty caption = "Y axis" default = 20 endparam float param rotz caption = "Z axis" default = 0 endparam float param size caption = "Polygon size" default = 0.2 endparam float param thick caption = "Line thickness" default = 0.02 endparam } class REB_TrapShapeSolid_OutlinePolygons(common.ulb:TrapShape) { public: import "common.ulb" import "reb.ulb" $define debug ; Constructor func REB_TrapShapeSolid_OutlinePolygons(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; call before each iteration func Init(complex pz) TrapShape.Init(pz) twopi = 2*#pi seed = @mseed mx = 0 my = 0 i = 0 x = 0.0 y = 0.0 out = false repeat if @morph seed = random (seed) mx = 0.1*seed/#randomrange seed = random(seed) my = 0.1*seed/#randomrange endif if @inside vx[i] = sin(i*twopi/@sides)*(1+10*mx/@sides) vy[i] = cos(i*twopi/@sides)*(1+10*my/@sides) else vx[i] = cos(i*twopi/@sides)*(1+10*mx/@sides) vy[i] = sin(i*twopi/@sides)*(1+10*my/@sides) endif v[i] = vx[i] + flip(vy[i]) i = i + 1 until i == @sides endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) complex lim = (100,0) if !@inside d = 1e10 else d = 0 endif size = @size if @inside if @sides == 3 size = size/350.877 elseif @sides == 4 size = size/200.000 elseif @sides == 5 size = size/145.985 elseif @sides == 6 size = size/115.607 elseif @sides == 7 size = size/96.618 elseif @sides == 8 size = size/82.987 elseif @sides == 9 size = size/72.993 elseif @sides == 10 size = size/65.146 endif endif complex pzs = pz/size i = 0 ; ; calculate r[i] and t[i] for first n-1 sides ; repeat t[i]=(pzs-v[i])/(v[i+1]-v[i]) x=real(t[i]) y=imag(t[i]) if y > 0 out = false endif if(x<0.0) r[i]=sqr(x)+sqr(y) elseif(x>1.0) r[i]=sqr(x-1.0)+sqr(y) else r[i]=sqr(y) endif r[i]=sqrt(r[i])*cabs(v[i+1]-v[i]) i = i + 1 until i == (@sides-1) ; ; calculate r[i] and t[i] for the last side ; t[@sides-1]=(pzs-v[@sides-1])/(v[0]-v[@sides-1]) x=real(t[@sides-1]) y=imag(t[@sides-1]) if y > 0 out = false endif if(x<0.0) r[@sides-1]=sqr(x)+sqr(y) elseif(x>1.0) r[@sides-1]=sqr(x-1.0)+sqr(y) else r[@sides-1]=sqr(y) endif r[@sides-1]=sqrt(r[@sides-1])*cabs(v[0]-v[@sides-1]) i = 0 repeat if ((r[i] < @thick)&&!@inside) || (!out && t[i] > lim) d = r[i] m_LastZ = m_LastZ + t[i] endif i = i + 1 until i == @sides m_lastZ = m_lastZ/@sides^2 return d endfunc protected: complex v[10] complex t[10] float r[10] float vx[10] float vy[10] float twopi int seed float mx float my int i float x float y bool out float d default: title = "Polygons" int param v_trapshapesolidpolygon caption = "Version (Trap Shape Solid and Outlined Polygons)" 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_trapshapesolidpolygon < 100 endparam heading text = "This is a TrapShape that is still under development. I will try to \ maintain backwards compatibility, but I cannot guarantee it. The \ Trapshape creates solid and outline regular polygons from 3 sides \ to 10 sides." endheading int param sides caption="# of sides" default = 5 min = 3 max = 10 endparam float param size caption = "Polygon size" default = 0.2 endparam float param thick caption = "Line thickness" default = 0.02 visible = !@inside endparam bool param morph caption="Morph the polygon" default=false endparam int param mseed caption = "Morph seed" default = 123456789 visible = @morph endparam bool param inside caption = "Solid Polygon" default = false endparam } class REB_RangeColoringWrapper(common.ulb:TrapShape) { ; Based upone JLB_Range Coloring. public: import "common.ulb" ; Constructor func REB_RangeColoringWrapper(Generic pparent) TrapShape.TrapShape(pparent) m_TrapShape = new @f_TrapShape(this) endfunc func Init(complex pz) m_TrapShape.Init(pz) m_RangeLow = @p_scale*(1.0-0.5*@p_width) m_RangeHigh = @p_scale*(1.0+0.5*@p_width) ang = -@p_rot*#pi/180 m_Rotate = cos(ang) + flip(sin(ang)) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) pz = pz * m_Rotate dist = m_TrapShape.Iterate(pz) m_LastZ = m_TrapShape.m_LastZ dmin = dist*m_RangeLow dmax = dist*m_RangeHigh dist = cabs(pz - @p_Center) if((dist >= dmin) && (dist <= dmax)) ; in the range dist = (dist-dmin)/(dmax-dmin) ; 0 <= dist <= 1 else dist = 1e100 endif return dist endfunc trapshape m_trapshape float m_RangeLow float m_RangeHigh complex m_Rotate float dist float dmin float dmax float ang default: title = "Range Coloring Wrapper" int param v_RangeColoringWrapper caption = "Version (Range Coloring Wrapper)" 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_RangeColoringWrapper < 100 endparam TrapShape param f_TrapShape caption = "TrapShape" default = REB_TrapShapeBifolium endparam param p_scale caption = "Range scale" default = 0.9 endparam param p_width caption = "Range width" default = 0.1 endparam complex param p_Center caption = "Curve center" default = (0.0,0.0) endparam float param p_rot caption = "Rotation angle" default = 0.0 hint = "degrees" endparam } class TrapShapeDoodads(common.ulb:TrapShape) { ; transcribed from the Doodads traps of Dennis Magar. ; I have been unable to contact Dennis. If he objects I will remove ; the trapshape. public: import "common.ulb" func TrapShapeDoodads(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; call before each iteration func Init(complex pz) TrapShape.Init(pz) x = 0 y = 0 zr = 0 zi = 0 zz = 0 z1 = 0 a2 = 0 s1 = 0 g1 = 0 ff = 0 gc = 0 zc = 0 fc = 0 zr1 = 0 zi1 = 0 fmr = real(@fm) fmi = imag(@fm) sn = 1 if @m % 2 == 1 sn = -1 endif vsa = sn*@sa/10 vsb = abs(@sb/10) endfunc ; call for each iterated point float func Iterate(complex pz) TrapShape.Iterate(pz) z1 = pz zc = @fn4(z1) zr = real(zc) zi = imag(zc) if (@m > 3 && @m < 26) || @mr == 5 || @mr == 8 \ || @mr == 9 || @mr == 12 gc = @fn3(@fn1(@fn2(z1))) g1 = cabs(gc) endif if @m == 7 || @mr == 5 a2 = atan2(gc) endif if @m == 8 || @m == 9 || @m == 12 || @m == 13 \ || @m > 19 || @mr == 9 || @mr == 11 s1 = cabs(zc) endif if @m == 12 || @m == 13 || @m == 22 || @m == 23 \ || @m == 26 || @m == 27 || @mr == 10 || @mr == 12 ff = cabs(@fn3(@fn1(real(z1))+@fn2(imag(z1)))) endif if @m >27 fc = @fn3(@fn1(real(z1))+flip(@fn2(imag(z1)))) endif if @mr < 5 || @mr >= 13 zr1 = real(@fn1(zr*fmr)) zi1 = real(@fn2(zi*fmi)) endif if @mrf zr1 = abs(zr1) zi1 = abs(zi1) endif if @mr == 0 zz = real(@fn3(zr1*zi1)) elseif @mr == 1 zz = real(@fn3(zr1+zi1)) elseif @mr == 2 zz = real(@fn3(zr1/zi1)) elseif @mr == 3 zz = real(@fn3(zi1^zr1)) elseif @mr == 4 zz = real(@fn3(zr1^zi1)) elseif @mr == 5 zz = real(@fn4(@fn3(abs(@fn1(g1*fmr)-@fn2(a2*fmi))))) elseif @mr == 6 if !@mrf zz = real(atan(@fn3(@fn1(zr*fmr)) \ /(@fn3(@fn2(zi^2*fmi))))) else zz = real(atan(@fn3(abs(@fn1(zr*fmr)) \ /(@fn3(abs(@fn2(zi^2*fmi))))))) endif elseif @mr == 7 zz = cabs(recip(@fn3(@fn2(@fn1(zc*fmr*2))))) elseif @mr == 8 zz = real(@fn3(@fn1(abs((g1-zr)*fmr/(g1-zi)*fmi))))^.1 elseif @mr == 9 float temp = abs((g1-zr)*fmr/(g1+1e-20)) zz = real(@fn3(abs(@fn1(temp)-@fn2(s1*fmi)))) elseif @mr == 10 zz = cabs(@fn4(ff*fmr-gc*fmi))^2 elseif @mr == 11 zz = cabs(@fn4(s1-1)*fmr/(s1+1)*fmi) elseif @mr == 12 zz = cabs(@fn4(g1)*fmr/(ff)*fmi) elseif @mr == 13 zz = real(@fn3(zi1/zr1)) elseif @mr == 14 zz = real(@fn3((zi1*zr1)/(zi1+zr1))) elseif @mr == 15 zz = real(@fn3((zi1-zr1)/(zi1+zr1))) endif if @m < 2 y = zr elseif @m == 2 || @m == 3 y = zr*3-zi elseif @m == 4 y = abs(g1^3/(zr-g1)) elseif @m == 5 y = zr/2+g1 elseif @m == 6 y = g1^3 elseif @m == 7 y = g1^2/a2 elseif @m == 8 || @m == 9 y = zr*s1/zi elseif @m == 10 || @m == 11 y = g1^2 elseif @m == 12 || @m == 13 y = g1-abs((ff-g1)/s1) elseif @m == 14 || @m == 15 y = g1-zr/g1 elseif @m == 16 || @m == 17 y = g1-abs(zr/g1) elseif @m == 18 || @m == 19 y = g1 elseif @m == 20 || @m == 21 y = s1*.1/g1^2 elseif @m == 22 || @m == 23 y = g1^2-abs((ff-g1)/s1) elseif @m == 24 || @m == 25 y = g1^2-s1 elseif @m == 26 || @m == 27 y = ff else y = imag(fc) endif y = real(@fn9(y - @tad/10)) if @sa < 0 && sn == -1 y = y * (-@sa+5)/5 vsa = sn*@sa/20 endif if @sb > 0 y = y % vsb endif if @m % 2 == 0 x = zz - @mul*(real(abs(@fn1(y - abs(@fn2(y)))))) else x = zz - @mul*y endif if @sb < 0 x = x % vsb endif x = x + vsa xb = (@fn8(x + flip(y)))^@pwr zz = cabs(z1 - xb) m_lastz = xb return zz endfunc protected: float x float y float zr float zi float zz float a2 float s1 float g1 float ff complex gc complex zc complex fc complex z1 float zr1 float zi1 float fmr float fmi int sn float vsa float vsb default: title = "Doodad Traps" int param v_doodad caption = "Version (Doodad Traps)" 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_doodad < 100 endparam param trp caption = "More Trap Parameters" hint = "Additional parameters less frequently used." default = true endparam param m caption = " Trap Mode" enum = "1" "2" "3" "4" "5" "6" "7" "8" \ "9" "A" "B" "C" "D" "E" "F" "G" \ "H" "I" "J" "K" "L" "M" "N" "O" \ "P" "Q" "R" "S" "T" "U" default = 0 endparam param mr caption = "Flavor" enum = "A" "B" "C" "D" "E" "F" "G" \ "H" "I" "J" "K" "L" "M" "N" \ "O" "P" default = 0 endparam param mrf caption = "Apply ABS to Flavor" default = false visible = @mr < 5 && @trp endparam param tad caption = "Trap Addend" default = 0.0 visible = @trp endparam param fm caption = "Flavor Multiplier" default = (1,1) visible = @trp endparam param pwr caption = "`Trap Power'" default = 3.0 visible = @trp endparam param mul caption = " Trap Multiplier" default = 3.0 visible = @trp endparam param sb caption = "'Ripple' Control" hint = "A few Trap Modes are unaffected by this \ parameter. Useful Range is -50 to 50" default = 0.0 visible = @trp endparam param sa caption = "Expand+|-Contract" hint = "Useful Range is around -10 to 10" default = 0.0 visible = @trp endparam heading caption = "Functions" endheading func fn4 caption = "Initial function" default = ident() endfunc func fn1 caption = "Real function" default = ident() endfunc func fn2 caption = "Imag function" default = ident() endfunc func fn3 caption = "Overall function" default = ident() endfunc func fn9 caption = "First Trap function" default = ident() visible = @trp endfunc func fn8 caption = "Final Trap function" default = ident() endfunc } class REB_ShapeTextureMerge(common.ulb:TrapShape) { ; This is a wrappoer transform which allows you to use 2-3 ; trap shapes an trap shape textures in a trap shape slot. ; If you need more than three trap shapes, put a TrapShapeTextureMerge ; object in one or more of the slots. $define debug public: import "common.ulb" import "dmj5.ulb" func REB_ShapeTextureMerge(Generic pparent) TrapShape.TrapShape(pparent) int a = 0 int b = 1 int c = 2 if @trapno == "2" if @merge_order2 == "2 1" a = 1 b = 0 endif endif if @trapno == "2" m_Enables[a] = true m_Enables[b] = true m_Enables[c] = false m_tmax = 2 else m_Enables[a] = true m_Enables[b] = true m_Enables[c] = true m_tmax = 3 endif m_Elements[a] = new @f_trapshape1(this) m_Elements[b] = new @f_trapshape2(this) m_Elements[c] = new @f_trapshape3(this) weightF[a] = @weightf1 weightF[b] = @weightf2 weightF[c] = @weightf3 endfunc func Init(complex pz) TrapShape.Init(pz) m_TextureValue = 0 int j = 0 while (j < m_tmax) if (m_Enables[j]) m_Elements[j].Init(pz) distance[j] = 0 distance3[j] = 0 endif j = j + 1 endwhile dist = 0 endfunc float func Iterate(complex pz) TrapShape.Iterate(pz) if m_Enables[0] distance[0] = m_Elements[0].Iterate(pz)*weightf[0] LastZ[0] = m_Elements[0].GetTransformedPoint() if @v_REB_ShapeTextureMerge < 101 if @tamode == "-A" distance[0] = - distance[0] elseif @tamode == "|A|" distance[0] = abs(distance[0]) elseif @tamode == "A*A" distance[0] = distance[0]*distance[0] elseif @tamode == "-A*A" distance[0] = -distance[0]*distance[0] elseif @tamode == "A*A*A" distance[0] = distance[0]*distance[0]*distance[0] elseif @tamode == "-A*A*A" distance[0] = -distance[0]*distance[0]*distance[0] elseif @tamode == "|A*A*A|" distance[0] = abs(distance[0]*distance[0]*distance[0]) elseif @tamode == "log(A)" distance[0] = log(distance[0]) elseif @tamode == "exp(A)" distance[0] = exp(distance[0]) endif else if @tamode2 == "-A" distance[0] = - distance[0] elseif @tamode2 == "|A|" distance[0] = abs(distance[0]) elseif @tamode2 == "A*A" distance[0] = distance[0]*distance[0] elseif @tamode2 == "-A*A" distance[0] = -distance[0]*distance[0] elseif @tamode2 == "A*A*A" distance[0] = distance[0]*distance[0]*distance[0] elseif @tamode2 == "-A*A*A" distance[0] = -distance[0]*distance[0]*distance[0] elseif @tamode2 == "|A*A*A|" distance[0] = abs(distance[0]*distance[0]*distance[0]) endif distance[0] = real(@mFuncA(distance[0])) endif endif if m_Enables[1] distance[1] = m_Elements[1].Iterate(pz)*weightf[1] LastZ[1] = m_Elements[1].GetTransformedPoint() if @v_REB_ShapeTextureMerge < 101 if @tbmode == "-B" distance[1] = - distance[1] elseif @tbmode == "|B|" distance[1] = abs(distance[1]) elseif @tbmode == "B*B" distance[1] = distance[1]*distance[1] elseif @tbmode == "-B*B" distance[1] = -distance[1]*distance[1] elseif @tbmode == "B*B*B" distance[1] = distance[1]*distance[1]*distance[1] elseif @tbmode == "-B*B*B" distance[1] = -distance[1]*distance[1]*distance[1] elseif @tbmode == "|B*B*B|" distance[1] = abs(distance[1]*distance[1]*distance[1]) elseif @tbmode == "log(B)" distance[1] = log(distance[1]) elseif @tbmode == "exp(B)" distance[1] = exp(distance[1]) endif else if @tbmode2 == "-B" distance[1] = - distance[1] elseif @tbmode2 == "|B|" distance[1] = abs(distance[1]) elseif @tbmode2 == "B*B" distance[1] = distance[1]*distance[1] elseif @tbmode2 == "-B*B" distance[1] = -distance[1]*distance[1] elseif @tbmode2 == "B*B*B" distance[1] = distance[1]*distance[1]*distance[1] elseif @tbmode2 == "-B*B*B" distance[1] = -distance[1]*distance[1]*distance[1] elseif @tbmode2 == "|B*B*B|" distance[1] = abs(distance[1]*distance[1]*distance[1]) endif distance[1] = real(@mFuncB(distance[1])) endif endif if m_Enables[2] distance[2] = m_Elements[2].Iterate(pz)*weightf[2] LastZ[2] = m_Elements[2].GetTransformedPoint() if @v_REB_ShapeTextureMerge < 101 if @tcmode == "-C" distance[2] = - distance[2] elseif @tcmode == "|C|" distance[2] = abs(distance[2]) elseif @tcmode == "C*C" distance[2] = distance[2]*distance[2] elseif @tcmode == "-C*C" distance[2] = -distance[2]*distance[2] elseif @tcmode == "C*C*C" distance[2] = distance[2]*distance[2]*distance[2] elseif @tcmode == "-C*C*C" distance[2] = -distance[2]*distance[2]*distance[2] elseif @tcmode == "|C*C*C|" distance[2] = abs(distance[2]*distance[2]*distance[2]) elseif @tcmode == "log(C)" distance[2] = log(distance[2]) elseif @tcmode == "exp(C)" distance[2] = exp(distance[2]) endif else if @tcmode2 == "-C" distance[2] = - distance[2] elseif @tcmode2 == "|C|" distance[2] = abs(distance[2]) elseif @tcmode2 == "C*C" distance[2] = distance[2]*distance[2] elseif @tcmode2 == "-C*C" distance[2] = -distance[2]*distance[2] elseif @tcmode2 == "C*C*C" distance[2] = distance[2]*distance[2]*distance[2] elseif @tcmode2 == "-C*C*C" distance[2] = -distance[2]*distance[2]*distance[2] elseif @tcmode2 == "|C*C*C|" distance[2] = abs(distance[2]*distance[2]*distance[2]) endif distance[2] = real(@mFuncC(distance[2])) endif endif if @trapno == "3" if @tterm31 == "A" distance3[0] = distance[0] elseif @tterm31 == "1/A" distance3[0] = 1/distance[0] elseif @tterm31 == "B" distance3[0] = distance[1] elseif @tterm31 == "1/B" distance3[0] = 1/distance[1] elseif @tterm31 == "C" distance3[0] = distance[2] elseif @tterm31 == "1/C" distance3[0] = 1/distance[2] endif if @tterm32 == "A" distance3[1] = distance[0] elseif @tterm32 == "1/A" distance3[1] = 1/distance[0] elseif @tterm32 == "B" distance3[1] = distance[1] elseif @tterm32 == "1/B" distance3[1] = 1/distance[1] elseif @tterm32 == "C" distance3[1] = distance[2] elseif @tterm32 == "1/C" distance3[1] = 1/distance[2] endif if @tterm33 == "A" distance3[2] = distance[0] elseif @tterm33 == "1/A" distance3[2] = 1/distance[0] elseif @tterm33 == "B" distance3[2] = distance[1] elseif @tterm33 == "1/B" distance3[2] = 1/distance[1] elseif @tterm33 == "C" distance3[2] = distance[2] elseif @tterm33 == "1/C" distance3[2] = 1/distance[2] endif endif if @trapno == "2" if @p_mergemode == "minimum" float dmin = 1e100 if distance[0] < distance[1] dmin = distance[0] m_lastz = lastz[0] else dmin = distance[1] m_lastz = lastz[1] endif return dmin elseif @p_mergemode == "maximum" float dmax = -1e100 if distance[0] > distance[1] dmax = distance[0] m_lastz = lastz[0] else dmax = distance[1] m_lastz = lastz[1] endif return dmax elseif @p_mergemode == "add" m_lastZ = lastz[0] + lastz[1] return distance[0]+distance[1] elseif @p_mergemode == "|A-B|" m_LastZ = abs(lastz[0] - lastz[1]) return abs(distance[0]-distance[1]) elseif @p_mergemode == "multiply" m_LastZ = lastz[0]*lastz[1] return distance[0]*distance[1] elseif @p_mergemode == "divide" m_LastZ = lastz[0]/lastz[1] if distance[1] == 0 distance[1] = 1e-10 endif return distance[0]/distance[1] elseif @p_mergemode == "1/(A*B)" m_lastZ = 1/(lastz[0]*lastz[1]) return 1/(distance[0]*distance[1]) elseif @p_mergemode == "exponentiate" m_lastZ = lastz[0]^lastz[1] return distance[0]^distance[1] elseif @p_mergemode == "A" m_lastZ = lastz[0] return distance[0] elseif @p_mergemode == "B" m_lastZ = lastz[1] return distance[1] elseif @p_mergemode == "and" if distance[0] < @width && distance[1] < @width dist = distance[0] m_lastZ = lastz[0] else dist = @width m_lastZ = @width endif return dist elseif @p_mergemode == "or" if distance[0] < @width dist = distance[0] m_lastZ = lastz[0] elseif distance[1] < @width dist = distance[1] m_lastZ = lastz[1] else dist = @width m_lastz = @width endif return dist elseif @p_mergemode == "xor" if distance[0] < @width && distance[1] >= @width dist = distance[0] m_lastZ = lastz[0] elseif distance[1] < @width && distance[0] >= @width dist = distance[1] m_lastZ = lastz[1] else dist = @width m_lastz = @width endif return dist endif elseif @trapno == "3" if @tmerge1 == "+" dist = distance3[0]+distance3[1] m_lastZ = lastz[0] + lastz[1] elseif @tmerge1 == "*" dist = distance3[0]*distance3[1] m_lastZ = lastz[0] * lastz[1] elseif @tmerge1 == "^" dist = distance3[0]^distance3[1] m_lastZ = lastz[0] ^ lastz[1] elseif @tmerge1 == "min" if distance3[0] < distance3[1] dist = distance3[0] m_lastZ = lastz[0] else dist = distance3[1] m_lastZ = lastz[1] endif elseif @tmerge1 == "max" if distance3[0] > distance3[1] dist = distance3[0] m_lastZ = lastz[0] else dist = distance3[1] m_lastZ = lastz[1] endif elseif @tmerge1 == "and" if distance3[0] < @width && distance3[1] < @width dist = distance3[0] m_lastZ = lastz[0] else dist = @width m_lastZ = @width endif elseif @tmerge1 == "or" if distance3[0] < @width dist = distance3[0] m_lastZ = lastz[0] elseif distance3[1] < @width dist = distance3[1] m_lastZ = lastz[1] else dist = @width m_lastZ = @width endif elseif @tmerge1 == "xor" if distance3[0] < @width && distance3[1] >= @width dist = distance3[0] m_lastZ = lastz[0] elseif distance3[1] < @width && distance3[0] >= @width dist = distance3[1] m_lastZ = lastz[1] else dist = @width m_lastZ = @width endif endif if @tmerge2 == "+" dist = dist+distance3[2] m_lastZ = m_lastz + lastz[2] elseif @tmerge2 == "*" dist = dist*distance3[2] m_lastZ = m_lastz * lastz[2] elseif @tmerge2 == "^" dist = dist^distance3[2] m_lastZ = m_lastz ^ lastz[2] elseif @tmerge2 == "min" if dist < distance3[2] ; else dist = distance3[2] m_lastZ = lastz[2] endif elseif @tmerge2 == "max" if dist > distance3[2] ; else dist = distance3[2] m_lastZ = lastz[2] endif elseif @tmerge2 == "and" if dist < @width && distance3[2] < @width ; else dist = @width m_lastZ = @width endif elseif @tmerge2 == "or" if dist < @width ; elseif distance3[2] < @width dist = distance3[2] m_lastZ = lastz[2] else dist = @width m_lastZ = @width endif elseif @tmerge2 == "xor" if dist < @width && distance3[2] >= @width ; elseif distance3[2] < @width && dist >= @width dist = distance3[2] m_lastZ = lastz[2] else dist = @width m_lastZ = @width endif endif return dist endif return 0 endfunc func SetThreshold(float pthreshold) int j = 0 while (j < 3) if (m_Enables[j]) m_Elements[j].SetThreshold(pthreshold) endif j = j + 1 endwhile endfunc complex func GetTransformedPoint() return m_LastZ endfunc protected: bool m_Enables[3] float distance[3] float distance3[3] TrapShape m_Elements[3] float weightF[3] float m_TextureValue int m_tmax complex lastz[3] float dist default: title = "Trap Shape/Texture Merge" int param v_REB_ShapeTextureMerge caption = "Version (Trap Shape/Texture Merge)" default = 101 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_REB_ShapeTextureMerge < 101 endparam param tamode caption = "Trap A Mode" default = 0 enum = "A" "-A" "|A|" "A*A" "-A*A" "A*A*A" "-A*A*A" "|A*A*A|" "log(A)" "exp(A)" visible = @v_REB_ShapeTextureMerge < 101 endparam param tamode2 caption = "Trap A Mode" default = 0 enum = "A" "-A" "|A|" "A*A" "-A*A" "A*A*A" "-A*A*A" "|A*A*A|" visible = @v_REB_ShapeTextureMerge >= 101 endparam param tbmode caption = "Trap B Mode" default = 0 enum = "B" "-B" "|B|" "B*B" "-B*B" "B*B*B" "-B*B*B" "|B*B*B|" "log(B)" "exp(B)" visible = @v_REB_ShapeTextureMerge < 101 endparam param tcmode caption = "Trap C Mode" default = 0 enum = "C" "-C" "|C|" "C*C" "-C*C" "C*C*C" "-C*C*C" "|C*C*C|" "log(C)" "exp(C)" visible = @trapno == 1 && @v_REB_ShapeTextureMerge < 101 endparam param tbmode2 caption = "Trap B Mode" default = 0 enum = "B" "-B" "|B|" "B*B" "-B*B" "B*B*B" "-B*B*B" "|B*B*B|" visible = @v_REB_ShapeTextureMerge >= 101 endparam param tcmode2 caption = "Trap C Mode" default = 0 enum = "C" "-C" "|C|" "C*C" "-C*C" "C*C*C" "-C*C*C" "|C*C*C|" visible = @trapno == 1 && @v_REB_ShapeTextureMerge >= 101 endparam param tterm31 caption = "Merge Term 1" default = 0 enum = "A" "1/A" "B" "1/B" "C" "1/C" visible = @trapno == 1 endparam param tmerge1 caption = " Merge Operator 1" default = 0 enum = "min" "max" "+" "*" "^" "and" "or" "xor" visible = @trapno == 1 endparam param tterm32 caption = "Merge Term 2" default = 2 enum = "A" "1/A" "B" "1/B" "C" "1/C" visible = @trapno == 1 endparam param tmerge2 caption = " Merge Operator 2" default = 0 enum = "min" "max" "+" "*" "^" "and" "or" "xor" visible = @trapno == 1 endparam param tterm33 caption = "Merge Term 3" default = 4 enum = "A" "1/A" "B" "1/B" "C" "1/C" visible = @trapno == 1 endparam int param p_mergemode caption = "Merge Mode" enum = "minimum" "maximum" "add" "|A-B|" "multiply" "divide" "1/(A*B)" \ "exponentiate" "A" "B" "and" "or" "xor" default = 0 visible = @trapno == 0 endparam heading text = "Set the 'Thrshold' equal to the value of the 'Trap Threshold' for the \ Trap Mode. Other values may give interesting effects but will not give \ a true 'and', 'or' or 'xor' merge." visible = @p_mergemode == "AND" ||@p_mergemode == "OR" ||@p_mergemode == "xor" \ || @tmerge1 == "and" || @tmerge1 == "or" || @tmerge1 == "xor" \ || @tmerge2 == "and" || @tmerge2 == "or" || @tmerge2 == "xor" endheading float param @width caption = "Threshold" default = 0.25 visible = @p_mergemode == "AND"||@p_mergemode == "OR" ||@p_mergemode == "xor" \ || @tmerge1 == "and" || @tmerge1 == "or" || @tmerge1 == "xor" \ || @tmerge2 == "and" || @tmerge2 == "or" || @tmerge2 == "xor" endparam param trapno caption = "# of shapes" enum = "2" "3" endparam param merge_order2 caption = "Merge Order" enum = "1 2" "2 1" visible = @trapno == "2" && (@p_mergemode == "exponentiate" || @p_mergemode == "divide" \ || @p_mergemode == "and" ||@p_mergemode == "or" ||@p_mergemode == "xor" ) endparam func mfuncA caption = "Merge func A" default = ident() visible = @v_REB_ShapeTextureMerge >= 101 endfunc func mfuncB caption = "Merge func B" default = ident() visible = @v_REB_ShapeTextureMerge >= 101 endfunc func mfuncC caption = "Merge func C" default = ident() visible = @trapno == "3" && @v_REB_ShapeTextureMerge >= 101 endfunc TrapShape param f_trapshape1 caption = "Trap Shape" default = REB_TrapShapeBifolium hint = "Sets the trap shape for this slot. Using a TrapShapeBlock in this slot is recommended so that each trap shape can have its own position and transfer settings. If you do xor need these, you may load a TrapShape directly into this slot to reduce clutter." endparam float param weightF1 caption = "Weight factor" default = 1 endparam TrapShape param f_trapshape2 caption = "Trap Shape" default = DMJ_TrapShapeAstroid hint = "Sets the trap shape for this slot. Using a TrapShapeBlock in this slot is recommended so that each trap shape can have its own position and transfer settings. If you do xor need these, you may load a TrapShape directly into this slot to reduce clutter." endparam float param weightF2 caption = "Weight factor" default = 1 endparam TrapShape param f_trapshape3 caption = "Trap Shape" default = REB_TrapShapeAmpersand hint = "Sets the trap shape for this slot. Using a TrapShapeBlock in this slot is recommended so that each trap shape can have its own position and transfer settings. If you do need these, you may load a TrapShape directly into this slot to reduce clutter." visible = @trapno == "3" endparam float param weightF3 caption = "Weight factor" default = 1 visible = @trapno == "3" endparam } class REB_TrapShapeGaussianInteger(common.ulb:TrapShape) { ; Modified from the Gaussian Integer code of Kerry Mitchell public: func Init(complex pz) trapshape.Init(pz) r=0.0 rmin=1.0e12 rmax=0.0 rave=0.0 total=0.0 t=0.0 iter=0 itermin=0 itermax=0 zmin=(0.0,0.0) zmax=(0.0,0.0) if(@norm==1) ; pixel normalization normfac=#pixel elseif(@norm==2) ; factor normalization normfac=@fac elseif(@norm==3) ; f(z) normalization normfac=@normfunc(pz) else ; no normalization normfac=(1.0,0.0) endif logfac=@logseed endfunc float func Iterate(complex pz) TrapShape.Iterate(pz) iter = iter + 1 complex temp2=pz/@scale float return_val = 0 if @randomize logfac=4*logfac*(1-logfac) temp2=temp2*(1-@randomsize*logfac) endif if(@inttype==1) ; trunc temp=trunc(temp2/normfac) elseif(@inttype==2) ; floor temp=floor(temp2/normfac) elseif(@inttype==3) ; ceil temp=ceil(temp2/normfac) else ; round temp=round(temp2/normfac) endif remain=temp2-temp*normfac r=cabs(remain) total=total+r rave=total/iter if(rrmax) rmax=r zmax=temp2 itermax=iter endif if(@colorby==1) ; iteration @ min return_val=0.01*itermin elseif(@colorby==2) ; angle @ min t=atan2(zmin) t=t/pi if(t<0.0) t=t+2.0 endif return_val=0.5*t elseif(@colorby==3) ; maximum distance return_val=rmax elseif(@colorby==4) ; iteration @ max return_val=0.01*itermax elseif(@colorby==5) ; angle @ max t=atan2(zmax) t=t/pi if(t<0.0) t=t+2.0 endif return_val=0.5*t elseif(@colorby==6) ; average distance return_val=rave elseif(@colorby==7) ; min/mean/max angle zmax=(rave-rmin)+flip(rmax-rave) t=atan2(zmax) t=t/pi if(t<0.0) t=t+2.0 endif return_val=0.5*t elseif(@colorby==8) ; max/min ratio return_val=rmax/(rmin+1.e-12) else ; minimum distance return_val=rmin endif m_LastZ = exp(flip(2 * #pi * sqrt(2) * return_val%1)) return return_val%1 endfunc private: float r float rmin float rmax float rave float total float t int iter int itermin int itermax complex zmin complex zmax float logfac complex normfac default: title = "Full Gaussian Integer" heading text = "When used in the Trap Shape slot, Full Gaussian Integer will give \ results identical to Kerry Mitchell.s GaussianInteger in lkm.ucl. \ To get identical results set texture scale = 1.0, select a Trap Mode \ of Last with the trap threshold = 1, and select the trap color mode \ of Distance." endheading param inttype caption="Integer Type" default=0 enum="round(z)" "trunc(z)" "floor(z)" "ceil(z)" hint="Selects between four ways of reducing the orbit value z to an \ integer. Each will produce different effects." endparam param colorby caption="Color By" default=0 enum="minimum distance" "iteration @ min" "angle @ min" \ "maximum distance" "iteration @ max" "angle @ max" "average distance"\ "min/mean/max angle" "max/min ratio" hint="Selects what information from the fractal calculation is used to \ calculate the color of each point." endparam param norm caption="Normalization" default=0 enum="none" "pixel" "factor" "f(z)" hint="Selects an optional normalization algorithm that is applied to the \ integer values." endparam param fac caption=" Factor" default=(2.0,1.0) visible = @norm == "factor" hint="Specifies the normalization factor that is used if Normalization is \ set to 'factor'." endparam func normfunc caption=" Function" default=ident() hint="Selects the normalization function that is used if Normalization is \ set to 'f(z)'." visible = @norm == "f(z)" endfunc param randomize caption="Randomize" default=false hint="If checked, a random factor is applied to z at every iteration \ before finding the Gaussian integer." endparam param randomsize caption="Random Size" default=(0.1,0) hint="Specifies the size of the random factor to use if Randomize is \ checked. Larger values give more randomization." visible = @randomize endparam param logseed caption="Random Seed" default=0.1 min=0.0 max=1.0 hint="Specifies the randomization seed, between 0 and 1, to use if \ Randomize is checked. Every seed gives a different image." visible = @randomize endparam param scale caption = "Texture scale" default = 0.1 endparam } class REB_TrapShapeRoseRangeLite(common.ulb:TrapShape) { ; Modified from the Rose Range Lite code of Kerry Mitchell public: func Init(complex pz) trapshape.Init(pz) rminfac=@scale*(1.0-0.5*@rangewidth) rmaxfac=@scale*(1.0+0.5*@rangewidth) rz=0.0 tz=0.0 rmin=0.0 rmax=0.0 rn=0.0 rw = 0 rotangle=-@rot/180.0*#pi rfaze=@rphase/180*#pi rho=0 cycle_length=@ndo+@nskip jter=0 start_last=@start_cycle+@ncycle*cycle_length-1 iter = 0 doit = false endfunc float func Iterate(complex pz) TrapShape.Iterate(pz) iter = iter + 1 ; ; selected iterations ; if(@select_type=="do all") doit=true elseif(@select_type=="cycle") ; ; first iterations before the cycle ; if(iter<@start_cycle) if(@first_type=="do first") doit=true elseif(@first_type=="skip first") doit=false endif ; ; last iterations after the cycle ; elseif(iter>start_last) if(@last_type=="do last") doit=true elseif(@last_type=="skip last") doit=false endif ; ; cycle ; else jter=((iter-@start_cycle)%cycle_length)+1 if(jter<=@ndo) doit=true else doit=false endif endif endif if doit tz=atan2(pz)+rotangle rz=@ac*cos(@bc*tz)+@as*sin(@bs*tz) if !@widthfix rmin=rz*rminfac rmax=rz*rmaxfac rz=cabs(pz-@curvecenter) endif if(@vary_width==true) rho=(1-cos(@rfreq*tz+rfaze))/2 rw=rho*(@maxwidth-@minwidth)+@minwidth rminfac=@scale*(1-0.5*rw) rmaxfac=@scale*(1+0.5*rw) endif if @widthfix rmin=rz*rminfac rmax=rz*rmaxfac rz=cabs(pz-@curvecenter) endif if((rz>=rmin)&&(rz<=rmax)) rn=(rz-rmin)/(rmax-rmin) endif if((rzrmax)) rn = 1e20 endif else rn = 1e20 endif m_LastZ = exp(flip(2 * #pi * sqrt(2) * rn)) return rn endfunc private: float rminfac float rmaxfac float rz float tz float rmin float rmax float rn float rotangle float rfaze float rho float rw bool doit int jter int start_last int cycle_length int iter default: title = "Rose Range Lite" int param v_roserangelite caption = "Version (Rose Range Lite)" 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_roserangelite < 100 endparam heading text = "This is the trap shape version of Kerry Mitchell's Rose Range Lite. \ To duplicate the original Rose Range Lite shapes use the Last or First \ trap modes. For first angle and last angle use the Angle to Origin trap \ color mode. For first and last magnitude use the Distance trap color mode. \ You may have to rotate the gradient to duplicate the colors." endheading heading caption="selected iterations" endheading param select_type caption="select type" default=0 enum="do all" "cycle" endparam param first_type caption="first type" default=0 enum="skip first" "do first" hint="for iterations before the cycle" visible=(@select_type=="cycle") endparam param last_type caption="last type" default=0 enum="skip last" "do last" hint="for iterations after the cycle" visible=(@select_type=="cycle") endparam int param start_cycle caption="cycle starting iteration" default=3 min=1 visible=(@select_type=="cycle") endparam int param ndo caption="# to do each cycle" default=2 min=0 visible=(@select_type=="cycle") endparam int param nskip caption="# to skip each cycle" default=3 min=0 visible=(@select_type=="cycle") endparam int param ncycle caption="# of cycles" default=2 min=0 visible=(@select_type=="cycle") endparam param scale caption="range scale" default=1.0 endparam bool param vary_width caption="vary width" default=false endparam heading text = "With single iteration layers the widths may not match up correctly with the \ expected widths for multiple iteration single layer when 'vary_with' is set. The default \ for 'fix width' is false so that old uprs will render as originally designed. \ If you use this option make sure that 'fix width' is checked for both single and \ multiple iteration layers." visible = @vary_width endheading bool param widthfix caption ="fix width" default = false visible = @vary_width endparam float param rangewidth caption="range width" default=0.1 visible=(@vary_width==false) endparam float param minwidth caption="min range width" default=0.1 visible=(@vary_width==true) endparam float param maxwidth caption="max range width" default=0.4 visible=(@vary_width==true) endparam float param rfreq caption="range frequency" default=1 visible=(@vary_width==true) endparam float param rphase caption="range phase, deg" default=0 visible=(@vary_width==true) endparam param ac caption="cos amplitude" default=1.0 endparam param bc caption="cos frequency" default=3.0 endparam param as caption="sin amplitude" default=0.0 endparam param bs caption="sin frequency" default=0.0 endparam param curvecenter caption="curve center" default=(0.0,0.0) endparam param rot caption="rotation angle" default=0.0 hint="degrees" endparam } class REB_TrapShapeWorleyLite(common.ulb:TrapShape) { ; Implementation of Worley cellular noise with Worley fractal modulation.
;

; The Euclidian flavor is closely equivalent to Voronoi texturing. ; Jim Blue's random number generator was essential to its development. ; Additional methods of fractal modulation have been added based upon the ; Worley model. public: import "common.ulb" import "jlb.ulb" ; Constructor func REB_TrapShapeWorleyLite(Generic pparent) TrapShape.TrapShape(pparent) rndi = new JLB_Random(0) rndi.Init(@seed) rndi.SetNMax(5000) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) complex fzc complex fzz float dst float dst2 complex fzc1 complex fzc2 complex fzc3 complex fzc4 complex cells[12] float distance = 0 float test = 0 complex diff = 0 int rnds[24] float rp[12] float ip[12] int i = 1 rnds[0] = rndi.RandomIntInRange(@seed) while i < 24 rnds[i] = rndi.RandomIntInRange(0) i = i + 1 endwhile dst = 1e10 dst2 = 1e10 complex near = 0 complex z = (pz+(10,10))/@psize fzc = round(z) fzz = z - fzc ; create the grid fzc1 = fzc + (1,1)/2 fzc2 = fzc + (1,-1)/2 fzc3 = fzc + (-1,1)/2 fzc4 = fzc + (-1,-1)/2 ; create the random points ; cell 1 rp[0] = ((real(fzc1)-rnds[0])^5%rnds[6] - (imag(fzc1)+rnds[12])^3%rnds[18])^2 %2 - 1 ip[0] = ((real(fzc1)-rnds[1])^5%rnds[7] - (imag(fzc1)+rnds[13])^3%rnds[19])^2 %2 - 1 rp[1] = ((real(fzc1)-rnds[2])^5%rnds[8] - (imag(fzc1)+rnds[14])^3%rnds[20])^2 %2 - 1 ip[1] = ((real(fzc1)-rnds[3])^5%rnds[8] - (imag(fzc1)+rnds[15])^3%rnds[21])^2 %2 - 1 rp[2] = ((real(fzc1)-rnds[4])^5%rnds[10] - (imag(fzc1)+rnds[16])^3%rnds[22])^2 %2 - 1 ip[2] = ((real(fzc1)-rnds[5])^5%rnds[11] - (imag(fzc1)+rnds[17])^3%rnds[23])^2 %2 - 1 ; cell 2 rp[3] = ((real(fzc2)-rnds[0])^5%rnds[6] - (imag(fzc2)+rnds[12])^3%rnds[18])^2 %2 - 1 ip[3] = ((real(fzc2)-rnds[1])^5%rnds[7] - (imag(fzc2)+rnds[13])^3%rnds[19])^2 %2 - 1 rp[4] = ((real(fzc2)-rnds[2])^5%rnds[8] - (imag(fzc2)+rnds[14])^3%rnds[20])^2 %2 - 1 ip[4] = ((real(fzc2)-rnds[3])^5%rnds[8] - (imag(fzc2)+rnds[15])^3%rnds[21])^2 %2 - 1 rp[5] = ((real(fzc2)-rnds[4])^5%rnds[10] - (imag(fzc2)+rnds[16])^3%rnds[22])^2 %2 - 1 ip[5] = ((real(fzc2)-rnds[5])^5%rnds[11] - (imag(fzc2)+rnds[17])^3%rnds[23])^2 %2 - 1 ; cell 3 rp[6] = ((real(fzc3)-rnds[0])^5%rnds[6] - (imag(fzc3)+rnds[12])^3%rnds[18])^2 %2 - 1 ip[6] = ((real(fzc3)-rnds[1])^5%rnds[7] - (imag(fzc3)+rnds[13])^3%rnds[19])^2 %2 - 1 rp[7] = ((real(fzc3)-rnds[2])^5%rnds[8] - (imag(fzc3)+rnds[14])^3%rnds[20])^2 %2 - 1 ip[7] = ((real(fzc3)-rnds[3])^5%rnds[8] - (imag(fzc3)+rnds[15])^3%rnds[21])^2 %2 - 1 rp[8] = ((real(fzc3)-rnds[4])^5%rnds[10] - (imag(fzc3)+rnds[16])^3%rnds[22])^2 %2 - 1 ip[8] = ((real(fzc3)-rnds[5])^5%rnds[11] - (imag(fzc3)+rnds[17])^3%rnds[23])^2 %2 - 1 ; cell 4 rp[9] = ((real(fzc4)-rnds[0])^5%rnds[6] - (imag(fzc4)+rnds[12])^3%rnds[18])^2 %2 - 1 ip[9] = ((real(fzc4)-rnds[1])^5%rnds[7] - (imag(fzc4)+rnds[13])^3%rnds[19])^2 %2 - 1 rp[10] = ((real(fzc4)-rnds[2])^5%rnds[8] - (imag(fzc4)+rnds[14])^3%rnds[20])^2 %2 - 1 ip[10] = ((real(fzc4)-rnds[3])^5%rnds[8] - (imag(fzc4)+rnds[15])^3%rnds[21])^2 %2 - 1 rp[11] = ((real(fzc4)-rnds[4])^5%rnds[10] - (imag(fzc4)+rnds[16])^3%rnds[22])^2 %2 - 1 ip[11] = ((real(fzc4)-rnds[5])^5%rnds[11] - (imag(fzc4)+rnds[17])^3%rnds[23])^2 %2 - 1 ; put into the grids cells[0] = (rp[0] + flip(ip[0]) + (1,1))/2 cells[1] = (rp[1] + flip(ip[1]) + (1,1))/2 cells[2] = (rp[2] + flip(ip[2]) + (1,1))/2 cells[3] = (rp[3] + flip(ip[3]) + (1,-1))/2 cells[4] = (rp[4] + flip(ip[4]) + (1,-1))/2 cells[5] = (rp[5] + flip(ip[5]) + (1,-1))/2 cells[6] = (rp[6] + flip(ip[6]) + (-1,1))/2 cells[7] = (rp[7] + flip(ip[7]) + (-1,1))/2 cells[8] = (rp[8] + flip(ip[8]) + (-1,1))/2 cells[9] = (rp[9] + flip(ip[9]) + (-1,-1))/2 cells[10] = (rp[10] + flip(ip[10]) + (-1,-1))/2 cells[11] = (rp[11] + flip(ip[11]) + (-1,-1))/2 i = 0 while i < 12 diff = fzz - cells[i] if @flavor == "Euclidian" test = cabs(diff) elseif @flavor == "Manhattan" test = (abs(real(diff))^real(@mp) + abs(imag(diff))^imag(@mp)) elseif @flavor == "Chebychev" if abs(real(diff)) > abs(imag(diff)) test = abs(real(diff)) else test = abs(imag(diff)) endif elseif @flavor == "Minkovsky" test = (abs(real(diff))^@ex + abs(imag(diff))^@ex)^(1/@ex) elseif @flavor == "Exp/Log Manhattan" test = log(exp(abs(real(diff))) + exp(abs(imag(diff)))) endif if test < dst dst2 = dst dst = test near = fzc + cells[i] elseif test < dst2 dst2 = test endif i = i + 1 endwhile if @type == "Distance" distance = dst^@thick elseif @type == "2nd Distance" distance = (@smod*dst2-dst)^@thick elseif @type == "2nd Distance variant" distance = dst2^@thick elseif @type == "Mosaic" distance = cabs(1000*near) + 1000*atan(cabs(near)+#pi)%1 endif if @dmod != 0 distance = distance*@dmod endif if @type != "Mosaic" if @invert distance = abs(1-distance) endif else distance = distance % 1 endif m_LastZ = exp(flip(2 * #pi * sqrt(2) * distance)) return distance endfunc protected: JLB_Random rndi default: title = "Worley Lite" int param v_worleylite caption = "Version (Worley Lite)" 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_worleylite < 100 endparam param flavor caption = "Flavor" default = 4 enum = "Chebychev" "Euclidian" "Manhattan" "Exp/Log Manhattan" "Minkovsky" endparam float param ex caption = "Minkovsky param" default = 4 visible = @flavor == "Minkovsky" endparam complex param mp caption = "Manhattan pwr" default = (1,1) visible = @flavor == "Manhattan" endparam param type caption = "Worley type" default = 2 enum = "Distance" "2nd Distance" "2nd Distance variant" "Mosaic" endparam float param smod caption = "2nd dist mod" default = 1.0 visible = @type == "2nd Distance" endparam param psize caption = "Pattern Size" default = .15 endparam float param thick caption = "Thickness" default = 0.1 endparam float param dmod caption = "Dist modulator" default = 0.0 min = 0.0 endparam bool param invert caption = "Invert" default = false visible = @type != "Mosaic" endparam int param seed caption = "Worley seed" default = 123 endparam } class REB_ConvolutionShapeWrapper(common.ulb:TrapShape) { ; This wrapper allows you to use any trap shape and any convolution ; filter to produce blurred or sharpened (or other) trap effects. ; This is largely based upon BlurTrapWrapper of Damien Jones public: import "common.ulb" import "dmj5.ulb" func REB_ConvolutionShapeWrapper(Generic pparent) TrapShape.TrapShape(pparent) m_Filter = new @f_filter(this) m_Samples = length(m_Filter.m_Offsets) if @f_filter != REB_MedianFilter && @f_filter != REB_ColorPencilFilter && \ @f_filter != REB_OilPaintFilter setLength(m_TrapShapes, m_Samples) int j = 0 while (j < m_Samples) m_TrapShapes[j] = new @f_trapshape(this) j = j + 1 endwhile else setLength(m_TrapShapes, 1) setlength(med,m_samples) m_TrapShapes[0] = new @f_trapshape(this) endif endfunc func Init(complex pz) TrapShape.Init(pz) if @f_filter != REB_MedianFilter && @f_filter != REB_ColorPencilFilter && \ @f_filter != REB_OilPaintFilter int j = 0 while (j < m_Samples) m_TrapShapes[j].Init(pz) j = j + 1 endwhile else m_TrapShapes[0].Init(pz) endif if (@p_filterreset == 0 && DMJ_VariableConvolutionFilter(m_Filter) != 0) m_Filter.Init(pz) endif endfunc float func Iterate(complex pz) trapshape.Iterate(pz) if (@p_filterreset == 1 && DMJ_VariableConvolutionFilter(m_Filter) != 0) m_Filter.Init(pz) endif float dist = 0 float d = 0 float w = 0 float o = 0 int j = 0 if @f_filter != REB_MedianFilter && @f_filter != REB_ColorPencilFilter && \ @f_filter != REB_OilPaintFilter while (j < m_Samples) dist = m_TrapShapes[j].Iterate(pz+m_Filter.m_Offsets[j]) w = m_Filter.m_Weights[j] d = d + dist * w j = j + 1 endwhile w = m_Filter.m_Multiplier o = m_Filter.m_Bias d = d * w + o else int k = 0 int l = 0 float tmp = 0 int si = 0 int sj = 0 bool continue = true float dmin = 1e10 float dmax = 0 int bin[100] while k < 100 bin[k] = 0 k = k + 1 endwhile int val = 0 float maxval = 0 int maxvalidx = 0 k = 0 j = 0 while (j < m_Samples) med[j] = m_TrapShapes[0].Iterate(pz+m_Filter.m_Offsets[j]) if @f_filter == REB_ColorPencilFilter if med[j] < dmin dmin = med[j] endif if med[j] > dmax dmax = med[j] endif endif if @f_filter == REB_OilPaintFilter ; create a 100 bin histogram to determine the most common value val = round(med[j]*100) % 100 bin[val] = bin[val] + 1 if maxval < bin[val] maxval = bin[val] maxvalidx = j endif endif j = j + 1 endwhile if @f_filter == REB_MedianFilter ;heapsort without recursion l = round(m_samples/2)+1 k = m_samples tmp = 0 repeat if l > 1 l = l-1 tmp = med[l-1] else tmp = med[k-1] med[k-1] = med[0] k = k-1 if k == 0 med[0] = tmp continue = false endif endif if continue == true si = l sj = 2*l endif while (sj <= k) && (continue == true) if sj < k if med[sj-1] < med[sj] sj = sj + 1 endif endif if tmp < med[sj-1] med[si-1] = med[sj-1] si = sj sj = sj + sj else sj = k + 1 endif endwhile if (continue == true) med[si-1] = tmp endif until continue == false ; end heapsort d = med[round(m_samples/2)] endif if @f_filter == REB_ColorPencilFilter float r = med[round(m_samples/2)] float md = 0 float maskr = 0 if r == dmax md = 0 else md = abs(r-dmin) if md < abs(r-dmax) md = abs(r-dmax) endif endif md = md*255 r = r*255 maskr = 1/(md/(sqrt(r+1)/3)+1) d = (r + @cpr*((255-r)*maskr-md*r/100))/255 endif if @f_filter == REB_OilPaintFilter d = med[maxvalidx] endif endif return d endfunc protected: DMJ_ConvolutionFilter m_Filter int m_Samples TrapShape m_TrapShapes[] float med[] default: title = "Convolution Shape Wrapper" int param v_REB_ConvolutionShapeWrapper caption = "Version (REB_ConvolutionShapeWrapper)" 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_REB_ConvolutionShapeWrapper < 100 endparam heading text = "To use with image import (images as textures) replace the \ trap shape under Trap Position with Image Tile Texture." endheading TrapShape param f_trapshape caption = "Trap Shape" default = TrapShapeBlock hint = "Sets the trap shape that the convolution filter will be applied to." endparam DMJ_ConvolutionFilter param f_filter caption = "Convolution Filter" default = REB_NullFilter hint = "Sets the filter that will be applied." endparam float param cpr caption = "Color Pencil Intensity" default = 0.5 visible = @f_filter == REB_ColorPencilFilter endparam int param p_filterreset caption = "Reset Filter" default = 1 enum = "first iteration" "every iteration" hint = "Some convolution filters are position-dependent: the filter's effect varies from one part of the complex plane to another. For this kind of filter, you may choose whether to recompute the filter's effect only at the first iteration or on every iteration." visible = (@f_filter == DMJ_VariableConvolutionFilter) endparam } class Monnier_SFBM_II_Texture(common.ulb:TrapShape) { ; Trap shape based upon Sam Monnier's S.F.B.M. II ucl
; Used with his permission.
public: import "common.ulb" func Monnier_SFBM_II_Texture(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; call before each iteration func Init(complex pz) TrapShape.Init(pz) if @v_monniersfbm < 102 || (!@init && @v_monniersfbm >= 102) z = 0 zc1 = 0 zc2 = 0 zc3 = 0 zc4 = 0 i = 0 j = 0 jmax = 0 niter = 0 a = 0 sum = 0 x = 0 y = 0 d1 = 0 d2 = 0 d3 = 0 d4 = 0 nindex = 0 sindex = 0 scale = 1 cr1r = 0 cr1i = 0 cr2r = 0 cr2i = 0 cr3r = 0 cr3i = 0 cr4r = 0 cr4i = 0 crp1 = 0 crp2 = 0 crp3 = 0 crp4 = 0 norm = 1 if @interp == 0 niter = ceil(real(log(real(@fmm)-imag(@fmm))/log(1+@mstep))) else niter = ceil((real(@fmm)-imag(@fmm))/@mstep) endif if @mode == 0 jmax = 1 else jmax = 5 endif endif endfunc ; call for each iterated point float func Iterate(complex pz) TrapShape.Iterate(pz) if @v_monniersfbm >= 102 && @init z = 0 zc1 = 0 zc2 = 0 zc3 = 0 zc4 = 0 i = 0 j = 0 jmax = 0 niter = 0 a = 0 sum = 0 x = 0 y = 0 d1 = 0 d2 = 0 d3 = 0 d4 = 0 nindex = 0 sindex = 0 scale = 1 cr1r = 0 cr1i = 0 cr2r = 0 cr2i = 0 cr3r = 0 cr3i = 0 cr4r = 0 cr4i = 0 crp1 = 0 crp2 = 0 crp3 = 0 crp4 = 0 norm = 1 if @interp == 0 niter = ceil(real(log(real(@fmm)-imag(@fmm))/log(1+@mstep))) else niter = ceil((real(@fmm)-imag(@fmm))/@mstep) endif if @mode == 0 jmax = 1 else jmax = 5 endif endif while j < jmax z = pz/@size if @mode == 1 || @mode == 2 if j == 0 a = @cbl + @ctl + @cbr + @ctr + @cc;/20 elseif j == 1 z = z + @eps*(-1,-1) a = -@cbl elseif j == 2 z = z + @eps*(-1,1) a = -@ctl elseif j == 3 z = z + @eps*(1,-1) a = -@cbr elseif j == 4 z = z + @eps*(1,1) a = -@ctr endif else a = 1 endif j = j + 1 i = 0 while i < niter + 2 if i == 2 if @pptype == 0 z = (real(@pp)*(1/sqrt(imag(@ppp))*x + 1i*sqrt(imag(@ppp))*y)^real(@ppp)+(1-real(@pp))*z)*imag(@pp) else z = (real(@pp)*x^real(@ppp)*exp(imag(@ppp)*1i*y)+(1-real(@pp))*z)*imag(@pp) endif elseif i == 0 z = z/imag(@pp) endif z = z*exp(1i*pi/180*@rot) + 1 - 2i if i > 1 if @interp == 0 scale = (1+@mstep)^(i-2)*imag(@fmm) else scale = real(@fmm)-(i-1)*(@mstep+.001) endif endif i = i + 1 zc = round(scale*z)/scale zc1 = zc + (.5,.5)/scale zc2 = zc + (-.5,.5)/scale zc3 = zc + (.5,-.5)/scale zc4 = zc + (-.5,-.5)/scale cr1r = ((real(zc1)-859-i)^5 % (132+i) - (imag(zc1)+328+i)^3 % (113+i))^2 %2 - 1 if @noise != 6 && @noise != 8 && @noise != 10 && @noise != 12 && @noise != 14 cr2r = ((real(zc2)-859-i)^5 % (132+i) - (imag(zc2)+328+i)^3 % (113+i))^2 %2 - 1 cr3r = ((real(zc3)-859-i)^5 % (132+i) - (imag(zc3)+328+i)^3 % (113+i))^2 %2 - 1 cr4r = ((real(zc4)-859-i)^5 % (132+i) - (imag(zc4)+328+i)^3 % (113+i))^2 %2 - 1 endif if @noise == 0 || @noise == 5 cr1i = ((real(zc1)-465+i)^3 % (120+i) - (imag(zc1)-756+i)^2 % (107+i))^2 %2 - 1 cr2i = ((real(zc2)-465+i)^3 % (120+i) - (imag(zc2)-756+i)^2 % (107+i))^2 %2 - 1 cr3i = ((real(zc3)-465+i)^3 % (120+i) - (imag(zc3)-756+i)^2 % (107+i))^2 %2 - 1 cr4i = ((real(zc4)-465+i)^3 % (120+i) - (imag(zc4)-756+i)^2 % (107+i))^2 %2 - 1 endif if @noise == 0 v1 = (z - zc1)*scale v2 = (z - zc2)*scale v3 = (z - zc3)*scale v4 = (z - zc4)*scale crp1 = cr1r*real(v1) + cr1i*imag(v1) crp2 = cr2r*real(v2) + cr2i*imag(v2) crp3 = cr3r*real(v3) + cr3i*imag(v3) crp4 = cr4r*real(v4) + cr4i*imag(v4) elseif @noise == 1 crp1 = cr1r crp2 = cr1r crp3 = cr1r crp4 = cr1r norm = .5 elseif @noise == 2 crp1 = cr1r crp2 = cr2r crp3 = cr1r crp4 = cr2r norm = .5 elseif @noise == 3 crp1 = cr1r crp2 = cr2r crp3 = cr3r crp4 = cr2r norm = .5 elseif @noise == 4 crp1 = -cr1r crp2 = cr2r crp3 = cr3r crp4 = -cr4r norm = .5 elseif @noise == 5 crp1 = cr1r*abs(real(z-zc)*scale)^real(@noisep) + cr1i*abs(imag(z-zc)*scale)^imag(@noisep) crp2 = cr2r*abs(real(z-zc)*scale)^real(@noisep) + cr2i*abs(imag(z-zc)*scale)^imag(@noisep) crp3 = cr3r*abs(real(z-zc)*scale)^real(@noisep) + cr3i*abs(imag(z-zc)*scale)^imag(@noisep) crp4 = cr4r*abs(real(z-zc)*scale)^real(@noisep) + cr4i*abs(imag(z-zc)*scale)^imag(@noisep) norm = .2 elseif @noise == 6 crp1 = (cabs(z-zc)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 7 crp1 = cr1r*(cabs(z-zc)*scale-imag(@noisep))^real(@noisep) crp2 = cr2r*(cabs(z-zc)*scale-imag(@noisep))^real(@noisep) crp3 = cr3r*(cabs(z-zc)*scale-imag(@noisep))^real(@noisep) crp4 = cr4r*(cabs(z-zc)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 8 arg = atan2(z-zc) arg = -round(arg/(2*pi)*4)/4*(2*pi) ztest = (z-zc)*exp(1i*arg) crp1 = (real(ztest)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 9 arg = atan2(z-zc) arg = -round(arg/(2*pi)*4)/4*(2*pi) ztest = (z-zc)*exp(1i*arg) crp1 = cr1r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp2 = cr2r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp3 = cr3r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp4 = cr4r*(real(ztest)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 10 arg = atan2(z-zc) arg = -round(arg/(2*pi)*8)/8*(2*pi) ztest = (z-zc)*exp(1i*arg) crp1 = (real(ztest)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 11 arg = atan2(z-zc) arg = -round(arg/(2*pi)*8)/8*(2*pi) ztest = (z-zc)*exp(1i*arg) crp1 = cr1r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp2 = cr2r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp3 = cr3r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp4 = cr4r*(real(ztest)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 12 ztest = z - zc if real(cr1r) > 0 d1 = abs(cabs(ztest*scale+(.5,.5))-.5) d2 = abs(cabs(ztest*scale-(.5,.5))-.5) if d2 < d1 d1 = d2 endif else d1 = abs(cabs(ztest*scale+(.5,-.5))-.5) d2 = abs(cabs(ztest*scale-(.5,-.5))-.5) if d2 < d1 d1 = d2 endif endif crp1 = d1^real(@noisep) norm = .4 elseif @noise == 13 ztest = z - zc if real(cr1r) > 0 d1 = abs(cabs(ztest*scale+(.5,.5))-.5) d2 = abs(cabs(ztest*scale-(.5,.5))-.5) if d2 < d1 d1 = d2 endif else d1 = abs(cabs(ztest*scale+(.5,-.5))-.5) d2 = abs(cabs(ztest*scale-(.5,-.5))-.5) if d2 < d1 d1 = d2 endif endif crp1 = cr1r*(d1^real(@noisep)-imag(@noisep)) crp2 = cr2r*(d1^real(@noisep)-imag(@noisep)) crp3 = cr3r*(d1^real(@noisep)-imag(@noisep)) crp4 = cr4r*(d1^real(@noisep)-imag(@noisep)) norm = .4 elseif @noise == 14 ztest = (z - zc)*scale if real(cr1r) > 0 d1 = abs(real(ztest) - imag(ztest) -.5) d2 = abs(real(ztest) - imag(ztest) +.5) if d2 < d1 d1 = d2 endif else d1 = abs(real(ztest) + imag(ztest) -.5) d2 = abs(real(ztest) + imag(ztest) +.5) if d2 < d1 d1 = d2 endif endif crp1 = d1^real(@noisep) norm = .4 elseif @noise == 15 ztest = (z - zc)*scale if real(cr1r) > 0 d1 = abs(real(ztest) - imag(ztest) -.5) d2 = abs(real(ztest) - imag(ztest) +.5) if d2 < d1 d1 = d2 endif else d1 = abs(real(ztest) + imag(ztest) -.5) d2 = abs(real(ztest) + imag(ztest) +.5) if d2 < d1 d1 = d2 endif endif crp1 = cr1r*(d1^real(@noisep)-imag(@noisep)) crp2 = cr2r*(d1^real(@noisep)-imag(@noisep)) crp3 = cr3r*(d1^real(@noisep)-imag(@noisep)) crp4 = cr4r*(d1^real(@noisep)-imag(@noisep)) norm = .4 elseif @noise == 16 endif if @noise == 6 || @noise == 8 || @noise == 10 || @noise == 12 || @noise == 14 nindex = crp1 else d1 = real(z - zc)*scale + 0.5 d2 = (1 - d1) d3 = imag(z - zc)*scale + 0.5 d4 = (1 - d3) d1 = (.5 + .5*sin(pi*d1-pi/2))^@power d2 = (.5 + .5*sin(pi*d2-pi/2))^@power d3 = (.5 + .5*sin(pi*d3-pi/2))^@power d4 = (.5 + .5*sin(pi*d4-pi/2))^@power nindex = crp1*d1*d3 + crp3*d1*d4 + crp2*d2*d3 + crp4*d2*d4 endif if @f1 == 1 nindex = real(sin(100*real(@fp1)*nindex+imag(@fp1)))/10 elseif @f1 == 2 nindex = real(@fp1)*10*nindex+2+imag(@fp1) if abs(nindex) > 1 nindex = 1 endif nindex = real(asin(nindex))/4 elseif @f1 == 3 nindex = 20*real(@fp1)*nindex+1+imag(@fp1) if abs(nindex) > 1 nindex = 1 endif nindex = real(acos(nindex))/4 elseif @f1 == 4 nindex = real(atanh(20*real(@fp1)*nindex+imag(@fp1)))/8 elseif @f1 == 5 nindex = (20*nindex+imag(@fp1))^(2+real(@fp1))/160 elseif @f1 == 6 nindex = real((15*nindex+imag(@fp1))^(.1*real(@fp1))) elseif @f1 == 7 nindex = real(exp(10*real(@fp1)*nindex+imag(@fp1)-.5))/8 elseif @f1 == 8 nindex = real(round(5*real(@fp1)*nindex+imag(@fp1)/5))/4 elseif @f1 == 9 nindex = real(round(15*real(@fp1)*nindex+imag(@fp1)/5)^.1)/3 elseif @f1 == 10 if real(@fp1)<0.0 nindex = (sin(-(real(z)+(4+imag(@fp1))*nindex))+cos(-(imag(z)+(4+imag(@fp1))*nindex)))/15 else nindex = (sin(5*sqrt(real(@fp1))*(real(z)+(4+imag(@fp1))*nindex))+cos(5*1/sqrt(real(@fp1))*(imag(z)+(4+imag(@fp1))*nindex)))/15 endif endif if @f2 == 1 nindex = real(sin(100*real(@fp2)*nindex+imag(@fp2)))/10 elseif @f2 == 2 nindex = real(@fp2)*10*nindex+2+imag(@fp2) if abs(nindex) > 1 nindex = 1 endif nindex = real(asin(nindex))/4 elseif @f2 == 3 nindex = 20*real(@fp2)*nindex+1+imag(@fp2) if abs(nindex) > 1 nindex = 1 endif nindex = real(acos(nindex))/4 elseif @f2 == 4 nindex = real(atanh(20*real(@fp2)*nindex+imag(@fp2)))/8 elseif @f2 == 5 nindex = (20*nindex+imag(@fp2))^(2+real(@fp2))/160 elseif @f2 == 6 nindex = real((15*nindex+imag(@fp2))^(.1*real(@fp2))) elseif @f2 == 7 nindex = real(exp(10*real(@fp2)*nindex+imag(@fp2)-.5))/8 elseif @f2 == 8 nindex = real(round(5*real(@fp2)*nindex+imag(@fp2)/5))/4 elseif @f2 == 9 nindex = real(round(15*real(@fp2)*nindex+imag(@fp2)/5)^.1)/3 elseif @f2 == 10 if real(@fp2)<0.0 nindex = (sin(-(real(z)+(4+imag(@fp2))*nindex))+cos(-(imag(z)+(4+imag(@fp2))*nindex)))/15 else nindex = (sin(5*sqrt(real(@fp2))*(real(z)+(4+imag(@fp2))*nindex))+cos(5*1/sqrt(real(@fp2))*(imag(z)+(4+imag(@fp2))*nindex)))/15 endif endif nindex = real(nindex^@power2) if i == 1 x = nindex elseif i == 2 y = nindex else sindex = sindex + nindex/scale^@beta endif endwhile if @mode != 2 sum = sum + a*sindex else sum = sum + a*abs(sindex) endif sindex = 0 scale = 1 endwhile if @mode == 2 sum = 3*abs(sum) endif if @mode == 1 sindex = sum/(10*@eps*(abs(@cbl + @ctl + @cbr + @ctr)+1)) else sindex = sum endif if @interp == 0 d = 2*norm*sindex/(niter)^.5 else d = .4*norm*sindex endif if @v_monniersfbm >= 104 z = exp(flip(2 * #pi * sqrt(2) * d)) endif m_lastz = z return d endfunc protected: complex z complex zc1 complex zc2 complex zc3 complex zc4 int i int j int jmax int niter float a float sum float x float y float d1 float d2 float d3 float d4 float nindex float sindex float scale float cr1r float cr1i float cr2r float cr2i float cr3r float cr3i float cr4r float cr4i float crp1 float crp2 float crp3 float crp4 float norm float d default: title = "Monnier's S.F.B.M. II Texture" int param v_monniersfbm caption = "Version (Monnier's S.F.B.M. II Texture)" default = 104 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_monniersfbm < 104 endparam param init caption = "Init with each iter" default = true visible = @v_monniersfbm >= 102 endparam param size caption = "Pattern Size" default = 0.1 endparam param noise caption = "Noise Function" default = 0 enum = "Perlin" "Raw Gird" "Strips" "Corners" "Checkerboard" \ "Soft Gird" "Circles" "Soft Circles" "Squares" "Soft Squares" \ "Octogons" "Soft Octogons" "Roundy Truchet" "Soft Roundy Truchet" \ "Squarry Truchet" "Soft Squarry Truchet" endparam param noisep caption = "Noise F. Parameters" default = (.2,.5) hint = "Noise Function Parameters" endparam param f1 caption = "flavor 1" default = 0 enum = "Original" "Wavy" "Blobs" "Cut" "Messy" "Soft I" "Strings" "Soft II" "Sharp" "String-Sharp" "Random Phase" endparam param fp1 caption = "flavor 1 Parameters" default = (1,0) hint = "flavor 1 Parameters" endparam param f2 caption = "flavor 2" default = 0 enum = "Original" "Wavy" "Blobs" "Cut" "Messy" "Soft I" "Strings" "Soft II" "Sharp" "String-Sharp" "Random Phase" endparam param fp2 caption = "flavor 2 Parameters" default = (1,0) hint = "flavor 2 Parameters" endparam param mode caption = "Mode" default = 0 enum = "Normal" "Convolution" "Absolute Convolution" endparam param beta caption = "Beta (Spectral Density Parameter)" default = 1.0 hint = "Spectral Density Exponent" endparam param power caption = "Power" default = 2.0 endparam param power2 caption = "Post-Power" default = 1.0 endparam param pp caption = "Pre-Processing" default = (0,1) endparam param pptype caption = "Pre-Processing Type" default = 0 enum = "Cartesian" "Polar" hint = "Pre-Processing Type" endparam param ppp caption = "Pre-P. Power and Aspect" default = (1,1) hint = "Pre-Processing Power and Aspect" endparam param rot caption = "Rotation Step" default = 28.0 endparam param mstep caption = "Frequency Separation" default = 1.0 hint = "Frequency Separation" endparam param fmm caption = "Inv. of max/min Frequency" default = (40,1) hint = "Inverse of max/min Frequency" endparam param interp caption = "Frequency Interpolation" default = 0 enum = "Logarithmic" "Linear" hint = "Frequency Interpolation" endparam param cc caption = "Center Extra Weight" default = 0.0 endparam param cbl caption = "Bottom Left Weight" default = 1.0 endparam param ctl caption = "Top Left Weight" default = 0.0 endparam param cbr caption = "Bottom Right Weight" default = 0.0 endparam param ctr caption = "Top Right Weight" default = 0.0 endparam param eps caption = "Epsilon" default = 0.006 endparam } class REB_TrapShapeSlopeBasic(common.ulb:TrapShape) { ; Provides the basic trap shapes for Slope with Shapes.
public: import "common.ulb" ; constructor func REB_TrapShapeSlopeBasic(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; call for each iterated point float func Iterate(complex pz) TrapShape.Iterate(pz) float m_d = 0 if @zmode == 0 m_d = -10000 elseif @zmode == 1 m_d = |pz|; get current distance from origin elseif @zmode == 2 m_d = abs(real(pz)); get current distances from i axis elseif @zmode == 3 m_d = abs(imag(pz)); get current distances from r axis elseif @zmode == 4 m_d = abs(real(pz))+abs(imag(pz)); get current distances from i axis elseif @zmode == 5 m_d = abs(atan2(pz)); get current angles elseif @zmode == 6 m_d = -20000 endif m_lastZ = pz return m_d endfunc default: title = "Slope Basics" int param v_slopebasics caption = "Version (Slope Basics)" default = 101 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_slopebasics < 101 endparam heading text = "This plugin provides the basic slope height values." endheading param zmode caption = "Basic heights" default = 0 enum = "smoothed iteration" "smallest |z|" "smallest |real(z)|" \ "smallest |imag(z)|" "smallest summ(z)" "smallest |atan(z)|" endparam } class REB_ImageTileTexture(common.ulb:TrapShape) { ; ; Uses an image to create a texture.
;

; Converts the colors of an imported image to greyscale and then converts ; the greyscale value to a complex number to use as a texture. ; public: import "common.ulb" ; Constructor func REB_ImageTileTexture(Generic pparent) TrapShape.TrapShape(pparent) m_img = new @f_image(0) m_empty = m_img.GetEmpty() endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) color pcolor = rgba(0,0,0,0) if !m_empty complex m_zi = (0,1)^(@iangle/90.0) complex m_zs = (0,1)^(@sangle/90.0) complex pzrs = pz ; offset if !@itile pzrs = pzrs+@ioffset endif ; aspect ratio pzrs = real(pzrs) + flip(imag(pzrs)*@iaspect) ; rotation pzrs = pzrs*m_zi ; skew pzrs = real(pzrs)*m_zs + flip(imag(pzrs)) float width = m_img.getWidth() float height = m_img.getHeight() if @itile if @v_trapshapeimagetiletexture >= 103 pzrs = (pzrs+500+flip(500))*@scale*500 else pzrs = (pzrs+#width/2+flip(#height/2))*@scale*#width endif complex c = @adjx-2*((real(pzrs) % (width-1))/width) + \ flip(@adjy-2*((imag(pzrs) % (height-1))/height)) pcolor = m_img.getColor(c) else pcolor = m_img.getColor(pzrs*@scale) endif endif m_LastZ = exp(flip(2 * #pi * sqrt(2) * (1 - (0.3 * red(pcolor)+ 0.59 * green(pcolor) + 0.11 * blue(pcolor))))) return 1 - (0.3 * red(pcolor)+ 0.59 * green(pcolor) + 0.11 * blue(pcolor)) endfunc protected: ImageImport m_img int m_image_width int m_image_height float m_ratio bool m_empty default: title = "Image Tile Texture" int param v_trapshapeimagetiletexture caption = "Version (Trap Shape Image Tile Texture)" default = 103 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_trapshapeimagetiletexture < 103 endparam heading caption = "Image Parameters" endheading ImageImport param f_image caption = "Image" default = ImageImport endparam float param scale caption = "Image scale" default = 1 min = 0 hint = "Changes the scale of the image." endparam float param adjx caption = "Tile adj x" default = 0.99 min = 0.9 max = 1.1 endparam float param adjy caption = "Tile adj y" default = 0.999 min = 0.9 max = 1.1 endparam complex param ioffset caption = "Image offset" default = (0,0) visible = !@itile endparam float param iaspect caption = "Image aspect" default = 1.0 endparam float param iangle caption = "Image rotation" default = 0 hint = "Rotates the image" endparam float param sangle caption = "Image skew" default = 0 hint = "Skews the image" endparam bool param itile caption = "Tile the image" default = false endparam } class REB_TrapShapeChip(common.ulb:TrapShape) { ; Based upon the Chip strange attractor. Can also be used as a texture.
public: import "common.ulb" ; Constructor func REB_TrapShapeChip(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x if x != 0 x = y - x/abs(x)*cos(sqr(log(abs(@h2*x-@h3))))*atan(sqr(log(abs(@h3*x-@h2)))) else x = y - cos(sqr(log(abs(@h2*x-@h3))))*atan(sqr(log(abs(@h3*x-@h2)))) endif y = @h1 - pxx att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y)) float d = @distscale*|pz-(x + sgn*flip(y))| return d endfunc default: title = "Chip" heading text="Chip Attractor" endheading heading text="x -> y - sign(x)*cos(sqr(log(abs(b*x - c)))) \ * atan(sqr(log(abs(c*x - b))))" endheading heading text="y -> a - x" endheading int param v_trapshapechip caption = "Version (Trap Shape Chip)" default = 101 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_trapshapechip < 101 endparam float param h1 caption = "Chip param 1" default = -15 endparam float param h2 caption = "Chip param 2" default = -3 endparam float param h3 caption = "Chip param 3" default = 1 endparam float param distscale caption = "Distance scale" default = 0.01 endparam float param s caption = "Attractor scale" default = 40 endparam int param max_att_iterations caption = "Attractor iterations" default = 5 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeChip2(common.ulb:TrapShape) { ; Based upon the Chip strange attractor. Can also be used as a texture.
public: import "common.ulb" ; Constructor func REB_TrapShapeChip2(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float scale = sqrt(@h1*@h1+@h2*@h2+@h3*@h3) scale = @scaleadj*scale int sgn = 1 if @sgn sgn = -1 endif complex p = pz p = @fn1(p) float x = real(p)*scale float y = imag(p)*scale float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x if x != 0 x = y - x/abs(x)*cos(sqr(log(abs(@h2*x-@h3))))*atan(sqr(log(abs(@h3*x-@h2)))) else x = y - cos(sqr(log(abs(@h2*x-@h3))))*atan(sqr(log(abs(@h3*x-@h2)))) endif y = @h1 - pxx att_iter = att_iter + 1 endwhile m_LastZ = @fn2(x + sgn*flip(y)) float d = abs(|pz| - |m_LastZ|) if @v_trapshapechip2 >= 102 d = d*@dscale endif return d endfunc default: title = "Chip 2" heading caption="Chip Attractor" endheading heading text="x -> y - sign(x)*cos(sqr(log(abs(b*x - c)))) \ * atan(sqr(log(abs(c*x - b))))" endheading heading text="y -> a - x" endheading int param v_trapshapechip2 caption = "Version (Trap Shape Chip 2)" default = 102 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_trapshapechip2 < 102 endparam float param h1 caption = "Chip param 1" default = -15 endparam float param h2 caption = "Chip param 2" default = -3 endparam float param h3 caption = "Chip param 3" default = 1 endparam float param dscale caption = "Distance scale" default = 1 visible = @v_trapshapechip2 >= 102 endparam float param scaleadj caption = "Attractor scale" default = 1 endparam int param max_att_iterations caption = "Attractor iterations" default = 1 endparam func fn1 caption = "Pre Function" default = atan() endfunc func fn2 caption = "Post Function" default = sinh() endfunc bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeHenon2(common.ulb:TrapShape) { ; Uses the Henon strange attractor as the trap shape. public: import "common.ulb" ; Constructor func REB_TrapShapeHenon2(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float scale = sqrt(@h1*@h1+@h2*@h2) scale = @scaleadj*scale int sgn = 1 if @sgn sgn = -1 endif complex p = pz p = @fn1(p) float x = real(p)*scale float y = imag(p)*scale float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x x = 1 + y - @h1*x*x y = @h2*pxx att_iter = att_iter + 1 endwhile m_LastZ = @fn2(x + sgn*flip(y)) float d = abs(|pz| - |m_LastZ|) if @v_trapshapehenon2 >= 102 d = d*@dscale endif return d endfunc default: title = "Henon 2" heading text = "Henon attractor" endheading heading text = "x -> 1 + y - h1*x^2" endheading heading text = "y -> h2*x" endheading int param v_trapshapehenon2 caption = "Version (Trap Shape Henon 2)" default = 102 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_trapshapehenon2 < 102 endparam float param h1 caption = "Henon param 1" default = 1.4 endparam float param h2 caption = "Henon param 2" default = 0.3 endparam float param dscale caption = "Distance scale" default = 1 visible = @v_trapshapehenon2 >= 102 endparam float param scaleadj caption = "Attractor scale" default = 1 endparam int param max_att_iterations caption = "Attractor iterations" default = 5 endparam func fn1 caption = "Pre Function" default = atan() endfunc func fn2 caption = "Post Function" default = sinh() endfunc bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeHopalong2(common.ulb:TrapShape) { ; Uses the Hopalong strange attractor as the trap shape. Can also be used as a texture. public: import "common.ulb" ; Constructor func REB_TrapShapeHopalong2(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float scale = sqrt(@h1*@h1+@h2*@h2+@h3*@h3) scale = @scaleadj*scale int sgn = 1 if @sgn sgn = -1 endif complex p = pz p = @fn1(p) float x = real(p)*scale float y = imag(p)*scale float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations pxx = x if x != 0 x = y - x/abs(x)*sqrt(abs(@h2*x-@h3)) else x = y - sqrt(abs(@h2*x-3)) endif y = @h1 - pxx att_iter = att_iter + 1 endwhile m_LastZ = @fn2(x + sgn*flip(y)) float d = abs(|pz| - |m_LastZ|) if @v_trapshapehopalong2 >= 102 d = d*@dscale endif return d endfunc default: title = "Hopalong 2" heading text="Hopalong Attractor" endheading heading text="x -> y - sign(x)*sqrt(abs(b*x-c))" endheading heading text="y -> a - x" endheading int param v_trapshapehopalong2 caption = "Version (Trap Shape Hopalong 2)" default = 102 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_trapshapehopalong2 < 102 endparam float param h1 caption = "Hopalong param 1" default = 0.4 endparam float param h2 caption = "Hopalong param 2" default = 1 endparam float param h3 caption = "Hopalong param 3" default = 0 endparam float param dscale caption = "Distance scale" default = 1 visible = @v_trapshapehopalong2 >= 102 endparam float param scaleadj caption = "Attractor scale" default = 1 endparam int param max_att_iterations caption = "Attractor iterations" default = 1 endparam func fn1 caption = "Pre Function" default = atan() endfunc func fn2 caption = "Post Function" default = sinh() endfunc bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShape4DOrbit(common.ulb:TrapShape) { ; Based upon the 4D fractal formula approach of Gordon Lamb.
;

; This class can be used to explore in the two "hybridised" planes. ; Type SJ iterates in the "zc" plane, and type 3RDIM in the "cz" plane. ; The trap can create multiple fractal images of the chosen function. public: import "common.ulb" ; Constructor func REB_TrapShape4DOrbit(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) p = (0,0) px = pz*@scale c = 0 if @function == "Julia Frame-Robert" || @function == "Julia Ikenaga" || \ @function == "Julia Lambda" || @function == "Julia" px = @seed p = pz*@scale endif if @variant == "SJ" p = real(p) + flip(imag(p)*@r) c = @t + @r*real(px) + flip(imag(px)) else p = @r*real(p) + flip(imag(p)) c = @t + real(px) + flip(imag(px)*@r) endif p = @fn1(p) rt_iter = 0 while rt_iter < @max_iterations && (|p| < @bailout) if @function == "Mandelbrot" || @function == "Julia" p = p*p + c elseif @function == "Julia Lambda" p = c*p*(1-p) elseif @function == "Ikenaga" || @function == "Julia Ikenaga" p = p*p*p + (c-1)*p-c elseif @function == "Frame-Robert" || @function == "Julia Frame-Robert" p = p*p*p/5 + p*p + c endif rt_iter = rt_iter + 1 endwhile m_LastZ = @fn2(p) float d = abs(cabs(pz)-cabs(m_LastZ)) return d endfunc protected: complex p complex px complex c int rt_iter default: title = "4D Orbit" int param v_trapshape4dorbit caption = "Version (Trap Shape 4D Orbit)" default = 101 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_trapshape4dorbit < 101 endparam param t caption = "Translation" default = -0.75 endparam param r caption = "Tilt" default = 0.5 min = 0 max = 1 hint = "This parameter takes values between 0 and 1 inclusive." endparam param variant caption = "4D variant" default = 0 enum = "SJ" "3RDIM" hint = "These variants are based upon Gordon Lamb's 4D formulas." endparam param max_iterations caption = "4D iterations" hint = "This is the number of iterations for the 4D formula." default = 10 endparam float param bailout caption = "Bailout" default = 10000.0 endparam float param scale caption = "Scale" default = 1.0 endparam param function caption = "4D Fractal" default = 1 enum = "Frame-Robert" "Ikenaga" "Mandelbrot" "Julia Frame-Robert" \ "Julia Ikenaga" "Julia Lambda" "Julia" endparam complex param seed caption = "Julia seed" default = (0,0) visible = @function == "Julia Frame-Robert" || @function == "Julia Ikenaga" \ || @function == "Julia Lambda" || @function == "Julia" endparam func fn1 caption = "Pre Function" default = ident() endfunc func fn2 caption = "Post Function" default = ident() endfunc } class REB_TrapShapeCosMartin(common.ulb:TrapShape) { ; Uses the CosMartin strange attractor as the trap shape. Can also be used as a texture.
; CosMartin is the cosine variant of the Martin strange attractor.
public: import "common.ulb" ; Constructor func REB_TrapShapeCosMartin(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x x = y - cos(x) y = @h1 - pxx att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y)) float d = @distscale*|pz-(x + sgn*flip(y))| return d endfunc default: title = "CosMartin" heading text="CosMartin Attractor" endheading heading text="x -> y - cos(x)" endheading heading text="y -> a - x" endheading int param v_trapshapecosmartin caption = "Version (Trap Shape CosMartin)" default = 101 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_trapshapecosmartin < 101 endparam float param h1 caption = "CosMartin param" default = 6.28 endparam float param distscale caption = "Distance scale" default = 0.01 endparam float param s caption = "Attractor scale" default = 15 endparam int param max_att_iterations caption = "Attractor iterations" default = 5 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeCosMartin2(common.ulb:TrapShape) { ; Uses the CosMartin strange attractor as the trap shape. Can also be used as a texture.
; CosMartin is the cosine variant of the Martin strange attractor.
public: import "common.ulb" ; Constructor func REB_TrapShapeCosMartin2(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float scale = @h1 scale = @scaleadj*scale int sgn = 1 if @sgn sgn = -1 endif complex p = pz p = @fn1(p) float x = real(p)*scale float y = imag(p)*scale float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x x = y - cos(x) y = @h1 - pxx att_iter = att_iter + 1 endwhile m_LastZ = @fn2(x + sgn*flip(y)) float d = abs(|pz| - |m_LastZ|) if @v_trapshapecosmartin2 >= 102 d = d*@dscale endif return d endfunc default: title = "CosMartin 2" heading text="CosMartin Attractor" endheading heading text="x -> y - cos(x)" endheading heading text="y -> a - x" endheading int param v_trapshapecosmartin2 caption = "Version (Trap Shape CosMartin 2)" default = 102 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_trapshapecosmartin2 < 102 endparam float param h1 caption = "CosMartin param" default = 6.28 endparam float param dscale caption = "Distance scale" default = 1 visible = @v_trapshapecosmartin2 >= 102 endparam float param scaleadj caption = "Attractor scale" default = 1 endparam int param max_att_iterations caption = "Attractor iterations" default = 1 endparam func fn1 caption = "Pre Function" default = atan() endfunc func fn2 caption = "Post Function" default = sinh() endfunc bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeHenon(common.ulb:TrapShape) { ; This shape uses the Henon strange attractor public: import "common.ulb" ; Constructor func REB_TrapShapeHenon(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x x = 1 + y - @h1*x*x y = @h2*pxx att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y)) float d = @distscale*|pz-(x + sgn*flip(y))| return d endfunc default: title = "Henon" heading text = "Henon attractor" endheading heading text = "x -> 1 + y - h1*x^2" endheading heading text = "y -> h2*x" endheading int param v_trapshapehenon caption = "Version (Trap Shape Henon)" default = 101 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_trapshapehenon < 101 endparam float param h1 caption = "Henon param 1" default = 1.4 endparam float param h2 caption = "Henon param 2" default = 0.3 endparam float param distscale caption = "Distance scale" default = 1.0 endparam float param s caption = "Attractor scale" default = 1.0 endparam int param max_att_iterations caption = "Attractor iterations" default = 5 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeGingerbread(common.ulb:TrapShape) { ; This shape uses the Gingerbread strange attractor. public: import "common.ulb" ; Constructor func REB_TrapShapeGingerbread(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x x = 1 - y + abs(x) y = pxx att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y)) float d = @distscale*|pz-(x + sgn*flip(y))| return d endfunc default: title = "Gingerbread" heading text = "Gingerbread attractor" endheading heading text = "x -> y + abs(x)" endheading heading text = "y -> x" endheading int param v_trapshapegingerbread caption = "Version (Trap Shape Gingerbread)" default = 101 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_trapshapegingerbread < 101 endparam float param distscale caption = "Distance scale" default = 0.07 endparam float param s caption = "Attractor scale" default = 10 endparam int param max_att_iterations caption = "Attractor iterations" default = 10 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeDampedSine(common.ulb:TrapShape) { ; This shape uses the Damped sine equation. public: import "common.ulb" ; Constructor func REB_TrapShapeDampedSine(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@b float x = 5*@a*t float y = 5*@a*sin(t)/t m_lastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Damped Sine" int param v_DampedSine caption = "Version (Damped Sine)" 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_DampedSine < 100 endparam float param a caption = "Polar Parameter" default = 0.2 endparam float param b caption = "2nd polar Parameter" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } class REB_TrapShapeHopalong(common.ulb:TrapShape) { ; This shape uses the Hopalong strange attractor. It can also be used as a texture.
public: import "common.ulb" ; Constructor func REB_TrapShapeHopalong(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x if x != 0 x = y - x/abs(x)*sqrt(abs(@h2*x-@h3)) else x = y - sqrt(abs(@h2*x-3)) endif y = @h1 - pxx att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y)) float d = @distscale*|pz-(x + sgn*flip(y))| return d endfunc default: title = "Hopalong" heading text="Hopalong attractor" endheading heading text="x -> y - sign(x)*sqrt(abs(b*x-c))" endheading heading text="y -> a - x" endheading int param v_trapshapehopalong caption = "Version (Trap Shape Hopalong)" default = 101 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_trapshapehopalong < 101 endparam float param h1 caption = "Hopalong param 1" default = 0.4 endparam float param h2 caption = "Hopalong param 2" default = 1 endparam float param h3 caption = "Hopalong param 3" default = 0 endparam float param distscale caption = "Distance scale" default = 0.06 endparam float param s caption = "Attractor scale" default = 3 endparam int param max_att_iterations caption = "Attractor iterations" default = 5 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeKam_Torus(common.ulb:TrapShape) { ; This shape uses the Hopalong strange attractor. It can also be used as a texture.
public: import "common.ulb" ; Constructor func REB_TrapShapeKam_Torus(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s+@sorbit float y = imag(pz)*@s+@sorbit float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x x = x*cos(@a) - (y - x^2)*sin(@a) y = pxx*sin(@a) + (y - pxx^2)*cos(@a) att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y)) float d = @distscale*|pz-(x + sgn*flip(y))| return d endfunc default: title = "Kam Torus" heading text = "Kam Torus attractor" endheading heading text = "Kam Torus is the phase map for the Henon attractor" endheading heading text = "x -> x*cos(a) - (y-x^2)*sin(a)" endheading heading text = "y -> x*sin(a) + (y-x^2)*cos(a)" endheading heading text = "The full phase map is determined by progressing through a continuum of \ starting points for x and y." endheading int param v_trapshapeKamTorus caption = "Version (Trap Shape Kam Torus)" default = 101 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_trapshapeKamTorus < 101 endparam float param a caption = "Kam Torus param" default = 1.57 endparam float param sorbit caption = "Start orbit" default = 0.0 endparam float param distscale caption = "Distance scale" default = 1 endparam float param s caption = "Attractor scale" default = 1 endparam int param max_att_iterations caption = "Attractor iterations" default = 100 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeLatoocarfian(common.ulb:TrapShape) { ; This shape uses the Latoocarfian strange attractor public: import "common.ulb" ; Constructor func REB_TrapShapeLatoocarfian(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x x = sin(y*@h2) + @h3*sin(x*@h2) y = sin(pxx*@h1) + @h4*sin(y*@h1) att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y)) float d = @distscale*|pz-(x + sgn*flip(y))| return d endfunc default: title = "Latoocarfian" heading text = "Latoocarfian attractor" endheading heading text = "x -> sin(h2*y) + h3*sin(h2*x)" endheading heading text = "y -> sin(h1*x) + h4*sin(h1*y)" endheading int param v_trapshapelatoocarfian caption = "Version (Trap Shape Latoocarfian)" default = 101 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_trapshapelatoocarfian < 101 endparam float param h1 caption = "Latoocarfian 1" default = --0.960918 endparam float param h2 caption = "Latoocarfian 2" default = 2.879879 endparam float param h3 caption = "Latoocarfian 3" default = 0.765145 endparam float param h4 caption = "Latoocarfian 4" default = 0.744728 endparam float param distscale caption = "Distance scale" default = 1 endparam float param s caption = "Attractor scale" default = 1 endparam int param max_att_iterations caption = "Attractor iterations" default = 5 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeKaneko(common.ulb:TrapShape) { ; This shape uses the Kaneko strange attractor ; Suggested values to try: ; a b ;----------------- ; 0.1 1.67 ; 0.5 4.0 ; 0.17 1.3 ; 0.562 2.76 public: import "common.ulb" ; Constructor func REB_TrapShapeKaneko(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x if @kantype == "I" x = @a*x + (1-@a)*(1-@b*y^2) else x = @a*x + (1-@a)*(1-@b*abs(y)) endif y = pxx att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y)) float d = @distscale*|pz-(x + sgn*flip(y))| return d endfunc default: title = "Kaneko" heading text = "Kaneko attractor" endheading heading text = "There are two forms of the Kaneko attractor" endheading heading text = " Form I" endheading heading text = "x -> a*x + (1-a)*(1-b*y^2)" endheading heading text = "y -> x" endheading heading text = " Form II" endheading heading text = "x -> a*x + (1-a)*(1-b*abs(y))" endheading heading text = "y -> x" endheading int param v_trapshapeKaneko caption = "Version (Trap Shape Kaneko)" 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_trapshapeKaneko < 100 endparam param kantype caption = "Kaneko type" default = 0 enum = "I" "II" endparam param a caption = "parameter a" default = 0.4 endparam param b caption = "parameter b" default = 2.76 endparam float param distscale caption = "Distance scale" default = 0.5 endparam float param s caption = "Attractor scale" default = 2.5 endparam int param max_att_iterations caption = "Attractor iterations" default = 10 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeMira(common.ulb:TrapShape) { ; This shape uses the Mira strange attractor ; Suggested values to try: ; a b ;----------------- ; 0.29 1.0005 ; -0.48 0.93 ; -0.4 0.9999 ; -0.2 1.000 public: import "common.ulb" ; Constructor func REB_TrapShapeMira(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x x = @b*y + @a*x - (1-@a)*2*x^2/(1+x^2)^2 y = -pxx + @a*pxx - (1-@a)*2*pxx^2/(1+pxx^2)^2 att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y)) float d = @distscale*|pz-(x + sgn*flip(y))| return d endfunc default: title = "Mira" heading text = "Mira attractor" endheading heading text = "x -> b*y + a*x - (1-a)*2*x^2/(1+x^2)^2" endheading heading text = "y -> -x + a*x - (1-a)*2*x^2/(1+x^2)^2" endheading int param v_trapshapeMira caption = "Version (Trap Shape Mira)" 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_trapshapeMira < 100 endparam param a caption = "parameter a" default = -.399000001 endparam param b caption = "parameter b" default = 1.000001 endparam float param distscale caption = "Distance scale" default = 0.5 endparam float param s caption = "Attractor scale" default = 2.5 endparam int param max_att_iterations caption = "Attractor iterations" default = 10 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeTinkerbell(common.ulb:TrapShape) { ; This shape uses the Tinkerbell strange attractor public: import "common.ulb" ; Constructor func REB_TrapShapeTinkerbell(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s + @xoff float y = imag(pz)*@s + @yoff float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x x = x^2 - y^2 + @a*x + @b*y y = 2*pxx*y + @c*pxx + @d*y att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y)) float d = @distscale*|pz-(x + sgn*flip(y))| return d endfunc default: title = "Tinkerbell" heading text = "Tinkerbell attractor" endheading heading text = "x -> x^2 - y^2 + a*x + b*y" endheading heading text = "y -> 2*x*y + c*x + d*y" endheading int param v_trapshapeTinkerbell caption = "Version (Trap Shape Tinkerbell)" 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_trapshapeTinkerbell < 100 endparam float param a caption = "parameter a" default = 0.9 endparam float param b caption = "parameter b" default = -0.6103 endparam float param c caption = "parameter c" default = 2.0 endparam float param d caption = "parameter d" default = 0.5 endparam float param xoff caption = "x offset" default = -0.72 endparam float param yoff caption = "y offset" default = -0.64 endparam float param distscale caption = "Distance scale" default = 0.5 endparam float param s caption = "Attractor scale" default = -0.5 endparam int param max_att_iterations caption = "Attractor iterations" default = 15 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeLiar(common.ulb:TrapShape) { ; This shape uses the Liar formula of Chuck Ebbert. It is a texture shape.
public: import "common.ulb" ; Constructor func REB_TrapShapeLiar(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations pxx = x if @liartype == 0 if real(x + flip(pz)) < (@h1) x = @h2 - abs(y-x) y = abs(@h3 - pxx - y) endif elseif @liartype == 1 if imag(x + flip(pz)) < (@h1) x = @h2 - abs(y-x) y = abs(@h3 - pxx - y) endif else if cabs(x + flip(pz)) < (@h1) x = @h2 - abs(y-x) y = abs(@h3 - pxx - y) endif endif att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y)) float d = @distscale*|pz-(x + sgn*flip(y))| return d endfunc default: title = "Liar" heading text = "Liar attractor" endheading heading text = "There are three Liar types which depend upon the value of x + flip(z) \ where the real, the imaginary or the cabs value is compared to the \ parameter h1. If the quantity is less than h1 then new values of x \ and y are calculated, otherwise they are left the same. z is the complex \ value passed from the fractal function." endheading heading text = "x -> h2 - abs(y-x)" endheading heading text = "y -> abs(h3-x-y)" endheading int param v_trapshapeliar caption = "Version (Trap Shape Liar)" default = 101 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_trapshapeliar < 101 endparam param liartype caption = "Liar type" default = 0 enum = "real" "imag" "abs" endparam float param h1 caption = "Liar 1" default = 2.0 endparam float param h2 caption = "Liar 2" default = 0.5 endparam float param h3 caption = "Liar 3" default = 0.5 endparam float param distscale caption = "Distance scale" default = 0.5 endparam float param s caption = "Attractor scale" default = 0.1 endparam int param max_att_iterations caption = "Attractor iterations" default = 20 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapePickover(common.ulb:TrapShape) { ; This shape uses the Pickover strange attractor public: import "common.ulb" ; Constructor func REB_TrapShapePickover(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float ppz = @ppz float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations pxx = x x = real(@pfun1(y*@h1) - ppz*@pfun2(x*@h2)) y = real(ppz*@pfun3(pxx*@h3) - @pfun4(y*@h4)) ppz = real(@h5*@pfun5(pxx)) att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y)+ppz*@pw) float d = @distscale*|pz-(x + sgn*flip(y) + ppz*@pw)| return d endfunc default: title = "Pickover" heading text = "Pickover attractor" endheading heading text = "This attractor has been generalized to allow the use of multiple function \ settings." endheading heading text = "x -> fun1(y*h1) - z*fun2(x*h2)" endheading heading text = "y -> z*fun3(x*h3) - fun4(y*h4)" endheading heading text = "z -> h5*fun5(x)" endheading int param v_trapshapepickover caption = "Version (Trap Shape Pickover)" default = 101 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_trapshapepickover < 101 endparam heading text = "'Initialize Height' sets the starting z value for the attractor." endheading float param ppz caption = "Initialize Height" default = 0.5 endparam heading text = "'Height weight' determines the weight of the final z value which is added \ to the trap distance." endheading complex param pw caption = "Height weight" default = (0.5,0) endparam float param h1 caption = "Pickover 1" default = 2.24 endparam float param h2 caption = "Pickover 2" default = 0.43 endparam float param h3 caption = "Pickover 3" default = -0.65 endparam float param h4 caption = "Pickover 4" default = -2.43 endparam float param h5 caption = "Pickover 5" default = 1 endparam func pfun1 caption = "Pickover Fn 1" default = sin() endfunc func pfun2 caption = "Pickover Fn 2" default = cos() endfunc func pfun3 caption = "Pickover Fn 3" endfunc func pfun4 caption = "Pickover Fn 4" default = cos() endfunc func pfun5 caption = "Pickover Fn 5" default = sin() endfunc float param distscale caption = "Distance scale" default = 0.5 endparam float param s caption = "Attractor scale" default = 1 endparam int param max_att_iterations caption = "Attractor iterations" default = 5 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeQuadruptwo(common.ulb:TrapShape) { ; This shape uses the Quadruptwo strange attractor. public: import "common.ulb" ; Constructor func REB_TrapShapeQuadruptwo(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x if x != 0 x = y - x/abs(x)*sin(log(abs(@h2*x-@h3))) \ *atan(sqr(log(abs(@h3*x-@h2)))) else x = y - sin(log(abs(@h2*x-@h3))) \ *atan(sqr(log(abs(@h3*x-@h2)))) endif y = @h1 - pxx att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y)) float d = @distscale*|pz-(x + sgn*flip(y))| return d endfunc default: title = "Quadruptwo" int param v_trapshapequadruptwo caption = "Version (Trap Shape Quadruptwo)" default = 101 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_trapshapequadruptwo < 101 endparam float param h1 caption = "Quadruptwo param 1" default = 34 endparam float param h2 caption = "Quadruptwo param 2" default = 1 endparam float param h3 caption = "Quadruptwo param 3" default = 5 endparam float param distscale caption = "Distance scale" default = 0.0001 endparam float param s caption = "Attractor scale" default = 30 endparam int param max_att_iterations caption = "Attractor iterations" default = 50 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeSierpinski(common.ulb:TrapShape) { ; This shape uses the Sierpinski strange attractor. public: import "common.ulb" ; Constructor func REB_TrapShapeSierpinski(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) complex pp = pz*@s int att_iter = 0 while att_iter < @max_att_iterations if (imag(pp) > @h3) pp = @h1*real(pp) + flip(@h1*imag(pp) -@h2) elseif (real(pp) > @h4) pp = @h1*real(pp) -@h2 + flip(@h1*imag(pp)) else pp = @h1*real(pp) + flip(@h1*imag(pp)) endif att_iter = att_iter + 1 endwhile if !@sgn m_LastZ = pp else m_LastZ = conj(pp) endif float d = @distscale*|pz-pp| return d endfunc default: title = "Sierpinski" heading text = "Sierpinski atractor" endheading int param v_trapshapesierpinski caption = "Version (Trap Shape Sierpinski)" default = 101 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_trapshapesierpinski < 101 endparam float param h1 caption = "Sierpinski 1" default = 2 endparam float param h2 caption = "Sierpinski 2" default = 1 endparam float param h3 caption = "Sierpinski 3" default = 0.5 endparam float param h4 caption = "Sierpinski 4" default = 0.5 endparam float param distscale caption = "Distance scale" default = 1 endparam float param s caption = "Attractor scale" default = 0.1 endparam int param max_att_iterations caption = "Attractor iterations" default = 10 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeSprott3D(common.ulb:TrapShape) { ; This shape uses a Sprott strange attractor.
;

; The Sprott attractors were developed by Julien C. Sprott, and are ; based upon polynomials and linear differential equations of polynomials. public: import "common.ulb" ; Constructor func REB_TrapShapeSprott3D(Generic pparent) TrapShape.TrapShape(pparent) s3[0,1]=0.3,s3[0,2]=-0.8,s3[0,3]=-0.8,s3[0,4]=1.2,s3[0,5]=0.6,s3[0,6]=0.3,s3[0,7]=-0.7,s3[0,8]=0.5,s3[0,9]=-0.7,s3[0,10]=0.1,s3[0,11]=0.1,s3[0,12]=-0.4,s3[0,13]=0.7,s3[0,14]=0.7 s3[0,15]=-0.3,s3[0,16]=-0.5,s3[0,17]=1.0,s3[0,18]=-0.7,s3[0,19]=0.9,s3[0,20]=-0.3,s3[0,21]=0.1,s3[0,22]=0.8,s3[0,23]=0.4,s3[0,24]=-1.0,s3[0,25]=0.3,s3[0,26]=-1.0,s3[0,27]=0.6,s3[0,28]=0.2,s3[0,29]=-0.5,s3[0,30]=0.7 s3[1,1]=0.2,s3[1,2]=-0.6,s3[1,3]=1.1,s3[1,4]=-0.9,s3[1,5]=1.0,s3[1,6]=-0.4,s3[1,7]=1.2,s3[1,8]=-0.2,s3[1,9]=-0.3,s3[1,10]=-0.3,s3[1,11]=0.2,s3[1,12]=-0.5,s3[1,13]=0.7,s3[1,14]=0.3 s3[1,15]=-0.5,s3[1,16]=-0.1,s3[1,17]=0.2,s3[1,18]=-1.1,s3[1,19]=-0.2,s3[1,20]=-0.9,s3[1,21]=-0.6,s3[1,22]=0.5,s3[1,23]=1.1,s3[1,24]=-0.7,s3[1,25]=-0.9,s3[1,26]=-0.5,s3[1,27]=0.8,s3[1,28]=0.6,s3[1,29]=0.9,s3[1,30]=0.9 s3[2,1]=-1.0,s3[2,2]=0.2,s3[2,3]=-0.2,s3[2,4]=-0.1,s3[2,5]=-0.5,s3[2,6]=1.0,s3[2,7]=-0.5,s3[2,8]=-0.6,s3[2,9]=0.8,s3[2,10]=0.6,s3[2,11]=0.2,s3[2,12]=-0.9,s3[2,13]=-1.0,s3[2,14]=0.8 s3[2,15]=0.4,s3[2,16]=-0.4,s3[2,17]=0.3,s3[2,18]=-0.5,s3[2,19]=1.2,s3[2,20]=-0.5,s3[2,21]=0.8,s3[2,22]=-0.7,s3[2,23]=-0.6,s3[2,24]=-1.1,s3[2,25]=0.1,s3[2,26]=-1.2,s3[2,27]=-0.1,s3[2,28]=1.1,s3[2,29]=0.3,s3[2,30]=-1.0 s3[3,1]=-0.2,s3[3,2]=0.5,s3[3,3]=-0.6,s3[3,4]=0.3,s3[3,5]=0.6,s3[3,6]=-1.1,s3[3,7]=0.7,s3[3,8]=-0.3,s3[3,9]=0.6,s3[3,10]=-0.7,s3[3,11]=-0.3,s3[3,12]=0.6,s3[3,13]=-0.6,s3[3,14]=0.4 s3[3,15]=-1.1,s3[3,16]=-0.6,s3[3,17]=0.7,s3[3,18]=-1.2,s3[3,19]=0.5,s3[3,20]=-1.1,s3[3,21]=0.7,s3[3,22]=0.0,s3[3,23]=-0.4,s3[3,24]=0.1,s3[3,25]=0.5,s3[3,26]=0.4,s3[3,27]=-0.5,s3[3,28]=0.4,s3[3,29]=0.5,s3[3,30]=-0.9 s3[4,1]=-0.4,s3[4,2]=0.6,s3[4,3]=1.2,s3[4,4]=-0.5,s3[4,5]=1.0,s3[4,6]=-0.6,s3[4,7]=-1.0,s3[4,8]=1.2,s3[4,9]=0.4,s3[4,10]=0.8,s3[4,11]=-0.6,s3[4,12]=0.9,s3[4,13]=0.6,s3[4,14]=0.0 s3[4,15]=0.1,s3[4,16]=-0.8,s3[4,17]=0.2,s3[4,18]=-0.1,s3[4,19]=-0.5,s3[4,20]=-0.3,s3[4,21]=-0.4,s3[4,22]=0.6,s3[4,23]=0.0,s3[4,24]=-0.8,s3[4,25]=-1.0,s3[4,26]=-0.6,s3[4,27]=-1.2,s3[4,28]=0.8,s3[4,29]=-0.6,s3[4,30]=0.9 s3[5,1]=-1.1,s3[5,2]=-0.9,s3[5,3]=-0.4,s3[5,4]=-0.9,s3[5,5]=0.3,s3[5,6]=-0.7,s3[5,7]=0.5,s3[5,8]=0.7,s3[5,9]=0.4,s3[5,10]=0.2,s3[5,11]=-0.1,s3[5,12]=-1.0,s3[5,13]=-0.6,s3[5,14]=-0.5 s3[5,15]=0.6,s3[5,16]=-1.0,s3[5,17]=1.2,s3[5,18]=-0.5,s3[5,19]=-1.0,s3[5,20]=1.2,s3[5,21]=0.5,s3[5,22]=-1.0,s3[5,23]=-0.2,s3[5,24]=-0.9,s3[5,25]=0.6,s3[5,26]=0.4,s3[5,27]=-1.0,s3[5,28]=0.5,s3[5,29]=-0.1,s3[5,30]=-0.1 s3[6,1]=-0.2,s3[6,2]=0.8,s3[6,3]=0.9,s3[6,4]=1.0,s3[6,5]=0.7,s3[6,6]=-0.7,s3[6,7]=0.4,s3[6,8]=1.1,s3[6,9]=-0.8,s3[6,10]=1.0,s3[6,11]=0.8,s3[6,12]=0.5,s3[6,13]=-0.1,s3[6,14]=-0.5 s3[6,15]=-0.2,s3[6,16]=-0.9,s3[6,17]=-0.5,s3[6,18]=-0.8,s3[6,19]=0.6,s3[6,20]=0.7,s3[6,21]=-0.1,s3[6,22]=-0.3,s3[6,23]=-0.8,s3[6,24]=0.5,s3[6,25]=-0.6,s3[6,26]=0.3,s3[6,27]=-0.1,s3[6,28]=-0.1,s3[6,29]=0.6,s3[6,30]=0.8 s3[7,1]=-0.2,s3[7,2]=0.3,s3[7,3]=-1.2,s3[7,4]=-0.8,s3[7,5]=-1.0,s3[7,6]=0.4,s3[7,7]=-0.3,s3[7,8]=1.0,s3[7,9]=1.0,s3[7,10]=-0.8,s3[7,11]=0.1,s3[7,12]=0.8,s3[7,13]=1.2,s3[7,14]=-0.6 s3[7,15]=0.3,s3[7,16]=-1.2,s3[7,17]=1.2,s3[7,18]=0.8,s3[7,19]=0.5,s3[7,20]=-0.6,s3[7,21]=0.4,s3[7,22]=0.1,s3[7,23]=-0.4,s3[7,24]=-0.8,s3[7,25]=-0.6,s3[7,26]=-0.6,s3[7,27]=-0.7,s3[7,28]=-0.3,s3[7,29]=-0.4,s3[7,30]=-0.1 s3[8,1]=1.0,s3[8,2]=-0.4,s3[8,3]=-1.1,s3[8,4]=0.6,s3[8,5]=-0.2,s3[8,6]=-0.7,s3[8,7]=-0.7,s3[8,8]=-0.1,s3[8,9]=1.0,s3[8,10]=1.2,s3[8,11]=-0.2,s3[8,12]=1.2,s3[8,13]=-0.9,s3[8,14]=-0.6 s3[8,15]=0.6,s3[8,16]=-0.1,s3[8,17]=-0.4,s3[8,18]=0.8,s3[8,19]=0.1,s3[8,20]=-0.3,s3[8,21]=-0.1,s3[8,22]=0.5,s3[8,23]=-0.7,s3[8,24]=0.2,s3[8,25]=-0.8,s3[8,26]=-0.6,s3[8,27]=-0.6,s3[8,28]=-1.0,s3[8,29]=0.4,s3[8,30]=1.0 s3[9,1]=0.6,s3[9,2]=-0.3,s3[9,3]=-0.8,s3[9,4]=-0.2,s3[9,5]=0.7,s3[9,6]=0.4,s3[9,7]=1.2,s3[9,8]=0.7,s3[9,9]=0.2,s3[9,10]=0.5,s3[9,11]=0.1,s3[9,12]=-0.8,s3[9,13]=0.2,s3[9,14]=-0.6 s3[9,15]=0.8,s3[9,16]=0.3,s3[9,17]=0.0,s3[9,18]=0.7,s3[9,19]=-1.1,s3[9,20]=0.2,s3[9,21]=-0.7,s3[9,22]=1.0,s3[9,23]=1.2,s3[9,24]=0.8,s3[9,25]=0.5,s3[9,26]=0.0,s3[9,27]=-0.7,s3[9,28]=-0.9,s3[9,29]=0.5,s3[9,30]=1.1 s3[10,1]=-0.2,s3[10,2]=0.4,s3[10,3]=0.7,s3[10,4]=1.2,s3[10,5]=0.5,s3[10,6]=1.0,s3[10,7]=-1.1,s3[10,8]=0.0,s3[10,9]=1.2,s3[10,10]=-0.6,s3[10,11]=0.1,s3[10,12]=-1.1,s3[10,13]=-0.5,s3[10,14]=0.1 s3[10,15]=-0.7,s3[10,16]=-0.6,s3[10,17]=0.0,s3[10,18]=0.2,s3[10,19]=0.6,s3[10,20]=0.6,s3[10,21]=0.3,s3[10,22]=-0.5,s3[10,23]=-0.2,s3[10,24]=0.6,s3[10,25]=1.1,s3[10,26]=-0.4,s3[10,27]=0.7,s3[10,28]=-0.1,s3[10,29]=-0.2,s3[10,30]=-0.8 s3[11,1]=0.1,s3[11,2]=0.6,s3[11,3]=-0.5,s3[11,4]=0.9,s3[11,5]=0.0,s3[11,6]=-0.4,s3[11,7]=1.0,s3[11,8]=-0.8,s3[11,9]=1.2,s3[11,10]=0.9,s3[11,11]=0.1,s3[11,12]=0.1,s3[11,13]=-0.3,s3[11,14]=0.6 s3[11,15]=0.8,s3[11,16]=0.1,s3[11,17]=0.2,s3[11,18]=-1.0,s3[11,19]=0.3,s3[11,20]=-0.9,s3[11,21]=0.7,s3[11,22]=0.3,s3[11,23]=-0.7,s3[11,24]=-1.0,s3[11,25]=1.0,s3[11,26]=0.9,s3[11,27]=-0.5,s3[11,28]=0.1,s3[11,29]=0.2,s3[11,30]=-1.1 s3[12,1]=1.0,s3[12,2]=-0.4,s3[12,3]=-0.3,s3[12,4]=-0.4,s3[12,5]=-0.2,s3[12,6]=0.6,s3[12,7]=-0.8,s3[12,8]=1.2,s3[12,9]=0.9,s3[12,10]=0.6,s3[12,11]=-0.1,s3[12,12]=0.3,s3[12,13]=-0.6,s3[12,14]=0.0 s3[12,15]=-0.3,s3[12,16]=-0.8,s3[12,17]=-0.1,s3[12,18]=0.0,s3[12,19]=0.7,s3[12,20]=1.0,s3[12,21]=-0.9,s3[12,22]=0.6,s3[12,23]=0.6,s3[12,24]=0.4,s3[12,25]=0.8,s3[12,26]=-0.6,s3[12,27]=0.7,s3[12,28]=-0.4,s3[12,29]=1.1,s3[12,30]=1.0 s3[13,1]=1.2,s3[13,2]=0.7,s3[13,3]=-0.9,s3[13,4]=-1.1,s3[13,5]=1.2,s3[13,6]=-0.4,s3[13,7]=-0.7,s3[13,8]=0.8,s3[13,9]=-0.9,s3[13,10]=0.4,s3[13,11]=0.0,s3[13,12]=0.3,s3[13,13]=-0.5,s3[13,14]=-0.6 s3[13,15]=-0.9,s3[13,16]=0.7,s3[13,17]=0.5,s3[13,18]=0.2,s3[13,19]=-0.2,s3[13,20]=-1.0,s3[13,21]=-0.1,s3[13,22]=-0.1,s3[13,23]=0.1,s3[13,24]=-0.5,s3[13,25]=-0.2,s3[13,26]=1.1,s3[13,27]=-0.4,s3[13,28]=0.8,s3[13,29]=-0.1,s3[13,30]=-1.0 s3[14,1]=-0.5,s3[14,2]=0.1,s3[14,3]=0.7,s3[14,4]=-0.6,s3[14,5]=0.9,s3[14,6]=-0.9,s3[14,7]=-0.5,s3[14,8]=-0.9,s3[14,9]=0.3,s3[14,10]=-0.3,s3[14,11]=-0.3,s3[14,12]=-0.3,s3[14,13]=-0.2,s3[14,14]=0.8 s3[14,15]=0.4,s3[14,16]=0.3,s3[14,17]=1.1,s3[14,18]=-0.6,s3[14,19]=-0.2,s3[14,20]=0.1,s3[14,21]=1.2,s3[14,22]=0.2,s3[14,23]=0.2,s3[14,24]=-1.1,s3[14,25]=0.9,s3[14,26]=0.3,s3[14,27]=0.9,s3[14,28]=-1.1,s3[14,29]=1.2,s3[14,30]=-0.7 s3[15,1]=-0.5,s3[15,2]=-0.5,s3[15,3]=0.9,s3[15,4]=0.3,s3[15,5]=-0.3,s3[15,6]=-0.7,s3[15,7]=0.9,s3[15,8]=-0.9,s3[15,9]=-0.2,s3[15,10]=0.1,s3[15,11]=0.0,s3[15,12]=0.7,s3[15,13]=0.5,s3[15,14]=0.9 s3[15,15]=0.4,s3[15,16]=0.2,s3[15,17]=0.9,s3[15,18]=0.1,s3[15,19]=-0.3,s3[15,20]=1.2,s3[15,21]=0.7,s3[15,22]=-0.3,s3[15,23]=-1.2,s3[15,24]=-0.2,s3[15,25]=0.7,s3[15,26]=-1.1,s3[15,27]=-0.5,s3[15,28]=1.2,s3[15,29]=0.4,s3[15,30]=-1.0 s3[16,1]=-1.0,s3[16,2]=-0.2,s3[16,3]=-0.2,s3[16,4]=-0.3,s3[16,5]=-0.5,s3[16,6]=-1.1,s3[16,7]=0.0,s3[16,8]=1.0,s3[16,9]=0.6,s3[16,10]=0.9,s3[16,11]=-0.3,s3[16,12]=0.9,s3[16,13]=1.1,s3[16,14]=-1.1 s3[16,15]=0.2,s3[16,16]=0.3,s3[16,17]=0.5,s3[16,18]=0.2,s3[16,19]=-0.2,s3[16,20]=0.3,s3[16,21]=0.5,s3[16,22]=-0.6,s3[16,23]=-1.2,s3[16,24]=1.1,s3[16,25]=0.4,s3[16,26]=0.3,s3[16,27]=-0.5,s3[16,28]=0.2,s3[16,29]=-0.3,s3[16,30]=-0.7 s3[17,1]=0.1,s3[17,2]=0.4,s3[17,3]=0.0,s3[17,4]=-0.6,s3[17,5]=1.0,s3[17,6]=0.8,s3[17,7]=1.0,s3[17,8]=-0.2,s3[17,9]=-0.9,s3[17,10]=-0.2,s3[17,11]=-0.6,s3[17,12]=-1.1,s3[17,13]=0.7,s3[17,14]=-0.7 s3[17,15]=0.0,s3[17,16]=-0.8,s3[17,17]=0.3,s3[17,18]=0.6,s3[17,19]=-0.1,s3[17,20]=1.2,s3[17,21]=0.2,s3[17,22]=-0.8,s3[17,23]=-1.2,s3[17,24]=0.4,s3[17,25]=0.9,s3[17,26]=0.0,s3[17,27]=-0.4,s3[17,28]=-0.7,s3[17,29]=-0.3,s3[17,30]=-0.2 s3[18,1]=-0.6,s3[18,2]=1.2,s3[18,3]=1.2,s3[18,4]=1.0,s3[18,5]=0.2,s3[18,6]=0.5,s3[18,7]=0.5,s3[18,8]=0.6,s3[18,9]=0.5,s3[18,10]=0.9,s3[18,11]=-0.7,s3[18,12]=1.1,s3[18,13]=1.2,s3[18,14]=0.3 s3[18,15]=0.2,s3[18,16]=-0.2,s3[18,17]=0.6,s3[18,18]=1.1,s3[18,19]=0.0,s3[18,20]=-0.4,s3[18,21]=0.5,s3[18,22]=0.7,s3[18,23]=-0.5,s3[18,24]=0.9,s3[18,25]=1.0,s3[18,26]=0.2,s3[18,27]=-0.6,s3[18,28]=0.2,s3[18,29]=0.0,s3[18,30]=0.2 s3[19,1]=0.6,s3[19,2]=0.7,s3[19,3]=-1.0,s3[19,4]=-1.1,s3[19,5]=1.0,s3[19,6]=0.7,s3[19,7]=0.1,s3[19,8]=-0.2,s3[19,9]=-0.8,s3[19,10]=-0.4,s3[19,11]=-0.1,s3[19,12]=-0.4,s3[19,13]=0.9,s3[19,14]=-0.8 s3[19,15]=-0.1,s3[19,16]=-0.6,s3[19,17]=-0.7,s3[19,18]=-0.1,s3[19,19]=-0.1,s3[19,20]=-0.1,s3[19,21]=-0.1,s3[19,22]=0.9,s3[19,23]=-0.3,s3[19,24]=0.3,s3[19,25]=-0.1,s3[19,26]=-0.9,s3[19,27]=0.3,s3[19,28]=0.3,s3[19,29]=-0.8,s3[19,30]=-0.5 s3[20,1]=0.4,s3[20,2]=0.7,s3[20,3]=-1.2,s3[20,4]=0.6,s3[20,5]=1.0,s3[20,6]=0.2,s3[20,7]=-0.3,s3[20,8]=0.1,s3[20,9]=0.7,s3[20,10]=-1.0,s3[20,11]=0.4,s3[20,12]=0.7,s3[20,13]=1.2,s3[20,14]=-1.1 s3[20,15]=0.8,s3[20,16]=0.8,s3[20,17]=-1.0,s3[20,18]=-1.2,s3[20,19]=1.0,s3[20,20]=-1.1,s3[20,21]=0.0,s3[20,22]=-0.9,s3[20,23]=-1.2,s3[20,24]=1.0,s3[20,25]=-0.1,s3[20,26]=0.0,s3[20,27]=-0.2,s3[20,28]=-1.1,s3[20,29]=-0.7,s3[20,30]=-0.3 s3[21,1]=0.3,s3[21,2]=1.1,s3[21,3]=-0.9,s3[21,4]=-1.2,s3[21,5]=0.2,s3[21,6]=-0.1,s3[21,7]=-1.2,s3[21,8]=1.1,s3[21,9]=0.3,s3[21,10]=0.2,s3[21,11]=-0.8,s3[21,12]=0.3,s3[21,13]=1.2,s3[21,14]=-1.2 s3[21,15]=1.1,s3[21,16]=-0.1,s3[21,17]=0.9,s3[21,18]=-0.7,s3[21,19]=0.2,s3[21,20]=0.8,s3[21,21]=-0.7,s3[21,22]=-0.3,s3[21,23]=0.5,s3[21,24]=-0.1,s3[21,25]=-0.1,s3[21,26]=0.3,s3[21,27]=0.0,s3[21,28]=-1.1,s3[21,29]=-0.4,s3[21,30]=0.4 s3[22,1]=0.5,s3[22,2]=-0.7,s3[22,3]=-1.1,s3[22,4]=0.1,s3[22,5]=-0.5,s3[22,6]=0.3,s3[22,7]=-0.2,s3[22,8]=-0.9,s3[22,9]=-0.7,s3[22,10]=-0.1,s3[22,11]=-0.6,s3[22,12]=-1.0,s3[22,13]=-0.9,s3[22,14]=0.1 s3[22,15]=-0.7,s3[22,16]=-0.7,s3[22,17]=-0.6,s3[22,18]=-1.1,s3[22,19]=-1.1,s3[22,20]=0.2,s3[22,21]=-0.6,s3[22,22]=-0.2,s3[22,23]=-0.9,s3[22,24]=-0.2,s3[22,25]=-0.6,s3[22,26]=-0.6,s3[22,27]=0.0,s3[22,28]=0.6,s3[22,29]=-0.9,s3[22,30]=-1.1 s3[23,1]=0.8,s3[23,2]=-0.7,s3[23,3]=-0.9,s3[23,4]=-1.0,s3[23,5]=-0.3,s3[23,6]=0.9,s3[23,7]=0.5,s3[23,8]=-0.1,s3[23,9]=0.7,s3[23,10]=-1.0,s3[23,11]=0.5,s3[23,12]=-1.0,s3[23,13]=0.3,s3[23,14]=1.1 s3[23,15]=-0.2,s3[23,16]=-0.4,s3[23,17]=-0.2,s3[23,18]=1.0,s3[23,19]=0.4,s3[23,20]=-0.7,s3[23,21]=0.5,s3[23,22]=-1.2,s3[23,23]=-0.5,s3[23,24]=0.8,s3[23,25]=0.2,s3[23,26]=-0.8,s3[23,27]=0.0,s3[23,28]=1.1,s3[23,29]=-0.2,s3[23,30]=0.5 s3[24,1]=-1.0,s3[24,2]=-0.2,s3[24,3]=1.1,s3[24,4]=0.3,s3[24,5]=-0.4,s3[24,6]=-0.2,s3[24,7]=0.6,s3[24,8]=-0.1,s3[24,9]=0.5,s3[24,10]=-0.7,s3[24,11]=0.7,s3[24,12]=-0.4,s3[24,13]=0.7,s3[24,14]=0.2 s3[24,15]=-0.2,s3[24,16]=0.2,s3[24,17]=-1.2,s3[24,18]=0.0,s3[24,19]=0.0,s3[24,20]=-1.2,s3[24,21]=-0.5,s3[24,22]=-0.4,s3[24,23]=0.5,s3[24,24]=0.2,s3[24,25]=-0.5,s3[24,26]=-0.1,s3[24,27]=0.6,s3[24,28]=-0.4,s3[24,29]=0.1,s3[24,30]=1.0 s3[25,1]=-0.1,s3[25,2]=1.2,s3[25,3]=0.8,s3[25,4]=0.9,s3[25,5]=0.4,s3[25,6]=0.0,s3[25,7]=0.2,s3[25,8]=0.1,s3[25,9]=0.9,s3[25,10]=-1.1,s3[25,11]=-0.4,s3[25,12]=-0.4,s3[25,13]=0.5,s3[25,14]=-0.2 s3[25,15]=-0.8,s3[25,16]=-0.1,s3[25,17]=0.0,s3[25,18]=-0.6,s3[25,19]=0.9,s3[25,20]=0.9,s3[25,21]=-0.3,s3[25,22]=0.2,s3[25,23]=-0.3,s3[25,24]=1.1,s3[25,25]=1.0,s3[25,26]=0.0,s3[25,27]=0.8,s3[25,28]=-0.4,s3[25,29]=-0.4,s3[25,30]=-0.5 s3[26,1]=0.6,s3[26,2]=-1.0,s3[26,3]=-0.7,s3[26,4]=-1.0,s3[26,5]=-0.1,s3[26,6]=0.2,s3[26,7]=0.7,s3[26,8]=-1.2,s3[26,9]=0.5,s3[26,10]=0.2,s3[26,11]=0.3,s3[26,12]=-0.7,s3[26,13]=0.1,s3[26,14]=0.0 s3[26,15]=-0.9,s3[26,16]=-0.1,s3[26,17]=0.4,s3[26,18]=0.2,s3[26,19]=1.2,s3[26,20]=0.9,s3[26,21]=-0.7,s3[26,22]=-0.9,s3[26,23]=1.1,s3[26,24]=-0.7,s3[26,25]=-0.5,s3[26,26]=0.9,s3[26,27]=0.9,s3[26,28]=0.8,s3[26,29]=1.0,s3[26,30]=0.7 s3[27,1]=-0.3,s3[27,2]=-0.4,s3[27,3]=0.9,s3[27,4]=-1.2,s3[27,5]=-1.1,s3[27,6]=0.2,s3[27,7]=0.9,s3[27,8]=0.7,s3[27,9]=-0.8,s3[27,10]=0.6,s3[27,11]=-0.3,s3[27,12]=-0.7,s3[27,13]=0.9,s3[27,14]=-0.3 s3[27,15]=0.1,s3[27,16]=-0.6,s3[27,17]=-1.1,s3[27,18]=0.0,s3[27,19]=-0.2,s3[27,20]=-0.1,s3[27,21]=1.0,s3[27,22]=-0.4,s3[27,23]=-0.7,s3[27,24]=-0.3,s3[27,25]=-0.2,s3[27,26]=1.2,s3[27,27]=1.1,s3[27,28]=0.5,s3[27,29]=-0.8,s3[27,30]=1.0 s3[28,1]=-0.5,s3[28,2]=0.4,s3[28,3]=-0.5,s3[28,4]=-1.0,s3[28,5]=-0.1,s3[28,6]=0.2,s3[28,7]=1.2,s3[28,8]=-1.1,s3[28,9]=0.4,s3[28,10]=1.0,s3[28,11]=-0.3,s3[28,12]=-0.6,s3[28,13]=0.2,s3[28,14]=0.7 s3[28,15]=-0.8,s3[28,16]=1.2,s3[28,17]=-0.6,s3[28,18]=-0.7,s3[28,19]=0.1,s3[28,20]=1.1,s3[28,21]=0.3,s3[28,22]=0.6,s3[28,23]=0.7,s3[28,24]=1.2,s3[28,25]=-0.4,s3[28,26]=0.3,s3[28,27]=-0.6,s3[28,28]=-0.1,s3[28,29]=-0.7,s3[28,30]=0.7 s3[29,1]=0.4,s3[29,2]=0.1,s3[29,3]=-0.4,s3[29,4]=0.4,s3[29,5]=1.1,s3[29,6]=-0.1,s3[29,7]=0.3,s3[29,8]=-1.1,s3[29,9]=0.1,s3[29,10]=-0.8,s3[29,11]=-0.5,s3[29,12]=-0.4,s3[29,13]=0.4,s3[29,14]=-0.6 s3[29,15]=-0.1,s3[29,16]=0.3,s3[29,17]=0.3,s3[29,18]=1.2,s3[29,19]=-0.4,s3[29,20]=-1.0,s3[29,21]=-0.8,s3[29,22]=-1.2,s3[29,23]=0.7,s3[29,24]=0.7,s3[29,25]=-1.1,s3[29,26]=-1.0,s3[29,27]=0.4,s3[29,28]=-1.0,s3[29,29]=0.8,s3[29,30]=0.0 s3[30,1]=-0.6,s3[30,2]=-0.5,s3[30,3]=-1.0,s3[30,4]=0.7,s3[30,5]=-0.9,s3[30,6]=-1.0,s3[30,7]=1.1,s3[30,8]=1.0,s3[30,9]=-0.9,s3[30,10]=0.8,s3[30,11]=0.4,s3[30,12]=0.0,s3[30,13]=-0.4,s3[30,14]=-0.7 s3[30,15]=-0.6,s3[30,16]=-1.2,s3[30,17]=0.8,s3[30,18]=-1.2,s3[30,19]=-0.3,s3[30,20]=-0.7,s3[30,21]=0.0,s3[30,22]=-0.9,s3[30,23]=-0.2,s3[30,24]=-0.2,s3[30,25]=-0.8,s3[30,26]=0.7,s3[30,27]=0.2,s3[30,28]=1.1,s3[30,29]=-0.2,s3[30,30]=-0.4 s3[31,1]=-0.1,s3[31,2]=-0.3,s3[31,3]=-0.2,s3[31,4]=-1.2,s3[31,5]=-0.2,s3[31,6]=-0.4,s3[31,7]=0.7,s3[31,8]=0.1,s3[31,9]=0.2,s3[31,10]=0.0,s3[31,11]=0.5,s3[31,12]=0.6,s3[31,13]=-0.1,s3[31,14]=1.0 s3[31,15]=1.1,s3[31,16]=-0.5,s3[31,17]=0.1,s3[31,18]=0.0,s3[31,19]=-0.1,s3[31,20]=0.1,s3[31,21]=1.0,s3[31,22]=0.4,s3[31,23]=-0.8,s3[31,24]=0.5,s3[31,25]=-0.1,s3[31,26]=0.0,s3[31,27]=-0.6,s3[31,28]=-0.6,s3[31,29]=-1.1,s3[31,30]=0.9 s3[32,1]=0.0,s3[32,2]=0.3,s3[32,3]=-0.2,s3[32,4]=-1.0,s3[32,5]=0.0,s3[32,6]=-0.7,s3[32,7]=1.1,s3[32,8]=0.4,s3[32,9]=0.2,s3[32,10]=0.1,s3[32,11]=0.1,s3[32,12]=0.7,s3[32,13]=-0.3,s3[32,14]=1.0 s3[32,15]=-1.0,s3[32,16]=-0.7,s3[32,17]=-0.6,s3[32,18]=-0.5,s3[32,19]=0.4,s3[32,20]=-0.4,s3[32,21]=0.2,s3[32,22]=-0.8,s3[32,23]=-0.3,s3[32,24]=-0.1,s3[32,25]=0.8,s3[32,26]=0.4,s3[32,27]=0.3,s3[32,28]=0.0,s3[32,29]=-1.2,s3[32,30]=0.4 s3[33,1]=0.9,s3[33,2]=-1.2,s3[33,3]=-0.2,s3[33,4]=-0.6,s3[33,5]=-0.7,s3[33,6]=0.5,s3[33,7]=0.9,s3[33,8]=-0.4,s3[33,9]=-0.4,s3[33,10]=-0.2,s3[33,11]=0.2,s3[33,12]=0.3,s3[33,13]=-0.5,s3[33,14]=0.7 s3[33,15]=0.3,s3[33,16]=-1.0,s3[33,17]=0.5,s3[33,18]=0.3,s3[33,19]=-0.3,s3[33,20]=0.2,s3[33,21]=-1.2,s3[33,22]=0.1,s3[33,23]=-1.0,s3[33,24]=1.0,s3[33,25]=-0.7,s3[33,26]=-1.2,s3[33,27]=1.1,s3[33,28]=-0.1,s3[33,29]=1.0,s3[33,30]=0.8 s3[34,1]=0.2,s3[34,2]=-0.8,s3[34,3]=-0.9,s3[34,4]=-0.5,s3[34,5]=-0.9,s3[34,6]=-0.7,s3[34,7]=-0.8,s3[34,8]=-0.6,s3[34,9]=0.9,s3[34,10]=-0.5,s3[34,11]=0.0,s3[34,12]=0.2,s3[34,13]=0.2,s3[34,14]=0.1 s3[34,15]=0.2,s3[34,16]=-0.6,s3[34,17]=0.9,s3[34,18]=-1.2,s3[34,19]=0.1,s3[34,20]=0.9,s3[34,21]=-0.2,s3[34,22]=0.4,s3[34,23]=0.1,s3[34,24]=-0.8,s3[34,25]=0.9,s3[34,26]=0.7,s3[34,27]=0.7,s3[34,28]=0.7,s3[34,29]=0.8,s3[34,30]=-0.3 s3[35,1]=-0.4,s3[35,2]=0.1,s3[35,3]=0.5,s3[35,4]=0.5,s3[35,5]=-0.3,s3[35,6]=1.1,s3[35,7]=1.1,s3[35,8]=1.0,s3[35,9]=-1.0,s3[35,10]=0.3,s3[35,11]=-0.2,s3[35,12]=0.3,s3[35,13]=-0.8,s3[35,14]=0.9 s3[35,15]=-0.6,s3[35,16]=-1.2,s3[35,17]=0.6,s3[35,18]=-0.6,s3[35,19]=0.1,s3[35,20]=0.3,s3[35,21]=-0.3,s3[35,22]=-0.1,s3[35,23]=0.1,s3[35,24]=0.3,s3[35,25]=-0.1,s3[35,26]=0.6,s3[35,27]=-0.5,s3[35,28]=1.0,s3[35,29]=-0.2,s3[35,30]=-0.6 s3[36,1]=0.3,s3[36,2]=-0.6,s3[36,3]=0.3,s3[36,4]=-1.0,s3[36,5]=0.4,s3[36,6]=-0.2,s3[36,7]=0.8,s3[36,8]=0.8,s3[36,9]=-0.9,s3[36,10]=0.1,s3[36,11]=0.8,s3[36,12]=-0.4,s3[36,13]=-1.0,s3[36,14]=0.6 s3[36,15]=0.8,s3[36,16]=0.6,s3[36,17]=-0.1,s3[36,18]=-0.3,s3[36,19]=0.3,s3[36,20]=-1.0,s3[36,21]=0.6,s3[36,22]=-1.2,s3[36,23]=0.8,s3[36,24]=0.6,s3[36,25]=0.3,s3[36,26]=-0.4,s3[36,27]=0.3,s3[36,28]=-0.3,s3[36,29]=-0.4,s3[36,30]=-0.5 s3[37,1]=0.5,s3[37,2]=-1.2,s3[37,3]=1.0,s3[37,4]=0.8,s3[37,5]=-0.5,s3[37,6]=0.1,s3[37,7]=-0.5,s3[37,8]=0.2,s3[37,9]=-1.1,s3[37,10]=-0.1,s3[37,11]=0.0,s3[37,12]=-0.5,s3[37,13]=-0.6,s3[37,14]=-0.2 s3[37,15]=-0.3,s3[37,16]=0.8,s3[37,17]=0.2,s3[37,18]=-0.4,s3[37,19]=-0.5,s3[37,20]=-0.1,s3[37,21]=0.5,s3[37,22]=0.2,s3[37,23]=-0.3,s3[37,24]=-0.8,s3[37,25]=0.3,s3[37,26]=-0.1,s3[37,27]=-0.4,s3[37,28]=0.2,s3[37,29]=0.7,s3[37,30]=-0.2 s3[38,1]=0.7,s3[38,2]=-1.0,s3[38,3]=0.1,s3[38,4]=-0.3,s3[38,5]=0.9,s3[38,6]=0.3,s3[38,7]=-1.1,s3[38,8]=0.7,s3[38,9]=-0.7,s3[38,10]=0.5,s3[38,11]=0.4,s3[38,12]=-0.7,s3[38,13]=-1.0,s3[38,14]=0.3 s3[38,15]=1.2,s3[38,16]=-0.4,s3[38,17]=1.2,s3[38,18]=0.4,s3[38,19]=-0.3,s3[38,20]=0.4,s3[38,21]=0.2,s3[38,22]=-0.8,s3[38,23]=1.1,s3[38,24]=0.7,s3[38,25]=-0.5,s3[38,26]=-0.2,s3[38,27]=0.6,s3[38,28]=0.6,s3[38,29]=-1.1,s3[38,30]=0.5 s3[39,1]=-0.2,s3[39,2]=-1.0,s3[39,3]=0.1,s3[39,4]=0.4,s3[39,5]=-0.5,s3[39,6]=-1.2,s3[39,7]=-0.9,s3[39,8]=-0.1,s3[39,9]=-1.1,s3[39,10]=-0.4,s3[39,11]=0.0,s3[39,12]=0.4,s3[39,13]=0.9,s3[39,14]=-0.1 s3[39,15]=0.7,s3[39,16]=-0.2,s3[39,17]=0.7,s3[39,18]=0.4,s3[39,19]=-0.3,s3[39,20]=-1.0,s3[39,21]=0.1,s3[39,22]=-0.2,s3[39,23]=-0.7,s3[39,24]=-0.3,s3[39,25]=-0.3,s3[39,26]=-0.7,s3[39,27]=0.4,s3[39,28]=0.5,s3[39,29]=-0.8,s3[39,30]=0.7 s3[40,1]=0.4,s3[40,2]=0.9,s3[40,3]=-0.3,s3[40,4]=-0.3,s3[40,5]=0.3,s3[40,6]=0.9,s3[40,7]=-0.6,s3[40,8]=0.6,s3[40,9]=0.3,s3[40,10]=-0.9,s3[40,11]=0.3,s3[40,12]=0.0,s3[40,13]=-0.5,s3[40,14]=0.9 s3[40,15]=0.0,s3[40,16]=1.2,s3[40,17]=-1.1,s3[40,18]=0.9,s3[40,19]=-0.4,s3[40,20]=-0.1,s3[40,21]=1.2,s3[40,22]=-0.8,s3[40,23]=-0.4,s3[40,24]=0.6,s3[40,25]=0.7,s3[40,26]=0.0,s3[40,27]=-1.0,s3[40,28]=0.3,s3[40,29]=-0.9,s3[40,30]=0.0 s3[41,1]=-0.7,s3[41,2]=0.3,s3[41,3]=0.4,s3[41,4]=-1.2,s3[41,5]=0.5,s3[41,6]=0.3,s3[41,7]=-0.6,s3[41,8]=0.4,s3[41,9]=0.3,s3[41,10]=0.6,s3[41,11]=1.2,s3[41,12]=0.5,s3[41,13]=-0.5,s3[41,14]=0.6 s3[41,15]=-0.1,s3[41,16]=0.6,s3[41,17]=-0.9,s3[41,18]=-0.6,s3[41,19]=0.3,s3[41,20]=-0.1,s3[41,21]=-0.9,s3[41,22]=-0.3,s3[41,23]=0.0,s3[41,24]=0.1,s3[41,25]=-0.1,s3[41,26]=0.6,s3[41,27]=-0.4,s3[41,28]=-0.5,s3[41,29]=-0.7,s3[41,30]=-0.7 s3[42,1]=-0.3,s3[42,2]=-0.6,s3[42,3]=-0.5,s3[42,4]=-0.1,s3[42,5]=1.0,s3[42,6]=-0.6,s3[42,7]=-0.5,s3[42,8]=0.3,s3[42,9]=0.6,s3[42,10]=-0.2,s3[42,11]=0.3,s3[42,12]=1.0,s3[42,13]=-0.7,s3[42,14]=0.6 s3[42,15]=1.0,s3[42,16]=0.4,s3[42,17]=-0.7,s3[42,18]=1.1,s3[42,19]=0.4,s3[42,20]=0.2,s3[42,21]=0.1,s3[42,22]=-0.1,s3[42,23]=0.5,s3[42,24]=-0.5,s3[42,25]=0.1,s3[42,26]=-0.7,s3[42,27]=0.4,s3[42,28]=-0.4,s3[42,29]=-0.9,s3[42,30]=0.3 s3[43,1]=0.1,s3[43,2]=-0.6,s3[43,3]=0.5,s3[43,4]=-0.4,s3[43,5]=0.6,s3[43,6]=0.3,s3[43,7]=-0.3,s3[43,8]=0.8,s3[43,9]=-1.2,s3[43,10]=-1.1,s3[43,11]=0.3,s3[43,12]=0.6,s3[43,13]=-0.6,s3[43,14]=0.0 s3[43,15]=0.1,s3[43,16]=-0.8,s3[43,17]=-0.9,s3[43,18]=-0.6,s3[43,19]=0.3,s3[43,20]=-0.6,s3[43,21]=-0.6,s3[43,22]=0.9,s3[43,23]=-0.5,s3[43,24]=1.1,s3[43,25]=-0.2,s3[43,26]=0.0,s3[43,27]=0.7,s3[43,28]=-1.2,s3[43,29]=-1.1,s3[43,30]=-0.4 s3[44,1]=1.1,s3[44,2]=0.1,s3[44,3]=-0.3,s3[44,4]=0.2,s3[44,5]=-0.6,s3[44,6]=0.1,s3[44,7]=0.0,s3[44,8]=0.0,s3[44,9]=-1.1,s3[44,10]=-1.0,s3[44,11]=0.9,s3[44,12]=0.0,s3[44,13]=-0.3,s3[44,14]=0.9 s3[44,15]=-0.2,s3[44,16]=0.1,s3[44,17]=-0.7,s3[44,18]=0.7,s3[44,19]=-0.5,s3[44,20]=0.2,s3[44,21]=0.2,s3[44,22]=-0.6,s3[44,23]=-0.5,s3[44,24]=0.9,s3[44,25]=-0.2,s3[44,26]=0.9,s3[44,27]=-0.7,s3[44,28]=-0.8,s3[44,29]=0.5,s3[44,30]=-0.8 s3[45,1]=-0.2,s3[45,2]=-0.5,s3[45,3]=0.9,s3[45,4]=-0.2,s3[45,5]=-0.7,s3[45,6]=-0.6,s3[45,7]=-0.9,s3[45,8]=0.0,s3[45,9]=-0.5,s3[45,10]=-0.2,s3[45,11]=-0.1,s3[45,12]=-0.8,s3[45,13]=-0.2,s3[45,14]=0.4 s3[45,15]=0.3,s3[45,16]=-0.3,s3[45,17]=1.1,s3[45,18]=0.3,s3[45,19]=-0.1,s3[45,20]=-0.2,s3[45,21]=-0.3,s3[45,22]=0.6,s3[45,23]=0.2,s3[45,24]=0.6,s3[45,25]=0.0,s3[45,26]=-0.6,s3[45,27]=-1.0,s3[45,28]=0.6,s3[45,29]=0.9,s3[45,30]=0.0 s3[46,1]=0.1,s3[46,2]=-0.6,s3[46,3]=0.3,s3[46,4]=-0.1,s3[46,5]=0.0,s3[46,6]=0.3,s3[46,7]=1.2,s3[46,8]=0.0,s3[46,9]=-0.1,s3[46,10]=1.2,s3[46,11]=-1.2,s3[46,12]=1.0,s3[46,13]=-0.4,s3[46,14]=-0.1 s3[46,15]=1.1,s3[46,16]=-0.1,s3[46,17]=0.6,s3[46,18]=-1.1,s3[46,19]=-0.6,s3[46,20]=1.1,s3[46,21]=0.3,s3[46,22]=0.7,s3[46,23]=-0.7,s3[46,24]=1.2,s3[46,25]=1.1,s3[46,26]=-0.5,s3[46,27]=-0.1,s3[46,28]=0.1,s3[46,29]=-1.0,s3[46,30]=-0.4 s3[47,1]=-0.6,s3[47,2]=-1.2,s3[47,3]=-1.0,s3[47,4]=-0.4,s3[47,5]=0.9,s3[47,6]=-0.2,s3[47,7]=-0.7,s3[47,8]=-0.2,s3[47,9]=0.6,s3[47,10]=0.0,s3[47,11]=0.3,s3[47,12]=0.4,s3[47,13]=0.0,s3[47,14]=-0.9 s3[47,15]=-0.1,s3[47,16]=0.3,s3[47,17]=0.0,s3[47,18]=-0.4,s3[47,19]=-0.1,s3[47,20]=-0.3,s3[47,21]=-0.4,s3[47,22]=-0.6,s3[47,23]=-1.1,s3[47,24]=-0.5,s3[47,25]=-1.1,s3[47,26]=1.2,s3[47,27]=0.0,s3[47,28]=0.1,s3[47,29]=0.7,s3[47,30]=0.4 s3[48,1]=-0.4,s3[48,2]=-0.9,s3[48,3]=-1.0,s3[48,4]=-0.4,s3[48,5]=0.0,s3[48,6]=-0.1,s3[48,7]=-0.8,s3[48,8]=-0.9,s3[48,9]=0.3,s3[48,10]=0.0,s3[48,11]=0.8,s3[48,12]=-0.3,s3[48,13]=-0.7,s3[48,14]=0.4 s3[48,15]=-0.9,s3[48,16]=-0.9,s3[48,17]=0.2,s3[48,18]=-0.6,s3[48,19]=1.2,s3[48,20]=0.7,s3[48,21]=0.1,s3[48,22]=0.6,s3[48,23]=0.0,s3[48,24]=-0.1,s3[48,25]=0.3,s3[48,26]=-0.5,s3[48,27]=-0.7,s3[48,28]=0.7,s3[48,29]=-0.7,s3[48,30]=-1.1 s3[49,1]=-0.9,s3[49,2]=-1.1,s3[49,3]=0.0,s3[49,4]=0.2,s3[49,5]=-0.9,s3[49,6]=-1.0,s3[49,7]=0.8,s3[49,8]=-0.3,s3[49,9]=-1.0,s3[49,10]=-1.0,s3[49,11]=-0.9,s3[49,12]=0.3,s3[49,13]=0.0,s3[49,14]=-0.4 s3[49,15]=-0.1,s3[49,16]=0.0,s3[49,17]=0.2,s3[49,18]=-0.4,s3[49,19]=0.1,s3[49,20]=0.5,s3[49,21]=1.1,s3[49,22]=1.0,s3[49,23]=-0.4,s3[49,24]=0.4,s3[49,25]=-0.5,s3[49,26]=0.9,s3[49,27]=0.0,s3[49,28]=0.4,s3[49,29]=0.9,s3[49,30]=-0.4 s3[50,1]=0.2,s3[50,2]=0.7,s3[50,3]=-0.2,s3[50,4]=-1.0,s3[50,5]=0.3,s3[50,6]=0.7,s3[50,7]=-0.3,s3[50,8]=0.5,s3[50,9]=0.7,s3[50,10]=-0.7,s3[50,11]=-0.1,s3[50,12]=0.1,s3[50,13]=0.5,s3[50,14]=0.6 s3[50,15]=-0.2,s3[50,16]=-0.4,s3[50,17]=-1.2,s3[50,18]=1.1,s3[50,19]=-0.3,s3[50,20]=0.9,s3[50,21]=-0.1,s3[50,22]=0.2,s3[50,23]=-0.7,s3[50,24]=0.3,s3[50,25]=-0.8,s3[50,26]=-0.5,s3[50,27]=0.5,s3[50,28]=1.2,s3[50,29]=-1.0,s3[50,30]=0.9 endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float ppz = @ppz float pxx = 0 float pyy = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x pyy = y x = s3[@sd,1] + s3[@sd,2]*x + s3[@sd,3]*x*x + s3[@sd,4]*x*y \ + s3[@sd,5]*x*ppz + s3[@sd,6]*y + s3[@sd,7]*y*y + \ s3[@sd,8]*y*ppz + s3[@sd,9]*ppz + s3[@sd,10]*ppz*ppz y = s3[@sd,11] + s3[@sd,12]*pxx + s3[@sd,13]*pxx*pxx + s3[@sd,14]*pxx*y \ + s3[@sd,15]*pxx*ppz + s3[@sd,16]*y + s3[@sd,17]*y*y + \ s3[@sd,18]*y*ppz + s3[@sd,19]*ppz + s3[@sd,20]*ppz*ppz ppz = s3[@sd,21] + s3[@sd,22]*pxx + s3[@sd,23]*pxx*pxx + s3[@sd,24]*pxx*pyy + \ s3[@sd,25]*pxx*ppz + s3[@sd,26]*pyy + s3[@sd,27]*pyy*pyy + \ s3[@sd,28]*pyy*ppz + s3[@sd,29]*ppz + s3[@sd,30]*ppz*ppz att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y) + ppz*@pw) float d = @distscale*|pz-m_LastZ| return d endfunc private: float s3[51,31] default: title = "Sprott3D" heading text="Sprott 3D quadratic attractors" endheading heading text=" x -> Quadratic in x, y and z" endheading heading text=" y -> Quadratic in x, y and z" endheading heading text=" z -> Quadratic in x, y and z" endheading int param v_trapshapesprott3d caption = "Version (Trap Shape Sprott3D)" default = 101 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_trapshapesprott3d < 101 endparam param sd caption = "Sprott selector" default = 0 enum = "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" \ "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" \ "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" \ "45" "46" "47" "48" "49" "50" hint = "Each Sprott selector uses a different strange attractor." endparam heading text = "'Initialize Height' sets the starting z value for the attractor." endheading float param ppz caption = "Initialize Height" default = 0.5 endparam heading text = "'Height weight' determines the weight of the final z value which is added \ to the trap distance." endheading complex param pw caption = "Height weight" default = (0.5,0) endparam float param distscale caption = "Distance scale" default = 2 endparam float param s caption = "Attractor scale" default = 1 endparam int param max_att_iterations caption = "Attractor iterations" default = 15 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeSprott3D_Cubic(common.ulb:TrapShape) { ; This shape uses a Sprott strange attractor.
;

; The Sprott attractors were developed by Julien C. Sprott, and are ; based upon polynomials and linear differential equations of polynomials. public: import "common.ulb" ; Constructor func REB_TrapShapeSprott3D_Cubic(Generic pparent) TrapShape.TrapShape(pparent) s[0,1]=0.3,s[0,2]=-0.4,s[0,3]=1.0,s[0,4]=0.3,s[0,5]=0.5,s[0,6]=0.4,s[0,7]=0.7,s[0,8]=0.5,s[0,9]=0.9,s[0,10]=1.0,s[0,11]=1.2,s[0,12]=-0.4,s[0,13]=0.4,s[0,14]=-0.3,s[0,15]=-0.1,s[0,16]=-0.6,s[0,17]=-0.1,s[0,18]=1.1,s[0,19]=1.0,s[0,20]=0.6,s[0,21]=0.2,s[0,22]=0.6,s[0,23]=-1.1,s[0,24]=-1.0,s[0,25]=0.2,s[0,26]=0.4,s[0,27]=0.4,s[0,28]=0.2,s[0,29]=0.6,s[0,30]=-1.1 s[0,31]=0.6,s[0,32]=-0.4,s[0,33]=-1.1,s[0,34]=-0.1,s[0,35]=0.6,s[0,36]=-0.2,s[0,37]=-0.8,s[0,38]=-0.6,s[0,39]=0.6,s[0,40]=1.2,s[0,41]=-0.5,s[0,42]=0.3,s[0,43]=1.1,s[0,44]=-0.1,s[0,45]=0.9,s[0,46]=-1.0,s[0,47]=-0.6,s[0,48]=-0.3,s[0,49]=0.5,s[0,50]=0.4,s[0,51]=-0.8,s[0,52]=0.5,s[0,53]=-0.8,s[0,54]=-1.0,s[0,55]=0.1,s[0,56]=-0.9,s[0,57]=-1.1,s[0,58]=-0.7,s[0,59]=-0.1,s[0,60]=-0.6 s[1,1]=-0.1,s[1,2]=-0.6,s[1,3]=0.4,s[1,4]=-0.6,s[1,5]=-0.7,s[1,6]=0.3,s[1,7]=-0.7,s[1,8]=0.6,s[1,9]=-0.6,s[1,10]=-0.6,s[1,11]=0.8,s[1,12]=-0.6,s[1,13]=-0.8,s[1,14]=1.2,s[1,15]=0.4,s[1,16]=0.7,s[1,17]=0.1,s[1,18]=-0.7,s[1,19]=-0.5,s[1,20]=0.4,s[1,21]=-0.2,s[1,22]=1.0,s[1,23]=0.9,s[1,24]=0.8,s[1,25]=-1.1,s[1,26]=-0.3,s[1,27]=0.4,s[1,28]=-0.1,s[1,29]=1.1,s[1,30]=-0.2 s[1,31]=0.8,s[1,32]=0.6,s[1,33]=-0.3,s[1,34]=-0.3,s[1,35]=-1.0,s[1,36]=-0.2,s[1,37]=0.0,s[1,38]=0.3,s[1,39]=0.3,s[1,40]=0.1,s[1,41]=0.3,s[1,42]=0.9,s[1,43]=0.2,s[1,44]=0.0,s[1,45]=1.1,s[1,46]=1.0,s[1,47]=0.6,s[1,48]=-0.5,s[1,49]=-0.2,s[1,50]=0.8,s[1,51]=0.9,s[1,52]=-1.0,s[1,53]=-0.7,s[1,54]=1.1,s[1,55]=0.9,s[1,56]=-0.2,s[1,57]=-0.3,s[1,58]=0.5,s[1,59]=-0.9,s[1,60]=0.4 s[2,1]=0.7,s[2,2]=-0.3,s[2,3]=-0.3,s[2,4]=0.4,s[2,5]=0.1,s[2,6]=-0.8,s[2,7]=0.9,s[2,8]=-1.0,s[2,9]=1.1,s[2,10]=-0.1,s[2,11]=-0.4,s[2,12]=0.3,s[2,13]=-1.0,s[2,14]=-0.2,s[2,15]=0.9,s[2,16]=-1.0,s[2,17]=0.4,s[2,18]=0.4,s[2,19]=1.0,s[2,20]=0.3,s[2,21]=0.8,s[2,22]=0.2,s[2,23]=0.9,s[2,24]=-0.2,s[2,25]=0.6,s[2,26]=-0.2,s[2,27]=0.2,s[2,28]=-0.9,s[2,29]=-0.4,s[2,30]=-0.3 s[2,31]=-0.1,s[2,32]=-0.4,s[2,33]=0.3,s[2,34]=-0.2,s[2,35]=0.7,s[2,36]=0.1,s[2,37]=1.0,s[2,38]=-0.9,s[2,39]=-0.1,s[2,40]=-0.5,s[2,41]=0.0,s[2,42]=-0.8,s[2,43]=0.9,s[2,44]=1.1,s[2,45]=-1.2,s[2,46]=-0.6,s[2,47]=0.0,s[2,48]=0.5,s[2,49]=0.3,s[2,50]=-0.4,s[2,51]=-0.5,s[2,52]=0.0,s[2,53]=-0.3,s[2,54]=0.5,s[2,55]=0.5,s[2,56]=-1.2,s[2,57]=-0.2,s[2,58]=0.3,s[2,59]=-0.8,s[2,60]=1.2 s[3,1]=0.0,s[3,2]=0.6,s[3,3]=0.4,s[3,4]=-0.1,s[3,5]=-1.0,s[3,6]=0.3,s[3,7]=-0.7,s[3,8]=-0.5,s[3,9]=0.7,s[3,10]=0.7,s[3,11]=0.1,s[3,12]=-0.2,s[3,13]=-1.2,s[3,14]=-0.6,s[3,15]=0.4,s[3,16]=-0.1,s[3,17]=1.1,s[3,18]=-0.3,s[3,19]=-0.1,s[3,20]=-0.4,s[3,21]=0.4,s[3,22]=0.7,s[3,23]=-1.0,s[3,24]=0.8,s[3,25]=0.1,s[3,26]=-0.3,s[3,27]=0.9,s[3,28]=-1.2,s[3,29]=-0.4,s[3,30]=-0.7 s[3,31]=0.4,s[3,32]=0.8,s[3,33]=-0.9,s[3,34]=-0.4,s[3,35]=0.9,s[3,36]=0.4,s[3,37]=-0.5,s[3,38]=0.7,s[3,39]=0.7,s[3,40]=0.3,s[3,41]=-0.7,s[3,42]=0.5,s[3,43]=0.4,s[3,44]=0.3,s[3,45]=0.9,s[3,46]=0.8,s[3,47]=0.2,s[3,48]=-0.3,s[3,49]=0.1,s[3,50]=0.8,s[3,51]=0.5,s[3,52]=-0.6,s[3,53]=0.2,s[3,54]=1.0,s[3,55]=-0.3,s[3,56]=0.4,s[3,57]=0.7,s[3,58]=-0.4,s[3,59]=0.4,s[3,60]=0.9 s[4,1]=-0.6,s[4,2]=-0.8,s[4,3]=0.6,s[4,4]=-0.1,s[4,5]=-0.1,s[4,6]=0.2,s[4,7]=0.1,s[4,8]=0.1,s[4,9]=0.1,s[4,10]=-0.3,s[4,11]=0.2,s[4,12]=-0.7,s[4,13]=-0.1,s[4,14]=0.1,s[4,15]=-0.3,s[4,16]=-0.1,s[4,17]=-0.1,s[4,18]=-0.4,s[4,19]=-1.0,s[4,20]=-1.0,s[4,21]=0.2,s[4,22]=0.5,s[4,23]=0.8,s[4,24]=0.9,s[4,25]=-0.4,s[4,26]=0.2,s[4,27]=1.1,s[4,28]=0.5,s[4,29]=0.4,s[4,30]=0.8 s[4,31]=1.0,s[4,32]=0.1,s[4,33]=-0.6,s[4,34]=-0.3,s[4,35]=-1.2,s[4,36]=-1.0,s[4,37]=-0.3,s[4,38]=0.3,s[4,39]=1.2,s[4,40]=0.3,s[4,41]=-0.1,s[4,42]=-0.3,s[4,43]=0.0,s[4,44]=1.1,s[4,45]=-0.9,s[4,46]=-0.6,s[4,47]=-1.2,s[4,48]=0.8,s[4,49]=0.1,s[4,50]=0.1,s[4,51]=-0.6,s[4,52]=1.2,s[4,53]=-0.1,s[4,54]=-0.1,s[4,55]=1.2,s[4,56]=-0.8,s[4,57]=0.9,s[4,58]=1.0,s[4,59]=0.1,s[4,60]=-0.8 s[5,1]=-0.4,s[5,2]=0.7,s[5,3]=0.6,s[5,4]=1.2,s[5,5]=-0.6,s[5,6]=-0.5,s[5,7]=-0.1,s[5,8]=-0.8,s[5,9]=1.2,s[5,10]=-1.0,s[5,11]=1.0,s[5,12]=0.4,s[5,13]=0.2,s[5,14]=0.5,s[5,15]=0.8,s[5,16]=-0.7,s[5,17]=0.9,s[5,18]=0.7,s[5,19]=-0.3,s[5,20]=-0.7,s[5,21]=0.5,s[5,22]=-0.6,s[5,23]=-1.0,s[5,24]=-1.0,s[5,25]=-0.6,s[5,26]=1.1,s[5,27]=-0.6,s[5,28]=-0.3,s[5,29]=0.8,s[5,30]=0.6 s[5,31]=-0.2,s[5,32]=0.6,s[5,33]=-0.4,s[5,34]=0.2,s[5,35]=-1.1,s[5,36]=0.8,s[5,37]=-0.5,s[5,38]=-0.7,s[5,39]=-0.7,s[5,40]=0.8,s[5,41]=0.6,s[5,42]=-1.1,s[5,43]=0.8,s[5,44]=0.5,s[5,45]=0.1,s[5,46]=0.8,s[5,47]=-0.3,s[5,48]=1.1,s[5,49]=-1.1,s[5,50]=-0.9,s[5,51]=-0.8,s[5,52]=-1.0,s[5,53]=0.1,s[5,54]=0.9,s[5,55]=-0.2,s[5,56]=-0.1,s[5,57]=-0.3,s[5,58]=-0.7,s[5,59]=0.8,s[5,60]=-0.6 s[6,1]=-0.3,s[6,2]=-0.4,s[6,3]=0.0,s[6,4]=-0.8,s[6,5]=0.5,s[6,6]=1.1,s[6,7]=0.1,s[6,8]=0.3,s[6,9]=-0.5,s[6,10]=0.9,s[6,11]=0.7,s[6,12]=0.5,s[6,13]=-0.8,s[6,14]=0.6,s[6,15]=0.3,s[6,16]=0.5,s[6,17]=1.1,s[6,18]=-0.3,s[6,19]=1.1,s[6,20]=-0.4,s[6,21]=0.5,s[6,22]=-0.4,s[6,23]=-0.5,s[6,24]=1.0,s[6,25]=-0.4,s[6,26]=0.0,s[6,27]=-1.2,s[6,28]=-0.6,s[6,29]=0.9,s[6,30]=-0.2 s[6,31]=0.5,s[6,32]=-1.0,s[6,33]=0.2,s[6,34]=0.0,s[6,35]=1.0,s[6,36]=0.1,s[6,37]=0.6,s[6,38]=-0.2,s[6,39]=-1.2,s[6,40]=-0.3,s[6,41]=0.2,s[6,42]=0.2,s[6,43]=-1.0,s[6,44]=-0.4,s[6,45]=-0.1,s[6,46]=-0.1,s[6,47]=-0.2,s[6,48]=-0.1,s[6,49]=0.9,s[6,50]=-0.5,s[6,51]=0.1,s[6,52]=0.9,s[6,53]=0.9,s[6,54]=0.3,s[6,55]=1.1,s[6,56]=-0.6,s[6,57]=0.4,s[6,58]=-0.5,s[6,59]=0.9,s[6,60]=0.9 s[7,1]=0.6,s[7,2]=-0.5,s[7,3]=-0.6,s[7,4]=-0.5,s[7,5]=-0.9,s[7,6]=1.1,s[7,7]=0.1,s[7,8]=0.4,s[7,9]=0.0,s[7,10]=-1.1,s[7,11]=0.3,s[7,12]=1.1,s[7,13]=0.5,s[7,14]=0.0,s[7,15]=-0.9,s[7,16]=0.8,s[7,17]=0.0,s[7,18]=0.3,s[7,19]=-0.8,s[7,20]=-0.9,s[7,21]=-0.1,s[7,22]=0.3,s[7,23]=0.9,s[7,24]=-0.9,s[7,25]=0.5,s[7,26]=0.1,s[7,27]=-0.4,s[7,28]=-0.8,s[7,29]=-0.1,s[7,30]=-0.4 s[7,31]=0.0,s[7,32]=-0.4,s[7,33]=1.0,s[7,34]=-0.6,s[7,35]=0.5,s[7,36]=1.0,s[7,37]=0.0,s[7,38]=1.1,s[7,39]=0.1,s[7,40]=-0.4,s[7,41]=-0.5,s[7,42]=1.0,s[7,43]=1.0,s[7,44]=-0.9,s[7,45]=-0.5,s[7,46]=1.2,s[7,47]=0.1,s[7,48]=0.3,s[7,49]=-0.2,s[7,50]=-0.8,s[7,51]=-0.8,s[7,52]=-1.1,s[7,53]=0.0,s[7,54]=0.9,s[7,55]=-0.9,s[7,56]=0.3,s[7,57]=-0.7,s[7,58]=-0.3,s[7,59]=-0.7,s[7,60]=0.9 s[8,1]=-0.1,s[8,2]=-1.0,s[8,3]=-0.6,s[8,4]=0.8,s[8,5]=-0.3,s[8,6]=0.0,s[8,7]=0.5,s[8,8]=0.3,s[8,9]=1.1,s[8,10]=-0.7,s[8,11]=-0.3,s[8,12]=-1.0,s[8,13]=1.1,s[8,14]=0.6,s[8,15]=-1.1,s[8,16]=0.9,s[8,17]=0.3,s[8,18]=-1.1,s[8,19]=0.0,s[8,20]=-0.8,s[8,21]=0.0,s[8,22]=-0.4,s[8,23]=-0.9,s[8,24]=0.2,s[8,25]=-1.1,s[8,26]=-1.0,s[8,27]=-1.2,s[8,28]=0.9,s[8,29]=1.0,s[8,30]=0.8 s[8,31]=-0.2,s[8,32]=0.5,s[8,33]=0.6,s[8,34]=0.3,s[8,35]=1.1,s[8,36]=0.4,s[8,37]=0.5,s[8,38]=-1.0,s[8,39]=1.2,s[8,40]=-1.1,s[8,41]=0.0,s[8,42]=-0.1,s[8,43]=0.8,s[8,44]=1.2,s[8,45]=-0.6,s[8,46]=-0.8,s[8,47]=-0.6,s[8,48]=-0.6,s[8,49]=0.8,s[8,50]=1.2,s[8,51]=0.2,s[8,52]=0.5,s[8,53]=0.3,s[8,54]=0.8,s[8,55]=-0.6,s[8,56]=1.0,s[8,57]=0.5,s[8,58]=-0.5,s[8,59]=0.0,s[8,60]=0.1 s[9,1]=-0.1,s[9,2]=0.1,s[9,3]=-0.5,s[9,4]=-0.1,s[9,5]=0.6,s[9,6]=0.6,s[9,7]=0.6,s[9,8]=-0.7,s[9,9]=1.1,s[9,10]=-1.1,s[9,11]=0.0,s[9,12]=0.7,s[9,13]=-0.4,s[9,14]=-0.3,s[9,15]=-0.4,s[9,16]=-0.8,s[9,17]=0.1,s[9,18]=0.5,s[9,19]=-0.1,s[9,20]=-0.6,s[9,21]=0.0,s[9,22]=-0.1,s[9,23]=-0.4,s[9,24]=0.9,s[9,25]=0.7,s[9,26]=-1.0,s[9,27]=1.2,s[9,28]=-0.9,s[9,29]=0.1,s[9,30]=0.0 s[9,31]=0.5,s[9,32]=1.0,s[9,33]=-1.1,s[9,34]=0.4,s[9,35]=1.0,s[9,36]=0.3,s[9,37]=-1.1,s[9,38]=0.5,s[9,39]=-0.7,s[9,40]=-0.8,s[9,41]=-0.1,s[9,42]=-1.2,s[9,43]=0.5,s[9,44]=0.8,s[9,45]=-0.5,s[9,46]=0.2,s[9,47]=0.6,s[9,48]=-0.4,s[9,49]=1.2,s[9,50]=0.6,s[9,51]=0.0,s[9,52]=-1.2,s[9,53]=0.3,s[9,54]=-0.1,s[9,55]=-0.3,s[9,56]=-0.3,s[9,57]=-0.4,s[9,58]=0.3,s[9,59]=1.0,s[9,60]=-1.2 s[10,1]=-0.4,s[10,2]=-1.1,s[10,3]=-1.0,s[10,4]=-0.1,s[10,5]=0.8,s[10,6]=0.3,s[10,7]=0.7,s[10,8]=-0.6,s[10,9]=1.1,s[10,10]=0.6,s[10,11]=-0.4,s[10,12]=0.3,s[10,13]=-1.2,s[10,14]=0.7,s[10,15]=-1.1,s[10,16]=0.0,s[10,17]=-0.6,s[10,18]=0.3,s[10,19]=0.0,s[10,20]=-0.6,s[10,21]=-0.3,s[10,22]=-0.5,s[10,23]=0.5,s[10,24]=-0.7,s[10,25]=-1.2,s[10,26]=0.6,s[10,27]=-0.8,s[10,28]=0.2,s[10,29]=0.4,s[10,30]=0.9 s[10,31]=-0.6,s[10,32]=1.1,s[10,33]=0.8,s[10,34]=0.7,s[10,35]=-0.6,s[10,36]=1.2,s[10,37]=0.7,s[10,38]=0.9,s[10,39]=-0.5,s[10,40]=-1.1,s[10,41]=-0.2,s[10,42]=0.1,s[10,43]=0.7,s[10,44]=1.1,s[10,45]=-0.8,s[10,46]=-0.3,s[10,47]=0.4,s[10,48]=0.9,s[10,49]=-0.6,s[10,50]=1.2,s[10,51]=-0.8,s[10,52]=0.3,s[10,53]=0.3,s[10,54]=-0.3,s[10,55]=-0.9,s[10,56]=0.1,s[10,57]=-1.0,s[10,58]=0.6,s[10,59]=-0.4,s[10,60]=1.2 s[11,1]=1.0,s[11,2]=-0.3,s[11,3]=-0.5,s[11,4]=1.0,s[11,5]=1.1,s[11,6]=1.0,s[11,7]=-0.5,s[11,8]=-1.0,s[11,9]=-1.2,s[11,10]=-1.2,s[11,11]=-0.6,s[11,12]=-0.2,s[11,13]=-1.1,s[11,14]=-0.3,s[11,15]=0.0,s[11,16]=0.1,s[11,17]=0.3,s[11,18]=-0.5,s[11,19]=0.4,s[11,20]=-0.3,s[11,21]=-0.2,s[11,22]=-0.6,s[11,23]=0.8,s[11,24]=0.1,s[11,25]=1.2,s[11,26]=-0.7,s[11,27]=0.7,s[11,28]=-0.5,s[11,29]=-0.7,s[11,30]=-0.2 s[11,31]=1.2,s[11,32]=-0.1,s[11,33]=0.0,s[11,34]=-0.1,s[11,35]=-0.9,s[11,36]=0.8,s[11,37]=-0.5,s[11,38]=0.5,s[11,39]=0.4,s[11,40]=-0.5,s[11,41]=0.6,s[11,42]=0.3,s[11,43]=-0.3,s[11,44]=0.7,s[11,45]=0.3,s[11,46]=0.2,s[11,47]=0.7,s[11,48]=0.4,s[11,49]=0.0,s[11,50]=-0.5,s[11,51]=1.1,s[11,52]=-0.4,s[11,53]=0.5,s[11,54]=-1.0,s[11,55]=-0.7,s[11,56]=0.6,s[11,57]=1.1,s[11,58]=-1.2,s[11,59]=0.1,s[11,60]=0.3 s[12,1]=-0.2,s[12,2]=-0.9,s[12,3]=-0.8,s[12,4]=-0.2,s[12,5]=0.6,s[12,6]=-0.9,s[12,7]=0.0,s[12,8]=0.6,s[12,9]=1.1,s[12,10]=1.2,s[12,11]=-0.5,s[12,12]=0.0,s[12,13]=0.6,s[12,14]=1.0,s[12,15]=1.1,s[12,16]=-0.1,s[12,17]=-0.7,s[12,18]=-1.1,s[12,19]=-0.5,s[12,20]=0.8,s[12,21]=-0.2,s[12,22]=0.9,s[12,23]=1.1,s[12,24]=-0.1,s[12,25]=-0.4,s[12,26]=-0.3,s[12,27]=0.3,s[12,28]=1.1,s[12,29]=-0.9,s[12,30]=-0.5 s[12,31]=0.5,s[12,32]=0.3,s[12,33]=0.6,s[12,34]=0.9,s[12,35]=-0.4,s[12,36]=0.7,s[12,37]=1.1,s[12,38]=0.6,s[12,39]=-1.2,s[12,40]=0.2,s[12,41]=-0.1,s[12,42]=0.2,s[12,43]=-0.7,s[12,44]=0.8,s[12,45]=0.9,s[12,46]=0.4,s[12,47]=-0.6,s[12,48]=-0.2,s[12,49]=-1.1,s[12,50]=0.4,s[12,51]=-0.7,s[12,52]=-0.7,s[12,53]=0.5,s[12,54]=0.5,s[12,55]=0.7,s[12,56]=0.1,s[12,57]=0.4,s[12,58]=0.5,s[12,59]=-1.2,s[12,60]=0.8 s[13,1]=0.6,s[13,2]=-1.1,s[13,3]=-0.1,s[13,4]=-0.9,s[13,5]=0.0,s[13,6]=0.6,s[13,7]=-0.9,s[13,8]=0.4,s[13,9]=0.4,s[13,10]=-1.1,s[13,11]=-0.1,s[13,12]=-0.8,s[13,13]=0.5,s[13,14]=0.7,s[13,15]=-0.3,s[13,16]=-0.3,s[13,17]=-0.2,s[13,18]=1.1,s[13,19]=0.3,s[13,20]=-0.1,s[13,21]=0.0,s[13,22]=0.9,s[13,23]=-0.1,s[13,24]=-0.7,s[13,25]=-0.1,s[13,26]=0.3,s[13,27]=0.1,s[13,28]=-0.4,s[13,29]=1.0,s[13,30]=0.4 s[13,31]=-0.6,s[13,32]=-0.8,s[13,33]=0.4,s[13,34]=0.6,s[13,35]=0.5,s[13,36]=1.2,s[13,37]=0.3,s[13,38]=-0.7,s[13,39]=0.8,s[13,40]=0.9,s[13,41]=0.1,s[13,42]=0.3,s[13,43]=0.0,s[13,44]=-1.2,s[13,45]=0.0,s[13,46]=1.0,s[13,47]=1.1,s[13,48]=-1.2,s[13,49]=0.4,s[13,50]=0.0,s[13,51]=-0.8,s[13,52]=-0.9,s[13,53]=0.5,s[13,54]=1.1,s[13,55]=1.2,s[13,56]=-1.0,s[13,57]=0.2,s[13,58]=0.3,s[13,59]=0.0,s[13,60]=0.2 s[14,1]=-0.2,s[14,2]=-0.5,s[14,3]=-0.9,s[14,4]=-1.1,s[14,5]=-1.2,s[14,6]=-0.2,s[14,7]=0.5,s[14,8]=-1.1,s[14,9]=-0.7,s[14,10]=-0.4,s[14,11]=0.5,s[14,12]=0.1,s[14,13]=0.4,s[14,14]=0.1,s[14,15]=0.3,s[14,16]=0.1,s[14,17]=-1.2,s[14,18]=0.2,s[14,19]=0.2,s[14,20]=-0.3,s[14,21]=-0.2,s[14,22]=-0.2,s[14,23]=0.0,s[14,24]=-1.0,s[14,25]=0.4,s[14,26]=0.5,s[14,27]=0.7,s[14,28]=0.2,s[14,29]=-0.3,s[14,30]=0.5 s[14,31]=-0.2,s[14,32]=0.9,s[14,33]=0.8,s[14,34]=1.1,s[14,35]=-0.6,s[14,36]=-0.7,s[14,37]=-0.9,s[14,38]=-0.9,s[14,39]=1.2,s[14,40]=0.9,s[14,41]=0.1,s[14,42]=-0.9,s[14,43]=-0.6,s[14,44]=-1.0,s[14,45]=0.5,s[14,46]=1.0,s[14,47]=-0.2,s[14,48]=0.0,s[14,49]=-1.2,s[14,50]=0.1,s[14,51]=0.1,s[14,52]=-0.2,s[14,53]=0.7,s[14,54]=-0.7,s[14,55]=0.8,s[14,56]=-0.8,s[14,57]=0.8,s[14,58]=0.4,s[14,59]=-0.4,s[14,60]=-1.1 s[15,1]=-0.2,s[15,2]=0.2,s[15,3]=1.1,s[15,4]=-0.2,s[15,5]=-0.9,s[15,6]=-0.7,s[15,7]=-1.1,s[15,8]=0.7,s[15,9]=0.4,s[15,10]=-0.4,s[15,11]=-0.3,s[15,12]=-0.1,s[15,13]=-0.6,s[15,14]=0.9,s[15,15]=-0.8,s[15,16]=0.1,s[15,17]=-0.5,s[15,18]=0.9,s[15,19]=-1.0,s[15,20]=0.4,s[15,21]=0.1,s[15,22]=-0.1,s[15,23]=1.0,s[15,24]=0.9,s[15,25]=-1.1,s[15,26]=-0.1,s[15,27]=-0.3,s[15,28]=0.6,s[15,29]=-0.5,s[15,30]=1.0 s[15,31]=0.8,s[15,32]=-0.3,s[15,33]=0.3,s[15,34]=0.2,s[15,35]=-0.8,s[15,36]=0.5,s[15,37]=0.3,s[15,38]=-0.4,s[15,39]=1.1,s[15,40]=0.9,s[15,41]=0.6,s[15,42]=1.2,s[15,43]=0.8,s[15,44]=1.1,s[15,45]=1.1,s[15,46]=-0.7,s[15,47]=-0.2,s[15,48]=1.2,s[15,49]=1.0,s[15,50]=1.2,s[15,51]=-0.4,s[15,52]=-0.4,s[15,53]=-1.2,s[15,54]=-0.7,s[15,55]=-0.3,s[15,56]=-0.4,s[15,57]=0.9,s[15,58]=0.0,s[15,59]=0.7,s[15,60]=-1.0 s[16,1]=0.3,s[16,2]=-0.7,s[16,3]=-1.0,s[16,4]=0.1,s[16,5]=0.4,s[16,6]=-0.3,s[16,7]=-0.5,s[16,8]=1.0,s[16,9]=1.2,s[16,10]=-0.9,s[16,11]=-1.0,s[16,12]=-0.9,s[16,13]=-0.8,s[16,14]=0.7,s[16,15]=0.3,s[16,16]=-0.3,s[16,17]=1.2,s[16,18]=-0.2,s[16,19]=-1.0,s[16,20]=0.1,s[16,21]=0.3,s[16,22]=-0.3,s[16,23]=-0.9,s[16,24]=0.2,s[16,25]=0.7,s[16,26]=0.5,s[16,27]=-0.6,s[16,28]=-0.1,s[16,29]=-0.5,s[16,30]=-1.2 s[16,31]=0.5,s[16,32]=0.8,s[16,33]=-0.5,s[16,34]=-0.8,s[16,35]=0.5,s[16,36]=0.5,s[16,37]=-0.5,s[16,38]=-0.9,s[16,39]=0.2,s[16,40]=0.7,s[16,41]=-0.5,s[16,42]=-0.7,s[16,43]=0.3,s[16,44]=0.8,s[16,45]=-0.3,s[16,46]=-1.0,s[16,47]=-0.6,s[16,48]=-0.5,s[16,49]=-0.8,s[16,50]=0.7,s[16,51]=0.4,s[16,52]=-0.1,s[16,53]=-0.1,s[16,54]=0.2,s[16,55]=-0.1,s[16,56]=0.2,s[16,57]=0.6,s[16,58]=0.4,s[16,59]=-0.2,s[16,60]=-1.2 s[17,1]=0.9,s[17,2]=-0.9,s[17,3]=0.4,s[17,4]=-0.1,s[17,5]=0.9,s[17,6]=-0.6,s[17,7]=-0.7,s[17,8]=1.2,s[17,9]=-0.2,s[17,10]=1.2,s[17,11]=-1.2,s[17,12]=0.3,s[17,13]=-0.4,s[17,14]=0.8,s[17,15]=0.9,s[17,16]=-0.3,s[17,17]=-0.3,s[17,18]=-0.8,s[17,19]=-0.5,s[17,20]=0.1,s[17,21]=-0.2,s[17,22]=0.5,s[17,23]=0.0,s[17,24]=0.6,s[17,25]=1.1,s[17,26]=-0.1,s[17,27]=0.6,s[17,28]=-1.0,s[17,29]=0.1,s[17,30]=-0.8 s[17,31]=0.8,s[17,32]=-1.2,s[17,33]=-1.2,s[17,34]=-0.2,s[17,35]=0.5,s[17,36]=-0.6,s[17,37]=0.9,s[17,38]=-0.6,s[17,39]=1.2,s[17,40]=-0.9,s[17,41]=0.4,s[17,42]=0.6,s[17,43]=-0.3,s[17,44]=-1.2,s[17,45]=-1.0,s[17,46]=-0.5,s[17,47]=-0.7,s[17,48]=0.9,s[17,49]=0.5,s[17,50]=0.5,s[17,51]=-0.7,s[17,52]=-0.5,s[17,53]=-1.2,s[17,54]=-1.2,s[17,55]=-0.7,s[17,56]=0.0,s[17,57]=1.2,s[17,58]=0.4,s[17,59]=1.2,s[17,60]=-0.9 s[18,1]=0.1,s[18,2]=-0.5,s[18,3]=0.9,s[18,4]=1.0,s[18,5]=1.0,s[18,6]=0.8,s[18,7]=-0.9,s[18,8]=0.9,s[18,9]=-0.6,s[18,10]=1.0,s[18,11]=-0.1,s[18,12]=-0.2,s[18,13]=0.9,s[18,14]=0.9,s[18,15]=-0.3,s[18,16]=0.0,s[18,17]=0.4,s[18,18]=-0.2,s[18,19]=-0.4,s[18,20]=-0.7,s[18,21]=-0.3,s[18,22]=1.1,s[18,23]=0.9,s[18,24]=-0.7,s[18,25]=-0.1,s[18,26]=-1.2,s[18,27]=-0.1,s[18,28]=-0.1,s[18,29]=1.0,s[18,30]=-1.1 s[18,31]=1.0,s[18,32]=1.1,s[18,33]=0.2,s[18,34]=-1.1,s[18,35]=0.5,s[18,36]=-0.5,s[18,37]=0.5,s[18,38]=0.3,s[18,39]=-0.8,s[18,40]=0.8,s[18,41]=0.4,s[18,42]=0.4,s[18,43]=-0.1,s[18,44]=0.3,s[18,45]=-0.6,s[18,46]=-0.7,s[18,47]=0.6,s[18,48]=-0.6,s[18,49]=-1.2,s[18,50]=0.0,s[18,51]=0.4,s[18,52]=1.1,s[18,53]=0.2,s[18,54]=0.4,s[18,55]=1.0,s[18,56]=-0.6,s[18,57]=-0.8,s[18,58]=0.3,s[18,59]=-0.8,s[18,60]=0.8 s[19,1]=0.4,s[19,2]=-1.1,s[19,3]=-1.2,s[19,4]=0.8,s[19,5]=0.2,s[19,6]=0.6,s[19,7]=0.0,s[19,8]=-0.1,s[19,9]=-0.5,s[19,10]=0.9,s[19,11]=0.7,s[19,12]=1.1,s[19,13]=-0.8,s[19,14]=0.3,s[19,15]=0.3,s[19,16]=0.7,s[19,17]=0.1,s[19,18]=0.4,s[19,19]=-0.2,s[19,20]=-1.1,s[19,21]=0.0,s[19,22]=-0.6,s[19,23]=-0.8,s[19,24]=1.1,s[19,25]=0.3,s[19,26]=0.2,s[19,27]=0.6,s[19,28]=0.3,s[19,29]=-1.0,s[19,30]=0.7 s[19,31]=0.8,s[19,32]=-0.8,s[19,33]=-1.2,s[19,34]=-0.1,s[19,35]=-0.5,s[19,36]=0.3,s[19,37]=-1.1,s[19,38]=0.6,s[19,39]=-0.1,s[19,40]=-1.1,s[19,41]=0.1,s[19,42]=-0.5,s[19,43]=0.5,s[19,44]=1.2,s[19,45]=0.0,s[19,46]=-0.6,s[19,47]=-0.7,s[19,48]=-0.8,s[19,49]=0.5,s[19,50]=-0.2,s[19,51]=0.8,s[19,52]=0.1,s[19,53]=1.0,s[19,54]=-0.6,s[19,55]=0.5,s[19,56]=-0.9,s[19,57]=-0.1,s[19,58]=1.0,s[19,59]=-1.2,s[19,60]=-0.5 s[20,1]=0.2,s[20,2]=-1.0,s[20,3]=0.1,s[20,4]=0.7,s[20,5]=0.0,s[20,6]=0.7,s[20,7]=-0.3,s[20,8]=0.5,s[20,9]=-0.6,s[20,10]=-0.6,s[20,11]=-0.7,s[20,12]=0.7,s[20,13]=-0.7,s[20,14]=0.9,s[20,15]=1.1,s[20,16]=-0.9,s[20,17]=-0.1,s[20,18]=-0.4,s[20,19]=-0.6,s[20,20]=-0.6,s[20,21]=-0.1,s[20,22]=0.0,s[20,23]=1.0,s[20,24]=-0.7,s[20,25]=-0.6,s[20,26]=0.5,s[20,27]=0.3,s[20,28]=0.9,s[20,29]=0.9,s[20,30]=0.9 s[20,31]=-1.0,s[20,32]=0.0,s[20,33]=0.9,s[20,34]=-0.1,s[20,35]=-0.2,s[20,36]=0.9,s[20,37]=1.1,s[20,38]=-0.8,s[20,39]=0.1,s[20,40]=1.0,s[20,41]=0.0,s[20,42]=0.1,s[20,43]=0.6,s[20,44]=0.9,s[20,45]=-1.1,s[20,46]=0.4,s[20,47]=-0.9,s[20,48]=0.2,s[20,49]=-1.1,s[20,50]=1.0,s[20,51]=1.0,s[20,52]=0.9,s[20,53]=-1.0,s[20,54]=0.6,s[20,55]=-1.0,s[20,56]=-0.6,s[20,57]=-1.1,s[20,58]=0.2,s[20,59]=-0.7,s[20,60]=0.5 endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float ppz = @ppz float pxx = 0 float pyy = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x pyy = y x = s[@sd,1] + s[@sd,2]*x + s[@sd,3]*x*x + s[@sd,4]*x*x*x + s[@sd,5]*x*x*y + s[@sd,6]*x*x*ppz + s[@sd,7]*x*y + \ s[@sd,8]*x*y*y + s[@sd,9]*x*y*ppz + s[@sd,10]*x*ppz + s[@sd,11]*x*ppz*ppz + s[@sd,12]*y + s[@sd,13]*y*y + s[@sd,14]*y*y*y + \ s[@sd,15]*y*y*ppz + s[@sd,16]*y*ppz + s[@sd,17]*y*ppz*ppz + s[@sd,18]*ppz +s[@sd,19]*ppz*ppz +s[@sd,20]*ppz*ppz*ppz y = s[@sd,21] +s[@sd,22]*pxx +s[@sd,23]*pxx*pxx +s[@sd,24]*pxx*pxx*pxx +s[@sd,25]*pxx*pxx*y +s[@sd,26]*pxx*pxx*ppz +s[@sd,27]*pxx*y +\ s[@sd,28]*pxx*y*y +s[@sd,29]*pxx*y*ppz +s[@sd,30]*pxx*ppz +s[@sd,31]*pxx*ppz*ppz +s[@sd,32]*y +s[@sd,33]*y*y +s[@sd,34]*y*y*y + \ s[@sd,35]*y*y*ppz +s[@sd,36]*y*ppz +s[@sd,37]*y*ppz*ppz +s[@sd,38]*ppz +s[@sd,39]*ppz*ppz +s[@sd,40]*ppz*ppz*ppz ppz = s[@sd,41] +s[@sd,42]*pxx +s[@sd,43]*pxx*pxx +s[@sd,44]*pxx*pxx*pxx +s[@sd,45]*pxx*pxx*pyy +s[@sd,46]*pxx*pxx*ppz +s[@sd,47]*pxx*pyy + \ s[@sd,48]*pxx*pyy*pyy +s[@sd,49]*pxx*pyy*ppz +s[@sd,50]*pxx*ppz +s[@sd,51]*pxx*ppz*ppz +s[@sd,52]*pyy +s[@sd,53]*pyy*pyy +s[@sd,54]*pyy*pyy*pyy + \ s[@sd,55]*pyy*pyy*ppz +s[@sd,56]*pyy*ppz +s[@sd,57]*pyy*ppz*ppz +s[@sd,58]*ppz +s[@sd,59]*ppz*ppz +s[@sd,60]*ppz*ppz*ppz att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y) + ppz*@pw) float d = @distscale*|pz-(x + sgn*flip(y) + ppz*@pw)| return d endfunc private: float s[21,61] default: title = "Sprott3D_Cubic" heading text="Sprott 3D cubic attractors" endheading heading text=" x -> Cubic in x, y and z" endheading heading text=" y -> Cubic in x, y and z" endheading heading text=" z -> Cubic in x, y and z" endheading int param v_trapshapesprott3d_Cubic caption = "Version (Trap Shape Sprott3D_Cubic)" 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_trapshapesprott3d_Cubic < 100 endparam param sd caption = "Sprott selector" default = 0 enum = "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" \ "15" "16" "17" "18" "19" "20" hint = "Each Sprott selector uses a different strange attractor." endparam heading text = "'Initialize Height' sets the starting z value for the attractor." endheading float param ppz caption = "Initialize Height" default = 0.0 endparam heading text = "'Height weight' determines the weight of the final z value which is added \ to the trap distance." endheading complex param pw caption = "Height weight" default = (0.5,0) endparam float param distscale caption = "Distance scale" default = 2 endparam float param s caption = "Attractor scale" default = 1 endparam int param max_att_iterations caption = "Attractor iterations" default = 15 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeSprott3D_Cubic_ODE(common.ulb:TrapShape) { ; This shape uses a Sprott strange attractor.
;

; The Sprott attractors were developed by Julien C. Sprott, and are ; based upon polynomials and linear differential equations of polynomials. public: import "common.ulb" ; Constructor func REB_TrapShapeSprott3D_Cubic_ODE(Generic pparent) TrapShape.TrapShape(pparent) s[0,1]=0.4,s[0,2]=0.7,s[0,3]=-0.5,s[0,4]=-0.3,s[0,5]=1.1,s[0,6]=-0.9,s[0,7]=0.6,s[0,8]=-0.5,s[0,9]=0.7,s[0,10]=0.1,s[0,11]=0.9,s[0,12]=1.1,s[0,13]=-0.8,s[0,14]=0.9,s[0,15]=-1.1,s[0,16]=-0.6,s[0,17]=1.0,s[0,18]=-1.2,s[0,19]=1.0,s[0,20]=0.8,s[0,21]=1.2,s[0,22]=-1.1,s[0,23]=-0.4,s[0,24]=-0.9,s[0,25]=-0.9,s[0,26]=0.8,s[0,27]=-0.5,s[0,28]=-1.1,s[0,29]=-0.2,s[0,30]=-0.6 s[0,31]=1.1,s[0,32]=0.1,s[0,33]=0.4,s[0,34]=-1.0,s[0,35]=0.3,s[0,36]=-0.7,s[0,37]=-1.2,s[0,38]=-0.5,s[0,39]=1.1,s[0,40]=1.1,s[0,41]=0.6,s[0,42]=0.9,s[0,43]=-0.3,s[0,44]=0.0,s[0,45]=1.2,s[0,46]=-1.2,s[0,47]=-0.9,s[0,48]=-0.3,s[0,49]=1.2,s[0,50]=-0.8,s[0,51]=1.2,s[0,52]=-0.1,s[0,53]=0.8,s[0,54]=-0.5,s[0,55]=-1.2,s[0,56]=0.6,s[0,57]=-0.1,s[0,58]=1.1,s[0,59]=-1.0,s[0,60]=0.3 s[1,1]=0.7,s[1,2]=0.0,s[1,3]=0.0,s[1,4]=-1.0,s[1,5]=0.6,s[1,6]=0.3,s[1,7]=0.0,s[1,8]=0.7,s[1,9]=-0.4,s[1,10]=0.5,s[1,11]=1.0,s[1,12]=-0.2,s[1,13]=0.8,s[1,14]=0.5,s[1,15]=0.3 s[1,16]=-0.8,s[1,17]=0.4,s[1,18]=0.8,s[1,19]=0.8,s[1,20]=-1.2,s[1,21]=-0.2,s[1,22]=0.6,s[1,23]=-1.1,s[1,24]=-0.9,s[1,25]=0.7,s[1,26]=0.2,s[1,27]=0.9,s[1,28]=1.1,s[1,29]=-0.2,s[1,30]=0.8 s[1,31]=0.8,s[1,32]=-0.1,s[1,33]=-0.1,s[1,34]=-0.7,s[1,35]=-0.8,s[1,36]=1.0,s[1,37]=0.8,s[1,38]=-0.7,s[1,39]=-1.1,s[1,40]=0.1,s[1,41]=-0.2,s[1,42]=0.8,s[1,43]=0.8,s[1,44]=-0.2,s[1,45]=-0.5 s[1,46]=-0.4,s[1,47]=-0.8,s[1,48]=0.1,s[1,49]=0.3,s[1,50]=0.6,s[1,51]=0.1,s[1,52]=-0.7,s[1,53]=-0.5,s[1,54]=0.5,s[1,55]=-0.3,s[1,56]=-0.1,s[1,57]=-0.3,s[1,58]=-0.6,s[1,59]=0.2,s[1,60]=-0.2 s[2,1]=-0.2,s[2,2]=0.5,s[2,3]=-1.1,s[2,4]=-1.1,s[2,5]=0.6,s[2,6]=-1.0,s[2,7]=0.0,s[2,8]=-0.2,s[2,9]=1.0,s[2,10]=-0.8,s[2,11]=0.7,s[2,12]=0.3,s[2,13]=0.8,s[2,14]=0.0,s[2,15]=-0.1 s[2,16]=0.7,s[2,17]=-0.1,s[2,18]=-0.2,s[2,19]=1.1,s[2,20]=-0.7,s[2,21]=0.1,s[2,22]=-0.8,s[2,23]=-0.1,s[2,24]=-0.7,s[2,25]=0.3,s[2,26]=-0.9,s[2,27]=1.1,s[2,28]=-0.5,s[2,29]=0.6,s[2,30]=-0.4 s[2,31]=-0.4,s[2,32]=-0.9,s[2,33]=0.3,s[2,34]=-1.2,s[2,35]=0.2,s[2,36]=-0.6,s[2,37]=0.1,s[2,38]=0.2,s[2,39]=1.2,s[2,40]=0.1,s[2,41]=1.0,s[2,42]=-0.6,s[2,43]=0.5,s[2,44]=0.6,s[2,45]=-0.1 s[2,46]=1.0,s[2,47]=-1.1,s[2,48]=-0.6,s[2,49]=-1.2,s[2,50]=0.9,s[2,51]=0.6,s[2,52]=0.5,s[2,53]=-0.6,s[2,54]=0.8,s[2,55]=0.2,s[2,56]=0.9,s[2,57]=-0.7,s[2,58]=0.6,s[2,59]=-0.1,s[2,60]=-0.2 s[3,1]=1.0,s[3,2]=-0.7,s[3,3]=0.6,s[3,4]=-0.3,s[3,5]=-0.5,s[3,6]=-0.2,s[3,7]=-0.4,s[3,8]=-0.1,s[3,9]=-0.9,s[3,10]=-0.6,s[3,11]=1.0,s[3,12]=-0.1,s[3,13]=-0.6,s[3,14]=1.2,s[3,15]=-0.4 s[3,16]=-0.5,s[3,17]=-0.2,s[3,18]=0.5,s[3,19]=0.0,s[3,20]=0.7,s[3,21]=0.5,s[3,22]=0.4,s[3,23]=-0.4,s[3,24]=-0.2,s[3,25]=0.9,s[3,26]=-0.7,s[3,27]=0.6,s[3,28]=0.1,s[3,29]=1.0,s[3,30]=-0.6 s[3,31]=-1.1,s[3,32]=-1.0,s[3,33]=0.2,s[3,34]=-1.0,s[3,35]=0.4,s[3,36]=0.0,s[3,37]=-0.3,s[3,38]=-0.5,s[3,39]=-1.1,s[3,40]=1.2,s[3,41]=0.6,s[3,42]=-0.3,s[3,43]=-1.1,s[3,44]=-0.6,s[3,45]=-0.1 s[3,46]=-0.9,s[3,47]=-0.8,s[3,48]=-0.1,s[3,49]=0.5,s[3,50]=0.5,s[3,51]=-0.4,s[3,52]=-0.2,s[3,53]=0.8,s[3,54]=0.4,s[3,55]=-0.5,s[3,56]=0.4,s[3,57]=0.6,s[3,58]=0.7,s[3,59]=-0.6,s[3,60]=-0.6 s[4,1]=0.9,s[4,2]=-0.2,s[4,3]=-1.1,s[4,4]=-1.1,s[4,5]=0.9,s[4,6]=-0.4,s[4,7]=-0.1,s[4,8]=-0.4,s[4,9]=-1.0,s[4,10]=0.0,s[4,11]=0.1,s[4,12]=-0.7,s[4,13]=-0.8,s[4,14]=-0.6,s[4,15]=-1.2 s[4,16]=0.0,s[4,17]=0.1,s[4,18]=-0.1,s[4,19]=0.9,s[4,20]=1.2,s[4,21]=-0.2,s[4,22]=-0.8,s[4,23]=-0.6,s[4,24]=0.2,s[4,25]=-0.6,s[4,26]=0.7,s[4,27]=0.1,s[4,28]=1.2,s[4,29]=-0.1,s[4,30]=-0.3 s[4,31]=-0.8,s[4,32]=-0.1,s[4,33]=-1.2,s[4,34]=-1.2,s[4,35]=1.1,s[4,36]=-0.8,s[4,37]=0.1,s[4,38]=-0.9,s[4,39]=-0.3,s[4,40]=0.5,s[4,41]=0.6,s[4,42]=0.6,s[4,43]=0.6,s[4,44]=-1.1,s[4,45]=-0.4 s[4,46]=-0.4,s[4,47]=-0.4,s[4,48]=-0.7,s[4,49]=0.1,s[4,50]=0.8,s[4,51]=0.3,s[4,52]=-0.6,s[4,53]=-0.4,s[4,54]=-1.2,s[4,55]=0.6,s[4,56]=-0.7,s[4,57]=-0.7,s[4,58]=0.8,s[4,59]=0.3,s[4,60]=-0.3 s[5,1]=1.0,s[5,2]=0.4,s[5,3]=0.7,s[5,4]=-1.1,s[5,5]=-0.3,s[5,6]=-0.9,s[5,7]=0.9,s[5,8]=-0.3,s[5,9]=-0.3,s[5,10]=-0.6,s[5,11]=-0.1,s[5,12]=0.6,s[5,13]=0.7,s[5,14]=0.6,s[5,15]=-0.3 s[5,16]=-0.8,s[5,17]=-1.1,s[5,18]=0.2,s[5,19]=0.0,s[5,20]=-0.3,s[5,21]=-0.5,s[5,22]=-0.9,s[5,23]=1.0,s[5,24]=-0.4,s[5,25]=-1.0,s[5,26]=0.4,s[5,27]=0.5,s[5,28]=1.1,s[5,29]=0.6,s[5,30]=-1.2 s[5,31]=-0.2,s[5,32]=1.1,s[5,33]=1.0,s[5,34]=-0.9,s[5,35]=-0.2,s[5,36]=-0.5,s[5,37]=-0.8,s[5,38]=0.2,s[5,39]=-1.0,s[5,40]=-1.1,s[5,41]=0.6,s[5,42]=0.9,s[5,43]=0.3,s[5,44]=-0.2,s[5,45]=-0.9 s[5,46]=0.2,s[5,47]=-0.8,s[5,48]=0.2,s[5,49]=-1.2,s[5,50]=0.3,s[5,51]=0.4,s[5,52]=0.6,s[5,53]=-0.1,s[5,54]=1.1,s[5,55]=0.0,s[5,56]=0.5,s[5,57]=0.7,s[5,58]=0.7,s[5,59]=0.3,s[5,60]=0.1 s[6,1]=0.3,s[6,2]=-0.8,s[6,3]=1.1,s[6,4]=-0.7,s[6,5]=-0.7,s[6,6]=-1.2,s[6,7]=0.3,s[6,8]=-0.9,s[6,9]=0.2,s[6,10]=1.2,s[6,11]=-1.1,s[6,12]=-0.7,s[6,13]=-1.2,s[6,14]=-0.4,s[6,15]=-0.5 s[6,16]=-0.7,s[6,17]=-0.6,s[6,18]=-1.1,s[6,19]=-0.8,s[6,20]=0.8,s[6,21]=0.2,s[6,22]=0.7,s[6,23]=-0.7,s[6,24]=-0.4,s[6,25]=-1.0,s[6,26]=0.5,s[6,27]=0.2,s[6,28]=-1.1,s[6,29]=0.7,s[6,30]=1.1 s[6,31]=1.1,s[6,32]=-0.1,s[6,33]=-0.9,s[6,34]=0.1,s[6,35]=-0.9,s[6,36]=0.0,s[6,37]=0.3,s[6,38]=-1.0,s[6,39]=-0.5,s[6,40]=0.2,s[6,41]=-0.3,s[6,42]=-0.1,s[6,43]=0.4,s[6,44]=0.1,s[6,45]=-0.9 s[6,46]=0.2,s[6,47]=-1.0,s[6,48]=-0.4,s[6,49]=0.9,s[6,50]=-0.1,s[6,51]=-1.2,s[6,52]=-0.5,s[6,53]=-0.9,s[6,54]=0.4,s[6,55]=0.5,s[6,56]=0.3,s[6,57]=0.3,s[6,58]=-0.8,s[6,59]=-0.8,s[6,60]=-1.1 s[7,1]=-0.3,s[7,2]=0.6,s[7,3]=-1.0,s[7,4]=0.7,s[7,5]=-0.3,s[7,6]=-0.9,s[7,7]=1.2,s[7,8]=1.0,s[7,9]=-0.2,s[7,10]=0.1,s[7,11]=-0.8,s[7,12]=-0.9,s[7,13]=0.1,s[7,14]=-1.0,s[7,15]=0.9 s[7,16]=-1.0,s[7,17]=-0.3,s[7,18]=-0.1,s[7,19]=-0.5,s[7,20]=-0.2,s[7,21]=-0.4,s[7,22]=0.4,s[7,23]=-1.1,s[7,24]=0.7,s[7,25]=0.4,s[7,26]=0.7,s[7,27]=0.2,s[7,28]=0.7,s[7,29]=-0.2,s[7,30]=0.3 s[7,31]=0.6,s[7,32]=-0.3,s[7,33]=1.2,s[7,34]=0.9,s[7,35]=0.2,s[7,36]=-0.2,s[7,37]=-0.2,s[7,38]=1.1,s[7,39]=-0.6,s[7,40]=-0.5,s[7,41]=-0.8,s[7,42]=-0.5,s[7,43]=-1.0,s[7,44]=-0.4,s[7,45]=-0.8 s[7,46]=-0.7,s[7,47]=-0.8,s[7,48]=0.8,s[7,49]=-1.1,s[7,50]=0.5,s[7,51]=-0.9,s[7,52]=0.7,s[7,53]=0.2,s[7,54]=0.6,s[7,55]=1.1,s[7,56]=0.6,s[7,57]=0.7,s[7,58]=0.4,s[7,59]=0.8,s[7,60]=-0.9 s[8,1]=-0.1,s[8,2]=1.0,s[8,3]=0.4,s[8,4]=-0.6,s[8,5]=0.2,s[8,6]=1.2,s[8,7]=0.2,s[8,8]=-0.5,s[8,9]=1.0,s[8,10]=0.6,s[8,11]=0.3,s[8,12]=0.9,s[8,13]=0.2,s[8,14]=-0.2,s[8,15]=0.1 s[8,16]=-0.6,s[8,17]=-1.0,s[8,18]=0.6,s[8,19]=0.8,s[8,20]=-1.0,s[8,21]=-0.2,s[8,22]=1.1,s[8,23]=0.6,s[8,24]=-0.7,s[8,25]=-0.7,s[8,26]=-0.7,s[8,27]=0.7,s[8,28]=-0.1,s[8,29]=-0.2,s[8,30]=-1.1 s[8,31]=0.1,s[8,32]=1.1,s[8,33]=0.5,s[8,34]=0.1,s[8,35]=0.8,s[8,36]=-0.4,s[8,37]=-0.4,s[8,38]=-1.0,s[8,39]=1.2,s[8,40]=0.5,s[8,41]=-1.0,s[8,42]=-1.1,s[8,43]=-0.8,s[8,44]=0.8,s[8,45]=0.0 s[8,46]=-1.2,s[8,47]=-1.0,s[8,48]=-0.9,s[8,49]=0.8,s[8,50]=-0.4,s[8,51]=-0.9,s[8,52]=1.0,s[8,53]=0.8,s[8,54]=-0.9,s[8,55]=-0.9,s[8,56]=1.1,s[8,57]=-0.8,s[8,58]=0.9,s[8,59]=0.7,s[8,60]=-1.1 s[9,1]=-0.3,s[9,2]=0.8,s[9,3]=0.4,s[9,4]=-1.0,s[9,5]=0.7,s[9,6]=1.1,s[9,7]=1.1,s[9,8]=1.1,s[9,9]=0.1,s[9,10]=0.6,s[9,11]=0.3,s[9,12]=0.0,s[9,13]=0.6,s[9,14]=0.1,s[9,15]=0.0 s[9,16]=-0.3,s[9,17]=-1.0,s[9,18]=-1.0,s[9,19]=0.0,s[9,20]=-0.8,s[9,21]=-0.5,s[9,22]=0.9,s[9,23]=-0.6,s[9,24]=0.6,s[9,25]=-0.6,s[9,26]=0.4,s[9,27]=-0.2,s[9,28]=1.2,s[9,29]=-0.5,s[9,30]=0.3 s[9,31]=-0.9,s[9,32]=-1.0,s[9,33]=0.2,s[9,34]=-0.4,s[9,35]=0.0,s[9,36]=0.4,s[9,37]=-0.5,s[9,38]=-0.1,s[9,39]=-0.7,s[9,40]=0.4,s[9,41]=1.2,s[9,42]=-0.3,s[9,43]=0.7,s[9,44]=1.0,s[9,45]=0.8 s[9,46]=-0.1,s[9,47]=-0.9,s[9,48]=-0.2,s[9,49]=-0.9,s[9,50]=0.6,s[9,51]=0.5,s[9,52]=-0.3,s[9,53]=-0.2,s[9,54]=0.3,s[9,55]=-0.2,s[9,56]=-1.0,s[9,57]=0.1,s[9,58]=-0.6,s[9,59]=0.8,s[9,60]=-0.2 s[10,1]=0.9,s[10,2]=0.1,s[10,3]=-1.1,s[10,4]=0.5,s[10,5]=1.2,s[10,6]=-0.9,s[10,7]=-0.4,s[10,8]=-1.0,s[10,9]=-0.1,s[10,10]=0.8,s[10,11]=-0.4,s[10,12]=1.2,s[10,13]=-0.9,s[10,14]=0.0,s[10,15]=0.1 s[10,16]=-0.3,s[10,17]=-0.3,s[10,18]=0.1,s[10,19]=0.2,s[10,20]=1.0,s[10,21]=-0.8,s[10,22]=0.4,s[10,23]=0.9,s[10,24]=0.2,s[10,25]=-0.9,s[10,26]=-0.4,s[10,27]=-0.6,s[10,28]=1.0,s[10,29]=0.4,s[10,30]=0.0 s[10,31]=0.8,s[10,32]=-0.9,s[10,33]=0.3,s[10,34]=-0.2,s[10,35]=-0.3,s[10,36]=0.0,s[10,37]=-0.4,s[10,38]=-0.6,s[10,39]=0.6,s[10,40]=0.9,s[10,41]=-0.1,s[10,42]=1.0,s[10,43]=0.7,s[10,44]=0.2,s[10,45]=0.3 s[10,46]=0.0,s[10,47]=0.7,s[10,48]=-0.8,s[10,49]=1.2,s[10,50]=0.8,s[10,51]=0.0,s[10,52]=-1.1,s[10,53]=0.2,s[10,54]=0.1,s[10,55]=-0.7,s[10,56]=-0.7,s[10,57]=-0.8,s[10,58]=0.3,s[10,59]=0.8,s[10,60]=-0.6 s[11,1]=-0.3,s[11,2]=-0.3,s[11,3]=-0.9,s[11,4]=-1.2,s[11,5]=-0.6,s[11,6]=1.2,s[11,7]=0.9,s[11,8]=-0.5,s[11,9]=-0.5,s[11,10]=-0.9,s[11,11]=-0.9,s[11,12]=0.0,s[11,13]=-0.7,s[11,14]=0.0,s[11,15]=0.1 s[11,16]=-0.5,s[11,17]=0.1,s[11,18]=1.2,s[11,19]=-1.2,s[11,20]=-0.7,s[11,21]=-0.4,s[11,22]=-0.6,s[11,23]=0.3,s[11,24]=-1.2,s[11,25]=-1.2,s[11,26]=-0.2,s[11,27]=1.2,s[11,28]=1.1,s[11,29]=0.0,s[11,30]=0.4 s[11,31]=-1.2,s[11,32]=-0.2,s[11,33]=-1.1,s[11,34]=-1.1,s[11,35]=0.5,s[11,36]=-0.2,s[11,37]=0.0,s[11,38]=0.9,s[11,39]=-0.9,s[11,40]=0.9,s[11,41]=-0.4,s[11,42]=-0.5,s[11,43]=-0.9,s[11,44]=-0.6,s[11,45]=1.1 s[11,46]=-0.2,s[11,47]=0.7,s[11,48]=0.7,s[11,49]=-0.9,s[11,50]=-0.9,s[11,51]=-1.1,s[11,52]=0.9,s[11,53]=-0.8,s[11,54]=-1.0,s[11,55]=-0.6,s[11,56]=-0.8,s[11,57]=0.3,s[11,58]=0.8,s[11,59]=0.7,s[11,60]=-0.3 s[12,1]=0.5,s[12,2]=-1.0,s[12,3]=-0.4,s[12,4]=-0.7,s[12,5]=0.9,s[12,6]=0.9,s[12,7]=-0.9,s[12,8]=0.7,s[12,9]=0.9,s[12,10]=-1.2,s[12,11]=0.8,s[12,12]=0.2,s[12,13]=-0.4,s[12,14]=-1.0,s[12,15]=-0.9 s[12,16]=0.5,s[12,17]=-0.5,s[12,18]=0.0,s[12,19]=0.9,s[12,20]=-1.0,s[12,21]=0.8,s[12,22]=-0.9,s[12,23]=-0.9,s[12,24]=0.2,s[12,25]=0.4,s[12,26]=1.2,s[12,27]=0.8,s[12,28]=1.0,s[12,29]=-1.0,s[12,30]=0.3 s[12,31]=0.2,s[12,32]=-1.2,s[12,33]=-0.2,s[12,34]=-1.0,s[12,35]=-0.5,s[12,36]=-0.4,s[12,37]=-0.3,s[12,38]=-0.9,s[12,39]=-0.2,s[12,40]=0.2,s[12,41]=-0.9,s[12,42]=-0.3,s[12,43]=-1.2,s[12,44]=0.8,s[12,45]=1.1 s[12,46]=1.1,s[12,47]=-0.9,s[12,48]=0.1,s[12,49]=0.6,s[12,50]=-0.5,s[12,51]=-0.2,s[12,52]=0.2,s[12,53]=-0.3,s[12,54]=-0.9,s[12,55]=-0.6,s[12,56]=0.3,s[12,57]=0.6,s[12,58]=-0.1,s[12,59]=0.7,s[12,60]=-0.9 s[13,1]=-0.9,s[13,2]=-0.9,s[13,3]=-0.8,s[13,4]=0.3,s[13,5]=-0.9,s[13,6]=-1.1,s[13,7]=1.0,s[13,8]=0.0,s[13,9]=0.7,s[13,10]=-0.8,s[13,11]=1.0,s[13,12]=0.0,s[13,13]=-0.7,s[13,14]=-1.1,s[13,15]=-1.1 s[13,16]=-1.2,s[13,17]=0.7,s[13,18]=-0.7,s[13,19]=-0.1,s[13,20]=-1.1,s[13,21]=-1.0,s[13,22]=0.6,s[13,23]=-1.0,s[13,24]=0.5,s[13,25]=-0.7,s[13,26]=0.2,s[13,27]=-0.9,s[13,28]=-1.1,s[13,29]=0.6,s[13,30]=0.9 s[13,31]=0.6,s[13,32]=-1.1,s[13,33]=-0.1,s[13,34]=-0.5,s[13,35]=1.0,s[13,36]=-1.1,s[13,37]=-1.2,s[13,38]=-0.8,s[13,39]=0.7,s[13,40]=-0.8,s[13,41]=-0.7,s[13,42]=-0.8,s[13,43]=-0.8,s[13,44]=0.5,s[13,45]=0.6 s[13,46]=0.2,s[13,47]=-0.2,s[13,48]=0.7,s[13,49]=0.8,s[13,50]=0.0,s[13,51]=-1.2,s[13,52]=-0.3,s[13,53]=1.1,s[13,54]=-0.9,s[13,55]=0.1,s[13,56]=0.3,s[13,57]=-0.6,s[13,58]=-0.8,s[13,59]=0.1,s[13,60]=0.3 s[14,1]=-0.4,s[14,2]=-0.2,s[14,3]=0.5,s[14,4]=-1.0,s[14,5]=-0.2,s[14,6]=0.8,s[14,7]=-0.1,s[14,8]=0.7,s[14,9]=0.7,s[14,10]=-0.4,s[14,11]=0.4,s[14,12]=0.0,s[14,13]=0.7,s[14,14]=-0.1,s[14,15]=0.3 s[14,16]=-0.4,s[14,17]=-0.1,s[14,18]=-1.0,s[14,19]=0.3,s[14,20]=1.1,s[14,21]=1.2,s[14,22]=0.8,s[14,23]=0.2,s[14,24]=0.1,s[14,25]=-0.7,s[14,26]=-0.9,s[14,27]=-0.5,s[14,28]=1.1,s[14,29]=-1.1,s[14,30]=-0.2 s[14,31]=0.2,s[14,32]=0.5,s[14,33]=-0.8,s[14,34]=-1.1,s[14,35]=-1.1,s[14,36]=-0.2,s[14,37]=0.7,s[14,38]=0.8,s[14,39]=0.2,s[14,40]=0.0,s[14,41]=-0.4,s[14,42]=0.7,s[14,43]=0.6,s[14,44]=-0.3,s[14,45]=0.9 s[14,46]=-1.1,s[14,47]=-0.7,s[14,48]=0.3,s[14,49]=1.0,s[14,50]=0.3,s[14,51]=-0.7,s[14,52]=0.0,s[14,53]=0.6,s[14,54]=0.0,s[14,55]=0.8,s[14,56]=0.5,s[14,57]=0.4,s[14,58]=1.2,s[14,59]=1.0,s[14,60]=-0.7 s[15,1]=0.1,s[15,2]=0.0,s[15,3]=-0.7,s[15,4]=-0.8,s[15,5]=0.5,s[15,6]=1.0,s[15,7]=-0.6,s[15,8]=-0.8,s[15,9]=-0.7,s[15,10]=0.8,s[15,11]=1.0,s[15,12]=0.0,s[15,13]=0.2,s[15,14]=0.7,s[15,15]=0.6 s[15,16]=-0.3,s[15,17]=-1.0,s[15,18]=-1.0,s[15,19]=-0.1,s[15,20]=-0.5,s[15,21]=0.4,s[15,22]=-1.1,s[15,23]=-0.2,s[15,24]=0.3,s[15,25]=-1.1,s[15,26]=0.6,s[15,27]=0.4,s[15,28]=0.1,s[15,29]=-0.7,s[15,30]=-0.2 s[15,31]=-0.4,s[15,32]=-0.9,s[15,33]=0.0,s[15,34]=-0.1,s[15,35]=-0.1,s[15,36]=1.1,s[15,37]=0.2,s[15,38]=-0.5,s[15,39]=-0.5,s[15,40]=-0.7,s[15,41]=-1.0,s[15,42]=-0.5,s[15,43]=0.9,s[15,44]=0.8,s[15,45]=0.6 s[15,46]=0.1,s[15,47]=-0.2,s[15,48]=-1.0,s[15,49]=-0.5,s[15,50]=0.5,s[15,51]=-0.9,s[15,52]=0.7,s[15,53]=0.8,s[15,54]=-0.5,s[15,55]=-0.5,s[15,56]=-0.3,s[15,57]=1.1,s[15,58]=0.5,s[15,59]=0.9,s[15,60]=0.1 s[16,1]=-1.1,s[16,2]=0.2,s[16,3]=0.6,s[16,4]=-0.4,s[16,5]=-0.2,s[16,6]=1.0,s[16,7]=0.8,s[16,8]=-0.6,s[16,9]=-1.2,s[16,10]=-1.0,s[16,11]=0.1,s[16,12]=-0.5,s[16,13]=0.0,s[16,14]=0.1,s[16,15]=1.1 s[16,16]=1.2,s[16,17]=0.3,s[16,18]=1.1,s[16,19]=-0.7,s[16,20]=-0.6,s[16,21]=0.5,s[16,22]=-0.5,s[16,23]=-1.0,s[16,24]=0.9,s[16,25]=-1.0,s[16,26]=0.4,s[16,27]=1.2,s[16,28]=-0.2,s[16,29]=0.7,s[16,30]=0.5 s[16,31]=-1.0,s[16,32]=1.1,s[16,33]=1.1,s[16,34]=0.6,s[16,35]=0.0,s[16,36]=1.2,s[16,37]=0.1,s[16,38]=0.5,s[16,39]=0.9,s[16,40]=0.6,s[16,41]=0.5,s[16,42]=0.2,s[16,43]=0.2,s[16,44]=1.1,s[16,45]=-0.1 s[16,46]=-0.3,s[16,47]=-0.4,s[16,48]=0.9,s[16,49]=0.5,s[16,50]=0.8,s[16,51]=0.3,s[16,52]=-0.2,s[16,53]=-1.2,s[16,54]=1.1,s[16,55]=0.3,s[16,56]=0.5,s[16,57]=0.0,s[16,58]=-1.1,s[16,59]=0.2,s[16,60]=-0.5 s[17,1]=0.1,s[17,2]=0.9,s[17,3]=0.0,s[17,4]=-1.0,s[17,5]=0.2,s[17,6]=-0.7,s[17,7]=0.3,s[17,8]=1.0,s[17,9]=-0.5,s[17,10]=0.4,s[17,11]=0.4,s[17,12]=0.8,s[17,13]=-0.7,s[17,14]=-0.5,s[17,15]=-0.9 s[17,16]=0.2,s[17,17]=0.0,s[17,18]=0.1,s[17,19]=1.0,s[17,20]=0.9,s[17,21]=-0.4,s[17,22]=-0.2,s[17,23]=0.7,s[17,24]=-1.1,s[17,25]=-0.8,s[17,26]=-0.7,s[17,27]=0.3,s[17,28]=-0.7,s[17,29]=-0.7,s[17,30]=0.3 s[17,31]=1.2,s[17,32]=0.7,s[17,33]=0.6,s[17,34]=-1.2,s[17,35]=-0.1,s[17,36]=0.3,s[17,37]=0.1,s[17,38]=-0.1,s[17,39]=-0.1,s[17,40]=-1.0,s[17,41]=0.2,s[17,42]=0.4,s[17,43]=-0.8,s[17,44]=-0.1,s[17,45]=0.7 s[17,46]=-0.8,s[17,47]=-0.6,s[17,48]=-0.4,s[17,49]=-0.8,s[17,50]=0.7,s[17,51]=0.3,s[17,52]=1.1,s[17,53]=-0.5,s[17,54]=0.9,s[17,55]=0.9,s[17,56]=-1.0,s[17,57]=-0.9,s[17,58]=-1.0,s[17,59]=0.8,s[17,60]=-1.2 s[18,1]=0.0,s[18,2]=-0.7,s[18,3]=-0.1,s[18,4]=1.1,s[18,5]=-1.2,s[18,6]=0.8,s[18,7]=1.0,s[18,8]=-0.1,s[18,9]=0.2,s[18,10]=0.0,s[18,11]=-0.5,s[18,12]=-0.3,s[18,13]=0.1,s[18,14]=0.9,s[18,15]=1.2 s[18,16]=0.8,s[18,17]=0.6,s[18,18]=-1.2,s[18,19]=-0.8,s[18,20]=1.0,s[18,21]=0.4,s[18,22]=-0.6,s[18,23]=-0.7,s[18,24]=-0.2,s[18,25]=0.7,s[18,26]=0.0,s[18,27]=-0.6,s[18,28]=1.1,s[18,29]=1.2,s[18,30]=-0.6 s[18,31]=0.9,s[18,32]=1.1,s[18,33]=-0.2,s[18,34]=-1.2,s[18,35]=0.2,s[18,36]=0.5,s[18,37]=-0.2,s[18,38]=-1.1,s[18,39]=-0.5,s[18,40]=0.9,s[18,41]=0.5,s[18,42]=0.0,s[18,43]=1.0,s[18,44]=-0.7,s[18,45]=0.6 s[18,46]=-0.4,s[18,47]=0.0,s[18,48]=-0.9,s[18,49]=1.0,s[18,50]=-0.6,s[18,51]=-0.3,s[18,52]=-0.4,s[18,53]=0.0,s[18,54]=-0.9,s[18,55]=0.9,s[18,56]=0.5,s[18,57]=-0.3,s[18,58]=-1.2,s[18,59]=-0.1,s[18,60]=-1.1 s[19,1]=-1.1,s[19,2]=0.6,s[19,3]=0.6,s[19,4]=0.0,s[19,5]=-0.4,s[19,6]=-0.4,s[19,7]=-0.1,s[19,8]=-1.2,s[19,9]=-1.0,s[19,10]=1.2,s[19,11]=0.1,s[19,12]=-1.2,s[19,13]=-1.1,s[19,14]=0.6,s[19,15]=1.1 s[19,16]=1.1,s[19,17]=-0.6,s[19,18]=0.3,s[19,19]=0.4,s[19,20]=0.3,s[19,21]=1.1,s[19,22]=0.9,s[19,23]=-0.4,s[19,24]=1.1,s[19,25]=-0.3,s[19,26]=-1.1,s[19,27]=-0.9,s[19,28]=-1.2,s[19,29]=0.3,s[19,30]=0.3 s[19,31]=-1.1,s[19,32]=0.2,s[19,33]=-0.2,s[19,34]=-1.0,s[19,35]=-1.1,s[19,36]=0.9,s[19,37]=0.4,s[19,38]=-0.6,s[19,39]=1.1,s[19,40]=-0.1,s[19,41]=-0.7,s[19,42]=0.9,s[19,43]=-0.4,s[19,44]=-0.3,s[19,45]=0.7 s[19,46]=-0.8,s[19,47]=-1.2,s[19,48]=-0.1,s[19,49]=-0.3,s[19,50]=-0.6,s[19,51]=-1.1,s[19,52]=-0.2,s[19,53]=-1.2,s[19,54]=-1.1,s[19,55]=1.1,s[19,56]=-0.5,s[19,57]=0.9,s[19,58]=-0.3,s[19,59]=0.9,s[19,60]=-1.2 s[20,1]=-0.2,s[20,2]=-0.1,s[20,3]=0.6,s[20,4]=-0.1,s[20,5]=0.7,s[20,6]=0.2,s[20,7]=0.8,s[20,8]=-0.3,s[20,9]=0.7,s[20,10]=-0.9,s[20,11]=-0.1,s[20,12]=0.6,s[20,13]=-0.4,s[20,14]=-1.1,s[20,15]=0.8 s[20,16]=1.0,s[20,17]=-0.7,s[20,18]=-0.1,s[20,19]=-0.3,s[20,20]=-0.1,s[20,21]=-0.6,s[20,22]=0.1,s[20,23]=-0.5,s[20,24]=-0.4,s[20,25]=-1.2,s[20,26]=-1.2,s[20,27]=0.6,s[20,28]=-0.9,s[20,29]=0.8,s[20,30]=0.4 s[20,31]=1.1,s[20,32]=-0.9,s[20,33]=0.9,s[20,34]=-0.8,s[20,35]=0.5,s[20,36]=0.1,s[20,37]=0.3,s[20,38]=-1.2,s[20,39]=0.2,s[20,40]=-0.9,s[20,41]=-0.5,s[20,42]=-0.3,s[20,43]=1.1,s[20,44]=1.1,s[20,45]=0.8 s[20,46]=-0.4,s[20,47]=0.1,s[20,48]=-0.6,s[20,49]=0.7,s[20,50]=-0.8,s[20,51]=1.0,s[20,52]=-0.4,s[20,53]=-0.4,s[20,54]=0.9,s[20,55]=-0.1,s[20,56]=0.3,s[20,57]=-0.4,s[20,58]=-0.1,s[20,59]=-0.3,s[20,60]=-0.3 s[21,1]=-0.2,s[21,2]=-0.3,s[21,3]=-0.2,s[21,4]=0.9,s[21,5]=1.0,s[21,6]=-0.1,s[21,7]=0.0,s[21,8]=0.0,s[21,9]=0.6,s[21,10]=-1.0,s[21,11]=-1.2,s[21,12]=-0.7,s[21,13]=-0.5,s[21,14]=-0.1,s[21,15]=-0.6 s[21,16]=-0.6,s[21,17]=-0.2,s[21,18]=0.6,s[21,19]=-0.9,s[21,20]=-0.2,s[21,21]=-0.6,s[21,22]=0.7,s[21,23]=1.1,s[21,24]=-0.3,s[21,25]=0.6,s[21,26]=-1.1,s[21,27]=-0.9,s[21,28]=0.3,s[21,29]=0.2,s[21,30]=0.7 s[21,31]=0.3,s[21,32]=-1.2,s[21,33]=-0.9,s[21,34]=-0.1,s[21,35]=0.1,s[21,36]=1.2,s[21,37]=-1.2,s[21,38]=-1.1,s[21,39]=0.4,s[21,40]=0.3,s[21,41]=0.8,s[21,42]=-0.8,s[21,43]=1.1,s[21,44]=-0.4,s[21,45]=-1.2 s[21,46]=-0.5,s[21,47]=-0.3,s[21,48]=0.9,s[21,49]=0.5,s[21,50]=0.6,s[21,51]=-1.2,s[21,52]=-0.8,s[21,53]=0.4,s[21,54]=0.9,s[21,55]=0.4,s[21,56]=1.1,s[21,57]=0.2,s[21,58]=1.2,s[21,59]=0.3,s[21,60]=-1.1 s[22,1]=0.1,s[22,2]=0.7,s[22,3]=-0.9,s[22,4]=0.0,s[22,5]=0.3,s[22,6]=-0.8,s[22,7]=-1.1,s[22,8]=-0.5,s[22,9]=0.4,s[22,10]=-1.0,s[22,11]=0.2,s[22,12]=-0.3,s[22,13]=-1.0,s[22,14]=1.0,s[22,15]=-0.5 s[22,16]=-1.1,s[22,17]=0.4,s[22,18]=-0.9,s[22,19]=0.6,s[22,20]=0.5,s[22,21]=1.0,s[22,22]=-0.2,s[22,23]=-0.4,s[22,24]=0.4,s[22,25]=0.5,s[22,26]=0.1,s[22,27]=0.0,s[22,28]=-0.7,s[22,29]=-0.9,s[22,30]=-0.9 s[22,31]=-0.1,s[22,32]=0.6,s[22,33]=-0.8,s[22,34]=-0.4,s[22,35]=-1.1,s[22,36]=-1.0,s[22,37]=-1.2,s[22,38]=0.1,s[22,39]=-0.1,s[22,40]=-1.2,s[22,41]=-0.4,s[22,42]=0.8,s[22,43]=0.5,s[22,44]=0.2,s[22,45]=-1.1 s[22,46]=0.7,s[22,47]=0.2,s[22,48]=-0.7,s[22,49]=-0.2,s[22,50]=-1.2,s[22,51]=1.2,s[22,52]=0.5,s[22,53]=-0.8,s[22,54]=0.8,s[22,55]=-0.7,s[22,56]=0.7,s[22,57]=-1.2,s[22,58]=0.4,s[22,59]=1.2,s[22,60]=-1.1 s[23,1]=0.7,s[23,2]=-0.6,s[23,3]=-0.3,s[23,4]=-0.5,s[23,5]=-0.1,s[23,6]=1.2,s[23,7]=-0.2,s[23,8]=0.4,s[23,9]=0.7,s[23,10]=-1.2,s[23,11]=-0.4,s[23,12]=0.1,s[23,13]=0.0,s[23,14]=-0.5,s[23,15]=0.4 s[23,16]=-0.4,s[23,17]=-0.6,s[23,18]=-0.9,s[23,19]=1.1,s[23,20]=-1.1,s[23,21]=0.8,s[23,22]=-1.0,s[23,23]=-0.1,s[23,24]=-0.3,s[23,25]=0.9,s[23,26]=-0.4,s[23,27]=0.5,s[23,28]=-1.0,s[23,29]=1.1,s[23,30]=-0.4 s[23,31]=-0.1,s[23,32]=0.1,s[23,33]=0.2,s[23,34]=-0.2,s[23,35]=-1.2,s[23,36]=0.8,s[23,37]=-0.9,s[23,38]=0.1,s[23,39]=-0.3,s[23,40]=-0.7,s[23,41]=-0.1,s[23,42]=-1.0,s[23,43]=0.5,s[23,44]=-0.8,s[23,45]=1.1 s[23,46]=0.4,s[23,47]=-0.9,s[23,48]=-0.2,s[23,49]=-0.7,s[23,50]=1.0,s[23,51]=-1.2,s[23,52]=-0.3,s[23,53]=-0.7,s[23,54]=1.2,s[23,55]=0.5,s[23,56]=-0.1,s[23,57]=0.6,s[23,58]=-0.7,s[23,59]=0.9,s[23,60]=-1.2 s[24,1]=0.3,s[24,2]=0.9,s[24,3]=-0.9,s[24,4]=-0.7,s[24,5]=-1.1,s[24,6]=1.2,s[24,7]=-1.1,s[24,8]=1.0,s[24,9]=0.7,s[24,10]=1.2,s[24,11]=-0.7,s[24,12]=0.3,s[24,13]=1.2,s[24,14]=1.2,s[24,15]=0.3 s[24,16]=-0.1,s[24,17]=-0.6,s[24,18]=-1.2,s[24,19]=1.2,s[24,20]=1.2,s[24,21]=-0.9,s[24,22]=-0.2,s[24,23]=0.2,s[24,24]=-0.5,s[24,25]=-1.1,s[24,26]=-1.0,s[24,27]=-1.2,s[24,28]=-0.5,s[24,29]=0.2,s[24,30]=-0.2 s[24,31]=0.3,s[24,32]=-0.9,s[24,33]=0.4,s[24,34]=-0.9,s[24,35]=-0.5,s[24,36]=-1.0,s[24,37]=0.3,s[24,38]=0.6,s[24,39]=-0.5,s[24,40]=-1.0,s[24,41]=-0.8,s[24,42]=-0.1,s[24,43]=-1.0,s[24,44]=1.1,s[24,45]=-0.3 s[24,46]=-0.1,s[24,47]=0.2,s[24,48]=0.7,s[24,49]=-0.6,s[24,50]=1.0,s[24,51]=0.0,s[24,52]=-1.0,s[24,53]=0.5,s[24,54]=-0.4,s[24,55]=-0.9,s[24,56]=-0.8,s[24,57]=-0.2,s[24,58]=0.3,s[24,59]=-0.7,s[24,60]=-0.5 s[25,1]=1.2,s[25,2]=-0.9,s[25,3]=-0.5,s[25,4]=0.1,s[25,5]=0.2,s[25,6]=-0.8,s[25,7]=0.0,s[25,8]=1.2,s[25,9]=-0.5,s[25,10]=-0.1,s[25,11]=0.9,s[25,12]=-0.9,s[25,13]=-0.8,s[25,14]=0.1,s[25,15]=-0.9 s[25,16]=0.3,s[25,17]=-0.9,s[25,18]=-0.4,s[25,19]=-0.5,s[25,20]=-0.6,s[25,21]=-1.1,s[25,22]=-0.9,s[25,23]=-0.9,s[25,24]=0.9,s[25,25]=1.1,s[25,26]=0.6,s[25,27]=-0.3,s[25,28]=-0.1,s[25,29]=-1.2,s[25,30]=-1.1 s[25,31]=0.0,s[25,32]=0.1,s[25,33]=-0.7,s[25,34]=-0.7,s[25,35]=0.5,s[25,36]=-0.4,s[25,37]=1.0,s[25,38]=0.2,s[25,39]=0.7,s[25,40]=-0.5,s[25,41]=-0.4,s[25,42]=-0.1,s[25,43]=-0.1,s[25,44]=0.2,s[25,45]=0.2 s[25,46]=-0.7,s[25,47]=0.8,s[25,48]=1.1,s[25,49]=-0.1,s[25,50]=-0.6,s[25,51]=0.1,s[25,52]=0.5,s[25,53]=-0.5,s[25,54]=-0.4,s[25,55]=0.2,s[25,56]=1.0,s[25,57]=1.1,s[25,58]=0.0,s[25,59]=-0.1,s[25,60]=-1.2 s[26,1]=-0.6,s[26,2]=0.1,s[26,3]=-0.4,s[26,4]=-1.1,s[26,5]=-0.6,s[26,6]=0.1,s[26,7]=-1.0,s[26,8]=-1.0,s[26,9]=-0.6,s[26,10]=0.1,s[26,11]=-0.7,s[26,12]=0.9,s[26,13]=-0.4,s[26,14]=-0.1,s[26,15]=-1.0 s[26,16]=0.7,s[26,17]=0.9,s[26,18]=0.9,s[26,19]=0.7,s[26,20]=0.9,s[26,21]=1.2,s[26,22]=0.8,s[26,23]=0.1,s[26,24]=-1.2,s[26,25]=0.4,s[26,26]=0.8,s[26,27]=-0.8,s[26,28]=-0.2,s[26,29]=-0.7,s[26,30]=-0.8 s[26,31]=-1.2,s[26,32]=0.5,s[26,33]=0.3,s[26,34]=-0.4,s[26,35]=-0.6,s[26,36]=1.2,s[26,37]=-1.1,s[26,38]=0.1,s[26,39]=-0.6,s[26,40]=1.0,s[26,41]=-1.1,s[26,42]=-0.3,s[26,43]=0.2,s[26,44]=-0.6,s[26,45]=0.4 s[26,46]=-1.1,s[26,47]=-0.6,s[26,48]=0.9,s[26,49]=0.1,s[26,50]=-0.2,s[26,51]=-0.8,s[26,52]=-0.3,s[26,53]=-0.5,s[26,54]=0.0,s[26,55]=-1.2,s[26,56]=1.0,s[26,57]=-0.3,s[26,58]=-0.6,s[26,59]=0.3,s[26,60]=1.0 s[27,1]=0.1,s[27,2]=1.1,s[27,3]=0.1,s[27,4]=-0.9,s[27,5]=-0.4,s[27,6]=0.7,s[27,7]=0.1,s[27,8]=0.6,s[27,9]=0.9,s[27,10]=0.1,s[27,11]=0.9,s[27,12]=-0.1,s[27,13]=-0.9,s[27,14]=-0.6,s[27,15]=1.2 s[27,16]=0.1,s[27,17]=-0.6,s[27,18]=-0.5,s[27,19]=0.4,s[27,20]=-0.8,s[27,21]=-0.5,s[27,22]=0.7,s[27,23]=-0.8,s[27,24]=0.6,s[27,25]=-1.1,s[27,26]=-0.1,s[27,27]=-0.3,s[27,28]=-1.1,s[27,29]=-0.1,s[27,30]=0.3 s[27,31]=0.2,s[27,32]=-1.1,s[27,33]=-0.5,s[27,34]=1.1,s[27,35]=-0.1,s[27,36]=-0.6,s[27,37]=-0.6,s[27,38]=-1.1,s[27,39]=0.0,s[27,40]=-0.2,s[27,41]=-0.8,s[27,42]=0.1,s[27,43]=-0.6,s[27,44]=-0.4,s[27,45]=1.2 s[27,46]=0.9,s[27,47]=1.2,s[27,48]=0.3,s[27,49]=0.5,s[27,50]=0.7,s[27,51]=0.9,s[27,52]=-1.1,s[27,53]=0.1,s[27,54]=1.2,s[27,55]=-0.5,s[27,56]=-0.3,s[27,57]=-0.8,s[27,58]=0.1,s[27,59]=-1.2,s[27,60]=-0.7 s[28,1]=0.4,s[28,2]=-0.8,s[28,3]=-0.4,s[28,4]=0.1,s[28,5]=-0.2,s[28,6]=0.2,s[28,7]=1.0,s[28,8]=-0.5,s[28,9]=1.0,s[28,10]=0.5,s[28,11]=-0.7,s[28,12]=-0.5,s[28,13]=-0.8,s[28,14]=0.1,s[28,15]=0.7 s[28,16]=-0.8,s[28,17]=1.1,s[28,18]=1.0,s[28,19]=0.3,s[28,20]=0.0,s[28,21]=1.2,s[28,22]=-0.5,s[28,23]=-1.1,s[28,24]=-0.2,s[28,25]=0.2,s[28,26]=-0.8,s[28,27]=0.4,s[28,28]=-0.7,s[28,29]=0.7,s[28,30]=-1.1 s[28,31]=-1.1,s[28,32]=1.1,s[28,33]=-1.2,s[28,34]=-1.1,s[28,35]=-0.7,s[28,36]=0.6,s[28,37]=-1.2,s[28,38]=0.5,s[28,39]=0.9,s[28,40]=-1.0,s[28,41]=-0.4,s[28,42]=0.2,s[28,43]=-0.9,s[28,44]=0.5,s[28,45]=-1.2 s[28,46]=-0.2,s[28,47]=-0.4,s[28,48]=-0.8,s[28,49]=0.4,s[28,50]=-0.6,s[28,51]=0.0,s[28,52]=0.7,s[28,53]=-0.7,s[28,54]=1.2,s[28,55]=-0.1,s[28,56]=-0.7,s[28,57]=-1.1,s[28,58]=-0.3,s[28,59]=0.9,s[28,60]=-1.1 s[29,1]=-0.4,s[29,2]=-0.9,s[29,3]=-0.1,s[29,4]=0.0,s[29,5]=-0.9,s[29,6]=-0.2,s[29,7]=-0.3,s[29,8]=-0.4,s[29,9]=-0.3,s[29,10]=-0.9,s[29,11]=0.9,s[29,12]=-1.0,s[29,13]=0.8,s[29,14]=0.5,s[29,15]=-0.2 s[29,16]=0.4,s[29,17]=-0.9,s[29,18]=-0.1,s[29,19]=-1.2,s[29,20]=-0.8,s[29,21]=0.1,s[29,22]=0.5,s[29,23]=0.6,s[29,24]=0.6,s[29,25]=1.0,s[29,26]=-0.2,s[29,27]=-0.2,s[29,28]=0.1,s[29,29]=0.3,s[29,30]=-0.3 s[29,31]=-0.7,s[29,32]=-1.0,s[29,33]=-0.2,s[29,34]=-0.5,s[29,35]=-0.6,s[29,36]=0.7,s[29,37]=-1.1,s[29,38]=1.2,s[29,39]=-0.6,s[29,40]=0.4,s[29,41]=0.5,s[29,42]=-0.5,s[29,43]=-0.8,s[29,44]=0.4,s[29,45]=1.1 s[29,46]=0.1,s[29,47]=-0.3,s[29,48]=-0.2,s[29,49]=0.0,s[29,50]=-0.8,s[29,51]=-1.2,s[29,52]=0.1,s[29,53]=-0.4,s[29,54]=-1.2,s[29,55]=-1.1,s[29,56]=0.0,s[29,57]=-0.8,s[29,58]=-0.3,s[29,59]=-0.5,s[29,60]=-1.2 s[30,1]=0.3,s[30,2]=-0.8,s[30,3]=-0.8,s[30,4]=-1.0,s[30,5]=0.9,s[30,6]=1.2,s[30,7]=-1.0,s[30,8]=-0.3,s[30,9]=-1.0,s[30,10]=-0.8,s[30,11]=-1.0,s[30,12]=0.6,s[30,13]=0.8,s[30,14]=0.6,s[30,15]=0.8 s[30,16]=-0.4,s[30,17]=0.2,s[30,18]=0.7,s[30,19]=-1.1,s[30,20]=0.0,s[30,21]=-1.1,s[30,22]=-0.2,s[30,23]=0.1,s[30,24]=1.0,s[30,25]=-0.8,s[30,26]=-0.5,s[30,27]=1.0,s[30,28]=-0.5,s[30,29]=0.0,s[30,30]=-0.5 s[30,31]=0.2,s[30,32]=0.4,s[30,33]=-0.3,s[30,34]=-0.2,s[30,35]=-1.2,s[30,36]=1.2,s[30,37]=-1.0,s[30,38]=0.2,s[30,39]=1.0,s[30,40]=0.4,s[30,41]=0.0,s[30,42]=-0.7,s[30,43]=1.1,s[30,44]=-0.8,s[30,45]=0.2 s[30,46]=-0.8,s[30,47]=-1.2,s[30,48]=1.0,s[30,49]=0.9,s[30,50]=0.9,s[30,51]=0.7,s[30,52]=0.8,s[30,53]=0.9,s[30,54]=-1.2,s[30,55]=0.6,s[30,56]=-1.0,s[30,57]=0.5,s[30,58]=-1.1,s[30,59]=-0.5,s[30,60]=-0.8 s[31,1]=-0.3,s[31,2]=-0.2,s[31,3]=0.8,s[31,4]=-1.1,s[31,5]=-0.8,s[31,6]=0.0,s[31,7]=-1.0,s[31,8]=-0.9,s[31,9]=-1.0,s[31,10]=0.4,s[31,11]=-0.6,s[31,12]=-0.9,s[31,13]=-0.9,s[31,14]=0.0,s[31,15]=0.0 s[31,16]=-0.3,s[31,17]=0.6,s[31,18]=0.2,s[31,19]=0.1,s[31,20]=1.1,s[31,21]=1.1,s[31,22]=-1.0,s[31,23]=0.6,s[31,24]=1.2,s[31,25]=0.8,s[31,26]=1.2,s[31,27]=0.6,s[31,28]=0.4,s[31,29]=0.9,s[31,30]=0.1 s[31,31]=-1.0,s[31,32]=-1.0,s[31,33]=-0.4,s[31,34]=0.1,s[31,35]=0.2,s[31,36]=0.9,s[31,37]=0.4,s[31,38]=-0.8,s[31,39]=-0.8,s[31,40]=-0.3,s[31,41]=0.9,s[31,42]=-0.3,s[31,43]=-0.5,s[31,44]=0.0,s[31,45]=0.6 s[31,46]=0.1,s[31,47]=-1.0,s[31,48]=0.3,s[31,49]=-1.2,s[31,50]=-1.1,s[31,51]=-0.8,s[31,52]=0.3,s[31,53]=0.0,s[31,54]=0.8,s[31,55]=-0.9,s[31,56]=-0.6,s[31,57]=-0.1,s[31,58]=0.4,s[31,59]=0.9,s[31,60]=-0.7 s[32,1]=-0.2,s[32,2]=-0.5,s[32,3]=-0.7,s[32,4]=-0.6,s[32,5]=0.9,s[32,6]=0.0,s[32,7]=-0.2,s[32,8]=1.1,s[32,9]=1.0,s[32,10]=-0.5,s[32,11]=-1.2,s[32,12]=0.8,s[32,13]=-0.1,s[32,14]=-1.2,s[32,15]=-0.1 s[32,16]=0.2,s[32,17]=-1.0,s[32,18]=-0.6,s[32,19]=-0.9,s[32,20]=0.7,s[32,21]=-0.6,s[32,22]=0.8,s[32,23]=-0.6,s[32,24]=-0.5,s[32,25]=-1.0,s[32,26]=-1.0,s[32,27]=1.1,s[32,28]=1.0,s[32,29]=-0.6,s[32,30]=0.0 s[32,31]=-0.2,s[32,32]=1.0,s[32,33]=0.3,s[32,34]=-1.2,s[32,35]=0.1,s[32,36]=0.2,s[32,37]=-1.2,s[32,38]=1.1,s[32,39]=-1.1,s[32,40]=0.6,s[32,41]=-0.6,s[32,42]=0.4,s[32,43]=-0.3,s[32,44]=-1.2,s[32,45]=0.1 s[32,46]=-1.0,s[32,47]=0.5,s[32,48]=-0.5,s[32,49]=0.8,s[32,50]=0.0,s[32,51]=-1.1,s[32,52]=-0.7,s[32,53]=-0.7,s[32,54]=-0.8,s[32,55]=0.6,s[32,56]=0.1,s[32,57]=-0.9,s[32,58]=-0.6,s[32,59]=-0.7,s[32,60]=0.2 s[33,1]=0.9,s[33,2]=-0.2,s[33,3]=-1.1,s[33,4]=0.2,s[33,5]=0.6,s[33,6]=0.8,s[33,7]=0.0,s[33,8]=1.0,s[33,9]=0.2,s[33,10]=-0.5,s[33,11]=-0.1,s[33,12]=-0.7,s[33,13]=-0.4,s[33,14]=0.6,s[33,15]=-0.6 s[33,16]=0.4,s[33,17]=-0.6,s[33,18]=0.0,s[33,19]=1.1,s[33,20]=-0.9,s[33,21]=-0.7,s[33,22]=-0.8,s[33,23]=0.3,s[33,24]=-0.2,s[33,25]=1.0,s[33,26]=-0.6,s[33,27]=-0.2,s[33,28]=1.0,s[33,29]=-0.5,s[33,30]=0.6 s[33,31]=0.6,s[33,32]=-0.1,s[33,33]=-0.7,s[33,34]=-0.2,s[33,35]=1.1,s[33,36]=1.1,s[33,37]=0.4,s[33,38]=-0.9,s[33,39]=0.1,s[33,40]=1.2,s[33,41]=1.0,s[33,42]=-1.1,s[33,43]=0.0,s[33,44]=0.0,s[33,45]=-1.0 s[33,46]=-1.1,s[33,47]=0.7,s[33,48]=-0.7,s[33,49]=1.0,s[33,50]=-1.0,s[33,51]=-0.2,s[33,52]=-1.0,s[33,53]=-0.7,s[33,54]=-0.7,s[33,55]=0.9,s[33,56]=-0.9,s[33,57]=0.0,s[33,58]=0.2,s[33,59]=0.6,s[33,60]=-1.1 s[34,1]=0.3,s[34,2]=-0.5,s[34,3]=1.1,s[34,4]=0.2,s[34,5]=-1.1,s[34,6]=-0.1,s[34,7]=1.0,s[34,8]=0.7,s[34,9]=-0.4,s[34,10]=-1.0,s[34,11]=0.6,s[34,12]=-0.6,s[34,13]=0.2,s[34,14]=-1.0,s[34,15]=0.1 s[34,16]=-0.5,s[34,17]=-0.7,s[34,18]=-0.6,s[34,19]=0.5,s[34,20]=-0.7,s[34,21]=0.6,s[34,22]=0.3,s[34,23]=1.0,s[34,24]=0.8,s[34,25]=-0.5,s[34,26]=-0.8,s[34,27]=-1.2,s[34,28]=1.1,s[34,29]=0.7,s[34,30]=0.5 s[34,31]=0.7,s[34,32]=0.3,s[34,33]=-0.7,s[34,34]=-0.5,s[34,35]=1.0,s[34,36]=-1.2,s[34,37]=-0.2,s[34,38]=0.0,s[34,39]=-0.5,s[34,40]=1.0,s[34,41]=0.3,s[34,42]=-0.1,s[34,43]=-0.1,s[34,44]=-0.7,s[34,45]=0.0 s[34,46]=-1.0,s[34,47]=0.1,s[34,48]=0.3,s[34,49]=-1.1,s[34,50]=1.0,s[34,51]=0.5,s[34,52]=-0.5,s[34,53]=-0.5,s[34,54]=-0.4,s[34,55]=-0.9,s[34,56]=-0.8,s[34,57]=0.6,s[34,58]=0.2,s[34,59]=-0.8,s[34,60]=-0.6 s[35,1]=1.1,s[35,2]=-0.5,s[35,3]=-0.2,s[35,4]=-0.8,s[35,5]=0.6,s[35,6]=-1.2,s[35,7]=1.2,s[35,8]=-0.7,s[35,9]=-0.9,s[35,10]=-0.1,s[35,11]=0.5,s[35,12]=-0.5,s[35,13]=-0.5,s[35,14]=-0.1,s[35,15]=-0.6 s[35,16]=-0.9,s[35,17]=-0.1,s[35,18]=0.2,s[35,19]=-0.8,s[35,20]=-0.7,s[35,21]=0.5,s[35,22]=0.6,s[35,23]=-0.2,s[35,24]=0.0,s[35,25]=-0.8,s[35,26]=-0.8,s[35,27]=0.7,s[35,28]=0.7,s[35,29]=0.5,s[35,30]=-0.1 s[35,31]=-1.1,s[35,32]=-0.8,s[35,33]=-0.4,s[35,34]=0.0,s[35,35]=-0.8,s[35,36]=-1.1,s[35,37]=0.1,s[35,38]=-0.1,s[35,39]=-0.5,s[35,40]=-0.4,s[35,41]=-0.9,s[35,42]=0.4,s[35,43]=0.6,s[35,44]=1.2,s[35,45]=1.1 s[35,46]=0.8,s[35,47]=-1.1,s[35,48]=0.3,s[35,49]=-1.0,s[35,50]=0.7,s[35,51]=0.2,s[35,52]=-0.2,s[35,53]=-1.1,s[35,54]=1.0,s[35,55]=-1.0,s[35,56]=0.3,s[35,57]=-0.4,s[35,58]=-0.5,s[35,59]=0.1,s[35,60]=0.2 s[36,1]=-0.7,s[36,2]=1.0,s[36,3]=0.7,s[36,4]=0.0,s[36,5]=0.7,s[36,6]=-0.4,s[36,7]=0.8,s[36,8]=0.9,s[36,9]=-0.8,s[36,10]=-1.1,s[36,11]=1.0,s[36,12]=0.3,s[36,13]=0.2,s[36,14]=-0.3,s[36,15]=0.8 s[36,16]=-1.2,s[36,17]=-0.1,s[36,18]=1.0,s[36,19]=-0.7,s[36,20]=0.9,s[36,21]=0.1,s[36,22]=0.8,s[36,23]=0.1,s[36,24]=0.1,s[36,25]=-1.2,s[36,26]=-0.5,s[36,27]=0.8,s[36,28]=-0.6,s[36,29]=1.0,s[36,30]=-1.0 s[36,31]=0.2,s[36,32]=1.1,s[36,33]=-0.5,s[36,34]=0.3,s[36,35]=-1.2,s[36,36]=0.9,s[36,37]=0.3,s[36,38]=-1.1,s[36,39]=0.4,s[36,40]=-1.2,s[36,41]=-0.2,s[36,42]=-0.2,s[36,43]=-0.2,s[36,44]=-0.1,s[36,45]=0.9 s[36,46]=0.7,s[36,47]=-0.5,s[36,48]=0.2,s[36,49]=0.8,s[36,50]=0.3,s[36,51]=-1.2,s[36,52]=0.3,s[36,53]=-0.3,s[36,54]=-0.9,s[36,55]=-0.4,s[36,56]=-0.9,s[36,57]=0.0,s[36,58]=-0.7,s[36,59]=0.0,s[36,60]=-1.2 s[37,1]=-1.0,s[37,2]=0.7,s[37,3]=-0.8,s[37,4]=-0.5,s[37,5]=1.0,s[37,6]=-1.0,s[37,7]=0.8,s[37,8]=0.6,s[37,9]=0.3,s[37,10]=0.0,s[37,11]=0.9,s[37,12]=0.5,s[37,13]=0.0,s[37,14]=0.6,s[37,15]=1.2 s[37,16]=-0.6,s[37,17]=0.6,s[37,18]=-1.0,s[37,19]=0.8,s[37,20]=-0.9,s[37,21]=-1.0,s[37,22]=1.2,s[37,23]=-0.8,s[37,24]=-0.1,s[37,25]=0.4,s[37,26]=-1.0,s[37,27]=0.1,s[37,28]=-0.7,s[37,29]=-0.5,s[37,30]=-0.8 s[37,31]=0.8,s[37,32]=0.4,s[37,33]=-0.4,s[37,34]=-0.6,s[37,35]=-0.9,s[37,36]=1.2,s[37,37]=-0.1,s[37,38]=-0.5,s[37,39]=-0.4,s[37,40]=0.6,s[37,41]=-1.2,s[37,42]=-0.6,s[37,43]=0.1,s[37,44]=0.1,s[37,45]=0.8 s[37,46]=-1.1,s[37,47]=0.4,s[37,48]=0.2,s[37,49]=-0.2,s[37,50]=0.9,s[37,51]=-0.3,s[37,52]=0.0,s[37,53]=0.6,s[37,54]=0.7,s[37,55]=-1.1,s[37,56]=0.1,s[37,57]=0.0,s[37,58]=0.2,s[37,59]=-0.6,s[37,60]=0.4 s[38,1]=0.3,s[38,2]=0.0,s[38,3]=-0.4,s[38,4]=-0.6,s[38,5]=1.1,s[38,6]=0.4,s[38,7]=1.2,s[38,8]=0.1,s[38,9]=-0.6,s[38,10]=0.5,s[38,11]=-0.8,s[38,12]=-0.9,s[38,13]=0.2,s[38,14]=-0.7,s[38,15]=-0.7 s[38,16]=0.2,s[38,17]=0.0,s[38,18]=1.0,s[38,19]=1.0,s[38,20]=1.2,s[38,21]=0.8,s[38,22]=0.4,s[38,23]=-1.0,s[38,24]=-0.1,s[38,25]=-0.2,s[38,26]=0.6,s[38,27]=0.5,s[38,28]=0.2,s[38,29]=-0.8,s[38,30]=1.0 s[38,31]=-0.5,s[38,32]=1.1,s[38,33]=-0.9,s[38,34]=-0.2,s[38,35]=0.4,s[38,36]=0.0,s[38,37]=-0.3,s[38,38]=-0.6,s[38,39]=-0.8,s[38,40]=-1.2,s[38,41]=-0.2,s[38,42]=-0.7,s[38,43]=-0.6,s[38,44]=-0.2,s[38,45]=-0.7 s[38,46]=0.0,s[38,47]=-1.2,s[38,48]=-0.4,s[38,49]=-0.2,s[38,50]=0.6,s[38,51]=0.1,s[38,52]=0.8,s[38,53]=-0.3,s[38,54]=0.4,s[38,55]=-0.7,s[38,56]=-1.0,s[38,57]=-0.5,s[38,58]=0.8,s[38,59]=-0.8,s[38,60]=-0.2 s[39,1]=-0.6,s[39,2]=0.8,s[39,3]=-0.9,s[39,4]=0.1,s[39,5]=0.0,s[39,6]=0.8,s[39,7]=0.3,s[39,8]=-0.8,s[39,9]=0.2,s[39,10]=0.7,s[39,11]=0.0,s[39,12]=0.7,s[39,13]=1.2,s[39,14]=-1.1,s[39,15]=0.4 s[39,16]=0.9,s[39,17]=-1.0,s[39,18]=1.2,s[39,19]=-0.5,s[39,20]=-0.8,s[39,21]=0.1,s[39,22]=-1.1,s[39,23]=0.6,s[39,24]=0.8,s[39,25]=-0.6,s[39,26]=-0.6,s[39,27]=1.0,s[39,28]=-0.6,s[39,29]=0.8,s[39,30]=0.2 s[39,31]=0.9,s[39,32]=-0.9,s[39,33]=0.5,s[39,34]=-1.2,s[39,35]=1.1,s[39,36]=0.1,s[39,37]=1.2,s[39,38]=1.2,s[39,39]=-0.5,s[39,40]=0.7,s[39,41]=1.0,s[39,42]=0.9,s[39,43]=-0.4,s[39,44]=-0.6,s[39,45]=0.5 s[39,46]=0.4,s[39,47]=-0.8,s[39,48]=0.5,s[39,49]=-0.8,s[39,50]=-0.2,s[39,51]=1.1,s[39,52]=1.1,s[39,53]=-0.8,s[39,54]=-1.2,s[39,55]=-0.5,s[39,56]=-0.4,s[39,57]=0.1,s[39,58]=0.8,s[39,59]=-0.9,s[39,60]=0.1 s[40,1]=0.0,s[40,2]=0.8,s[40,3]=0.3,s[40,4]=-0.7,s[40,5]=0.3,s[40,6]=0.0,s[40,7]=-1.2,s[40,8]=0.3,s[40,9]=-0.8,s[40,10]=-0.2,s[40,11]=0.4,s[40,12]=-0.6,s[40,13]=-0.9,s[40,14]=-0.2,s[40,15]=-0.9 s[40,16]=-0.4,s[40,17]=-0.4,s[40,18]=-0.9,s[40,19]=0.1,s[40,20]=-1.2,s[40,21]=1.2,s[40,22]=-0.3,s[40,23]=-0.4,s[40,24]=-0.1,s[40,25]=-0.9,s[40,26]=-1.0,s[40,27]=0.8,s[40,28]=0.8,s[40,29]=-0.6,s[40,30]=-0.9 s[40,31]=0.9,s[40,32]=-1.1,s[40,33]=-0.5,s[40,34]=-0.3,s[40,35]=-0.9,s[40,36]=0.6,s[40,37]=0.9,s[40,38]=0.9,s[40,39]=-0.9,s[40,40]=1.2,s[40,41]=-0.9,s[40,42]=-1.2,s[40,43]=0.5,s[40,44]=-0.1,s[40,45]=0.9 s[40,46]=-1.0,s[40,47]=1.2,s[40,48]=-0.7,s[40,49]=-0.9,s[40,50]=1.1,s[40,51]=0.1,s[40,52]=-0.6,s[40,53]=0.9,s[40,54]=0.7,s[40,55]=0.0,s[40,56]=-0.2,s[40,57]=-1.0,s[40,58]=0.6,s[40,59]=1.1,s[40,60]=-0.7 s[41,1]=-0.6,s[41,2]=-0.9,s[41,3]=-0.9,s[41,4]=-0.3,s[41,5]=-0.6,s[41,6]=-0.4,s[41,7]=0.8,s[41,8]=0.4,s[41,9]=0.8,s[41,10]=-0.7,s[41,11]=-0.4,s[41,12]=-0.4,s[41,13]=-0.1,s[41,14]=0.6,s[41,15]=0.3 s[41,16]=0.2,s[41,17]=-1.0,s[41,18]=0.7,s[41,19]=-1.1,s[41,20]=0.8,s[41,21]=-0.1,s[41,22]=-0.1,s[41,23]=-0.8,s[41,24]=-0.4,s[41,25]=0.7,s[41,26]=-1.1,s[41,27]=0.6,s[41,28]=-0.3,s[41,29]=0.1,s[41,30]=0.3 s[41,31]=1.2,s[41,32]=-0.4,s[41,33]=0.6,s[41,34]=-1.2,s[41,35]=-0.2,s[41,36]=0.4,s[41,37]=-0.7,s[41,38]=0.6,s[41,39]=0.7,s[41,40]=0.8,s[41,41]=0.7,s[41,42]=-0.6,s[41,43]=-0.2,s[41,44]=0.1,s[41,45]=-0.3 s[41,46]=0.4,s[41,47]=1.2,s[41,48]=-1.1,s[41,49]=-0.1,s[41,50]=-0.7,s[41,51]=0.4,s[41,52]=-0.3,s[41,53]=-0.2,s[41,54]=-0.2,s[41,55]=-0.7,s[41,56]=-1.1,s[41,57]=0.2,s[41,58]=0.5,s[41,59]=0.5,s[41,60]=-0.2 s[42,1]=0.1,s[42,2]=-0.2,s[42,3]=-0.2,s[42,4]=-0.6,s[42,5]=0.6,s[42,6]=-1.0,s[42,7]=1.0,s[42,8]=0.7,s[42,9]=-1.1,s[42,10]=-1.2,s[42,11]=-0.3,s[42,12]=-1.1,s[42,13]=-0.7,s[42,14]=0.3,s[42,15]=-0.1 s[42,16]=-0.5,s[42,17]=-1.2,s[42,18]=0.6,s[42,19]=0.9,s[42,20]=-0.5,s[42,21]=0.3,s[42,22]=-1.1,s[42,23]=-0.9,s[42,24]=-0.1,s[42,25]=-0.1,s[42,26]=0.9,s[42,27]=0.7,s[42,28]=0.4,s[42,29]=-0.4,s[42,30]=-0.3 s[42,31]=-0.9,s[42,32]=1.1,s[42,33]=0.3,s[42,34]=-0.1,s[42,35]=-1.0,s[42,36]=0.7,s[42,37]=-0.5,s[42,38]=1.2,s[42,39]=-0.6,s[42,40]=1.2,s[42,41]=-1.0,s[42,42]=-0.8,s[42,43]=-0.9,s[42,44]=0.1,s[42,45]=-0.3 s[42,46]=-0.4,s[42,47]=1.1,s[42,48]=0.6,s[42,49]=-1.2,s[42,50]=-0.3,s[42,51]=0.0,s[42,52]=-0.2,s[42,53]=0.1,s[42,54]=-0.9,s[42,55]=0.5,s[42,56]=0.1,s[42,57]=0.0,s[42,58]=-1.1,s[42,59]=-0.1,s[42,60]=-1.2 s[43,1]=1.0,s[43,2]=-0.9,s[43,3]=-0.9,s[43,4]=0.5,s[43,5]=-0.8,s[43,6]=-1.1,s[43,7]=-1.1,s[43,8]=-1.2,s[43,9]=0.9,s[43,10]=1.2,s[43,11]=1.0,s[43,12]=-0.9,s[43,13]=-1.1,s[43,14]=-0.9,s[43,15]=0.1 s[43,16]=0.5,s[43,17]=0.2,s[43,18]=-0.6,s[43,19]=0.6,s[43,20]=-1.1,s[43,21]=-0.1,s[43,22]=0.0,s[43,23]=-1.0,s[43,24]=-0.7,s[43,25]=1.1,s[43,26]=-0.6,s[43,27]=0.1,s[43,28]=0.9,s[43,29]=1.1,s[43,30]=0.9 s[43,31]=1.1,s[43,32]=0.4,s[43,33]=1.1,s[43,34]=-0.1,s[43,35]=-0.7,s[43,36]=-0.4,s[43,37]=-0.6,s[43,38]=0.1,s[43,39]=0.6,s[43,40]=-0.6,s[43,41]=-0.2,s[43,42]=0.1,s[43,43]=-0.8,s[43,44]=0.3,s[43,45]=1.2 s[43,46]=0.6,s[43,47]=-1.0,s[43,48]=1.1,s[43,49]=0.3,s[43,50]=-0.7,s[43,51]=0.0,s[43,52]=-0.1,s[43,53]=1.2,s[43,54]=-0.2,s[43,55]=-1.0,s[43,56]=-0.2,s[43,57]=0.1,s[43,58]=0.9,s[43,59]=-1.2,s[43,60]=0.1 s[44,1]=1.0,s[44,2]=-1.0,s[44,3]=0.9,s[44,4]=-1.2,s[44,5]=0.5,s[44,6]=0.3,s[44,7]=-0.1,s[44,8]=-0.1,s[44,9]=-0.8,s[44,10]=1.0,s[44,11]=-0.3,s[44,12]=1.0,s[44,13]=-0.2,s[44,14]=1.1,s[44,15]=-0.7 s[44,16]=-0.8,s[44,17]=-0.6,s[44,18]=-1.0,s[44,19]=0.1,s[44,20]=0.1,s[44,21]=0.3,s[44,22]=1.2,s[44,23]=0.9,s[44,24]=0.5,s[44,25]=0.2,s[44,26]=0.8,s[44,27]=-0.5,s[44,28]=-0.6,s[44,29]=-0.3,s[44,30]=-0.3 s[44,31]=-0.1,s[44,32]=0.7,s[44,33]=0.7,s[44,34]=-0.3,s[44,35]=0.3,s[44,36]=-1.1,s[44,37]=-1.1,s[44,38]=-0.1,s[44,39]=-1.1,s[44,40]=-0.9,s[44,41]=-1.1,s[44,42]=-0.5,s[44,43]=1.0,s[44,44]=0.5,s[44,45]=0.0 s[44,46]=-0.5,s[44,47]=-0.5,s[44,48]=0.6,s[44,49]=-0.8,s[44,50]=-0.3,s[44,51]=1.1,s[44,52]=-0.5,s[44,53]=-0.5,s[44,54]=0.4,s[44,55]=-1.2,s[44,56]=0.1,s[44,57]=0.4,s[44,58]=0.0,s[44,59]=-1.1,s[44,60]=-1.2 s[45,1]=-1.0,s[45,2]=0.5,s[45,3]=1.2,s[45,4]=-0.6,s[45,5]=-0.1,s[45,6]=-0.4,s[45,7]=0.8,s[45,8]=-0.8,s[45,9]=0.6,s[45,10]=-0.2,s[45,11]=0.2,s[45,12]=0.1,s[45,13]=0.2,s[45,14]=0.5,s[45,15]=0.6 s[45,16]=1.1,s[45,17]=0.4,s[45,18]=-0.4,s[45,19]=-0.1,s[45,20]=0.2,s[45,21]=0.8,s[45,22]=0.0,s[45,23]=-0.9,s[45,24]=-0.6,s[45,25]=0.1,s[45,26]=0.1,s[45,27]=-1.0,s[45,28]=1.0,s[45,29]=-0.4,s[45,30]=0.1 s[45,31]=0.0,s[45,32]=-0.4,s[45,33]=1.1,s[45,34]=-1.2,s[45,35]=0.6,s[45,36]=-0.8,s[45,37]=-0.1,s[45,38]=0.5,s[45,39]=1.2,s[45,40]=0.9,s[45,41]=0.9,s[45,42]=0.7,s[45,43]=0.5,s[45,44]=0.2,s[45,45]=-0.3 s[45,46]=0.2,s[45,47]=-1.2,s[45,48]=-1.1,s[45,49]=-0.2,s[45,50]=0.6,s[45,51]=-1.2,s[45,52]=-0.7,s[45,53]=-1.2,s[45,54]=0.4,s[45,55]=0.1,s[45,56]=-0.6,s[45,57]=0.8,s[45,58]=0.4,s[45,59]=1.0,s[45,60]=-0.7 s[46,1]=-0.4,s[46,2]=0.4,s[46,3]=0.6,s[46,4]=-0.6,s[46,5]=-0.4,s[46,6]=-1.1,s[46,7]=-0.2,s[46,8]=-0.9,s[46,9]=0.0,s[46,10]=0.3,s[46,11]=-0.1,s[46,12]=0.8,s[46,13]=-0.9,s[46,14]=0.5,s[46,15]=-0.7 s[46,16]=0.7,s[46,17]=-0.5,s[46,18]=-1.2,s[46,19]=-0.1,s[46,20]=1.1,s[46,21]=-1.2,s[46,22]=-0.6,s[46,23]=1.1,s[46,24]=0.4,s[46,25]=-0.7,s[46,26]=0.4,s[46,27]=1.2,s[46,28]=-1.1,s[46,29]=-0.2,s[46,30]=-0.8 s[46,31]=-0.3,s[46,32]=-0.6,s[46,33]=0.0,s[46,34]=-0.7,s[46,35]=-0.6,s[46,36]=-0.8,s[46,37]=-1.2,s[46,38]=-0.7,s[46,39]=0.2,s[46,40]=0.4,s[46,41]=-0.3,s[46,42]=1.2,s[46,43]=-0.9,s[46,44]=-0.8,s[46,45]=1.0 s[46,46]=-0.6,s[46,47]=-0.1,s[46,48]=-0.9,s[46,49]=0.0,s[46,50]=0.2,s[46,51]=0.5,s[46,52]=-0.8,s[46,53]=-0.7,s[46,54]=0.2,s[46,55]=-0.6,s[46,56]=0.5,s[46,57]=0.3,s[46,58]=-0.3,s[46,59]=-0.2,s[46,60]=-0.1 s[47,1]=0.4,s[47,2]=-0.5,s[47,3]=0.4,s[47,4]=-0.1,s[47,5]=0.8,s[47,6]=-0.1,s[47,7]=-1.1,s[47,8]=0.2,s[47,9]=0.8,s[47,10]=1.1,s[47,11]=-0.1,s[47,12]=-1.2,s[47,13]=0.2,s[47,14]=1.1,s[47,15]=-0.5 s[47,16]=-0.1,s[47,17]=-1.0,s[47,18]=-0.1,s[47,19]=0.3,s[47,20]=0.1,s[47,21]=1.0,s[47,22]=-0.2,s[47,23]=1.1,s[47,24]=0.9,s[47,25]=-0.6,s[47,26]=0.8,s[47,27]=-0.6,s[47,28]=-1.2,s[47,29]=0.3,s[47,30]=0.0 s[47,31]=1.1,s[47,32]=0.2,s[47,33]=1.0,s[47,34]=0.0,s[47,35]=0.6,s[47,36]=0.8,s[47,37]=-0.3,s[47,38]=-0.8,s[47,39]=0.6,s[47,40]=0.1,s[47,41]=-0.7,s[47,42]=-1.0,s[47,43]=-0.5,s[47,44]=-0.5,s[47,45]=-0.3 s[47,46]=-0.5,s[47,47]=-0.6,s[47,48]=0.9,s[47,49]=1.2,s[47,50]=-0.2,s[47,51]=0.0,s[47,52]=-0.1,s[47,53]=-1.1,s[47,54]=0.6,s[47,55]=-0.9,s[47,56]=1.1,s[47,57]=-1.1,s[47,58]=-0.1,s[47,59]=-0.4,s[47,60]=-0.3 s[48,1]=1.2,s[48,2]=-1.2,s[48,3]=-0.7,s[48,4]=-1.0,s[48,5]=-0.1,s[48,6]=0.2,s[48,7]=0.6,s[48,8]=1.2,s[48,9]=1.0,s[48,10]=-0.5,s[48,11]=0.1,s[48,12]=0.6,s[48,13]=0.3,s[48,14]=0.3,s[48,15]=-0.3 s[48,16]=1.0,s[48,17]=0.0,s[48,18]=-1.2,s[48,19]=-0.4,s[48,20]=0.7,s[48,21]=-0.7,s[48,22]=-0.7,s[48,23]=0.4,s[48,24]=0.4,s[48,25]=-0.3,s[48,26]=-1.2,s[48,27]=-0.6,s[48,28]=-0.5,s[48,29]=1.1,s[48,30]=0.5 s[48,31]=-0.1,s[48,32]=-0.8,s[48,33]=-1.2,s[48,34]=-0.5,s[48,35]=0.2,s[48,36]=0.2,s[48,37]=-0.4,s[48,38]=-0.4,s[48,39]=-1.2,s[48,40]=-0.1,s[48,41]=0.3,s[48,42]=0.1,s[48,43]=0.3,s[48,44]=-0.2,s[48,45]=1.0 s[48,46]=-0.6,s[48,47]=0.6,s[48,48]=0.6,s[48,49]=1.2,s[48,50]=-1.2,s[48,51]=-1.1,s[48,52]=-0.7,s[48,53]=-0.4,s[48,54]=-0.1,s[48,55]=-0.7,s[48,56]=-0.9,s[48,57]=0.3,s[48,58]=0.9,s[48,59]=0.6,s[48,60]=-0.5 s[49,1]=-0.2,s[49,2]=-0.3,s[49,3]=0.2,s[49,4]=-0.3,s[49,5]=-0.8,s[49,6]=-0.9,s[49,7]=-0.5,s[49,8]=-0.4,s[49,9]=-1.1,s[49,10]=0.9,s[49,11]=0.3,s[49,12]=-0.3,s[49,13]=-0.7,s[49,14]=-0.5,s[49,15]=0.6 s[49,16]=0.1,s[49,17]=-0.3,s[49,18]=0.0,s[49,19]=-0.5,s[49,20]=0.7,s[49,21]=0.0,s[49,22]=0.6,s[49,23]=-0.7,s[49,24]=1.2,s[49,25]=-1.1,s[49,26]=-0.8,s[49,27]=0.7,s[49,28]=0.9,s[49,29]=-1.2,s[49,30]=-0.2 s[49,31]=0.9,s[49,32]=0.3,s[49,33]=-1.2,s[49,34]=-1.1,s[49,35]=0.7,s[49,36]=1.0,s[49,37]=-1.2,s[49,38]=-1.1,s[49,39]=1.2,s[49,40]=0.0,s[49,41]=-0.9,s[49,42]=0.8,s[49,43]=-0.3,s[49,44]=-1.1,s[49,45]=-0.7 s[49,46]=-0.9,s[49,47]=1.2,s[49,48]=0.4,s[49,49]=0.2,s[49,50]=-1.2,s[49,51]=1.1,s[49,52]=-1.1,s[49,53]=-0.3,s[49,54]=-0.5,s[49,55]=-0.6,s[49,56]=0.2,s[49,57]=-0.5,s[49,58]=-0.6,s[49,59]=-0.8,s[49,60]=-0.2 s[50,1]=0.5,s[50,2]=-0.2,s[50,3]=-0.5,s[50,4]=-0.8,s[50,5]=1.2,s[50,6]=-0.4,s[50,7]=-0.6,s[50,8]=-0.8,s[50,9]=-0.8,s[50,10]=1.2,s[50,11]=0.1,s[50,12]=0.3,s[50,13]=0.4,s[50,14]=0.3,s[50,15]=-0.3 s[50,16]=-1.1,s[50,17]=-0.9,s[50,18]=0.5,s[50,19]=1.1,s[50,20]=-1.2,s[50,21]=0.2,s[50,22]=-0.7,s[50,23]=0.7,s[50,24]=-0.7,s[50,25]=0.1,s[50,26]=-0.4,s[50,27]=-0.5,s[50,28]=1.2,s[50,29]=-0.1,s[50,30]=-1.0 s[50,31]=0.8,s[50,32]=-0.3,s[50,33]=0.0,s[50,34]=-0.5,s[50,35]=-0.6,s[50,36]=-0.2,s[50,37]=0.3,s[50,38]=0.1,s[50,39]=-0.9,s[50,40]=-0.1,s[50,41]=0.6,s[50,42]=0.7,s[50,43]=0.8,s[50,44]=-0.4,s[50,45]=-0.2 s[50,46]=0.6,s[50,47]=-0.5,s[50,48]=1.1,s[50,49]=-0.4,s[50,50]=0.4,s[50,51]=0.9,s[50,52]=-0.2,s[50,53]=-1.2,s[50,54]=-0.2,s[50,55]=0.0,s[50,56]=-0.1,s[50,57]=0.0,s[50,58]=0.5,s[50,59]=0.0,s[50,60]=-1.1 s[51,1]=-0.3,s[51,2]=0.1,s[51,3]=-0.1,s[51,4]=-0.5,s[51,5]=0.4,s[51,6]=-0.5,s[51,7]=0.4,s[51,8]=-0.5,s[51,9]=1.0,s[51,10]=0.4,s[51,11]=0.2,s[51,12]=0.8,s[51,13]=-0.4,s[51,14]=0.7,s[51,15]=-0.7 s[51,16]=-0.6,s[51,17]=-0.1,s[51,18]=-0.1,s[51,19]=-0.3,s[51,20]=-1.0,s[51,21]=-0.8,s[51,22]=1.2,s[51,23]=0.7,s[51,24]=-0.9,s[51,25]=0.4,s[51,26]=1.0,s[51,27]=0.1,s[51,28]=-0.1,s[51,29]=1.2,s[51,30]=0.7 s[51,31]=0.7,s[51,32]=1.0,s[51,33]=1.0,s[51,34]=-0.5,s[51,35]=-1.1,s[51,36]=-0.5,s[51,37]=-0.5,s[51,38]=-0.4,s[51,39]=-0.9,s[51,40]=1.2,s[51,41]=-0.7,s[51,42]=0.6,s[51,43]=0.3,s[51,44]=0.4,s[51,45]=0.1 s[51,46]=-0.2,s[51,47]=-0.5,s[51,48]=1.0,s[51,49]=-0.7,s[51,50]=0.6,s[51,51]=-0.4,s[51,52]=0.9,s[51,53]=0.0,s[51,54]=-0.1,s[51,55]=-0.9,s[51,56]=1.2,s[51,57]=1.1,s[51,58]=0.7,s[51,59]=-0.3,s[51,60]=-0.3 s[52,1]=-0.6,s[52,2]=-0.8,s[52,3]=-1.1,s[52,4]=-0.9,s[52,5]=-1.1,s[52,6]=1.0,s[52,7]=1.0,s[52,8]=-1.1,s[52,9]=0.5,s[52,10]=-1.0,s[52,11]=1.0,s[52,12]=1.2,s[52,13]=-0.7,s[52,14]=-0.1,s[52,15]=0.0 s[52,16]=0.4,s[52,17]=-0.7,s[52,18]=0.4,s[52,19]=-1.2,s[52,20]=0.2,s[52,21]=0.0,s[52,22]=0.9,s[52,23]=-0.3,s[52,24]=1.0,s[52,25]=-1.0,s[52,26]=-0.1,s[52,27]=-0.5,s[52,28]=0.9,s[52,29]=0.6,s[52,30]=0.6 s[52,31]=-0.4,s[52,32]=0.8,s[52,33]=0.5,s[52,34]=-0.4,s[52,35]=0.3,s[52,36]=1.2,s[52,37]=-0.8,s[52,38]=0.2,s[52,39]=0.2,s[52,40]=-0.5,s[52,41]=0.4,s[52,42]=0.6,s[52,43]=-0.8,s[52,44]=-0.2,s[52,45]=-1.2 s[52,46]=-1.2,s[52,47]=-1.1,s[52,48]=0.3,s[52,49]=1.2,s[52,50]=-1.1,s[52,51]=-0.1,s[52,52]=1.1,s[52,53]=0.5,s[52,54]=0.0,s[52,55]=0.0,s[52,56]=0.6,s[52,57]=-0.7,s[52,58]=-0.8,s[52,59]=-0.1,s[52,60]=0.4 s[53,1]=1.0,s[53,2]=0.3,s[53,3]=0.2,s[53,4]=-0.7,s[53,5]=-0.7,s[53,6]=0.9,s[53,7]=-0.7,s[53,8]=-0.1,s[53,9]=-0.8,s[53,10]=0.6,s[53,11]=-0.2,s[53,12]=-0.2,s[53,13]=0.1,s[53,14]=-0.9,s[53,15]=-1.2 s[53,16]=-1.2,s[53,17]=-1.1,s[53,18]=0.2,s[53,19]=-1.0,s[53,20]=0.1,s[53,21]=1.2,s[53,22]=-0.2,s[53,23]=-1.1,s[53,24]=0.7,s[53,25]=0.9,s[53,26]=0.6,s[53,27]=-0.2,s[53,28]=0.6,s[53,29]=0.4,s[53,30]=0.2 s[53,31]=-1.1,s[53,32]=0.1,s[53,33]=1.2,s[53,34]=-0.4,s[53,35]=1.0,s[53,36]=-1.0,s[53,37]=-0.6,s[53,38]=0.3,s[53,39]=-0.7,s[53,40]=0.6,s[53,41]=-0.5,s[53,42]=-1.1,s[53,43]=0.0,s[53,44]=-0.3,s[53,45]=-1.1 s[53,46]=0.6,s[53,47]=-1.1,s[53,48]=0.9,s[53,49]=-0.8,s[53,50]=0.3,s[53,51]=-0.1,s[53,52]=-0.1,s[53,53]=0.7,s[53,54]=-0.8,s[53,55]=-1.0,s[53,56]=0.0,s[53,57]=-0.9,s[53,58]=-1.1,s[53,59]=0.4,s[53,60]=-0.9 s[54,1]=0.1,s[54,2]=-0.1,s[54,3]=0.9,s[54,4]=-1.0,s[54,5]=1.1,s[54,6]=0.1,s[54,7]=0.0,s[54,8]=-1.2,s[54,9]=-1.1,s[54,10]=-0.1,s[54,11]=0.1,s[54,12]=1.2,s[54,13]=-0.4,s[54,14]=0.8,s[54,15]=0.4 s[54,16]=1.2,s[54,17]=0.1,s[54,18]=-0.7,s[54,19]=-0.8,s[54,20]=1.0,s[54,21]=1.0,s[54,22]=-0.7,s[54,23]=-1.2,s[54,24]=0.7,s[54,25]=-1.1,s[54,26]=0.9,s[54,27]=0.9,s[54,28]=0.3,s[54,29]=0.4,s[54,30]=-0.9 s[54,31]=0.4,s[54,32]=1.0,s[54,33]=1.1,s[54,34]=-0.8,s[54,35]=-0.9,s[54,36]=-0.4,s[54,37]=-0.9,s[54,38]=0.6,s[54,39]=1.2,s[54,40]=0.7,s[54,41]=0.7,s[54,42]=1.0,s[54,43]=0.8,s[54,44]=-1.1,s[54,45]=-0.3 s[54,46]=-0.3,s[54,47]=1.0,s[54,48]=-0.9,s[54,49]=0.5,s[54,50]=1.2,s[54,51]=1.0,s[54,52]=0.4,s[54,53]=-1.2,s[54,54]=-0.5,s[54,55]=0.0,s[54,56]=-0.4,s[54,57]=1.2,s[54,58]=-0.5,s[54,59]=-0.4,s[54,60]=-0.1 s[55,1]=-0.3,s[55,2]=1.0,s[55,3]=-0.4,s[55,4]=0.0,s[55,5]=-1.2,s[55,6]=0.2,s[55,7]=-0.9,s[55,8]=0.1,s[55,9]=-0.3,s[55,10]=1.2,s[55,11]=-0.8,s[55,12]=1.2,s[55,13]=1.2,s[55,14]=-0.1,s[55,15]=-0.5 s[55,16]=-1.1,s[55,17]=1.1,s[55,18]=-0.8,s[55,19]=-0.9,s[55,20]=-1.1,s[55,21]=-0.9,s[55,22]=-0.4,s[55,23]=0.6,s[55,24]=0.4,s[55,25]=0.7,s[55,26]=0.2,s[55,27]=-0.9,s[55,28]=1.0,s[55,29]=-0.1,s[55,30]=0.1 s[55,31]=1.0,s[55,32]=-1.0,s[55,33]=0.9,s[55,34]=-0.4,s[55,35]=0.0,s[55,36]=-0.8,s[55,37]=-1.1,s[55,38]=-0.9,s[55,39]=1.1,s[55,40]=-0.1,s[55,41]=0.5,s[55,42]=0.4,s[55,43]=0.5,s[55,44]=0.7,s[55,45]=1.2 s[55,46]=-0.7,s[55,47]=-0.3,s[55,48]=0.1,s[55,49]=0.4,s[55,50]=1.1,s[55,51]=0.6,s[55,52]=0.8,s[55,53]=-0.5,s[55,54]=-0.2,s[55,55]=0.7,s[55,56]=-0.8,s[55,57]=-0.4,s[55,58]=-0.2,s[55,59]=-0.4,s[55,60]=-1.0 s[56,1]=-0.5,s[56,2]=0.5,s[56,3]=0.6,s[56,4]=-1.1,s[56,5]=-0.5,s[56,6]=1.2,s[56,7]=0.6,s[56,8]=-1.0,s[56,9]=0.2,s[56,10]=0.4,s[56,11]=0.1,s[56,12]=-0.6,s[56,13]=-0.4,s[56,14]=-0.8,s[56,15]=-1.2 s[56,16]=0.2,s[56,17]=1.1,s[56,18]=-0.4,s[56,19]=0.0,s[56,20]=-0.8,s[56,21]=1.2,s[56,22]=-0.2,s[56,23]=0.0,s[56,24]=-0.5,s[56,25]=0.2,s[56,26]=0.9,s[56,27]=0.0,s[56,28]=0.6,s[56,29]=0.6,s[56,30]=-0.2 s[56,31]=1.1,s[56,32]=0.4,s[56,33]=1.1,s[56,34]=0.0,s[56,35]=0.6,s[56,36]=1.1,s[56,37]=-0.1,s[56,38]=-0.5,s[56,39]=1.2,s[56,40]=0.3,s[56,41]=-0.5,s[56,42]=-0.5,s[56,43]=0.8,s[56,44]=0.7,s[56,45]=-0.1 s[56,46]=-1.2,s[56,47]=-0.1,s[56,48]=-0.2,s[56,49]=1.1,s[56,50]=0.6,s[56,51]=-0.9,s[56,52]=-0.7,s[56,53]=0.5,s[56,54]=-1.2,s[56,55]=1.0,s[56,56]=1.1,s[56,57]=0.0,s[56,58]=-0.5,s[56,59]=0.0,s[56,60]=-1.2 s[57,1]=-0.5,s[57,2]=-1.2,s[57,3]=-0.7,s[57,4]=-0.4,s[57,5]=0.1,s[57,6]=0.0,s[57,7]=-0.5,s[57,8]=0.9,s[57,9]=0.0,s[57,10]=-0.7,s[57,11]=0.6,s[57,12]=-1.0,s[57,13]=0.2,s[57,14]=-0.5,s[57,15]=0.2 s[57,16]=-0.2,s[57,17]=-1.0,s[57,18]=-0.2,s[57,19]=0.3,s[57,20]=0.4,s[57,21]=-1.0,s[57,22]=0.7,s[57,23]=0.1,s[57,24]=0.1,s[57,25]=-1.0,s[57,26]=0.1,s[57,27]=-0.5,s[57,28]=-0.1,s[57,29]=-0.4,s[57,30]=-0.1 s[57,31]=0.5,s[57,32]=-0.4,s[57,33]=-1.0,s[57,34]=0.0,s[57,35]=0.3,s[57,36]=0.2,s[57,37]=-0.6,s[57,38]=-0.8,s[57,39]=1.1,s[57,40]=1.0,s[57,41]=0.1,s[57,42]=-1.1,s[57,43]=-0.1,s[57,44]=0.6,s[57,45]=-1.1 s[57,46]=-1.1,s[57,47]=-1.1,s[57,48]=1.2,s[57,49]=-0.2,s[57,50]=-0.1,s[57,51]=-0.5,s[57,52]=-1.0,s[57,53]=-0.5,s[57,54]=0.0,s[57,55]=0.9,s[57,56]=0.5,s[57,57]=-0.5,s[57,58]=-1.0,s[57,59]=0.6,s[57,60]=-0.4 s[58,1]=1.2,s[58,2]=0.3,s[58,3]=-0.7,s[58,4]=-1.2,s[58,5]=0.9,s[58,6]=0.6,s[58,7]=-0.3,s[58,8]=0.0,s[58,9]=0.8,s[58,10]=-0.2,s[58,11]=0.6,s[58,12]=-1.1,s[58,13]=-0.9,s[58,14]=-1.0,s[58,15]=-0.4 s[58,16]=0.8,s[58,17]=0.5,s[58,18]=0.1,s[58,19]=0.3,s[58,20]=-1.2,s[58,21]=1.0,s[58,22]=0.4,s[58,23]=0.0,s[58,24]=1.1,s[58,25]=-0.3,s[58,26]=-0.2,s[58,27]=0.3,s[58,28]=1.2,s[58,29]=-0.6,s[58,30]=-0.4 s[58,31]=-0.9,s[58,32]=0.9,s[58,33]=-0.8,s[58,34]=-0.4,s[58,35]=0.2,s[58,36]=1.0,s[58,37]=-0.1,s[58,38]=0.5,s[58,39]=-0.4,s[58,40]=0.1,s[58,41]=-0.7,s[58,42]=-0.6,s[58,43]=0.9,s[58,44]=0.3,s[58,45]=0.8 s[58,46]=-0.6,s[58,47]=1.1,s[58,48]=1.2,s[58,49]=0.0,s[58,50]=0.5,s[58,51]=-0.4,s[58,52]=-0.8,s[58,53]=-1.0,s[58,54]=-1.2,s[58,55]=1.1,s[58,56]=-1.1,s[58,57]=-0.5,s[58,58]=-1.0,s[58,59]=-1.1,s[58,60]=-0.8 s[59,1]=0.4,s[59,2]=-1.2,s[59,3]=0.1,s[59,4]=-1.1,s[59,5]=-0.6,s[59,6]=0.3,s[59,7]=1.1,s[59,8]=-0.8,s[59,9]=-0.1,s[59,10]=0.6,s[59,11]=0.3,s[59,12]=0.2,s[59,13]=0.4,s[59,14]=-0.8,s[59,15]=1.0 s[59,16]=0.7,s[59,17]=0.3,s[59,18]=1.2,s[59,19]=0.3,s[59,20]=-0.4,s[59,21]=-0.2,s[59,22]=-1.1,s[59,23]=0.9,s[59,24]=0.7,s[59,25]=-0.6,s[59,26]=-0.4,s[59,27]=-0.7,s[59,28]=-0.3,s[59,29]=-1.0,s[59,30]=0.5 s[59,31]=1.1,s[59,32]=0.6,s[59,33]=-0.3,s[59,34]=0.1,s[59,35]=-0.8,s[59,36]=0.0,s[59,37]=-0.1,s[59,38]=-0.4,s[59,39]=0.6,s[59,40]=0.4,s[59,41]=-0.8,s[59,42]=-0.3,s[59,43]=-0.6,s[59,44]=0.8,s[59,45]=-0.9 s[59,46]=-1.2,s[59,47]=0.7,s[59,48]=1.0,s[59,49]=0.1,s[59,50]=-0.4,s[59,51]=0.5,s[59,52]=1.1,s[59,53]=-0.7,s[59,54]=-0.4,s[59,55]=-0.8,s[59,56]=0.1,s[59,57]=0.8,s[59,58]=1.1,s[59,59]=0.3,s[59,60]=-0.5 s[60,1]=1.2,s[60,2]=-0.8,s[60,3]=-0.1,s[60,4]=-0.5,s[60,5]=-0.2,s[60,6]=-0.5,s[60,7]=0.8,s[60,8]=-0.7,s[60,9]=0.3,s[60,10]=0.3,s[60,11]=-0.3,s[60,12]=-0.3,s[60,13]=-0.7,s[60,14]=0.8,s[60,15]=-0.5 s[60,16]=0.0,s[60,17]=0.2,s[60,18]=0.0,s[60,19]=-1.1,s[60,20]=0.0,s[60,21]=0.8,s[60,22]=0.7,s[60,23]=0.3,s[60,24]=-1.2,s[60,25]=0.5,s[60,26]=0.9,s[60,27]=0.9,s[60,28]=-0.8,s[60,29]=-0.1,s[60,30]=-1.2 s[60,31]=-0.6,s[60,32]=0.2,s[60,33]=0.0,s[60,34]=-0.6,s[60,35]=-0.3,s[60,36]=0.9,s[60,37]=0.9,s[60,38]=-0.2,s[60,39]=0.8,s[60,40]=-0.8,s[60,41]=0.4,s[60,42]=-0.3,s[60,43]=-0.5,s[60,44]=-0.1,s[60,45]=1.0 s[60,46]=0.6,s[60,47]=0.0,s[60,48]=-0.5,s[60,49]=-1.0,s[60,50]=0.7,s[60,51]=0.5,s[60,52]=-0.5,s[60,53]=0.9,s[60,54]=-1.1,s[60,55]=-0.3,s[60,56]=0.0,s[60,57]=-0.8,s[60,58]=-1.0,s[60,59]=0.0,s[60,60]=-1.2 s[61,1]=0.0,s[61,2]=0.7,s[61,3]=0.9,s[61,4]=0.4,s[61,5]=-1.0,s[61,6]=0.3,s[61,7]=-1.2,s[61,8]=1.1,s[61,9]=-0.3,s[61,10]=0.1,s[61,11]=-0.8,s[61,12]=-0.3,s[61,13]=-0.1,s[61,14]=-1.1,s[61,15]=-0.3 s[61,16]=-0.8,s[61,17]=0.1,s[61,18]=-0.8,s[61,19]=0.2,s[61,20]=0.7,s[61,21]=0.0,s[61,22]=1.1,s[61,23]=-0.5,s[61,24]=0.8,s[61,25]=0.1,s[61,26]=-0.4,s[61,27]=1.0,s[61,28]=-0.5,s[61,29]=-0.8,s[61,30]=-0.2 s[61,31]=1.0,s[61,32]=1.2,s[61,33]=0.3,s[61,34]=-0.1,s[61,35]=0.3,s[61,36]=-1.2,s[61,37]=-1.1,s[61,38]=-0.9,s[61,39]=1.2,s[61,40]=0.4,s[61,41]=-0.8,s[61,42]=-0.9,s[61,43]=-0.6,s[61,44]=-0.9,s[61,45]=1.2 s[61,46]=0.0,s[61,47]=0.3,s[61,48]=-0.3,s[61,49]=0.4,s[61,50]=1.0,s[61,51]=0.1,s[61,52]=0.8,s[61,53]=1.1,s[61,54]=1.2,s[61,55]=0.8,s[61,56]=-0.8,s[61,57]=0.9,s[61,58]=-0.2,s[61,59]=0.5,s[61,60]=-1.1 s[62,1]=0.8,s[62,2]=-1.2,s[62,3]=-0.7,s[62,4]=0.3,s[62,5]=-0.6,s[62,6]=1.1,s[62,7]=-0.4,s[62,8]=-0.3,s[62,9]=-0.8,s[62,10]=0.7,s[62,11]=-0.9,s[62,12]=0.3,s[62,13]=0.7,s[62,14]=1.2,s[62,15]=-0.5 s[62,16]=-1.1,s[62,17]=-0.7,s[62,18]=1.0,s[62,19]=-0.1,s[62,20]=0.0,s[62,21]=-1.2,s[62,22]=-0.9,s[62,23]=-0.3,s[62,24]=-0.3,s[62,25]=-0.1,s[62,26]=1.0,s[62,27]=-1.0,s[62,28]=0.7,s[62,29]=1.1,s[62,30]=-0.4 s[62,31]=0.7,s[62,32]=-0.9,s[62,33]=-0.3,s[62,34]=-0.7,s[62,35]=0.4,s[62,36]=1.0,s[62,37]=0.5,s[62,38]=-0.2,s[62,39]=0.8,s[62,40]=0.9,s[62,41]=-1.2,s[62,42]=1.1,s[62,43]=0.4,s[62,44]=-0.9,s[62,45]=0.7 s[62,46]=-0.5,s[62,47]=-0.5,s[62,48]=-0.6,s[62,49]=-0.7,s[62,50]=0.8,s[62,51]=1.1,s[62,52]=-1.2,s[62,53]=-0.4,s[62,54]=-0.8,s[62,55]=-0.7,s[62,56]=0.2,s[62,57]=-0.2,s[62,58]=0.4,s[62,59]=-1.1,s[62,60]=-0.7 s[63,1]=-1.2,s[63,2]=0.9,s[63,3]=0.6,s[63,4]=-0.6,s[63,5]=-0.6,s[63,6]=0.9,s[63,7]=-0.3,s[63,8]=-0.8,s[63,9]=0.5,s[63,10]=0.5,s[63,11]=0.3,s[63,12]=-0.3,s[63,13]=1.0,s[63,14]=-0.2,s[63,15]=-0.3 s[63,16]=0.2,s[63,17]=-0.9,s[63,18]=0.2,s[63,19]=0.7,s[63,20]=0.4,s[63,21]=-0.8,s[63,22]=-1.0,s[63,23]=0.7,s[63,24]=0.4,s[63,25]=0.9,s[63,26]=0.4,s[63,27]=-0.2,s[63,28]=-0.7,s[63,29]=0.4,s[63,30]=-0.7 s[63,31]=1.0,s[63,32]=0.8,s[63,33]=0.3,s[63,34]=-1.1,s[63,35]=-0.1,s[63,36]=0.0,s[63,37]=0.0,s[63,38]=0.0,s[63,39]=0.0,s[63,40]=-0.4,s[63,41]=0.0,s[63,42]=-0.2,s[63,43]=0.4,s[63,44]=0.6,s[63,45]=0.8 s[63,46]=-0.5,s[63,47]=0.4,s[63,48]=-0.6,s[63,49]=-0.9,s[63,50]=-1.0,s[63,51]=-0.9,s[63,52]=-1.2,s[63,53]=0.1,s[63,54]=0.4,s[63,55]=-0.5,s[63,56]=0.1,s[63,57]=1.1,s[63,58]=-0.8,s[63,59]=-0.5,s[63,60]=-0.6 s[64,1]=-0.2,s[64,2]=0.2,s[64,3]=-0.3,s[64,4]=0.0,s[64,5]=0.4,s[64,6]=-1.0,s[64,7]=-0.1,s[64,8]=-0.9,s[64,9]=1.2,s[64,10]=-0.6,s[64,11]=-0.7,s[64,12]=-0.4,s[64,13]=1.1,s[64,14]=0.6,s[64,15]=-1.0 s[64,16]=0.7,s[64,17]=0.2,s[64,18]=-0.1,s[64,19]=-1.1,s[64,20]=0.8,s[64,21]=-0.7,s[64,22]=1.2,s[64,23]=0.6,s[64,24]=-0.9,s[64,25]=0.0,s[64,26]=-1.0,s[64,27]=-0.4,s[64,28]=-0.6,s[64,29]=0.1,s[64,30]=0.8 s[64,31]=-1.0,s[64,32]=1.2,s[64,33]=-0.2,s[64,34]=-1.1,s[64,35]=0.3,s[64,36]=-0.4,s[64,37]=0.7,s[64,38]=1.2,s[64,39]=0.1,s[64,40]=-0.6,s[64,41]=-0.1,s[64,42]=-0.4,s[64,43]=-0.5,s[64,44]=-1.0,s[64,45]=0.7 s[64,46]=1.1,s[64,47]=-0.1,s[64,48]=-0.1,s[64,49]=-0.7,s[64,50]=0.2,s[64,51]=-0.7,s[64,52]=0.1,s[64,53]=0.9,s[64,54]=0.7,s[64,55]=-1.0,s[64,56]=0.2,s[64,57]=0.0,s[64,58]=0.1,s[64,59]=0.9,s[64,60]=-1.0 s[65,1]=-1.1,s[65,2]=0.7,s[65,3]=-1.0,s[65,4]=-0.3,s[65,5]=-0.7,s[65,6]=0.6,s[65,7]=0.6,s[65,8]=-0.2,s[65,9]=-0.4,s[65,10]=0.5,s[65,11]=-0.9,s[65,12]=0.7,s[65,13]=0.0,s[65,14]=-1.2,s[65,15]=1.0 s[65,16]=-0.9,s[65,17]=-0.8,s[65,18]=0.6,s[65,19]=0.4,s[65,20]=0.4,s[65,21]=-1.2,s[65,22]=0.7,s[65,23]=0.4,s[65,24]=0.1,s[65,25]=-0.9,s[65,26]=0.1,s[65,27]=-0.2,s[65,28]=0.2,s[65,29]=0.4,s[65,30]=-0.2 s[65,31]=-0.1,s[65,32]=0.7,s[65,33]=0.8,s[65,34]=0.1,s[65,35]=-1.1,s[65,36]=0.0,s[65,37]=-0.2,s[65,38]=-1.0,s[65,39]=1.1,s[65,40]=0.7,s[65,41]=0.1,s[65,42]=-1.1,s[65,43]=0.8,s[65,44]=0.3,s[65,45]=-0.1 s[65,46]=-1.1,s[65,47]=0.1,s[65,48]=-0.8,s[65,49]=1.2,s[65,50]=-0.1,s[65,51]=-0.6,s[65,52]=0.8,s[65,53]=-0.1,s[65,54]=0.7,s[65,55]=1.1,s[65,56]=-0.3,s[65,57]=-0.7,s[65,58]=-0.3,s[65,59]=0.0,s[65,60]=-1.0 s[66,1]=0.1,s[66,2]=-0.3,s[66,3]=-0.5,s[66,4]=-0.9,s[66,5]=0.5,s[66,6]=-1.0,s[66,7]=0.3,s[66,8]=-0.7,s[66,9]=-0.7,s[66,10]=-0.4,s[66,11]=-0.4,s[66,12]=-0.4,s[66,13]=1.1,s[66,14]=-0.8,s[66,15]=-0.9 s[66,16]=0.7,s[66,17]=0.9,s[66,18]=-0.1,s[66,19]=0.5,s[66,20]=-0.1,s[66,21]=0.5,s[66,22]=0.8,s[66,23]=-0.6,s[66,24]=-0.4,s[66,25]=-0.1,s[66,26]=-0.7,s[66,27]=-0.7,s[66,28]=1.1,s[66,29]=-0.6,s[66,30]=-0.5 s[66,31]=0.6,s[66,32]=-0.7,s[66,33]=-0.2,s[66,34]=-0.5,s[66,35]=0.2,s[66,36]=0.3,s[66,37]=0.3,s[66,38]=-0.1,s[66,39]=0.8,s[66,40]=1.1,s[66,41]=0.3,s[66,42]=-1.1,s[66,43]=-0.2,s[66,44]=0.8,s[66,45]=-0.7 s[66,46]=0.1,s[66,47]=0.5,s[66,48]=0.4,s[66,49]=0.6,s[66,50]=1.2,s[66,51]=-0.4,s[66,52]=0.5,s[66,53]=-0.6,s[66,54]=0.9,s[66,55]=-0.2,s[66,56]=0.6,s[66,57]=-0.3,s[66,58]=-0.1,s[66,59]=0.0,s[66,60]=-1.2 s[67,1]=-0.3,s[67,2]=0.7,s[67,3]=-0.9,s[67,4]=-1.0,s[67,5]=-1.0,s[67,6]=0.5,s[67,7]=-0.9,s[67,8]=-1.2,s[67,9]=0.3,s[67,10]=0.8,s[67,11]=1.2,s[67,12]=-0.2,s[67,13]=0.1,s[67,14]=-0.6,s[67,15]=-1.1 s[67,16]=0.4,s[67,17]=0.1,s[67,18]=-1.1,s[67,19]=-0.6,s[67,20]=0.8,s[67,21]=-1.2,s[67,22]=-0.4,s[67,23]=-0.8,s[67,24]=1.2,s[67,25]=0.3,s[67,26]=0.3,s[67,27]=0.6,s[67,28]=0.9,s[67,29]=0.1,s[67,30]=-0.9 s[67,31]=1.0,s[67,32]=-0.9,s[67,33]=-0.6,s[67,34]=-1.1,s[67,35]=-0.9,s[67,36]=1.0,s[67,37]=-1.2,s[67,38]=0.2,s[67,39]=-0.7,s[67,40]=0.1,s[67,41]=0.6,s[67,42]=-0.7,s[67,43]=-0.5,s[67,44]=0.4,s[67,45]=-0.9 s[67,46]=-1.2,s[67,47]=-0.2,s[67,48]=-0.9,s[67,49]=1.2,s[67,50]=0.7,s[67,51]=0.3,s[67,52]=-1.2,s[67,53]=0.6,s[67,54]=0.2,s[67,55]=0.5,s[67,56]=1.1,s[67,57]=1.0,s[67,58]=1.2,s[67,59]=-0.1,s[67,60]=0.1 s[68,1]=0.8,s[68,2]=-1.0,s[68,3]=-1.0,s[68,4]=-0.7,s[68,5]=0.2,s[68,6]=0.3,s[68,7]=-0.7,s[68,8]=0.1,s[68,9]=0.9,s[68,10]=-0.8,s[68,11]=1.0,s[68,12]=-0.5,s[68,13]=1.0,s[68,14]=-0.9,s[68,15]=-0.1 s[68,16]=0.8,s[68,17]=1.0,s[68,18]=1.0,s[68,19]=-1.2,s[68,20]=-0.6,s[68,21]=-0.9,s[68,22]=0.6,s[68,23]=0.1,s[68,24]=0.4,s[68,25]=-1.2,s[68,26]=-0.2,s[68,27]=0.4,s[68,28]=-0.3,s[68,29]=1.1,s[68,30]=-1.0 s[68,31]=-1.2,s[68,32]=-0.6,s[68,33]=0.2,s[68,34]=-0.5,s[68,35]=1.0,s[68,36]=-0.6,s[68,37]=0.7,s[68,38]=0.0,s[68,39]=1.1,s[68,40]=0.3,s[68,41]=0.7,s[68,42]=0.7,s[68,43]=0.5,s[68,44]=-0.9,s[68,45]=-0.2 s[68,46]=0.7,s[68,47]=-0.4,s[68,48]=-0.5,s[68,49]=-0.4,s[68,50]=0.8,s[68,51]=1.0,s[68,52]=-1.1,s[68,53]=-1.0,s[68,54]=-0.4,s[68,55]=-0.4,s[68,56]=-1.1,s[68,57]=-0.9,s[68,58]=1.1,s[68,59]=1.1,s[68,60]=-0.9 s[69,1]=0.5,s[69,2]=1.1,s[69,3]=-0.2,s[69,4]=-0.2,s[69,5]=1.1,s[69,6]=-0.2,s[69,7]=-1.2,s[69,8]=-1.0,s[69,9]=-1.0,s[69,10]=-0.2,s[69,11]=0.5,s[69,12]=-1.0,s[69,13]=-0.3,s[69,14]=-0.8,s[69,15]=-1.2 s[69,16]=1.2,s[69,17]=0.2,s[69,18]=-0.7,s[69,19]=-0.5,s[69,20]=-0.7,s[69,21]=-0.5,s[69,22]=0.1,s[69,23]=-0.3,s[69,24]=-0.6,s[69,25]=-0.9,s[69,26]=-0.8,s[69,27]=1.2,s[69,28]=0.1,s[69,29]=0.3,s[69,30]=0.0 s[69,31]=0.8,s[69,32]=-0.2,s[69,33]=-1.2,s[69,34]=-0.3,s[69,35]=1.2,s[69,36]=-0.5,s[69,37]=0.4,s[69,38]=1.1,s[69,39]=-0.3,s[69,40]=0.3,s[69,41]=0.0,s[69,42]=-0.3,s[69,43]=0.4,s[69,44]=0.3,s[69,45]=-0.2 s[69,46]=0.7,s[69,47]=0.8,s[69,48]=0.5,s[69,49]=0.5,s[69,50]=0.2,s[69,51]=-0.2,s[69,52]=1.0,s[69,53]=0.0,s[69,54]=-0.6,s[69,55]=0.8,s[69,56]=0.8,s[69,57]=0.3,s[69,58]=0.7,s[69,59]=-0.4,s[69,60]=-1.1 s[70,1]=-0.3,s[70,2]=0.3,s[70,3]=-0.1,s[70,4]=0.7,s[70,5]=0.0,s[70,6]=-1.0,s[70,7]=-1.2,s[70,8]=-0.1,s[70,9]=0.2,s[70,10]=-1.2,s[70,11]=-0.5,s[70,12]=-1.0,s[70,13]=1.1,s[70,14]=-0.2,s[70,15]=0.1 s[70,16]=1.0,s[70,17]=0.0,s[70,18]=1.0,s[70,19]=-1.1,s[70,20]=0.6,s[70,21]=-1.2,s[70,22]=0.6,s[70,23]=0.7,s[70,24]=-0.6,s[70,25]=0.9,s[70,26]=-0.7,s[70,27]=0.4,s[70,28]=-0.3,s[70,29]=0.8,s[70,30]=0.4 s[70,31]=0.4,s[70,32]=-1.2,s[70,33]=1.0,s[70,34]=-0.3,s[70,35]=-0.7,s[70,36]=-0.3,s[70,37]=0.8,s[70,38]=0.9,s[70,39]=0.2,s[70,40]=-0.1,s[70,41]=1.2,s[70,42]=0.4,s[70,43]=-0.4,s[70,44]=-0.3,s[70,45]=-0.3 s[70,46]=0.6,s[70,47]=-0.7,s[70,48]=-0.9,s[70,49]=0.2,s[70,50]=-0.8,s[70,51]=-0.7,s[70,52]=-0.5,s[70,53]=0.7,s[70,54]=-0.3,s[70,55]=0.6,s[70,56]=-0.6,s[70,57]=-0.6,s[70,58]=0.5,s[70,59]=1.2,s[70,60]=-0.5 s[71,1]=0.9,s[71,2]=0.1,s[71,3]=0.0,s[71,4]=-1.0,s[71,5]=-0.5,s[71,6]=-0.7,s[71,7]=-1.2,s[71,8]=0.2,s[71,9]=0.0,s[71,10]=-0.3,s[71,11]=0.8,s[71,12]=1.0,s[71,13]=-0.9,s[71,14]=-1.0,s[71,15]=-1.2 s[71,16]=-0.2,s[71,17]=-0.7,s[71,18]=-0.9,s[71,19]=-1.2,s[71,20]=-1.1,s[71,21]=-1.1,s[71,22]=0.4,s[71,23]=0.7,s[71,24]=-0.8,s[71,25]=-0.8,s[71,26]=-0.5,s[71,27]=-1.1,s[71,28]=0.7,s[71,29]=0.8,s[71,30]=0.4 s[71,31]=-0.5,s[71,32]=1.2,s[71,33]=-0.7,s[71,34]=-0.9,s[71,35]=0.4,s[71,36]=1.1,s[71,37]=-0.2,s[71,38]=0.9,s[71,39]=1.0,s[71,40]=-0.3,s[71,41]=-1.2,s[71,42]=0.0,s[71,43]=-1.0,s[71,44]=0.5,s[71,45]=-0.5 s[71,46]=0.9,s[71,47]=-1.2,s[71,48]=-0.3,s[71,49]=-0.8,s[71,50]=0.9,s[71,51]=1.2,s[71,52]=-0.3,s[71,53]=0.5,s[71,54]=-0.7,s[71,55]=-0.2,s[71,56]=-0.2,s[71,57]=-0.6,s[71,58]=0.9,s[71,59]=0.1,s[71,60]=-1.0 s[72,1]=-0.5,s[72,2]=-0.3,s[72,3]=-0.1,s[72,4]=0.2,s[72,5]=0.7,s[72,6]=-0.1,s[72,7]=-0.1,s[72,8]=-0.9,s[72,9]=-0.3,s[72,10]=0.3,s[72,11]=1.1,s[72,12]=-1.2,s[72,13]=0.2,s[72,14]=0.7,s[72,15]=-0.2 s[72,16]=-1.2,s[72,17]=1.0,s[72,18]=-1.1,s[72,19]=0.5,s[72,20]=0.4,s[72,21]=0.1,s[72,22]=-0.6,s[72,23]=0.5,s[72,24]=-0.8,s[72,25]=-0.6,s[72,26]=0.9,s[72,27]=-1.0,s[72,28]=0.9,s[72,29]=0.4,s[72,30]=-0.2 s[72,31]=0.5,s[72,32]=-0.8,s[72,33]=-0.8,s[72,34]=-1.0,s[72,35]=-1.2,s[72,36]=-0.1,s[72,37]=0.7,s[72,38]=0.6,s[72,39]=1.1,s[72,40]=0.3,s[72,41]=-1.1,s[72,42]=-0.4,s[72,43]=0.0,s[72,44]=-0.1,s[72,45]=1.2 s[72,46]=-0.7,s[72,47]=0.9,s[72,48]=-1.1,s[72,49]=-0.7,s[72,50]=0.3,s[72,51]=-0.8,s[72,52]=-0.9,s[72,53]=-1.0,s[72,54]=-1.0,s[72,55]=-0.8,s[72,56]=-1.0,s[72,57]=-0.1,s[72,58]=-1.2,s[72,59]=-1.2,s[72,60]=-1.1 s[73,1]=0.9,s[73,2]=-1.2,s[73,3]=0.7,s[73,4]=-0.8,s[73,5]=0.8,s[73,6]=1.1,s[73,7]=-1.1,s[73,8]=-0.3,s[73,9]=0.2,s[73,10]=-0.3,s[73,11]=-1.2,s[73,12]=0.6,s[73,13]=0.3,s[73,14]=-0.9,s[73,15]=1.1 s[73,16]=0.7,s[73,17]=-0.3,s[73,18]=1.1,s[73,19]=-0.8,s[73,20]=1.0,s[73,21]=1.1,s[73,22]=0.9,s[73,23]=-1.2,s[73,24]=0.8,s[73,25]=0.5,s[73,26]=1.2,s[73,27]=-1.1,s[73,28]=0.3,s[73,29]=0.2,s[73,30]=-0.6 s[73,31]=0.4,s[73,32]=-0.5,s[73,33]=0.2,s[73,34]=0.4,s[73,35]=0.6,s[73,36]=-0.3,s[73,37]=1.2,s[73,38]=0.3,s[73,39]=0.0,s[73,40]=0.3,s[73,41]=1.0,s[73,42]=-1.2,s[73,43]=-1.2,s[73,44]=-1.1,s[73,45]=-0.4 s[73,46]=0.7,s[73,47]=-1.2,s[73,48]=-0.6,s[73,49]=0.5,s[73,50]=-0.4,s[73,51]=0.3,s[73,52]=0.8,s[73,53]=-0.4,s[73,54]=-0.9,s[73,55]=-0.4,s[73,56]=-1.1,s[73,57]=-0.5,s[73,58]=0.1,s[73,59]=0.4,s[73,60]=-1.1 s[74,1]=0.6,s[74,2]=0.0,s[74,3]=-0.1,s[74,4]=-0.9,s[74,5]=0.7,s[74,6]=-1.0,s[74,7]=-1.1,s[74,8]=0.3,s[74,9]=-0.3,s[74,10]=-0.6,s[74,11]=-0.2,s[74,12]=-0.7,s[74,13]=-0.3,s[74,14]=-1.1,s[74,15]=-0.8 s[74,16]=-0.2,s[74,17]=0.0,s[74,18]=-0.7,s[74,19]=-0.4,s[74,20]=0.1,s[74,21]=-0.4,s[74,22]=1.1,s[74,23]=0.0,s[74,24]=0.0,s[74,25]=-0.4,s[74,26]=-0.7,s[74,27]=1.2,s[74,28]=-0.8,s[74,29]=0.1,s[74,30]=0.7 s[74,31]=-0.7,s[74,32]=1.2,s[74,33]=0.4,s[74,34]=-0.8,s[74,35]=-0.1,s[74,36]=0.1,s[74,37]=-0.6,s[74,38]=-0.9,s[74,39]=1.2,s[74,40]=0.1,s[74,41]=0.2,s[74,42]=-1.1,s[74,43]=-0.7,s[74,44]=-0.3,s[74,45]=-0.7 s[74,46]=-0.9,s[74,47]=1.1,s[74,48]=0.6,s[74,49]=0.9,s[74,50]=0.0,s[74,51]=-1.2,s[74,52]=-0.5,s[74,53]=0.2,s[74,54]=1.0,s[74,55]=0.2,s[74,56]=-0.3,s[74,57]=-0.6,s[74,58]=-0.6,s[74,59]=-1.0,s[74,60]=-1.2 s[75,1]=0.2,s[75,2]=-1.0,s[75,3]=-1.1,s[75,4]=-0.7,s[75,5]=0.0,s[75,6]=0.7,s[75,7]=-1.1,s[75,8]=0.6,s[75,9]=0.8,s[75,10]=0.7,s[75,11]=1.0,s[75,12]=-0.2,s[75,13]=-1.0,s[75,14]=0.0,s[75,15]=-0.8 s[75,16]=-1.0,s[75,17]=-0.2,s[75,18]=0.4,s[75,19]=0.9,s[75,20]=1.2,s[75,21]=-0.7,s[75,22]=-0.1,s[75,23]=1.2,s[75,24]=0.1,s[75,25]=-0.5,s[75,26]=0.7,s[75,27]=-0.7,s[75,28]=-1.0,s[75,29]=1.1,s[75,30]=1.2 s[75,31]=1.1,s[75,32]=0.1,s[75,33]=0.5,s[75,34]=0.1,s[75,35]=1.1,s[75,36]=-0.3,s[75,37]=0.0,s[75,38]=0.1,s[75,39]=0.4,s[75,40]=-1.0,s[75,41]=0.1,s[75,42]=-0.5,s[75,43]=1.2,s[75,44]=-0.8,s[75,45]=1.1 s[75,46]=0.4,s[75,47]=0.9,s[75,48]=0.3,s[75,49]=-0.3,s[75,50]=0.1,s[75,51]=-1.0,s[75,52]=0.0,s[75,53]=-1.2,s[75,54]=-1.0,s[75,55]=0.5,s[75,56]=0.4,s[75,57]=0.5,s[75,58]=-0.2,s[75,59]=0.3,s[75,60]=-0.6 s[76,1]=0.7,s[76,2]=-0.4,s[76,3]=-0.2,s[76,4]=0.4,s[76,5]=0.2,s[76,6]=0.9,s[76,7]=-0.1,s[76,8]=-1.2,s[76,9]=0.1,s[76,10]=-1.2,s[76,11]=-0.3,s[76,12]=1.1,s[76,13]=-0.7,s[76,14]=0.5,s[76,15]=1.0 s[76,16]=-1.2,s[76,17]=0.2,s[76,18]=1.2,s[76,19]=-1.1,s[76,20]=0.9,s[76,21]=1.2,s[76,22]=-0.2,s[76,23]=1.2,s[76,24]=-0.5,s[76,25]=-0.2,s[76,26]=-0.2,s[76,27]=-0.4,s[76,28]=0.3,s[76,29]=-0.4,s[76,30]=0.5 s[76,31]=0.3,s[76,32]=1.0,s[76,33]=-1.2,s[76,34]=-0.6,s[76,35]=1.1,s[76,36]=-1.1,s[76,37]=-0.5,s[76,38]=-1.2,s[76,39]=-0.1,s[76,40]=-1.0,s[76,41]=0.1,s[76,42]=0.4,s[76,43]=-1.1,s[76,44]=-0.3,s[76,45]=1.2 s[76,46]=0.2,s[76,47]=0.6,s[76,48]=-1.0,s[76,49]=-1.0,s[76,50]=0.5,s[76,51]=-0.9,s[76,52]=1.2,s[76,53]=-0.1,s[76,54]=0.0,s[76,55]=-0.8,s[76,56]=-0.2,s[76,57]=0.3,s[76,58]=-1.2,s[76,59]=-1.1,s[76,60]=-1.0 s[77,1]=-0.1,s[77,2]=0.9,s[77,3]=0.8,s[77,4]=-1.1,s[77,5]=-0.1,s[77,6]=0.6,s[77,7]=-0.5,s[77,8]=0.1,s[77,9]=-0.1,s[77,10]=0.8,s[77,11]=-1.1,s[77,12]=0.3,s[77,13]=1.2,s[77,14]=1.2,s[77,15]=-1.2 s[77,16]=0.5,s[77,17]=0.8,s[77,18]=-0.8,s[77,19]=-1.0,s[77,20]=1.0,s[77,21]=0.9,s[77,22]=1.1,s[77,23]=0.9,s[77,24]=0.6,s[77,25]=-0.1,s[77,26]=1.2,s[77,27]=0.7,s[77,28]=-1.0,s[77,29]=1.0,s[77,30]=0.8 s[77,31]=-0.8,s[77,32]=-0.3,s[77,33]=0.2,s[77,34]=0.0,s[77,35]=-0.7,s[77,36]=0.4,s[77,37]=0.6,s[77,38]=-0.5,s[77,39]=-0.2,s[77,40]=0.5,s[77,41]=-0.7,s[77,42]=0.1,s[77,43]=-0.1,s[77,44]=0.2,s[77,45]=-0.4 s[77,46]=-0.2,s[77,47]=-1.0,s[77,48]=-0.6,s[77,49]=0.6,s[77,50]=1.2,s[77,51]=-0.1,s[77,52]=0.4,s[77,53]=0.0,s[77,54]=-1.2,s[77,55]=1.0,s[77,56]=0.2,s[77,57]=-1.0,s[77,58]=0.1,s[77,59]=0.7,s[77,60]=-0.3 s[78,1]=0.4,s[78,2]=-0.3,s[78,3]=-0.6,s[78,4]=-0.7,s[78,5]=1.0,s[78,6]=-0.8,s[78,7]=-1.1,s[78,8]=0.2,s[78,9]=1.1,s[78,10]=-1.0,s[78,11]=1.0,s[78,12]=-0.8,s[78,13]=0.6,s[78,14]=-0.1,s[78,15]=-1.0 s[78,16]=-0.9,s[78,17]=1.1,s[78,18]=1.2,s[78,19]=-0.7,s[78,20]=0.6,s[78,21]=0.5,s[78,22]=-0.6,s[78,23]=-0.1,s[78,24]=-0.4,s[78,25]=-0.5,s[78,26]=-0.9,s[78,27]=0.1,s[78,28]=0.1,s[78,29]=0.0,s[78,30]=0.4 s[78,31]=0.4,s[78,32]=-1.2,s[78,33]=-0.2,s[78,34]=-1.0,s[78,35]=-0.4,s[78,36]=0.1,s[78,37]=0.1,s[78,38]=0.1,s[78,39]=0.3,s[78,40]=0.8,s[78,41]=-1.2,s[78,42]=0.6,s[78,43]=0.0,s[78,44]=-1.0,s[78,45]=0.5 s[78,46]=0.6,s[78,47]=0.7,s[78,48]=0.2,s[78,49]=0.0,s[78,50]=-0.2,s[78,51]=-0.8,s[78,52]=1.0,s[78,53]=0.1,s[78,54]=-1.1,s[78,55]=-0.3,s[78,56]=0.6,s[78,57]=0.7,s[78,58]=-0.7,s[78,59]=-0.5,s[78,60]=0.5 s[79,1]=-1.0,s[79,2]=-0.2,s[79,3]=0.1,s[79,4]=-0.8,s[79,5]=-0.6,s[79,6]=-0.5,s[79,7]=0.5,s[79,8]=-0.7,s[79,9]=-1.1,s[79,10]=-0.7,s[79,11]=0.4,s[79,12]=1.1,s[79,13]=1.0,s[79,14]=1.2,s[79,15]=-0.5 s[79,16]=0.1,s[79,17]=-0.5,s[79,18]=0.4,s[79,19]=0.8,s[79,20]=-0.8,s[79,21]=-0.6,s[79,22]=-0.3,s[79,23]=-0.7,s[79,24]=-0.5,s[79,25]=1.0,s[79,26]=0.8,s[79,27]=-0.6,s[79,28]=0.3,s[79,29]=-1.0,s[79,30]=1.1 s[79,31]=0.5,s[79,32]=-0.6,s[79,33]=-0.8,s[79,34]=-0.7,s[79,35]=-0.9,s[79,36]=-1.2,s[79,37]=1.0,s[79,38]=0.2,s[79,39]=-0.6,s[79,40]=-0.7,s[79,41]=-1.2,s[79,42]=-1.1,s[79,43]=-0.6,s[79,44]=-0.2,s[79,45]=-0.1 s[79,46]=-0.7,s[79,47]=0.2,s[79,48]=-0.5,s[79,49]=-0.1,s[79,50]=0.6,s[79,51]=0.0,s[79,52]=-1.2,s[79,53]=0.9,s[79,54]=1.1,s[79,55]=-0.3,s[79,56]=0.9,s[79,57]=-0.3,s[79,58]=0.5,s[79,59]=-0.8,s[79,60]=-0.8 s[80,1]=-0.8,s[80,2]=1.2,s[80,3]=0.1,s[80,4]=0.0,s[80,5]=0.7,s[80,6]=-0.9,s[80,7]=0.5,s[80,8]=-1.1,s[80,9]=-0.5,s[80,10]=0.7,s[80,11]=-0.6,s[80,12]=-0.6,s[80,13]=0.1,s[80,14]=-1.1,s[80,15]=0.7 s[80,16]=-0.5,s[80,17]=-0.4,s[80,18]=-0.7,s[80,19]=0.4,s[80,20]=0.5,s[80,21]=0.7,s[80,22]=0.8,s[80,23]=-0.7,s[80,24]=0.8,s[80,25]=-0.9,s[80,26]=0.0,s[80,27]=0.4,s[80,28]=0.0,s[80,29]=-0.4,s[80,30]=0.5 s[80,31]=1.0,s[80,32]=-1.1,s[80,33]=0.8,s[80,34]=0.0,s[80,35]=0.5,s[80,36]=0.3,s[80,37]=0.3,s[80,38]=0.5,s[80,39]=1.1,s[80,40]=-0.2,s[80,41]=1.0,s[80,42]=-0.7,s[80,43]=-1.0,s[80,44]=-0.9,s[80,45]=1.1 s[80,46]=-0.5,s[80,47]=-0.3,s[80,48]=1.0,s[80,49]=-0.2,s[80,50]=1.2,s[80,51]=-0.9,s[80,52]=1.0,s[80,53]=-0.1,s[80,54]=0.5,s[80,55]=0.8,s[80,56]=-0.4,s[80,57]=-0.5,s[80,58]=1.0,s[80,59]=-0.1,s[80,60]=-0.9 s[81,1]=0.6,s[81,2]=0.5,s[81,3]=0.7,s[81,4]=-1.0,s[81,5]=0.3,s[81,6]=0.8,s[81,7]=1.2,s[81,8]=-0.7,s[81,9]=-0.7,s[81,10]=-0.9,s[81,11]=-1.1,s[81,12]=0.0,s[81,13]=-0.6,s[81,14]=0.4,s[81,15]=1.0 s[81,16]=-0.6,s[81,17]=0.8,s[81,18]=0.0,s[81,19]=-1.1,s[81,20]=0.0,s[81,21]=0.1,s[81,22]=-0.5,s[81,23]=-0.2,s[81,24]=0.4,s[81,25]=1.1,s[81,26]=0.0,s[81,27]=0.4,s[81,28]=1.1,s[81,29]=-1.2,s[81,30]=0.7 s[81,31]=0.5,s[81,32]=-0.3,s[81,33]=0.4,s[81,34]=-1.1,s[81,35]=0.3,s[81,36]=0.2,s[81,37]=0.4,s[81,38]=-1.0,s[81,39]=-0.9,s[81,40]=-1.1,s[81,41]=0.2,s[81,42]=-1.2,s[81,43]=0.3,s[81,44]=-1.1,s[81,45]=1.2 s[81,46]=0.1,s[81,47]=0.5,s[81,48]=1.1,s[81,49]=0.9,s[81,50]=-0.7,s[81,51]=-0.5,s[81,52]=0.8,s[81,53]=1.1,s[81,54]=0.8,s[81,55]=-1.0,s[81,56]=0.2,s[81,57]=0.2,s[81,58]=0.3,s[81,59]=-0.4,s[81,60]=0.4 s[82,1]=-0.5,s[82,2]=0.3,s[82,3]=0.6,s[82,4]=-1.1,s[82,5]=0.1,s[82,6]=-1.2,s[82,7]=-0.9,s[82,8]=1.1,s[82,9]=1.1,s[82,10]=1.1,s[82,11]=-0.2,s[82,12]=0.5,s[82,13]=0.7,s[82,14]=-0.7,s[82,15]=-1.2 s[82,16]=-0.7,s[82,17]=0.4,s[82,18]=1.1,s[82,19]=-0.3,s[82,20]=-0.6,s[82,21]=0.2,s[82,22]=-0.4,s[82,23]=-0.8,s[82,24]=0.1,s[82,25]=-0.8,s[82,26]=-0.1,s[82,27]=-0.6,s[82,28]=0.3,s[82,29]=-0.7,s[82,30]=1.0 s[82,31]=0.1,s[82,32]=-0.5,s[82,33]=1.1,s[82,34]=-1.2,s[82,35]=-1.2,s[82,36]=-0.6,s[82,37]=1.2,s[82,38]=0.9,s[82,39]=0.7,s[82,40]=-0.3,s[82,41]=1.2,s[82,42]=0.3,s[82,43]=1.2,s[82,44]=0.8,s[82,45]=0.3 s[82,46]=0.1,s[82,47]=1.0,s[82,48]=-0.8,s[82,49]=-0.9,s[82,50]=0.4,s[82,51]=0.1,s[82,52]=0.2,s[82,53]=-0.1,s[82,54]=-0.2,s[82,55]=0.0,s[82,56]=0.0,s[82,57]=-0.8,s[82,58]=0.1,s[82,59]=1.0,s[82,60]=-0.7 s[83,1]=-0.7,s[83,2]=0.5,s[83,3]=-0.8,s[83,4]=-0.1,s[83,5]=0.4,s[83,6]=1.2,s[83,7]=0.4,s[83,8]=0.1,s[83,9]=0.1,s[83,10]=0.2,s[83,11]=0.6,s[83,12]=0.8,s[83,13]=0.2,s[83,14]=-0.8,s[83,15]=-0.3 s[83,16]=0.2,s[83,17]=0.2,s[83,18]=0.7,s[83,19]=-0.1,s[83,20]=-0.4,s[83,21]=-0.7,s[83,22]=-1.0,s[83,23]=0.5,s[83,24]=1.2,s[83,25]=-0.3,s[83,26]=-1.2,s[83,27]=0.5,s[83,28]=-0.6,s[83,29]=1.2,s[83,30]=0.7 s[83,31]=0.5,s[83,32]=-0.8,s[83,33]=1.1,s[83,34]=-0.4,s[83,35]=-0.6,s[83,36]=-1.1,s[83,37]=0.1,s[83,38]=1.2,s[83,39]=0.1,s[83,40]=-0.7,s[83,41]=-0.4,s[83,42]=-0.9,s[83,43]=1.0,s[83,44]=0.7,s[83,45]=-1.2 s[83,46]=1.0,s[83,47]=0.1,s[83,48]=-0.4,s[83,49]=1.1,s[83,50]=0.0,s[83,51]=-0.4,s[83,52]=0.7,s[83,53]=-0.1,s[83,54]=1.0,s[83,55]=-1.2,s[83,56]=-0.1,s[83,57]=0.2,s[83,58]=-0.5,s[83,59]=-0.3,s[83,60]=-1.1 s[84,1]=0.9,s[84,2]=1.1,s[84,3]=-0.1,s[84,4]=-0.6,s[84,5]=0.8,s[84,6]=0.1,s[84,7]=0.1,s[84,8]=0.1,s[84,9]=-0.6,s[84,10]=0.1,s[84,11]=1.1,s[84,12]=0.2,s[84,13]=-0.5,s[84,14]=-0.3,s[84,15]=-0.1 s[84,16]=-0.2,s[84,17]=1.0,s[84,18]=-0.5,s[84,19]=1.1,s[84,20]=0.1,s[84,21]=-0.9,s[84,22]=-0.5,s[84,23]=0.7,s[84,24]=-0.4,s[84,25]=-1.0,s[84,26]=0.3,s[84,27]=-0.8,s[84,28]=0.6,s[84,29]=-0.4,s[84,30]=0.4 s[84,31]=0.5,s[84,32]=0.1,s[84,33]=0.5,s[84,34]=-0.4,s[84,35]=1.2,s[84,36]=-0.4,s[84,37]=1.0,s[84,38]=-1.1,s[84,39]=0.7,s[84,40]=-0.5,s[84,41]=0.6,s[84,42]=1.1,s[84,43]=0.6,s[84,44]=0.2,s[84,45]=-0.1 s[84,46]=-0.7,s[84,47]=0.1,s[84,48]=0.2,s[84,49]=-0.4,s[84,50]=1.2,s[84,51]=-0.1,s[84,52]=-0.8,s[84,53]=0.3,s[84,54]=0.0,s[84,55]=0.1,s[84,56]=-0.3,s[84,57]=0.2,s[84,58]=1.1,s[84,59]=-0.6,s[84,60]=-1.2 s[85,1]=0.7,s[85,2]=0.2,s[85,3]=0.2,s[85,4]=-0.2,s[85,5]=0.8,s[85,6]=-1.0,s[85,7]=-0.5,s[85,8]=0.2,s[85,9]=-1.2,s[85,10]=0.8,s[85,11]=0.4,s[85,12]=1.0,s[85,13]=1.2,s[85,14]=-0.4,s[85,15]=-1.1 s[85,16]=0.7,s[85,17]=0.2,s[85,18]=-0.3,s[85,19]=0.9,s[85,20]=1.0,s[85,21]=-1.2,s[85,22]=0.0,s[85,23]=-1.2,s[85,24]=0.2,s[85,25]=-0.8,s[85,26]=-0.6,s[85,27]=-1.1,s[85,28]=0.5,s[85,29]=-0.8,s[85,30]=0.0 s[85,31]=0.5,s[85,32]=-0.6,s[85,33]=-0.3,s[85,34]=0.2,s[85,35]=-0.7,s[85,36]=-0.2,s[85,37]=-0.8,s[85,38]=1.0,s[85,39]=-1.1,s[85,40]=1.0,s[85,41]=-0.1,s[85,42]=-0.2,s[85,43]=-0.6,s[85,44]=-1.1,s[85,45]=-0.5 s[85,46]=0.4,s[85,47]=-1.2,s[85,48]=-0.2,s[85,49]=-1.1,s[85,50]=-1.2,s[85,51]=0.9,s[85,52]=0.0,s[85,53]=0.4,s[85,54]=-0.3,s[85,55]=-0.8,s[85,56]=0.9,s[85,57]=-1.0,s[85,58]=-0.2,s[85,59]=0.2,s[85,60]=0.2 s[86,1]=-1.0,s[86,2]=0.1,s[86,3]=-0.9,s[86,4]=0.0,s[86,5]=-0.6,s[86,6]=0.5,s[86,7]=-1.2,s[86,8]=1.1,s[86,9]=-0.3,s[86,10]=0.8,s[86,11]=-1.1,s[86,12]=0.4,s[86,13]=0.0,s[86,14]=0.7,s[86,15]=0.6 s[86,16]=0.1,s[86,17]=0.4,s[86,18]=0.7,s[86,19]=1.1,s[86,20]=0.9,s[86,21]=0.2,s[86,22]=0.5,s[86,23]=1.1,s[86,24]=0.4,s[86,25]=-1.1,s[86,26]=0.8,s[86,27]=1.0,s[86,28]=0.9,s[86,29]=-0.8,s[86,30]=0.2 s[86,31]=-1.2,s[86,32]=0.5,s[86,33]=0.5,s[86,34]=1.2,s[86,35]=0.0,s[86,36]=-1.0,s[86,37]=-0.9,s[86,38]=-0.5,s[86,39]=-1.0,s[86,40]=-0.8,s[86,41]=-0.5,s[86,42]=1.0,s[86,43]=-0.2,s[86,44]=-1.2,s[86,45]=-0.5 s[86,46]=-0.8,s[86,47]=-0.7,s[86,48]=0.6,s[86,49]=-0.1,s[86,50]=-0.7,s[86,51]=0.9,s[86,52]=1.2,s[86,53]=-0.7,s[86,54]=-0.8,s[86,55]=-1.0,s[86,56]=-0.8,s[86,57]=0.0,s[86,58]=-1.2,s[86,59]=0.4,s[86,60]=-0.3 s[87,1]=-0.2,s[87,2]=1.2,s[87,3]=0.1,s[87,4]=-0.6,s[87,5]=-0.2,s[87,6]=0.6,s[87,7]=-1.2,s[87,8]=-0.1,s[87,9]=0.5,s[87,10]=0.9,s[87,11]=-1.2,s[87,12]=-0.6,s[87,13]=-0.3,s[87,14]=0.3,s[87,15]=-0.6 s[87,16]=0.7,s[87,17]=-1.1,s[87,18]=-0.6,s[87,19]=0.0,s[87,20]=0.6,s[87,21]=-0.9,s[87,22]=0.4,s[87,23]=-0.9,s[87,24]=0.9,s[87,25]=-0.9,s[87,26]=-1.2,s[87,27]=0.0,s[87,28]=0.4,s[87,29]=0.5,s[87,30]=-0.8 s[87,31]=-0.5,s[87,32]=0.2,s[87,33]=-0.6,s[87,34]=-0.6,s[87,35]=-0.1,s[87,36]=0.1,s[87,37]=0.9,s[87,38]=1.2,s[87,39]=0.5,s[87,40]=-0.8,s[87,41]=0.3,s[87,42]=0.5,s[87,43]=0.5,s[87,44]=-0.5,s[87,45]=1.2 s[87,46]=0.3,s[87,47]=0.7,s[87,48]=0.6,s[87,49]=0.3,s[87,50]=-0.5,s[87,51]=0.9,s[87,52]=-0.1,s[87,53]=0.5,s[87,54]=0.2,s[87,55]=-1.2,s[87,56]=-0.5,s[87,57]=-0.6,s[87,58]=-0.6,s[87,59]=0.7,s[87,60]=0.0 s[88,1]=0.2,s[88,2]=0.7,s[88,3]=0.0,s[88,4]=-1.2,s[88,5]=-0.6,s[88,6]=0.0,s[88,7]=-0.7,s[88,8]=1.2,s[88,9]=0.7,s[88,10]=0.4,s[88,11]=0.4,s[88,12]=0.6,s[88,13]=-0.2,s[88,14]=0.6,s[88,15]=-1.1 s[88,16]=0.3,s[88,17]=-0.9,s[88,18]=-0.6,s[88,19]=0.6,s[88,20]=0.5,s[88,21]=-0.5,s[88,22]=-0.7,s[88,23]=0.8,s[88,24]=-0.1,s[88,25]=-1.1,s[88,26]=-0.3,s[88,27]=0.6,s[88,28]=0.8,s[88,29]=-0.8,s[88,30]=-0.2 s[88,31]=-0.8,s[88,32]=0.9,s[88,33]=0.6,s[88,34]=-1.1,s[88,35]=0.4,s[88,36]=0.6,s[88,37]=-1.0,s[88,38]=1.1,s[88,39]=0.1,s[88,40]=0.7,s[88,41]=-0.6,s[88,42]=1.0,s[88,43]=-0.7,s[88,44]=1.1,s[88,45]=0.3 s[88,46]=0.5,s[88,47]=0.8,s[88,48]=0.8,s[88,49]=0.1,s[88,50]=1.2,s[88,51]=-1.0,s[88,52]=0.8,s[88,53]=-0.2,s[88,54]=-0.8,s[88,55]=1.1,s[88,56]=1.1,s[88,57]=-0.9,s[88,58]=0.1,s[88,59]=-1.0,s[88,60]=-0.9 s[89,1]=-0.8,s[89,2]=-1.0,s[89,3]=1.2,s[89,4]=0.6,s[89,5]=-0.5,s[89,6]=-0.3,s[89,7]=-0.2,s[89,8]=-1.0,s[89,9]=-0.7,s[89,10]=-0.2,s[89,11]=-0.6,s[89,12]=-0.4,s[89,13]=-0.3,s[89,14]=-1.0,s[89,15]=0.8 s[89,16]=0.5,s[89,17]=-0.2,s[89,18]=-0.4,s[89,19]=-0.6,s[89,20]=1.2,s[89,21]=-0.9,s[89,22]=-1.1,s[89,23]=0.7,s[89,24]=-0.3,s[89,25]=-0.4,s[89,26]=-0.7,s[89,27]=1.0,s[89,28]=0.2,s[89,29]=-0.5,s[89,30]=-0.6 s[89,31]=0.0,s[89,32]=0.6,s[89,33]=1.1,s[89,34]=0.0,s[89,35]=0.1,s[89,36]=0.5,s[89,37]=0.5,s[89,38]=0.9,s[89,39]=-0.9,s[89,40]=-0.1,s[89,41]=-0.5,s[89,42]=-0.6,s[89,43]=0.1,s[89,44]=-0.3,s[89,45]=-0.1 s[89,46]=-0.3,s[89,47]=-1.1,s[89,48]=-0.3,s[89,49]=0.4,s[89,50]=0.9,s[89,51]=-0.5,s[89,52]=-0.1,s[89,53]=-0.1,s[89,54]=0.2,s[89,55]=1.1,s[89,56]=-1.2,s[89,57]=0.4,s[89,58]=-0.8,s[89,59]=-0.3,s[89,60]=-1.2 s[90,1]=0.6,s[90,2]=-1.2,s[90,3]=-0.6,s[90,4]=-0.8,s[90,5]=-0.1,s[90,6]=-1.0,s[90,7]=0.1,s[90,8]=-0.6,s[90,9]=0.8,s[90,10]=0.9,s[90,11]=-0.4,s[90,12]=0.2,s[90,13]=0.3,s[90,14]=0.0,s[90,15]=0.0 s[90,16]=1.2,s[90,17]=0.1,s[90,18]=0.1,s[90,19]=-0.6,s[90,20]=0.2,s[90,21]=0.9,s[90,22]=-0.3,s[90,23]=0.5,s[90,24]=0.0,s[90,25]=-0.3,s[90,26]=-0.4,s[90,27]=-1.0,s[90,28]=-0.8,s[90,29]=-0.6,s[90,30]=0.0 s[90,31]=0.6,s[90,32]=-0.5,s[90,33]=-0.3,s[90,34]=-0.6,s[90,35]=0.4,s[90,36]=-0.9,s[90,37]=1.1,s[90,38]=0.6,s[90,39]=-0.5,s[90,40]=-1.1,s[90,41]=0.4,s[90,42]=-1.1,s[90,43]=1.1,s[90,44]=-1.2,s[90,45]=0.5 s[90,46]=1.0,s[90,47]=0.6,s[90,48]=1.1,s[90,49]=0.2,s[90,50]=0.4,s[90,51]=0.7,s[90,52]=0.0,s[90,53]=0.0,s[90,54]=0.0,s[90,55]=-1.2,s[90,56]=-0.4,s[90,57]=-0.5,s[90,58]=1.2,s[90,59]=0.5,s[90,60]=-0.4 s[91,1]=-0.5,s[91,2]=0.4,s[91,3]=0.6,s[91,4]=0.2,s[91,5]=0.8,s[91,6]=-0.6,s[91,7]=0.1,s[91,8]=1.0,s[91,9]=-1.0,s[91,10]=0.4,s[91,11]=-0.6,s[91,12]=0.4,s[91,13]=1.0,s[91,14]=-0.7,s[91,15]=-0.5,s[91,16]=1.0,s[91,17]=-0.5,s[91,18]=0.7,s[91,19]=-0.2,s[91,20]=0.4,s[91,21]=0.0,s[91,22]=-1.1,s[91,23]=-1.0,s[91,24]=0.6,s[91,25]=-0.6,s[91,26]=-0.6,s[91,27]=0.2,s[91,28]=0.8,s[91,29]=0.7,s[91,30]=-1.1 s[91,31]=0.8,s[91,32]=0.7,s[91,33]=0.2,s[91,34]=-1.1,s[91,35]=0.1,s[91,36]=0.9,s[91,37]=0.4,s[91,38]=0.5,s[91,39]=-0.1,s[91,40]=0.0,s[91,41]=-1.1,s[91,42]=-0.4,s[91,43]=0.6,s[91,44]=0.9,s[91,45]=1.0,s[91,46]=-0.1,s[91,47]=-0.9,s[91,48]=0.1,s[91,49]=0.6,s[91,50]=-0.8,s[91,51]=-0.9,s[91,52]=0.0,s[91,53]=-0.1,s[91,54]=0.6,s[91,55]=-0.5,s[91,56]=-0.7,s[91,57]=-0.9,s[91,58]=-1.0,s[91,59]=0.2,s[91,60]=-1.1 s[92,1]=0.7,s[92,2]=-0.1,s[92,3]=0.5,s[92,4]=-0.7,s[92,5]=1.1,s[92,6]=-1.2,s[92,7]=-1.0,s[92,8]=-1.1,s[92,9]=-1.2,s[92,10]=0.1,s[92,11]=-0.4,s[92,12]=1.0,s[92,13]=0.0,s[92,14]=-0.1,s[92,15]=-0.4,s[92,16]=-0.1,s[92,17]=0.8,s[92,18]=-0.2,s[92,19]=-0.4,s[92,20]=0.7,s[92,21]=0.8,s[92,22]=0.3,s[92,23]=1.2,s[92,24]=-0.7,s[92,25]=-0.2,s[92,26]=-0.5,s[92,27]=-1.1,s[92,28]=-0.5,s[92,29]=0.7,s[92,30]=0.7 s[92,31]=-1.1,s[92,32]=0.7,s[92,33]=0.5,s[92,34]=-0.7,s[92,35]=-0.2,s[92,36]=0.1,s[92,37]=0.8,s[92,38]=-1.1,s[92,39]=-0.3,s[92,40]=0.0,s[92,41]=-0.3,s[92,42]=-1.0,s[92,43]=0.3,s[92,44]=-1.0,s[92,45]=-0.4,s[92,46]=0.6,s[92,47]=1.1,s[92,48]=-0.3,s[92,49]=-0.3,s[92,50]=-1.2,s[92,51]=0.9,s[92,52]=0.5,s[92,53]=-1.1,s[92,54]=-0.1,s[92,55]=0.1,s[92,56]=-1.2,s[92,57]=0.1,s[92,58]=-1.0,s[92,59]=0.2,s[92,60]=-0.9 s[93,1]=0.0,s[93,2]=0.7,s[93,3]=-0.3,s[93,4]=-0.8,s[93,5]=-1.2,s[93,6]=-0.5,s[93,7]=-0.2,s[93,8]=-1.1,s[93,9]=-0.4,s[93,10]=-0.3,s[93,11]=0.6,s[93,12]=-1.2,s[93,13]=0.0,s[93,14]=0.1,s[93,15]=1.2,s[93,16]=0.2,s[93,17]=0.8,s[93,18]=1.2,s[93,19]=-0.6,s[93,20]=0.6,s[93,21]=1.1,s[93,22]=1.0,s[93,23]=0.2,s[93,24]=0.3,s[93,25]=-1.0,s[93,26]=0.9,s[93,27]=-0.4,s[93,28]=-1.1,s[93,29]=1.0,s[93,30]=0.1 s[93,31]=0.3,s[93,32]=0.4,s[93,33]=-0.8,s[93,34]=-0.3,s[93,35]=0.1,s[93,36]=0.9,s[93,37]=-0.9,s[93,38]=-0.6,s[93,39]=-0.6,s[93,40]=0.4,s[93,41]=-0.7,s[93,42]=-0.3,s[93,43]=0.3,s[93,44]=-0.7,s[93,45]=0.3,s[93,46]=-1.2,s[93,47]=-0.6,s[93,48]=0.4,s[93,49]=0.1,s[93,50]=-0.1,s[93,51]=-1.1,s[93,52]=0.1,s[93,53]=-0.7,s[93,54]=0.2,s[93,55]=-1.1,s[93,56]=0.6,s[93,57]=-0.1,s[93,58]=0.9,s[93,59]=0.5,s[93,60]=-0.5 s[94,1]=-1.0,s[94,2]=-1.0,s[94,3]=-1.2,s[94,4]=-1.0,s[94,5]=0.5,s[94,6]=-0.9,s[94,7]=0.2,s[94,8]=1.0,s[94,9]=0.4,s[94,10]=0.7,s[94,11]=-0.2,s[94,12]=0.3,s[94,13]=1.2,s[94,14]=0.4,s[94,15]=1.0,s[94,16]=0.1,s[94,17]=0.1,s[94,18]=-0.8,s[94,19]=1.0,s[94,20]=0.3,s[94,21]=-0.1,s[94,22]=-0.3,s[94,23]=0.5,s[94,24]=0.5,s[94,25]=0.5,s[94,26]=0.1,s[94,27]=-0.2,s[94,28]=-0.8,s[94,29]=-0.9,s[94,30]=1.0 s[94,31]=0.0,s[94,32]=-0.8,s[94,33]=-0.6,s[94,34]=-1.0,s[94,35]=-0.2,s[94,36]=0.3,s[94,37]=0.0,s[94,38]=0.6,s[94,39]=-0.1,s[94,40]=0.4,s[94,41]=-0.4,s[94,42]=0.1,s[94,43]=-1.2,s[94,44]=1.0,s[94,45]=-0.4,s[94,46]=0.1,s[94,47]=-0.4,s[94,48]=-1.0,s[94,49]=-0.1,s[94,50]=0.8,s[94,51]=-1.1,s[94,52]=-0.4,s[94,53]=-0.5,s[94,54]=0.1,s[94,55]=0.8,s[94,56]=0.6,s[94,57]=0.9,s[94,58]=0.1,s[94,59]=0.2,s[94,60]=-0.4 s[95,1]=0.3,s[95,2]=-0.5,s[95,3]=0.8,s[95,4]=-1.1,s[95,5]=-0.4,s[95,6]=-0.6,s[95,7]=0.4,s[95,8]=-0.1,s[95,9]=-0.5,s[95,10]=-0.5,s[95,11]=1.1,s[95,12]=-1.1,s[95,13]=-0.9,s[95,14]=-0.3,s[95,15]=-0.9,s[95,16]=-0.7,s[95,17]=0.6,s[95,18]=-0.9,s[95,19]=-0.4,s[95,20]=-0.3,s[95,21]=-0.3,s[95,22]=0.5,s[95,23]=0.8,s[95,24]=0.8,s[95,25]=1.0,s[95,26]=-0.7,s[95,27]=-1.1,s[95,28]=0.0,s[95,29]=-1.2,s[95,30]=0.2 s[95,31]=0.2,s[95,32]=0.9,s[95,33]=-1.0,s[95,34]=-1.0,s[95,35]=-1.1,s[95,36]=0.4,s[95,37]=0.6,s[95,38]=1.1,s[95,39]=0.9,s[95,40]=-0.1,s[95,41]=0.1,s[95,42]=0.2,s[95,43]=0.4,s[95,44]=0.5,s[95,45]=0.0,s[95,46]=-1.2,s[95,47]=0.2,s[95,48]=0.7,s[95,49]=-0.3,s[95,50]=-0.8,s[95,51]=-0.1,s[95,52]=0.3,s[95,53]=0.3,s[95,54]=-0.9,s[95,55]=-0.4,s[95,56]=0.5,s[95,57]=0.3,s[95,58]=-0.2,s[95,59]=0.7,s[95,60]=-0.2 s[96,1]=0.1,s[96,2]=0.7,s[96,3]=-0.9,s[96,4]=1.0,s[96,5]=0.1,s[96,6]=1.2,s[96,7]=-0.4,s[96,8]=-1.2,s[96,9]=0.7,s[96,10]=1.2,s[96,11]=1.1,s[96,12]=-0.9,s[96,13]=0.7,s[96,14]=0.4,s[96,15]=-1.1,s[96,16]=0.9,s[96,17]=0.9,s[96,18]=-1.1,s[96,19]=-0.6,s[96,20]=0.6,s[96,21]=-1.2,s[96,22]=-0.8,s[96,23]=-1.2,s[96,24]=0.2,s[96,25]=1.2,s[96,26]=1.1,s[96,27]=-0.8,s[96,28]=-0.7,s[96,29]=0.2,s[96,30]=-0.2 s[96,31]=0.6,s[96,32]=-0.7,s[96,33]=1.1,s[96,34]=0.1,s[96,35]=0.7,s[96,36]=0.7,s[96,37]=0.5,s[96,38]=0.4,s[96,39]=0.1,s[96,40]=0.3,s[96,41]=1.0,s[96,42]=0.0,s[96,43]=-0.9,s[96,44]=-0.3,s[96,45]=0.4,s[96,46]=0.7,s[96,47]=-0.2,s[96,48]=0.7,s[96,49]=-0.6,s[96,50]=-0.2,s[96,51]=0.9,s[96,52]=1.2,s[96,53]=-0.9,s[96,54]=-0.4,s[96,55]=-1.0,s[96,56]=0.0,s[96,57]=0.4,s[96,58]=-0.9,s[96,59]=0.6,s[96,60]=-0.5 s[97,1]=-0.2,s[97,2]=-0.4,s[97,3]=-0.2,s[97,4]=-0.6,s[97,5]=0.7,s[97,6]=-0.8,s[97,7]=-1.0,s[97,8]=-0.7,s[97,9]=-1.1,s[97,10]=-0.1,s[97,11]=-0.7,s[97,12]=1.2,s[97,13]=1.0,s[97,14]=-0.3,s[97,15]=0.6,s[97,16]=-0.4,s[97,17]=-0.7,s[97,18]=1.0,s[97,19]=-0.1,s[97,20]=0.9,s[97,21]=1.1,s[97,22]=0.7,s[97,23]=-0.8,s[97,24]=0.8,s[97,25]=0.9,s[97,26]=-0.3,s[97,27]=-0.6,s[97,28]=0.5,s[97,29]=0.8,s[97,30]=-1.2 s[97,31]=-0.1,s[97,32]=-0.3,s[97,33]=0.3,s[97,34]=-1.1,s[97,35]=-0.1,s[97,36]=-0.9,s[97,37]=0.5,s[97,38]=0.9,s[97,39]=-0.8,s[97,40]=0.5,s[97,41]=-0.4,s[97,42]=-0.2,s[97,43]=0.2,s[97,44]=-0.3,s[97,45]=-0.8,s[97,46]=-0.4,s[97,47]=1.2,s[97,48]=-0.3,s[97,49]=0.4,s[97,50]=-0.2,s[97,51]=0.1,s[97,52]=-0.7,s[97,53]=-0.8,s[97,54]=0.3,s[97,55]=-0.5,s[97,56]=0.5,s[97,57]=-0.4,s[97,58]=0.7,s[97,59]=-0.8,s[97,60]=-0.8 s[98,1]=-0.5,s[98,2]=-0.3,s[98,3]=-0.9,s[98,4]=-1.1,s[98,5]=-0.3,s[98,6]=0.9,s[98,7]=1.0,s[98,8]=-0.5,s[98,9]=0.2,s[98,10]=-1.2,s[98,11]=0.0,s[98,12]=-0.8,s[98,13]=-0.3,s[98,14]=0.8,s[98,15]=1.1,s[98,16]=-0.4,s[98,17]=-0.9,s[98,18]=0.0,s[98,19]=0.9,s[98,20]=0.1,s[98,21]=0.6,s[98,22]=-0.5,s[98,23]=0.6,s[98,24]=-1.0,s[98,25]=-1.1,s[98,26]=-1.1,s[98,27]=-0.5,s[98,28]=-0.6,s[98,29]=0.9,s[98,30]=0.3 s[98,31]=-1.2,s[98,32]=-0.4,s[98,33]=-0.3,s[98,34]=-0.6,s[98,35]=-1.1,s[98,36]=0.1,s[98,37]=-0.1,s[98,38]=0.8,s[98,39]=-0.7,s[98,40]=1.0,s[98,41]=-0.1,s[98,42]=0.6,s[98,43]=-1.2,s[98,44]=-0.6,s[98,45]=0.1,s[98,46]=-1.0,s[98,47]=0.7,s[98,48]=-0.6,s[98,49]=0.4,s[98,50]=-1.2,s[98,51]=-0.7,s[98,52]=-0.6,s[98,53]=-0.9,s[98,54]=0.4,s[98,55]=-0.3,s[98,56]=-0.5,s[98,57]=-0.8,s[98,58]=0.1,s[98,59]=0.8,s[98,60]=-1.2 s[99,1]=0.3,s[99,2]=1.0,s[99,3]=0.3,s[99,4]=0.0,s[99,5]=-0.7,s[99,6]=-0.9,s[99,7]=-0.8,s[99,8]=0.5,s[99,9]=0.8,s[99,10]=-0.8,s[99,11]=-0.5,s[99,12]=0.6,s[99,13]=-0.3,s[99,14]=-0.5,s[99,15]=0.4,s[99,16]=1.2,s[99,17]=-0.1,s[99,18]=0.4,s[99,19]=0.6,s[99,20]=0.5,s[99,21]=0.6,s[99,22]=0.2,s[99,23]=-0.2,s[99,24]=0.7,s[99,25]=1.0,s[99,26]=0.9,s[99,27]=0.4,s[99,28]=0.1,s[99,29]=-0.1,s[99,30]=1.0 s[99,31]=-0.2,s[99,32]=-1.0,s[99,33]=0.5,s[99,34]=-0.8,s[99,35]=-0.8,s[99,36]=0.1,s[99,37]=0.5,s[99,38]=-0.2,s[99,39]=1.2,s[99,40]=-1.0,s[99,41]=0.0,s[99,42]=-0.4,s[99,43]=-0.2,s[99,44]=-0.6,s[99,45]=1.2,s[99,46]=0.3,s[99,47]=-0.3,s[99,48]=-1.1,s[99,49]=-0.2,s[99,50]=-0.3,s[99,51]=1.1,s[99,52]=-1.0,s[99,53]=0.0,s[99,54]=0.9,s[99,55]=0.6,s[99,56]=-1.2,s[99,57]=-0.6,s[99,58]=-0.1,s[99,59]=-0.2,s[99,60]=0.3 s[100,1]=-1.1,s[100,2]=0.5,s[100,3]=0.5,s[100,4]=0.0,s[100,5]=0.9,s[100,6]=-0.8,s[100,7]=0.3,s[100,8]=-0.9,s[100,9]=0.9,s[100,10]=-0.7,s[100,11]=-1.2,s[100,12]=0.5,s[100,13]=-1.2,s[100,14]=-0.1,s[100,15]=0.0,s[100,16]=1.1,s[100,17]=-0.9,s[100,18]=-1.1,s[100,19]=-0.9,s[100,20]=0.0,s[100,21]=-0.3,s[100,22]=-0.1,s[100,23]=1.2,s[100,24]=-1.2,s[100,25]=0.8,s[100,26]=0.5,s[100,27]=0.4,s[100,28]=-0.5,s[100,29]=0.6,s[100,30]=0.3 s[100,31]=-0.3,s[100,32]=-0.3,s[100,33]=-0.5,s[100,34]=-0.9,s[100,35]=-0.9,s[100,36]=0.7,s[100,37]=0.3,s[100,38]=-0.3,s[100,39]=-0.2,s[100,40]=-1.0,s[100,41]=-0.7,s[100,42]=0.1,s[100,43]=0.2,s[100,44]=0.4,s[100,45]=0.2,s[100,46]=1.1,s[100,47]=-1.2,s[100,48]=0.3,s[100,49]=-0.3,s[100,50]=0.2,s[100,51]=0.9,s[100,52]=0.7,s[100,53]=-0.6,s[100,54]=0.9,s[100,55]=-1.2,s[100,56]=1.2,s[100,57]=0.6,s[100,58]=0.3,s[100,59]=-0.5,s[100,60]=-0.1 s[101,1]=0.8,s[101,2]=-0.3,s[101,3]=-0.4,s[101,4]=-1.1,s[101,5]=-0.2,s[101,6]=0.4,s[101,7]=0.5,s[101,8]=-0.1,s[101,9]=-0.1,s[101,10]=0.4,s[101,11]=0.6,s[101,12]=0.1,s[101,13]=-1.0,s[101,14]=0.2,s[101,15]=0.8,s[101,16]=0.8,s[101,17]=1.2,s[101,18]=-1.0,s[101,19]=0.1,s[101,20]=0.0,s[101,21]=-0.1,s[101,22]=-0.2,s[101,23]=-1.1,s[101,24]=-0.2,s[101,25]=-0.9,s[101,26]=0.0,s[101,27]=-0.7,s[101,28]=-1.1,s[101,29]=0.8,s[101,30]=0.8 s[101,31]=-0.6,s[101,32]=-1.1,s[101,33]=0.0,s[101,34]=-1.2,s[101,35]=1.2,s[101,36]=-1.2,s[101,37]=-1.0,s[101,38]=1.0,s[101,39]=-0.7,s[101,40]=0.2,s[101,41]=-0.1,s[101,42]=-0.1,s[101,43]=-0.2,s[101,44]=-0.5,s[101,45]=0.0,s[101,46]=0.9,s[101,47]=0.1,s[101,48]=1.0,s[101,49]=0.0,s[101,50]=-0.4,s[101,51]=-0.3,s[101,52]=1.2,s[101,53]=-0.3,s[101,54]=1.0,s[101,55]=1.2,s[101,56]=-0.4,s[101,57]=0.0,s[101,58]=-0.5,s[101,59]=1.1,s[101,60]=-0.6 s[102,1]=0.9,s[102,2]=-0.1,s[102,3]=-1.0,s[102,4]=-0.3,s[102,5]=-0.3,s[102,6]=-0.4,s[102,7]=0.4,s[102,8]=-0.2,s[102,9]=0.8,s[102,10]=-0.1,s[102,11]=-0.7,s[102,12]=0.3,s[102,13]=1.2,s[102,14]=0.3,s[102,15]=0.8,s[102,16]=-0.7,s[102,17]=-0.8,s[102,18]=0.3,s[102,19]=0.7,s[102,20]=-1.2,s[102,21]=-0.7,s[102,22]=-0.9,s[102,23]=-0.7,s[102,24]=-1.0,s[102,25]=0.8,s[102,26]=0.2,s[102,27]=0.4,s[102,28]=-0.9,s[102,29]=0.8,s[102,30]=0.7 s[102,31]=0.1,s[102,32]=0.2,s[102,33]=0.0,s[102,34]=-1.1,s[102,35]=-0.1,s[102,36]=1.1,s[102,37]=-0.6,s[102,38]=0.0,s[102,39]=0.9,s[102,40]=0.1,s[102,41]=-1.0,s[102,42]=1.0,s[102,43]=0.4,s[102,44]=-1.1,s[102,45]=-0.5,s[102,46]=0.7,s[102,47]=-0.9,s[102,48]=0.4,s[102,49]=0.3,s[102,50]=0.0,s[102,51]=0.1,s[102,52]=0.5,s[102,53]=-1.2,s[102,54]=-0.4,s[102,55]=-1.2,s[102,56]=1.2,s[102,57]=-0.8,s[102,58]=-1.2,s[102,59]=-1.2,s[102,60]=0.0 s[103,1]=1.1,s[103,2]=-1.0,s[103,3]=-1.1,s[103,4]=1.1,s[103,5]=0.6,s[103,6]=0.1,s[103,7]=-0.9,s[103,8]=-0.6,s[103,9]=0.4,s[103,10]=0.1,s[103,11]=-0.4,s[103,12]=0.2,s[103,13]=0.0,s[103,14]=0.6,s[103,15]=0.1,s[103,16]=0.7,s[103,17]=-0.7,s[103,18]=0.5,s[103,19]=-1.0,s[103,20]=-0.7,s[103,21]=0.7,s[103,22]=0.7,s[103,23]=0.0,s[103,24]=-0.6,s[103,25]=0.8,s[103,26]=-0.1,s[103,27]=-1.1,s[103,28]=-0.3,s[103,29]=0.6,s[103,30]=0.5 s[103,31]=1.1,s[103,32]=0.9,s[103,33]=0.7,s[103,34]=-0.2,s[103,35]=-0.8,s[103,36]=0.7,s[103,37]=-0.8,s[103,38]=-0.2,s[103,39]=1.0,s[103,40]=0.4,s[103,41]=-0.7,s[103,42]=0.8,s[103,43]=0.4,s[103,44]=0.7,s[103,45]=0.3,s[103,46]=0.1,s[103,47]=-0.4,s[103,48]=-0.2,s[103,49]=0.9,s[103,50]=-1.2,s[103,51]=-0.6,s[103,52]=-0.8,s[103,53]=-0.5,s[103,54]=0.2,s[103,55]=1.1,s[103,56]=-0.9,s[103,57]=0.1,s[103,58]=-1.0,s[103,59]=0.0,s[103,60]=-0.5 s[104,1]=0.2,s[104,2]=-0.5,s[104,3]=0.0,s[104,4]=-0.7,s[104,5]=0.6,s[104,6]=-0.3,s[104,7]=0.6,s[104,8]=-0.4,s[104,9]=0.5,s[104,10]=-0.6,s[104,11]=-1.0,s[104,12]=-0.1,s[104,13]=-1.1,s[104,14]=-0.4,s[104,15]=-1.2,s[104,16]=0.6,s[104,17]=1.0,s[104,18]=0.3,s[104,19]=0.8,s[104,20]=0.7,s[104,21]=0.3,s[104,22]=-0.3,s[104,23]=-0.3,s[104,24]=-1.2,s[104,25]=0.8,s[104,26]=-1.1,s[104,27]=0.4,s[104,28]=1.2,s[104,29]=0.4,s[104,30]=0.3 s[104,31]=-0.4,s[104,32]=0.0,s[104,33]=0.3,s[104,34]=-0.9,s[104,35]=-1.1,s[104,36]=-0.7,s[104,37]=0.7,s[104,38]=-1.1,s[104,39]=-0.8,s[104,40]=-0.6,s[104,41]=-0.1,s[104,42]=1.0,s[104,43]=0.8,s[104,44]=-0.7,s[104,45]=0.3,s[104,46]=1.1,s[104,47]=-0.9,s[104,48]=0.3,s[104,49]=0.6,s[104,50]=-0.8,s[104,51]=-0.3,s[104,52]=0.4,s[104,53]=0.3,s[104,54]=-0.2,s[104,55]=1.2,s[104,56]=0.1,s[104,57]=0.2,s[104,58]=-0.3,s[104,59]=-0.1,s[104,60]=0.0 s[105,1]=-1.1,s[105,2]=-0.4,s[105,3]=-0.9,s[105,4]=-0.6,s[105,5]=-0.3,s[105,6]=0.7,s[105,7]=0.7,s[105,8]=-0.1,s[105,9]=-1.2,s[105,10]=0.9,s[105,11]=-0.2,s[105,12]=0.8,s[105,13]=-0.9,s[105,14]=0.2,s[105,15]=1.2,s[105,16]=-0.7,s[105,17]=0.7,s[105,18]=0.2,s[105,19]=0.2,s[105,20]=-1.1,s[105,21]=0.3,s[105,22]=1.1,s[105,23]=-0.9,s[105,24]=0.5,s[105,25]=0.1,s[105,26]=-0.8,s[105,27]=0.8,s[105,28]=0.0,s[105,29]=-0.6,s[105,30]=0.1 s[105,31]=-1.0,s[105,32]=0.8,s[105,33]=-0.9,s[105,34]=-1.0,s[105,35]=-0.4,s[105,36]=0.6,s[105,37]=-0.3,s[105,38]=1.2,s[105,39]=0.0,s[105,40]=-0.3,s[105,41]=1.2,s[105,42]=1.2,s[105,43]=0.9,s[105,44]=-0.1,s[105,45]=0.0,s[105,46]=-0.8,s[105,47]=-0.7,s[105,48]=-0.9,s[105,49]=-0.4,s[105,50]=0.5,s[105,51]=-0.4,s[105,52]=-0.1,s[105,53]=-1.1,s[105,54]=1.2,s[105,55]=-0.8,s[105,56]=-1.0,s[105,57]=-0.6,s[105,58]=-1.2,s[105,59]=0.3,s[105,60]=-0.4 s[106,1]=0.0,s[106,2]=0.4,s[106,3]=0.9,s[106,4]=0.1,s[106,5]=0.7,s[106,6]=0.0,s[106,7]=1.1,s[106,8]=-1.1,s[106,9]=-0.8,s[106,10]=-1.2,s[106,11]=0.8,s[106,12]=-1.1,s[106,13]=0.6,s[106,14]=1.0,s[106,15]=0.9,s[106,16]=-0.2,s[106,17]=-0.1,s[106,18]=0.1,s[106,19]=0.9,s[106,20]=1.2,s[106,21]=0.3,s[106,22]=0.4,s[106,23]=-0.2,s[106,24]=-0.2,s[106,25]=1.2,s[106,26]=0.6,s[106,27]=-0.8,s[106,28]=-1.2,s[106,29]=0.1,s[106,30]=-1.1 s[106,31]=0.0,s[106,32]=-0.6,s[106,33]=-1.0,s[106,34]=-0.1,s[106,35]=0.8,s[106,36]=1.1,s[106,37]=0.4,s[106,38]=0.6,s[106,39]=-0.5,s[106,40]=-0.2,s[106,41]=-0.1,s[106,42]=-1.0,s[106,43]=0.4,s[106,44]=0.6,s[106,45]=-0.6,s[106,46]=0.3,s[106,47]=0.1,s[106,48]=0.9,s[106,49]=0.4,s[106,50]=1.2,s[106,51]=-1.0,s[106,52]=-0.8,s[106,53]=-0.3,s[106,54]=-0.1,s[106,55]=0.2,s[106,56]=-0.3,s[106,57]=-0.4,s[106,58]=0.0,s[106,59]=0.9,s[106,60]=0.6 s[107,1]=1.0,s[107,2]=-0.9,s[107,3]=0.8,s[107,4]=0.9,s[107,5]=0.0,s[107,6]=0.1,s[107,7]=0.9,s[107,8]=0.4,s[107,9]=-1.1,s[107,10]=-0.6,s[107,11]=-0.3,s[107,12]=1.1,s[107,13]=0.7,s[107,14]=-0.7,s[107,15]=0.8,s[107,16]=-1.2,s[107,17]=0.4,s[107,18]=-0.1,s[107,19]=-1.0,s[107,20]=0.2,s[107,21]=-0.3,s[107,22]=-1.2,s[107,23]=-1.0,s[107,24]=0.9,s[107,25]=-0.7,s[107,26]=-0.8,s[107,27]=0.7,s[107,28]=1.0,s[107,29]=0.2,s[107,30]=0.7 s[107,31]=0.6,s[107,32]=-0.3,s[107,33]=-0.2,s[107,34]=0.8,s[107,35]=0.1,s[107,36]=-0.6,s[107,37]=-0.2,s[107,38]=-0.4,s[107,39]=0.7,s[107,40]=-1.0,s[107,41]=0.4,s[107,42]=-0.7,s[107,43]=-1.2,s[107,44]=-0.4,s[107,45]=-0.2,s[107,46]=1.0,s[107,47]=-1.0,s[107,48]=-0.5,s[107,49]=-1.2,s[107,50]=0.7,s[107,51]=0.7,s[107,52]=0.1,s[107,53]=-1.2,s[107,54]=1.1,s[107,55]=-0.5,s[107,56]=1.0,s[107,57]=-0.9,s[107,58]=0.3,s[107,59]=-0.3,s[107,60]=-0.8 s[108,1]=-0.8,s[108,2]=1.2,s[108,3]=1.1,s[108,4]=-0.9,s[108,5]=1.1,s[108,6]=0.2,s[108,7]=-0.2,s[108,8]=-0.1,s[108,9]=0.5,s[108,10]=-0.7,s[108,11]=-0.3,s[108,12]=-0.3,s[108,13]=0.4,s[108,14]=0.4,s[108,15]=0.1,s[108,16]=0.1,s[108,17]=-0.1,s[108,18]=-0.2,s[108,19]=1.0,s[108,20]=-0.7,s[108,21]=0.2,s[108,22]=0.5,s[108,23]=0.2,s[108,24]=-0.6,s[108,25]=-1.0,s[108,26]=-1.1,s[108,27]=0.2,s[108,28]=-1.0,s[108,29]=-0.2,s[108,30]=-1.1 s[108,31]=0.4,s[108,32]=1.2,s[108,33]=0.0,s[108,34]=-0.9,s[108,35]=-0.6,s[108,36]=-0.7,s[108,37]=0.4,s[108,38]=1.2,s[108,39]=-0.7,s[108,40]=0.6,s[108,41]=-0.1,s[108,42]=1.0,s[108,43]=-0.5,s[108,44]=0.6,s[108,45]=-0.3,s[108,46]=1.0,s[108,47]=-0.1,s[108,48]=1.2,s[108,49]=-0.8,s[108,50]=-0.5,s[108,51]=-0.1,s[108,52]=-1.0,s[108,53]=0.0,s[108,54]=-1.2,s[108,55]=-0.2,s[108,56]=-1.1,s[108,57]=0.1,s[108,58]=0.6,s[108,59]=0.7,s[108,60]=-0.6 s[109,1]=0.3,s[109,2]=0.7,s[109,3]=-0.9,s[109,4]=-1.0,s[109,5]=-0.2,s[109,6]=0.7,s[109,7]=-0.5,s[109,8]=0.7,s[109,9]=0.8,s[109,10]=0.9,s[109,11]=-0.6,s[109,12]=-1.2,s[109,13]=1.1,s[109,14]=-0.4,s[109,15]=0.9,s[109,16]=1.0,s[109,17]=-1.1,s[109,18]=0.3,s[109,19]=0.6,s[109,20]=0.2,s[109,21]=0.9,s[109,22]=-0.1,s[109,23]=-0.7,s[109,24]=-0.4,s[109,25]=-0.8,s[109,26]=-0.4,s[109,27]=-0.1,s[109,28]=-0.6,s[109,29]=0.1,s[109,30]=1.0 s[109,31]=-0.7,s[109,32]=-1.1,s[109,33]=0.8,s[109,34]=0.0,s[109,35]=-0.7,s[109,36]=-0.2,s[109,37]=-1.2,s[109,38]=1.2,s[109,39]=-1.1,s[109,40]=0.1,s[109,41]=1.2,s[109,42]=-0.5,s[109,43]=0.7,s[109,44]=-1.1,s[109,45]=-0.6,s[109,46]=0.1,s[109,47]=-1.0,s[109,48]=-0.3,s[109,49]=0.7,s[109,50]=0.0,s[109,51]=-0.6,s[109,52]=-0.6,s[109,53]=-1.0,s[109,54]=-1.0,s[109,55]=0.5,s[109,56]=0.3,s[109,57]=-1.0,s[109,58]=-0.9,s[109,59]=-1.1,s[109,60]=-0.6 s[110,1]=-0.3,s[110,2]=-1.2,s[110,3]=0.9,s[110,4]=-1.2,s[110,5]=-0.6,s[110,6]=-0.4,s[110,7]=-1.1,s[110,8]=1.0,s[110,9]=0.9,s[110,10]=-0.6,s[110,11]=-0.5,s[110,12]=0.1,s[110,13]=-0.6,s[110,14]=0.2,s[110,15]=0.0,s[110,16]=0.7,s[110,17]=0.7,s[110,18]=0.4,s[110,19]=0.1,s[110,20]=0.0,s[110,21]=0.8,s[110,22]=1.0,s[110,23]=0.9,s[110,24]=0.0,s[110,25]=0.6,s[110,26]=-0.9,s[110,27]=-0.8,s[110,28]=0.1,s[110,29]=0.6,s[110,30]=-0.8 s[110,31]=1.0,s[110,32]=1.1,s[110,33]=-0.2,s[110,34]=-1.1,s[110,35]=0.6,s[110,36]=0.3,s[110,37]=-1.1,s[110,38]=0.7,s[110,39]=-0.8,s[110,40]=-0.8,s[110,41]=-0.3,s[110,42]=-0.1,s[110,43]=-0.3,s[110,44]=-0.4,s[110,45]=0.6,s[110,46]=0.1,s[110,47]=-0.4,s[110,48]=-1.1,s[110,49]=0.8,s[110,50]=-0.5,s[110,51]=-0.5,s[110,52]=-1.1,s[110,53]=-1.2,s[110,54]=-0.1,s[110,55]=0.4,s[110,56]=1.2,s[110,57]=1.1,s[110,58]=0.8,s[110,59]=0.0,s[110,60]=-1.0 s[111,1]=1.2,s[111,2]=0.8,s[111,3]=0.4,s[111,4]=-1.1,s[111,5]=1.0,s[111,6]=-1.2,s[111,7]=-0.4,s[111,8]=-0.9,s[111,9]=-0.3,s[111,10]=-0.4,s[111,11]=1.1,s[111,12]=1.0,s[111,13]=0.7,s[111,14]=0.9,s[111,15]=-0.7,s[111,16]=-0.5,s[111,17]=-0.6,s[111,18]=0.0,s[111,19]=1.2,s[111,20]=-0.9,s[111,21]=-0.6,s[111,22]=-1.0,s[111,23]=1.1,s[111,24]=1.1,s[111,25]=-0.2,s[111,26]=-0.4,s[111,27]=-0.8,s[111,28]=-0.3,s[111,29]=0.2,s[111,30]=0.9 s[111,31]=-0.9,s[111,32]=-1.0,s[111,33]=-0.2,s[111,34]=-0.8,s[111,35]=-0.7,s[111,36]=-0.6,s[111,37]=0.7,s[111,38]=-0.7,s[111,39]=-1.1,s[111,40]=-0.4,s[111,41]=-1.1,s[111,42]=-1.1,s[111,43]=1.2,s[111,44]=1.0,s[111,45]=0.8,s[111,46]=0.8,s[111,47]=-1.0,s[111,48]=-1.1,s[111,49]=0.9,s[111,50]=-0.4,s[111,51]=-0.9,s[111,52]=0.6,s[111,53]=-0.5,s[111,54]=-0.7,s[111,55]=-0.9,s[111,56]=0.5,s[111,57]=0.4,s[111,58]=1.1,s[111,59]=1.2,s[111,60]=-0.8 s[112,1]=1.0,s[112,2]=0.6,s[112,3]=-0.2,s[112,4]=-1.1,s[112,5]=0.3,s[112,6]=-0.8,s[112,7]=0.1,s[112,8]=-0.7,s[112,9]=0.9,s[112,10]=-0.1,s[112,11]=-1.1,s[112,12]=-1.1,s[112,13]=0.7,s[112,14]=0.4,s[112,15]=-0.2,s[112,16]=0.4,s[112,17]=0.7,s[112,18]=0.9,s[112,19]=-0.4,s[112,20]=0.6,s[112,21]=-0.9,s[112,22]=-0.1,s[112,23]=0.6,s[112,24]=-0.8,s[112,25]=0.6,s[112,26]=-0.7,s[112,27]=-1.2,s[112,28]=-0.6,s[112,29]=-0.2,s[112,30]=-0.7 s[112,31]=-0.1,s[112,32]=-0.3,s[112,33]=0.0,s[112,34]=0.3,s[112,35]=1.1,s[112,36]=1.2,s[112,37]=-0.1,s[112,38]=1.1,s[112,39]=0.4,s[112,40]=-0.3,s[112,41]=-1.0,s[112,42]=-1.2,s[112,43]=-0.6,s[112,44]=1.1,s[112,45]=-0.5,s[112,46]=-1.1,s[112,47]=-1.2,s[112,48]=0.2,s[112,49]=1.1,s[112,50]=-0.8,s[112,51]=-1.1,s[112,52]=0.0,s[112,53]=0.7,s[112,54]=0.5,s[112,55]=1.1,s[112,56]=-0.9,s[112,57]=1.0,s[112,58]=-0.7,s[112,59]=-0.6,s[112,60]=-0.2 s[113,1]=0.1,s[113,2]=-0.3,s[113,3]=-0.2,s[113,4]=-0.2,s[113,5]=0.3,s[113,6]=-0.8,s[113,7]=-0.2,s[113,8]=1.2,s[113,9]=-0.8,s[113,10]=0.9,s[113,11]=-0.9,s[113,12]=0.0,s[113,13]=-0.6,s[113,14]=0.0,s[113,15]=0.7,s[113,16]=-0.4,s[113,17]=0.3,s[113,18]=-0.8,s[113,19]=-0.8,s[113,20]=-0.2,s[113,21]=0.8,s[113,22]=0.6,s[113,23]=0.7,s[113,24]=1.1,s[113,25]=-0.2,s[113,26]=-0.4,s[113,27]=0.0,s[113,28]=-1.0,s[113,29]=0.6,s[113,30]=-0.4 s[113,31]=-0.2,s[113,32]=-0.2,s[113,33]=-0.6,s[113,34]=0.7,s[113,35]=0.3,s[113,36]=-0.2,s[113,37]=-1.2,s[113,38]=-0.7,s[113,39]=1.1,s[113,40]=0.2,s[113,41]=-0.5,s[113,42]=0.2,s[113,43]=0.2,s[113,44]=1.1,s[113,45]=0.4,s[113,46]=0.8,s[113,47]=0.4,s[113,48]=-0.5,s[113,49]=-1.0,s[113,50]=1.2,s[113,51]=1.1,s[113,52]=0.8,s[113,53]=0.6,s[113,54]=0.7,s[113,55]=-0.6,s[113,56]=-0.7,s[113,57]=-0.6,s[113,58]=-0.2,s[113,59]=0.9,s[113,60]=-1.0 s[114,1]=-1.1,s[114,2]=0.2,s[114,3]=1.1,s[114,4]=-0.8,s[114,5]=0.3,s[114,6]=0.8,s[114,7]=-1.1,s[114,8]=0.3,s[114,9]=0.2,s[114,10]=0.8,s[114,11]=-1.1,s[114,12]=0.1,s[114,13]=-0.1,s[114,14]=-0.2,s[114,15]=0.4,s[114,16]=-0.1,s[114,17]=-0.7,s[114,18]=0.6,s[114,19]=-0.7,s[114,20]=0.0,s[114,21]=-0.8,s[114,22]=0.9,s[114,23]=0.7,s[114,24]=0.4,s[114,25]=0.2,s[114,26]=-0.4,s[114,27]=0.5,s[114,28]=1.0,s[114,29]=-0.1,s[114,30]=0.4 s[114,31]=0.5,s[114,32]=-0.8,s[114,33]=-0.4,s[114,34]=-1.2,s[114,35]=-0.5,s[114,36]=0.8,s[114,37]=0.5,s[114,38]=1.1,s[114,39]=-0.9,s[114,40]=-0.5,s[114,41]=1.1,s[114,42]=-1.2,s[114,43]=-0.5,s[114,44]=-0.9,s[114,45]=-1.0,s[114,46]=-0.3,s[114,47]=1.1,s[114,48]=-0.3,s[114,49]=0.9,s[114,50]=0.0,s[114,51]=0.2,s[114,52]=0.6,s[114,53]=0.2,s[114,54]=0.9,s[114,55]=0.4,s[114,56]=-0.1,s[114,57]=1.2,s[114,58]=-0.1,s[114,59]=0.7,s[114,60]=-0.4 s[115,1]=1.2,s[115,2]=-0.5,s[115,3]=0.1,s[115,4]=0.3,s[115,5]=0.3,s[115,6]=0.4,s[115,7]=0.9,s[115,8]=1.1,s[115,9]=0.1,s[115,10]=0.0,s[115,11]=-0.2,s[115,12]=0.0,s[115,13]=-1.1,s[115,14]=-0.5,s[115,15]=0.1,s[115,16]=-0.6,s[115,17]=0.6,s[115,18]=-0.9,s[115,19]=-1.1,s[115,20]=-0.2,s[115,21]=-0.8,s[115,22]=-1.2,s[115,23]=-0.1,s[115,24]=-0.1,s[115,25]=-1.0,s[115,26]=0.5,s[115,27]=0.9,s[115,28]=-0.1,s[115,29]=1.1,s[115,30]=-0.1 s[115,31]=0.2,s[115,32]=1.2,s[115,33]=1.1,s[115,34]=0.1,s[115,35]=1.0,s[115,36]=-0.2,s[115,37]=-0.7,s[115,38]=-1.1,s[115,39]=0.2,s[115,40]=0.0,s[115,41]=-0.3,s[115,42]=0.2,s[115,43]=0.4,s[115,44]=-1.2,s[115,45]=-1.2,s[115,46]=-0.2,s[115,47]=0.5,s[115,48]=-1.1,s[115,49]=0.3,s[115,50]=0.0,s[115,51]=0.3,s[115,52]=0.7,s[115,53]=0.5,s[115,54]=-0.1,s[115,55]=-0.6,s[115,56]=0.0,s[115,57]=0.8,s[115,58]=0.1,s[115,59]=0.4,s[115,60]=-1.0 s[116,1]=-0.9,s[116,2]=-0.7,s[116,3]=-0.8,s[116,4]=0.6,s[116,5]=-1.1,s[116,6]=0.1,s[116,7]=0.9,s[116,8]=0.0,s[116,9]=0.8,s[116,10]=0.6,s[116,11]=0.2,s[116,12]=-1.0,s[116,13]=0.2,s[116,14]=-0.7,s[116,15]=-0.2,s[116,16]=1.0,s[116,17]=-0.6,s[116,18]=1.0,s[116,19]=0.1,s[116,20]=0.0,s[116,21]=-0.3,s[116,22]=1.1,s[116,23]=0.5,s[116,24]=0.5,s[116,25]=0.0,s[116,26]=-0.8,s[116,27]=-1.0,s[116,28]=-1.0,s[116,29]=0.7,s[116,30]=0.8 s[116,31]=0.0,s[116,32]=0.3,s[116,33]=0.0,s[116,34]=0.1,s[116,35]=-0.5,s[116,36]=-0.6,s[116,37]=0.2,s[116,38]=-0.1,s[116,39]=-1.0,s[116,40]=-0.7,s[116,41]=0.6,s[116,42]=0.8,s[116,43]=-0.2,s[116,44]=0.2,s[116,45]=0.3,s[116,46]=-1.1,s[116,47]=0.3,s[116,48]=-0.2,s[116,49]=-0.3,s[116,50]=-1.1,s[116,51]=-1.0,s[116,52]=0.3,s[116,53]=-0.7,s[116,54]=0.9,s[116,55]=1.2,s[116,56]=1.1,s[116,57]=-0.7,s[116,58]=0.0,s[116,59]=-0.7,s[116,60]=-0.3 s[117,1]=0.0,s[117,2]=1.2,s[117,3]=-1.0,s[117,4]=-0.6,s[117,5]=0.0,s[117,6]=0.6,s[117,7]=-0.6,s[117,8]=1.2,s[117,9]=0.3,s[117,10]=-0.4,s[117,11]=-1.0,s[117,12]=-0.7,s[117,13]=1.2,s[117,14]=-1.1,s[117,15]=0.9,s[117,16]=-0.4,s[117,17]=-0.3,s[117,18]=0.8,s[117,19]=-1.0,s[117,20]=-0.8,s[117,21]=-1.2,s[117,22]=0.3,s[117,23]=-0.8,s[117,24]=0.0,s[117,25]=-1.2,s[117,26]=-1.0,s[117,27]=1.2,s[117,28]=0.1,s[117,29]=0.2,s[117,30]=0.6 s[117,31]=-0.6,s[117,32]=-0.7,s[117,33]=0.2,s[117,34]=-0.4,s[117,35]=1.0,s[117,36]=0.4,s[117,37]=0.0,s[117,38]=0.0,s[117,39]=-0.3,s[117,40]=-0.3,s[117,41]=-1.2,s[117,42]=-1.2,s[117,43]=-1.0,s[117,44]=0.9,s[117,45]=0.1,s[117,46]=0.0,s[117,47]=0.7,s[117,48]=-0.9,s[117,49]=-0.7,s[117,50]=0.3,s[117,51]=-0.7,s[117,52]=-0.2,s[117,53]=0.0,s[117,54]=0.2,s[117,55]=1.2,s[117,56]=-0.3,s[117,57]=1.1,s[117,58]=-0.7,s[117,59]=0.5,s[117,60]=-1.2 s[118,1]=-0.7,s[118,2]=-0.5,s[118,3]=1.2,s[118,4]=0.1,s[118,5]=-1.1,s[118,6]=0.5,s[118,7]=-0.6,s[118,8]=-0.3,s[118,9]=-0.1,s[118,10]=-1.0,s[118,11]=-0.2,s[118,12]=0.0,s[118,13]=-0.2,s[118,14]=0.9,s[118,15]=-0.9,s[118,16]=-0.9,s[118,17]=-0.9,s[118,18]=1.1,s[118,19]=1.0,s[118,20]=0.1,s[118,21]=-0.3,s[118,22]=-1.2,s[118,23]=0.7,s[118,24]=1.2,s[118,25]=-0.8,s[118,26]=-0.1,s[118,27]=0.4,s[118,28]=-1.2,s[118,29]=-0.3,s[118,30]=0.9 s[118,31]=-0.4,s[118,32]=-1.2,s[118,33]=0.5,s[118,34]=-0.8,s[118,35]=1.0,s[118,36]=0.7,s[118,37]=0.0,s[118,38]=1.1,s[118,39]=-0.7,s[118,40]=0.1,s[118,41]=0.2,s[118,42]=-0.9,s[118,43]=-0.7,s[118,44]=-0.9,s[118,45]=0.3,s[118,46]=-0.3,s[118,47]=1.2,s[118,48]=0.3,s[118,49]=-1.2,s[118,50]=-0.5,s[118,51]=0.8,s[118,52]=0.3,s[118,53]=0.3,s[118,54]=0.2,s[118,55]=-0.4,s[118,56]=0.9,s[118,57]=-0.3,s[118,58]=0.3,s[118,59]=0.4,s[118,60]=-0.5 s[119,1]=0.7,s[119,2]=-1.0,s[119,3]=-0.5,s[119,4]=-1.1,s[119,5]=-0.7,s[119,6]=-0.4,s[119,7]=0.2,s[119,8]=0.1,s[119,9]=0.7,s[119,10]=-0.1,s[119,11]=-0.1,s[119,12]=1.1,s[119,13]=-0.7,s[119,14]=-0.2,s[119,15]=0.1,s[119,16]=0.6,s[119,17]=-1.2,s[119,18]=-1.1,s[119,19]=0.4,s[119,20]=1.1,s[119,21]=-0.6,s[119,22]=-1.2,s[119,23]=-0.4,s[119,24]=1.1,s[119,25]=1.1,s[119,26]=1.2,s[119,27]=0.5,s[119,28]=-0.4,s[119,29]=0.0,s[119,30]=-1.1 s[119,31]=-0.1,s[119,32]=-1.2,s[119,33]=-1.2,s[119,34]=-0.6,s[119,35]=-1.0,s[119,36]=0.5,s[119,37]=-1.1,s[119,38]=-0.2,s[119,39]=0.2,s[119,40]=-0.2,s[119,41]=-0.7,s[119,42]=-0.7,s[119,43]=0.8,s[119,44]=0.0,s[119,45]=-0.1,s[119,46]=-1.0,s[119,47]=0.6,s[119,48]=-1.1,s[119,49]=-1.1,s[119,50]=-0.5,s[119,51]=0.2,s[119,52]=-1.2,s[119,53]=1.2,s[119,54]=0.6,s[119,55]=-0.1,s[119,56]=-0.3,s[119,57]=0.2,s[119,58]=-0.6,s[119,59]=-0.5,s[119,60]=0.0 s[120,1]=-0.8,s[120,2]=-0.4,s[120,3]=0.3,s[120,4]=-1.0,s[120,5]=-1.0,s[120,6]=-1.2,s[120,7]=0.1,s[120,8]=0.4,s[120,9]=-0.2,s[120,10]=0.6,s[120,11]=0.6,s[120,12]=0.8,s[120,13]=-0.3,s[120,14]=-1.0,s[120,15]=-1.2,s[120,16]=0.1,s[120,17]=1.1,s[120,18]=-0.7,s[120,19]=0.6,s[120,20]=-0.8,s[120,21]=-0.9,s[120,22]=-0.8,s[120,23]=-0.2,s[120,24]=-0.3,s[120,25]=-1.2,s[120,26]=1.0,s[120,27]=-0.8,s[120,28]=-0.6,s[120,29]=1.2,s[120,30]=-1.1 s[120,31]=0.9,s[120,32]=1.1,s[120,33]=-0.1,s[120,34]=-0.5,s[120,35]=0.3,s[120,36]=1.2,s[120,37]=-0.4,s[120,38]=0.5,s[120,39]=0.1,s[120,40]=-0.6,s[120,41]=0.7,s[120,42]=0.6,s[120,43]=0.6,s[120,44]=1.1,s[120,45]=-1.2,s[120,46]=-0.7,s[120,47]=-0.6,s[120,48]=0.2,s[120,49]=1.1,s[120,50]=-0.8,s[120,51]=-1.0,s[120,52]=-1.0,s[120,53]=-0.7,s[120,54]=1.2,s[120,55]=-0.8,s[120,56]=0.5,s[120,57]=-0.9,s[120,58]=0.2,s[120,59]=0.7,s[120,60]=-1.1 s[121,1]=-0.6,s[121,2]=-0.1,s[121,3]=-0.4,s[121,4]=-1.0,s[121,5]=-0.2,s[121,6]=-0.9,s[121,7]=0.4,s[121,8]=-1.0,s[121,9]=0.9,s[121,10]=-0.6,s[121,11]=1.0,s[121,12]=1.2,s[121,13]=1.1,s[121,14]=0.9,s[121,15]=-0.8,s[121,16]=-0.8,s[121,17]=-1.2,s[121,18]=-0.3,s[121,19]=0.1,s[121,20]=0.7,s[121,21]=-0.1,s[121,22]=-0.3,s[121,23]=0.0,s[121,24]=0.8,s[121,25]=-1.2,s[121,26]=0.5,s[121,27]=0.9,s[121,28]=1.2,s[121,29]=-0.2,s[121,30]=-0.8 s[121,31]=0.3,s[121,32]=1.0,s[121,33]=0.4,s[121,34]=1.2,s[121,35]=-0.9,s[121,36]=-0.2,s[121,37]=-0.2,s[121,38]=-0.3,s[121,39]=1.1,s[121,40]=0.2,s[121,41]=0.2,s[121,42]=-0.4,s[121,43]=0.9,s[121,44]=-0.8,s[121,45]=0.8,s[121,46]=-1.1,s[121,47]=0.0,s[121,48]=1.0,s[121,49]=-0.6,s[121,50]=-1.0,s[121,51]=0.9,s[121,52]=-0.3,s[121,53]=0.8,s[121,54]=-0.6,s[121,55]=-0.8,s[121,56]=0.1,s[121,57]=0.5,s[121,58]=0.1,s[121,59]=1.2,s[121,60]=-0.9 s[122,1]=0.7,s[122,2]=0.9,s[122,3]=-1.0,s[122,4]=-1.2,s[122,5]=-0.1,s[122,6]=-1.2,s[122,7]=0.4,s[122,8]=0.8,s[122,9]=-1.1,s[122,10]=0.3,s[122,11]=-1.0,s[122,12]=0.6,s[122,13]=-0.1,s[122,14]=0.8,s[122,15]=0.3,s[122,16]=-1.1,s[122,17]=0.0,s[122,18]=-0.7,s[122,19]=1.1,s[122,20]=1.1,s[122,21]=0.8,s[122,22]=-1.2,s[122,23]=-0.8,s[122,24]=-0.5,s[122,25]=0.0,s[122,26]=-0.8,s[122,27]=-0.1,s[122,28]=0.2,s[122,29]=0.5,s[122,30]=-0.1 s[122,31]=0.5,s[122,32]=1.2,s[122,33]=0.7,s[122,34]=-1.0,s[122,35]=-1.1,s[122,36]=-1.1,s[122,37]=0.0,s[122,38]=-0.4,s[122,39]=-0.5,s[122,40]=0.9,s[122,41]=0.7,s[122,42]=-1.0,s[122,43]=0.1,s[122,44]=-0.6,s[122,45]=0.8,s[122,46]=0.4,s[122,47]=-0.3,s[122,48]=0.0,s[122,49]=-0.2,s[122,50]=-0.6,s[122,51]=-0.8,s[122,52]=-0.8,s[122,53]=-0.3,s[122,54]=-0.3,s[122,55]=0.7,s[122,56]=-1.0,s[122,57]=-1.1,s[122,58]=-0.6,s[122,59]=1.2,s[122,60]=-0.1 s[123,1]=0.9,s[123,2]=0.1,s[123,3]=0.1,s[123,4]=-1.2,s[123,5]=0.1,s[123,6]=0.7,s[123,7]=-1.0,s[123,8]=-0.6,s[123,9]=0.1,s[123,10]=0.6,s[123,11]=-1.1,s[123,12]=0.8,s[123,13]=-0.1,s[123,14]=0.1,s[123,15]=0.0,s[123,16]=-0.9,s[123,17]=-0.3,s[123,18]=1.1,s[123,19]=-1.0,s[123,20]=-0.9,s[123,21]=-0.9,s[123,22]=-0.7,s[123,23]=-1.0,s[123,24]=-1.1,s[123,25]=-1.2,s[123,26]=-0.8,s[123,27]=-0.1,s[123,28]=-0.2,s[123,29]=-0.7,s[123,30]=-1.2 s[123,31]=1.2,s[123,32]=-0.2,s[123,33]=-1.2,s[123,34]=-0.7,s[123,35]=-0.2,s[123,36]=-0.1,s[123,37]=0.4,s[123,38]=-0.8,s[123,39]=0.0,s[123,40]=1.1,s[123,41]=0.4,s[123,42]=1.1,s[123,43]=-0.7,s[123,44]=1.2,s[123,45]=-0.8,s[123,46]=-1.2,s[123,47]=0.7,s[123,48]=-0.7,s[123,49]=0.1,s[123,50]=1.1,s[123,51]=0.0,s[123,52]=-0.8,s[123,53]=-0.1,s[123,54]=-1.1,s[123,55]=0.9,s[123,56]=-1.2,s[123,57]=-1.2,s[123,58]=0.4,s[123,59]=-0.4,s[123,60]=-1.0 s[124,1]=-0.7,s[124,2]=0.9,s[124,3]=0.9,s[124,4]=-0.8,s[124,5]=1.0,s[124,6]=-1.1,s[124,7]=0.6,s[124,8]=-0.1,s[124,9]=-0.3,s[124,10]=-0.9,s[124,11]=0.1,s[124,12]=1.0,s[124,13]=-0.3,s[124,14]=0.5,s[124,15]=-0.5,s[124,16]=0.3,s[124,17]=1.2,s[124,18]=-0.2,s[124,19]=1.2,s[124,20]=-0.2,s[124,21]=-1.1,s[124,22]=-0.5,s[124,23]=1.0,s[124,24]=-0.9,s[124,25]=-1.0,s[124,26]=-1.1,s[124,27]=0.8,s[124,28]=0.9,s[124,29]=-0.3,s[124,30]=-1.1 s[124,31]=0.1,s[124,32]=-0.1,s[124,33]=-0.4,s[124,34]=0.6,s[124,35]=0.9,s[124,36]=0.5,s[124,37]=0.4,s[124,38]=-1.0,s[124,39]=0.8,s[124,40]=1.0,s[124,41]=-0.5,s[124,42]=-0.5,s[124,43]=1.2,s[124,44]=-1.1,s[124,45]=-0.4,s[124,46]=0.3,s[124,47]=-1.2,s[124,48]=0.6,s[124,49]=0.3,s[124,50]=-0.4,s[124,51]=-0.5,s[124,52]=1.0,s[124,53]=-0.4,s[124,54]=-0.7,s[124,55]=0.6,s[124,56]=-0.7,s[124,57]=-0.1,s[124,58]=-0.4,s[124,59]=-1.1,s[124,60]=-0.4 s[125,1]=-0.1,s[125,2]=-0.2,s[125,3]=-0.6,s[125,4]=-0.3,s[125,5]=0.7,s[125,6]=-0.2,s[125,7]=-0.5,s[125,8]=-0.1,s[125,9]=-0.5,s[125,10]=0.4,s[125,11]=0.7,s[125,12]=1.1,s[125,13]=0.6,s[125,14]=0.5,s[125,15]=1.1,s[125,16]=-0.9,s[125,17]=0.2,s[125,18]=-0.8,s[125,19]=0.7,s[125,20]=1.2,s[125,21]=-0.1,s[125,22]=0.7,s[125,23]=-1.0,s[125,24]=-1.1,s[125,25]=1.0,s[125,26]=-0.2,s[125,27]=0.4,s[125,28]=-0.9,s[125,29]=0.2,s[125,30]=0.8 s[125,31]=0.3,s[125,32]=-0.3,s[125,33]=-0.4,s[125,34]=-1.0,s[125,35]=0.6,s[125,36]=1.0,s[125,37]=0.3,s[125,38]=0.8,s[125,39]=1.1,s[125,40]=1.1,s[125,41]=-1.0,s[125,42]=0.5,s[125,43]=0.4,s[125,44]=-0.5,s[125,45]=0.3,s[125,46]=-0.4,s[125,47]=-0.3,s[125,48]=1.2,s[125,49]=0.8,s[125,50]=-0.3,s[125,51]=-0.1,s[125,52]=-1.0,s[125,53]=0.6,s[125,54]=-0.4,s[125,55]=-0.9,s[125,56]=-0.6,s[125,57]=0.0,s[125,58]=-1.1,s[125,59]=-1.0,s[125,60]=-0.6 s[126,1]=0.2,s[126,2]=1.1,s[126,3]=-0.9,s[126,4]=-0.1,s[126,5]=0.6,s[126,6]=0.2,s[126,7]=1.1,s[126,8]=-0.6,s[126,9]=-0.8,s[126,10]=0.2,s[126,11]=-1.2,s[126,12]=0.4,s[126,13]=-0.1,s[126,14]=-1.2,s[126,15]=-0.5,s[126,16]=-0.6,s[126,17]=-0.7,s[126,18]=0.0,s[126,19]=-0.5,s[126,20]=0.3,s[126,21]=0.1,s[126,22]=1.2,s[126,23]=-0.2,s[126,24]=-0.5,s[126,25]=-1.0,s[126,26]=0.6,s[126,27]=1.2,s[126,28]=1.1,s[126,29]=0.5,s[126,30]=0.1 s[126,31]=0.0,s[126,32]=-0.2,s[126,33]=-0.6,s[126,34]=1.0,s[126,35]=-1.2,s[126,36]=0.2,s[126,37]=-0.4,s[126,38]=0.4,s[126,39]=0.7,s[126,40]=0.7,s[126,41]=-0.8,s[126,42]=0.4,s[126,43]=0.6,s[126,44]=-0.1,s[126,45]=0.7,s[126,46]=-0.9,s[126,47]=1.2,s[126,48]=-0.2,s[126,49]=0.2,s[126,50]=-0.5,s[126,51]=-0.2,s[126,52]=-1.2,s[126,53]=-0.8,s[126,54]=-0.8,s[126,55]=0.7,s[126,56]=-0.9,s[126,57]=-0.1,s[126,58]=0.9,s[126,59]=-1.2,s[126,60]=-0.7 s[127,1]=-0.1,s[127,2]=-0.1,s[127,3]=-0.3,s[127,4]=-0.3,s[127,5]=-0.6,s[127,6]=1.0,s[127,7]=-0.5,s[127,8]=0.4,s[127,9]=-0.3,s[127,10]=-0.8,s[127,11]=0.3,s[127,12]=0.9,s[127,13]=0.3,s[127,14]=0.6,s[127,15]=1.1,s[127,16]=-0.7,s[127,17]=-0.9,s[127,18]=1.1,s[127,19]=1.1,s[127,20]=0.9,s[127,21]=0.1,s[127,22]=0.1,s[127,23]=0.7,s[127,24]=-1.2,s[127,25]=-0.1,s[127,26]=-0.5,s[127,27]=-0.7,s[127,28]=0.5,s[127,29]=0.0,s[127,30]=1.1 s[127,31]=-1.0,s[127,32]=-0.4,s[127,33]=-0.4,s[127,34]=-1.0,s[127,35]=0.9,s[127,36]=-0.9,s[127,37]=-0.9,s[127,38]=0.8,s[127,39]=0.0,s[127,40]=0.6,s[127,41]=-0.5,s[127,42]=0.4,s[127,43]=0.6,s[127,44]=0.7,s[127,45]=1.1,s[127,46]=-0.9,s[127,47]=0.5,s[127,48]=-0.9,s[127,49]=-0.5,s[127,50]=1.1,s[127,51]=0.3,s[127,52]=0.4,s[127,53]=-0.9,s[127,54]=-0.4,s[127,55]=-0.4,s[127,56]=0.9,s[127,57]=-0.7,s[127,58]=-1.2,s[127,59]=-0.5,s[127,60]=1.1 s[128,1]=-0.5,s[128,2]=-0.3,s[128,3]=1.1,s[128,4]=-1.0,s[128,5]=-0.6,s[128,6]=0.8,s[128,7]=0.6,s[128,8]=0.4,s[128,9]=-1.1,s[128,10]=-1.1,s[128,11]=1.1,s[128,12]=0.2,s[128,13]=-1.2,s[128,14]=0.1,s[128,15]=0.8,s[128,16]=0.3,s[128,17]=-0.4,s[128,18]=-0.1,s[128,19]=0.7,s[128,20]=1.1,s[128,21]=-0.3,s[128,22]=-0.1,s[128,23]=-1.0,s[128,24]=0.2,s[128,25]=0.4,s[128,26]=0.5,s[128,27]=1.0,s[128,28]=-0.4,s[128,29]=-0.7,s[128,30]=1.0 s[128,31]=0.4,s[128,32]=-1.1,s[128,33]=-1.2,s[128,34]=-1.2,s[128,35]=0.2,s[128,36]=-0.4,s[128,37]=-0.9,s[128,38]=0.7,s[128,39]=-0.7,s[128,40]=0.5,s[128,41]=1.1,s[128,42]=-1.0,s[128,43]=0.1,s[128,44]=-0.5,s[128,45]=-1.2,s[128,46]=-0.6,s[128,47]=0.4,s[128,48]=0.8,s[128,49]=0.8,s[128,50]=-0.1,s[128,51]=-0.7,s[128,52]=0.8,s[128,53]=0.3,s[128,54]=1.1,s[128,55]=-0.9,s[128,56]=-0.3,s[128,57]=1.1,s[128,58]=0.4,s[128,59]=1.0,s[128,60]=-0.1 s[129,1]=0.4,s[129,2]=-1.1,s[129,3]=1.2,s[129,4]=-0.5,s[129,5]=0.1,s[129,6]=0.9,s[129,7]=-1.0,s[129,8]=-0.9,s[129,9]=0.5,s[129,10]=-1.1,s[129,11]=-0.2,s[129,12]=-0.2,s[129,13]=0.9,s[129,14]=-0.5,s[129,15]=0.7,s[129,16]=-0.4,s[129,17]=-0.2,s[129,18]=0.4,s[129,19]=0.3,s[129,20]=0.8,s[129,21]=-0.7,s[129,22]=-0.5,s[129,23]=0.5,s[129,24]=-0.4,s[129,25]=0.3,s[129,26]=1.1,s[129,27]=-0.2,s[129,28]=1.0,s[129,29]=-0.7,s[129,30]=-0.5 s[129,31]=-0.2,s[129,32]=1.2,s[129,33]=-1.1,s[129,34]=-1.1,s[129,35]=-1.1,s[129,36]=-1.0,s[129,37]=-0.4,s[129,38]=1.2,s[129,39]=-0.5,s[129,40]=0.2,s[129,41]=0.1,s[129,42]=-0.2,s[129,43]=0.1,s[129,44]=0.8,s[129,45]=-1.0,s[129,46]=-1.2,s[129,47]=-0.4,s[129,48]=-0.4,s[129,49]=0.3,s[129,50]=-1.2,s[129,51]=0.7,s[129,52]=0.4,s[129,53]=-0.7,s[129,54]=-0.8,s[129,55]=-1.1,s[129,56]=-0.7,s[129,57]=-0.3,s[129,58]=-0.8,s[129,59]=0.4,s[129,60]=0.2 s[130,1]=-0.6,s[130,2]=-1.0,s[130,3]=1.2,s[130,4]=1.0,s[130,5]=0.6,s[130,6]=-0.5,s[130,7]=1.0,s[130,8]=0.8,s[130,9]=-0.9,s[130,10]=-0.2,s[130,11]=-1.0,s[130,12]=-0.3,s[130,13]=-1.2,s[130,14]=0.1,s[130,15]=-0.2,s[130,16]=-1.2,s[130,17]=-1.0,s[130,18]=-1.2,s[130,19]=0.4,s[130,20]=0.9,s[130,21]=0.7,s[130,22]=-0.6,s[130,23]=-0.5,s[130,24]=1.1,s[130,25]=0.2,s[130,26]=1.2,s[130,27]=0.1,s[130,28]=1.2,s[130,29]=0.7,s[130,30]=0.1 s[130,31]=-0.6,s[130,32]=-0.2,s[130,33]=0.6,s[130,34]=0.2,s[130,35]=-0.7,s[130,36]=1.2,s[130,37]=-1.1,s[130,38]=-0.1,s[130,39]=0.3,s[130,40]=-1.0,s[130,41]=-0.8,s[130,42]=-1.1,s[130,43]=0.9,s[130,44]=0.0,s[130,45]=-0.9,s[130,46]=-1.2,s[130,47]=0.7,s[130,48]=-0.2,s[130,49]=-0.6,s[130,50]=-0.3,s[130,51]=-0.2,s[130,52]=-1.0,s[130,53]=-0.6,s[130,54]=0.6,s[130,55]=-0.5,s[130,56]=-0.3,s[130,57]=0.4,s[130,58]=-1.0,s[130,59]=1.1,s[130,60]=-0.2 s[131,1]=0.2,s[131,2]=-1.1,s[131,3]=-0.4,s[131,4]=0.6,s[131,5]=0.8,s[131,6]=-1.1,s[131,7]=-0.4,s[131,8]=0.0,s[131,9]=0.1,s[131,10]=-0.3,s[131,11]=0.5,s[131,12]=0.6,s[131,13]=0.4,s[131,14]=-0.1,s[131,15]=-0.6,s[131,16]=0.9,s[131,17]=-1.1,s[131,18]=0.6,s[131,19]=-1.2,s[131,20]=-1.1,s[131,21]=0.2,s[131,22]=0.7,s[131,23]=0.5,s[131,24]=-0.6,s[131,25]=-1.0,s[131,26]=0.1,s[131,27]=0.1,s[131,28]=-0.5,s[131,29]=-0.7,s[131,30]=-0.6 s[131,31]=1.0,s[131,32]=-1.1,s[131,33]=-0.9,s[131,34]=1.1,s[131,35]=0.2,s[131,36]=-0.2,s[131,37]=-0.3,s[131,38]=0.9,s[131,39]=0.6,s[131,40]=0.4,s[131,41]=1.2,s[131,42]=-1.0,s[131,43]=-0.7,s[131,44]=0.6,s[131,45]=0.3,s[131,46]=0.0,s[131,47]=0.9,s[131,48]=-0.4,s[131,49]=0.5,s[131,50]=1.1,s[131,51]=1.0,s[131,52]=-0.2,s[131,53]=-0.9,s[131,54]=-0.7,s[131,55]=-1.1,s[131,56]=-0.4,s[131,57]=0.7,s[131,58]=1.2,s[131,59]=-0.9,s[131,60]=0.4 endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float ppz = @ppz float pxx = 0 float pyy = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x pyy = y x = x + 0.1*(s[@sd,1] + s[@sd,2]*x + s[@sd,3]*x*x + s[@sd,4]*x*x*x + s[@sd,5]*x*x*y + s[@sd,6]*x*x*ppz + s[@sd,7]*x*y + \ s[@sd,8]*x*y*y + s[@sd,9]*x*y*ppz + s[@sd,10]*x*ppz + s[@sd,11]*x*ppz*ppz + s[@sd,12]*y + s[@sd,13]*y*y + s[@sd,14]*y*y*y + \ s[@sd,15]*y*y*ppz + s[@sd,16]*y*ppz + s[@sd,17]*y*ppz*ppz + s[@sd,18]*ppz +s[@sd,19]*ppz*ppz +s[@sd,20]*ppz*ppz*ppz) y = y + 0.1*(s[@sd,21] +s[@sd,22]*pxx +s[@sd,23]*pxx*pxx +s[@sd,24]*pxx*pxx*pxx +s[@sd,25]*pxx*pxx*y +s[@sd,26]*pxx*pxx*ppz +s[@sd,27]*pxx*y +\ s[@sd,28]*pxx*y*y +s[@sd,29]*pxx*y*ppz +s[@sd,30]*pxx*ppz +s[@sd,31]*pxx*ppz*ppz +s[@sd,32]*y +s[@sd,33]*y*y +s[@sd,34]*y*y*y + \ s[@sd,35]*y*y*ppz +s[@sd,36]*y*ppz +s[@sd,37]*y*ppz*ppz +s[@sd,38]*ppz +s[@sd,39]*ppz*ppz +s[@sd,40]*ppz*ppz*ppz) ppz = ppz + 0.1*(s[@sd,41] +s[@sd,42]*pxx +s[@sd,43]*pxx*pxx +s[@sd,44]*pxx*pxx*pxx +s[@sd,45]*pxx*pxx*pyy +s[@sd,46]*pxx*pxx*ppz +s[@sd,47]*pxx*pyy + \ s[@sd,48]*pxx*pyy*pyy +s[@sd,49]*pxx*pyy*ppz +s[@sd,50]*pxx*ppz +s[@sd,51]*pxx*ppz*ppz +s[@sd,52]*pyy +s[@sd,53]*pyy*pyy +s[@sd,54]*pyy*pyy*pyy + \ s[@sd,55]*pyy*pyy*ppz +s[@sd,56]*pyy*ppz +s[@sd,57]*pyy*ppz*ppz +s[@sd,58]*ppz +s[@sd,59]*ppz*ppz +s[@sd,60]*ppz*ppz*ppz) att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y) + ppz*@pw) float d = @distscale*|pz-(x + sgn*flip(y) + ppz*@pw)| return d endfunc private: float s[132,61] default: title = "Sprott3D_Cubic_ODE" heading text="Sprott 3D cubic attractors" endheading heading text=" x -> x + 0.1*(Cubic in x, y and z)" endheading heading text=" y -> y + 0.1*(Cubic in x, y and z)" endheading heading text=" z -> z + 0.1*(Cubic in x, y and z)" endheading int param v_trapshapesprott3d_Cubic_ODE caption = "Version (Trap Shape Sprott3D_Cubic_ODE)" 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_trapshapesprott3d_Cubic_ODE < 100 endparam param sd caption = "Sprott selector" default = 0 enum = "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" \ "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" \ "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" \ "45" "46" "47" "48" "49" "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" \ "60" "61" "62" "63" "64" "65" "66" "67" "69" "69" "70" "71" "72" "73" "74" \ "75" "76" "77" "78" "79" "80" "81" "82" "83" "84" "85" "86" "87" "88" "89" \ "90" "91" "92" "93" "94" "95" "96" "97" "98" "99" "100" "101" "102" "103" \ "104" "105" "106" "107" "108" "109" "110" "111" "112" "113" "114" "115" \ "116" "117" "118" "119" "120" "121" "122" "123" "124" "125" "126" "127" \ "128" "129" "130" "131" hint = "Each Sprott selector uses a different strange attractor." endparam heading text = "'Initialize Height' sets the starting z value for the attractor." endheading float param ppz caption = "Initialize Height" default = 0.0 endparam heading text = "'Height weight' determines the weight of the final z value which is added \ to the trap distance." endheading complex param pw caption = "Height weight" default = (0.5,0) endparam float param distscale caption = "Distance scale" default = 2 endparam float param s caption = "Attractor scale" default = 1 endparam int param max_att_iterations caption = "Attractor iterations" default = 15 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeSprott4D(common.ulb:TrapShape) { ; This shape uses a Sprott strange attractor.
;

; The Sprott attractors were developed by Julien C. Sprott, and are ; based upon polynomials and linear differential equations of polynomials. public: import "common.ulb" ; Constructor func REB_TrapShapeSprott4D(Generic pparent) TrapShape.TrapShape(pparent) s[0,1]=-0.6,s[0,2]=0.5,s[0,3]=1.0,s[0,4]=-0.6,s[0,5]=0.9,s[0,6]=0.3,s[0,7]=1.0,s[0,8]=0.4,s[0,9]=-0.6,s[0,10]=1.0,s[0,11]=-0.3,s[0,12]=-1.0,s[0,13]=0.3,s[0,14]=-0.4,s[0,15]=0.5,s[0,16]=-0.3,s[0,17]=1.0,s[0,18]=0.0,s[0,19]=0.1,s[0,20]=0.7,s[0,21]=0.3,s[0,22]=0.3,s[0,23]=0.3,s[0,24]=-0.6,s[0,25]=0.7,s[0,26]=0.4,s[0,27]=-0.7,s[0,28]=-0.5,s[0,29]=0.1,s[0,30]=-0.1 s[0,31]=0.0,s[0,32]=-0.1,s[0,33]=0.8,s[0,34]=0.3,s[0,35]=0.3,s[0,36]=-0.1,s[0,37]=-0.3,s[0,38]=0.9,s[0,39]=1.0,s[0,40]=-0.8,s[0,41]=0.6,s[0,42]=-0.6,s[0,43]=-0.4,s[0,44]=0.6,s[0,45]=-0.4,s[0,46]=-0.5,s[0,47]=0.3,s[0,48]=-0.5,s[0,49]=0.5,s[0,50]=1.2,s[0,51]=-0.1,s[0,52]=1.1,s[0,53]=0.3,s[0,54]=-1.2,s[0,55]=1.0,s[0,56]=0.2,s[0,57]=-1.2,s[0,58]=0.3,s[0,59]=-0.5,s[0,60]=0.1 s[1,1]=-0.4,s[1,2]=0.1,s[1,3]=1.1,s[1,4]=0.6,s[1,5]=-1.2,s[1,6]=-0.6,s[1,7]=0.4,s[1,8]=0.4,s[1,9]=0.0,s[1,10]=0.0,s[1,11]=0.2,s[1,12]=-0.9,s[1,13]=-0.8,s[1,14]=-0.3,s[1,15]=-0.2,s[1,16]=0.3,s[1,17]=0.1,s[1,18]=0.3,s[1,19]=-0.4,s[1,20]=0.7,s[1,21]=0.2,s[1,22]=-0.5,s[1,23]=-0.5,s[1,24]=-0.6,s[1,25]=-1.2,s[1,26]=0.4,s[1,27]=0.1,s[1,28]=0.1,s[1,29]=0.3,s[1,30]=-0.3,s[1,31]=0.6,s[1,32]=0.8,s[1,33]=0.0,s[1,34]=1.0,s[1,35]=-1.0,s[1,36]=0.4,s[1,37]=1.2,s[1,38]=0.4,s[1,39]=-0.5,s[1,40]=-0.5,s[1,41]=-0.7,s[1,42]=0.3,s[1,43]=1.1,s[1,44]=-0.4,s[1,45]=-0.3,s[1,46]=0.0,s[1,47]=0.6,s[1,48]=-0.7,s[1,49]=1.0,s[1,50]=0.3,s[1,51]=1.0,s[1,52]=-0.1,s[1,53]=0.1,s[1,54]=1.0,s[1,55]=0.1,s[1,56]=0.4,s[1,57]=0.9,s[1,58]=-0.1,s[1,59]=0.5,s[1,60]=-0.5 s[2,1]=-0.2,s[2,2]=0.6,s[2,3]=0.2,s[2,4]=-0.2,s[2,5]=0.4,s[2,6]=-0.9,s[2,7]=-0.6,s[2,8]=0.9,s[2,9]=-0.6,s[2,10]=0.8,s[2,11]=-0.7,s[2,12]=-0.5,s[2,13]=1.0,s[2,14]=0.4,s[2,15]=1.2,s[2,16]=-0.1,s[2,17]=0.6,s[2,18]=-0.7,s[2,19]=0.8,s[2,20]=1.2,s[2,21]=-0.7,s[2,22]=0.4,s[2,23]=-1.1,s[2,24]=-0.9,s[2,25]=-0.5,s[2,26]=0.7,s[2,27]=-1.1,s[2,28]=0.6,s[2,29]=1.1,s[2,30]=-0.8,s[2,31]=0.0,s[2,32]=-0.5,s[2,33]=0.2,s[2,34]=0.8,s[2,35]=0.6,s[2,36]=0.1,s[2,37]=-0.9,s[2,38]=-1.0,s[2,39]=-0.3,s[2,40]=0.3,s[2,41]=-0.6,s[2,42]=-0.4,s[2,43]=-0.9,s[2,44]=0.1,s[2,45]=-0.2,s[2,46]=0.1,s[2,47]=-0.6,s[2,48]=0.3,s[2,49]=-0.2,s[2,50]=0.4,s[2,51]=-0.1,s[2,52]=0.6,s[2,53]=-0.1,s[2,54]=-0.9,s[2,55]=0.4,s[2,56]=1.0,s[2,57]=0.3,s[2,58]=-0.3,s[2,59]=0.1,s[2,60]=0.4 s[3,1]=-0.1,s[3,2]=0.4,s[3,3]=-1.2,s[3,4]=-0.1,s[3,5]=-0.7,s[3,6]=1.2,s[3,7]=-0.4,s[3,8]=-0.3,s[3,9]=0.0,s[3,10]=-0.3,s[3,11]=-0.2,s[3,12]=-0.2,s[3,13]=-1.0,s[3,14]=0.2,s[3,15]=-1.1,s[3,16]=-0.7,s[3,17]=-0.4,s[3,18]=0.9,s[3,19]=0.1,s[3,20]=1.1,s[3,21]=-0.7,s[3,22]=-0.8,s[3,23]=-0.1,s[3,24]=0.8,s[3,25]=-0.6,s[3,26]=0.6,s[3,27]=-0.6,s[3,28]=-1.1,s[3,29]=0.1,s[3,30]=1.0,s[3,31]=-0.5,s[3,32]=-1.2,s[3,33]=1.2,s[3,34]=1.0,s[3,35]=-0.9,s[3,36]=-0.4,s[3,37]=0.4,s[3,38]=1.2,s[3,39]=-0.9,s[3,40]=0.5,s[3,41]=-0.3,s[3,42]=0.2,s[3,43]=0.8,s[3,44]=1.0,s[3,45]=0.1,s[3,46]=-0.1,s[3,47]=0.0,s[3,48]=-0.1,s[3,49]=0.2,s[3,50]=0.3,s[3,51]=-1.2,s[3,52]=-0.2,s[3,53]=-0.3,s[3,54]=-0.7,s[3,55]=-1.1,s[3,56]=-0.7,s[3,57]=0.4,s[3,58]=-0.5,s[3,59]=-0.5,s[3,60]=-0.9 s[4,1]=-0.1,s[4,2]=0.5,s[4,3]=-0.1,s[4,4]=-0.9,s[4,5]=0.9,s[4,6]=-0.4,s[4,7]=0.5,s[4,8]=-0.7,s[4,9]=-0.3,s[4,10]=0.5,s[4,11]=-0.3,s[4,12]=-0.6,s[4,13]=-0.4,s[4,14]=-0.1,s[4,15]=0.8,s[4,16]=0.4,s[4,17]=1.2,s[4,18]=1.2,s[4,19]=1.2,s[4,20]=0.6,s[4,21]=-0.7,s[4,22]=-0.2,s[4,23]=-0.5,s[4,24]=0.0,s[4,25]=0.4,s[4,26]=0.4,s[4,27]=0.2,s[4,28]=1.0,s[4,29]=0.5,s[4,30]=0.0,s[4,31]=-0.4,s[4,32]=-0.4,s[4,33]=0.3,s[4,34]=0.5,s[4,35]=-0.6,s[4,36]=0.1,s[4,37]=0.4,s[4,38]=-0.3,s[4,39]=-0.5,s[4,40]=0.5,s[4,41]=-0.2,s[4,42]=-0.2,s[4,43]=-0.5,s[4,44]=1.2,s[4,45]=-0.9,s[4,46]=0.0,s[4,47]=1.1,s[4,48]=0.6,s[4,49]=-0.4,s[4,50]=1.2,s[4,51]=0.0,s[4,52]=-0.7,s[4,53]=0.3,s[4,54]=-0.1,s[4,55]=0.4,s[4,56]=0.5,s[4,57]=1.0,s[4,58]=0.6,s[4,59]=0.6,s[4,60]=-0.9 s[5,1]=0.0,s[5,2]=-0.9,s[5,3]=-0.9,s[5,4]=-0.2,s[5,5]=-1.0,s[5,6]=-1.1,s[5,7]=0.5,s[5,8]=0.2,s[5,9]=-0.2,s[5,10]=1.2,s[5,11]=-0.3,s[5,12]=0.0,s[5,13]=1.1,s[5,14]=1.1,s[5,15]=0.4,s[5,16]=-0.2,s[5,17]=0.3,s[5,18]=-1.1,s[5,19]=0.0,s[5,20]=-0.3,s[5,21]=0.6,s[5,22]=0.6,s[5,23]=0.0,s[5,24]=0.6,s[5,25]=0.8,s[5,26]=0.5,s[5,27]=0.1,s[5,28]=-0.4,s[5,29]=-0.2,s[5,30]=0.6,s[5,31]=0.2,s[5,32]=0.1,s[5,33]=-1.1,s[5,34]=0.7,s[5,35]=1.0,s[5,36]=0.8,s[5,37]=-1.0,s[5,38]=-1.0,s[5,39]=0.2,s[5,40]=0.3,s[5,41]=0.5,s[5,42]=-1.2,s[5,43]=-0.6,s[5,44]=0.0,s[5,45]=-0.7,s[5,46]=0.3,s[5,47]=0.1,s[5,48]=0.1,s[5,49]=0.7,s[5,50]=0.9,s[5,51]=-0.6,s[5,52]=0.5,s[5,53]=0.1,s[5,54]=-0.8,s[5,55]=0.4,s[5,56]=-0.9,s[5,57]=0.4,s[5,58]=1.2,s[5,59]=0.1,s[5,60]=-0.1 s[6,1]=0.0,s[6,2]=1.0,s[6,3]=1.2,s[6,4]=-0.2,s[6,5]=-1.2,s[6,6]=0.5,s[6,7]=1.1,s[6,8]=-0.3,s[6,9]=-0.6,s[6,10]=1.1,s[6,11]=0.5,s[6,12]=-0.9,s[6,13]=-0.1,s[6,14]=0.0,s[6,15]=-0.2,s[6,16]=-0.2,s[6,17]=-0.8,s[6,18]=0.6,s[6,19]=-0.5,s[6,20]=0.1,s[6,21]=0.6,s[6,22]=-0.3,s[6,23]=-0.8,s[6,24]=0.4,s[6,25]=-0.5,s[6,26]=-0.3,s[6,27]=0.5,s[6,28]=0.9,s[6,29]=-0.8,s[6,30]=-0.8,s[6,31]=0.5,s[6,32]=0.6,s[6,33]=1.0,s[6,34]=1.0,s[6,35]=-0.7,s[6,36]=1.1,s[6,37]=-0.8,s[6,38]=-0.8,s[6,39]=-0.1,s[6,40]=0.6,s[6,41]=-0.6,s[6,42]=-0.6,s[6,43]=0.0,s[6,44]=0.8,s[6,45]=-1.2,s[6,46]=0.2,s[6,47]=-0.8,s[6,48]=-0.5,s[6,49]=1.0,s[6,50]=1.2,s[6,51]=1.1,s[6,52]=-0.1,s[6,53]=0.0,s[6,54]=-0.5,s[6,55]=0.1,s[6,56]=-0.1,s[6,57]=0.0,s[6,58]=-0.1,s[6,59]=0.2,s[6,60]=0.1 s[7,1]=-0.2,s[7,2]=1.0,s[7,3]=1.0,s[7,4]=-0.7,s[7,5]=0.7,s[7,6]=0.4,s[7,7]=-0.5,s[7,8]=1.0,s[7,9]=-0.7,s[7,10]=-0.7,s[7,11]=-1.1,s[7,12]=-0.2,s[7,13]=-1.0,s[7,14]=-0.7,s[7,15]=-0.5,s[7,16]=0.0,s[7,17]=0.8,s[7,18]=0.6,s[7,19]=0.9,s[7,20]=-0.7,s[7,21]=-0.7,s[7,22]=-0.7,s[7,23]=-1.2,s[7,24]=0.1,s[7,25]=-1.0,s[7,26]=0.5,s[7,27]=0.2,s[7,28]=-0.6,s[7,29]=0.6,s[7,30]=0.6,s[7,31]=0.3,s[7,32]=0.3,s[7,33]=-0.6,s[7,34]=0.2,s[7,35]=1.2,s[7,36]=0.7,s[7,37]=0.7,s[7,38]=-1.0,s[7,39]=-1.2,s[7,40]=0.2,s[7,41]=0.1,s[7,42]=-0.4,s[7,43]=0.8,s[7,44]=-0.1,s[7,45]=0.3,s[7,46]=-0.6,s[7,47]=0.5,s[7,48]=-0.4,s[7,49]=0.7,s[7,50]=-0.8,s[7,51]=-1.2,s[7,52]=0.4,s[7,53]=0.9,s[7,54]=0.9,s[7,55]=0.4,s[7,56]=-0.4,s[7,57]=-1.0,s[7,58]=-1.1,s[7,59]=-0.2,s[7,60]=-0.2 s[8,1]=0.1,s[8,2]=-0.6,s[8,3]=-0.7,s[8,4]=0.2,s[8,5]=-0.7,s[8,6]=0.0,s[8,7]=-0.2,s[8,8]=-1.0,s[8,9]=1.2,s[8,10]=-0.4,s[8,11]=-0.7,s[8,12]=-0.6,s[8,13]=-0.3,s[8,14]=0.6,s[8,15]=0.6,s[8,16]=0.2,s[8,17]=0.9,s[8,18]=0.4,s[8,19]=-0.2,s[8,20]=0.8,s[8,21]=1.2,s[8,22]=-0.2,s[8,23]=0.8,s[8,24]=-0.5,s[8,25]=0.7,s[8,26]=-0.4,s[8,27]=0.7,s[8,28]=-0.3,s[8,29]=1.0,s[8,30]=-0.8,s[8,31]=0.0,s[8,32]=0.8,s[8,33]=-0.5,s[8,34]=0.1,s[8,35]=0.3,s[8,36]=1.1,s[8,37]=0.0,s[8,38]=-0.7,s[8,39]=-1.2,s[8,40]=-1.1,s[8,41]=0.8,s[8,42]=1.0,s[8,43]=1.1,s[8,44]=-0.6,s[8,45]=-1.2,s[8,46]=0.0,s[8,47]=0.4,s[8,48]=0.1,s[8,49]=0.4,s[8,50]=0.2,s[8,51]=1.1,s[8,52]=0.0,s[8,53]=-0.6,s[8,54]=0.4,s[8,55]=0.7,s[8,56]=0.9,s[8,57]=-0.3,s[8,58]=0.4,s[8,59]=0.2,s[8,60]=-1.2 s[9,1]=0.5,s[9,2]=-0.4,s[9,3]=-0.9,s[9,4]=-0.7,s[9,5]=0.0,s[9,6]=-0.4,s[9,7]=-0.5,s[9,8]=0.5,s[9,9]=-0.2,s[9,10]=-0.4,s[9,11]=0.5,s[9,12]=-1.2,s[9,13]=0.1,s[9,14]=-0.8,s[9,15]=0.1,s[9,16]=-0.4,s[9,17]=0.1,s[9,18]=0.9,s[9,19]=0.7,s[9,20]=-0.9,s[9,21]=0.1,s[9,22]=-0.3,s[9,23]=-0.2,s[9,24]=-1.1,s[9,25]=0.5,s[9,26]=0.9,s[9,27]=-1.2,s[9,28]=-0.7,s[9,29]=0.1,s[9,30]=1.0,s[9,31]=0.3,s[9,32]=0.4,s[9,33]=-0.3,s[9,34]=-0.9,s[9,35]=-0.9,s[9,36]=0.2,s[9,37]=-0.9,s[9,38]=-1.2,s[9,39]=0.0,s[9,40]=0.9,s[9,41]=-0.3,s[9,42]=-0.4,s[9,43]=1.0,s[9,44]=0.2,s[9,45]=-0.4,s[9,46]=0.4,s[9,47]=0.2,s[9,48]=1.0,s[9,49]=-0.7,s[9,50]=0.4,s[9,51]=-1.1,s[9,52]=-0.6,s[9,53]=-0.3,s[9,54]=-0.3,s[9,55]=-0.8,s[9,56]=-0.7,s[9,57]=-0.4,s[9,58]=0.5,s[9,59]=-0.8,s[9,60]=1.2 s[10,1]=-0.4,s[10,2]=0.9,s[10,3]=-0.4,s[10,4]=-0.3,s[10,5]=1.2,s[10,6]=-0.9,s[10,7]=1.0,s[10,8]=0.6,s[10,9]=-0.2,s[10,10]=-1.0,s[10,11]=-1.2,s[10,12]=-0.6,s[10,13]=0.7,s[10,14]=0.4,s[10,15]=-1.2,s[10,16]=0.0,s[10,17]=-0.3,s[10,18]=-0.9,s[10,19]=1.0,s[10,20]=-0.1,s[10,21]=1.2,s[10,22]=-1.0,s[10,23]=-1.1,s[10,24]=-0.2,s[10,25]=-0.3,s[10,26]=-0.6,s[10,27]=-0.9,s[10,28]=-0.3,s[10,29]=-0.2,s[10,30]=-0.1,s[10,31]=-0.6,s[10,32]=-0.8,s[10,33]=-0.8,s[10,34]=-1.2,s[10,35]=-0.1,s[10,36]=-1.0,s[10,37]=-1.1,s[10,38]=-1.0,s[10,39]=-1.0,s[10,40]=-0.7,s[10,41]=0.5,s[10,42]=0.5,s[10,43]=0.0,s[10,44]=-0.3,s[10,45]=-0.6,s[10,46]=0.1,s[10,47]=0.0,s[10,48]=0.1,s[10,49]=0.6,s[10,50]=0.7,s[10,51]=-0.1,s[10,52]=-1.1,s[10,53]=1.1,s[10,54]=0.4,s[10,55]=1.2,s[10,56]=1.2,s[10,57]=0.1,s[10,58]=1.2,s[10,59]=0.7,s[10,60]=0.8 s[11,1]=-0.2,s[11,2]=0.1,s[11,3]=-0.9,s[11,4]=0.9,s[11,5]=1.0,s[11,6]=1.1,s[11,7]=0.0,s[11,8]=0.2,s[11,9]=-0.3,s[11,10]=-1.0,s[11,11]=-0.1,s[11,12]=0.3,s[11,13]=0.3,s[11,14]=-0.7,s[11,15]=-0.9,s[11,16]=-0.9,s[11,17]=-0.6,s[11,18]=1.0,s[11,19]=-0.6,s[11,20]=-0.7,s[11,21]=-1.2,s[11,22]=-0.5,s[11,23]=0.0,s[11,24]=0.2,s[11,25]=0.3,s[11,26]=-0.2,s[11,27]=-0.2,s[11,28]=0.6,s[11,29]=-0.3,s[11,30]=1.0,s[11,31]=-0.3,s[11,32]=0.7,s[11,33]=-0.4,s[11,34]=0.5,s[11,35]=-1.0,s[11,36]=-0.7,s[11,37]=-0.9,s[11,38]=0.3,s[11,39]=-1.1,s[11,40]=1.2,s[11,41]=-0.3,s[11,42]=0.8,s[11,43]=0.1,s[11,44]=0.8,s[11,45]=-1.2,s[11,46]=-0.1,s[11,47]=-0.9,s[11,48]=-0.5,s[11,49]=1.2,s[11,50]=-0.8,s[11,51]=0.0,s[11,52]=1.0,s[11,53]=0.3,s[11,54]=0.1,s[11,55]=0.7,s[11,56]=0.8,s[11,57]=1.2,s[11,58]=0.6,s[11,59]=0.0,s[11,60]=0.1 s[12,1]=0.2,s[12,2]=-0.1,s[12,3]=0.6,s[12,4]=-0.1,s[12,5]=-1.2,s[12,6]=-0.9,s[12,7]=-0.9,s[12,8]=-0.9,s[12,9]=0.4,s[12,10]=-0.7,s[12,11]=0.3,s[12,12]=-0.4,s[12,13]=-1.2,s[12,14]=-0.4,s[12,15]=0.8,s[12,16]=-0.4,s[12,17]=1.0,s[12,18]=-0.5,s[12,19]=-1.1,s[12,20]=-0.7,s[12,21]=1.2,s[12,22]=0.4,s[12,23]=0.6,s[12,24]=0.8,s[12,25]=0.3,s[12,26]=0.6,s[12,27]=0.5,s[12,28]=0.3,s[12,29]=-0.8,s[12,30]=-0.9,s[12,31]=0.0,s[12,32]=-0.3,s[12,33]=1.1,s[12,34]=0.5,s[12,35]=-0.4,s[12,36]=-0.9,s[12,37]=0.7,s[12,38]=0.6,s[12,39]=1.1,s[12,40]=-0.6,s[12,41]=0.1,s[12,42]=-0.4,s[12,43]=0.9,s[12,44]=0.8,s[12,45]=-0.1,s[12,46]=0.0,s[12,47]=0.8,s[12,48]=0.8,s[12,49]=0.3,s[12,50]=-0.4,s[12,51]=-0.1,s[12,52]=-0.1,s[12,53]=-0.7,s[12,54]=-0.6,s[12,55]=-0.9,s[12,56]=0.4,s[12,57]=-0.5,s[12,58]=0.5,s[12,59]=0.6,s[12,60]=-0.9 s[13,1]=0.0,s[13,2]=-0.5,s[13,3]=0.5,s[13,4]=-0.5,s[13,5]=0.9,s[13,6]=-0.4,s[13,7]=0.2,s[13,8]=-0.5,s[13,9]=0.3,s[13,10]=-0.2,s[13,11]=-0.1,s[13,12]=-0.9,s[13,13]=-0.3,s[13,14]=0.1,s[13,15]=-1.0,s[13,16]=-0.2,s[13,17]=-0.8,s[13,18]=-0.1,s[13,19]=-1.2,s[13,20]=0.6,s[13,21]=-0.2,s[13,22]=-0.9,s[13,23]=0.4,s[13,24]=-0.3,s[13,25]=-0.6,s[13,26]=0.8,s[13,27]=0.0,s[13,28]=-1.2,s[13,29]=0.1,s[13,30]=1.1,s[13,31]=-0.4,s[13,32]=-0.1,s[13,33]=1.2,s[13,34]=0.1,s[13,35]=0.4,s[13,36]=-0.5,s[13,37]=-0.9,s[13,38]=0.2,s[13,39]=1.0,s[13,40]=-0.7,s[13,41]=0.7,s[13,42]=-0.6,s[13,43]=-0.6,s[13,44]=0.4,s[13,45]=1.1,s[13,46]=0.0,s[13,47]=0.1,s[13,48]=0.4,s[13,49]=-0.2,s[13,50]=0.4,s[13,51]=1.2,s[13,52]=0.7,s[13,53]=-0.4,s[13,54]=0.5,s[13,55]=1.2,s[13,56]=-0.8,s[13,57]=0.2,s[13,58]=-1.1,s[13,59]=0.2,s[13,60]=-0.9 s[14,1]=0.6,s[14,2]=-0.7,s[14,3]=-0.5,s[14,4]=-0.7,s[14,5]=1.0,s[14,6]=0.4,s[14,7]=-0.5,s[14,8]=-1.0,s[14,9]=-0.6,s[14,10]=-0.3,s[14,11]=-0.9,s[14,12]=-1.0,s[14,13]=0.0,s[14,14]=1.2,s[14,15]=-0.5,s[14,16]=0.1,s[14,17]=-0.4,s[14,18]=0.0,s[14,19]=0.5,s[14,20]=-1.0,s[14,21]=0.3,s[14,22]=0.3,s[14,23]=1.2,s[14,24]=0.0,s[14,25]=-0.4,s[14,26]=0.7,s[14,27]=0.5,s[14,28]=1.0,s[14,29]=0.3,s[14,30]=0.6,s[14,31]=0.1,s[14,32]=0.6,s[14,33]=-1.1,s[14,34]=0.2,s[14,35]=-0.8,s[14,36]=1.1,s[14,37]=-0.8,s[14,38]=0.6,s[14,39]=-1.1,s[14,40]=0.8,s[14,41]=0.0,s[14,42]=-0.3,s[14,43]=-0.5,s[14,44]=-0.5,s[14,45]=-0.8,s[14,46]=0.3,s[14,47]=-0.6,s[14,48]=0.1,s[14,49]=0.2,s[14,50]=1.0,s[14,51]=1.0,s[14,52]=-1.0,s[14,53]=1.2,s[14,54]=0.3,s[14,55]=-0.1,s[14,56]=0.3,s[14,57]=0.8,s[14,58]=0.2,s[14,59]=0.1,s[14,60]=0.5 s[15,1]=-0.1,s[15,2]=-1.0,s[15,3]=0.1,s[15,4]=0.8,s[15,5]=0.3,s[15,6]=1.1,s[15,7]=0.1,s[15,8]=-0.3,s[15,9]=0.5,s[15,10]=0.5,s[15,11]=0.7,s[15,12]=0.9,s[15,13]=0.4,s[15,14]=0.5,s[15,15]=-0.3,s[15,16]=0.2,s[15,17]=0.1,s[15,18]=0.1,s[15,19]=0.6,s[15,20]=-1.2,s[15,21]=0.5,s[15,22]=-0.7,s[15,23]=0.7,s[15,24]=-0.6,s[15,25]=0.5,s[15,26]=-0.2,s[15,27]=0.4,s[15,28]=0.1,s[15,29]=0.9,s[15,30]=0.2,s[15,31]=-0.2,s[15,32]=-1.2,s[15,33]=0.9,s[15,34]=-0.1,s[15,35]=-1.1,s[15,36]=0.6,s[15,37]=0.1,s[15,38]=-0.1,s[15,39]=-1.0,s[15,40]=0.4,s[15,41]=0.5,s[15,42]=0.7,s[15,43]=0.3,s[15,44]=0.4,s[15,45]=-0.4,s[15,46]=-0.2,s[15,47]=-0.5,s[15,48]=0.6,s[15,49]=0.1,s[15,50]=-0.8,s[15,51]=0.8,s[15,52]=-0.6,s[15,53]=0.5,s[15,54]=-1.2,s[15,55]=-1.0,s[15,56]=0.3,s[15,57]=1.1,s[15,58]=0.3,s[15,59]=-0.4,s[15,60]=-0.3 s[16,1]=0.1,s[16,2]=-0.2,s[16,3]=-0.7,s[16,4]=-1.1,s[16,5]=-0.4,s[16,6]=0.0,s[16,7]=-0.7,s[16,8]=-0.8,s[16,9]=-0.2,s[16,10]=-0.7,s[16,11]=-0.1,s[16,12]=0.1,s[16,13]=0.0,s[16,14]=0.0,s[16,15]=-1.1,s[16,16]=-0.2,s[16,17]=0.3,s[16,18]=1.2,s[16,19]=0.3,s[16,20]=0.9,s[16,21]=0.9,s[16,22]=-0.6,s[16,23]=0.0,s[16,24]=0.8,s[16,25]=1.0,s[16,26]=0.2,s[16,27]=-0.6,s[16,28]=-1.2,s[16,29]=-0.8,s[16,30]=0.5,s[16,31]=0.0,s[16,32]=-0.3,s[16,33]=-0.6,s[16,34]=-0.2,s[16,35]=-0.9,s[16,36]=0.2,s[16,37]=0.2,s[16,38]=-0.8,s[16,39]=-0.3,s[16,40]=-0.8,s[16,41]=-0.2,s[16,42]=1.0,s[16,43]=0.8,s[16,44]=1.0,s[16,45]=0.3,s[16,46]=0.3,s[16,47]=-0.6,s[16,48]=-1.1,s[16,49]=0.6,s[16,50]=-1.0,s[16,51]=0.2,s[16,52]=0.3,s[16,53]=0.1,s[16,54]=0.4,s[16,55]=1.1,s[16,56]=0.6,s[16,57]=-0.3,s[16,58]=0.1,s[16,59]=0.7,s[16,60]=0.0 s[17,1]=0.0,s[17,2]=0.1,s[17,3]=1.1,s[17,4]=1.1,s[17,5]=0.9,s[17,6]=1.2,s[17,7]=-0.8,s[17,8]=-0.3,s[17,9]=0.6,s[17,10]=0.2,s[17,11]=0.0,s[17,12]=0.0,s[17,13]=0.7,s[17,14]=-1.0,s[17,15]=-0.2,s[17,16]=-0.2,s[17,17]=0.2,s[17,18]=0.4,s[17,19]=0.0,s[17,20]=0.2,s[17,21]=0.2,s[17,22]=0.2,s[17,23]=-1.2,s[17,24]=0.0,s[17,25]=-0.8,s[17,26]=0.8,s[17,27]=1.0,s[17,28]=-1.2,s[17,29]=0.1,s[17,30]=0.0,s[17,31]=-0.2,s[17,32]=-0.8,s[17,33]=-0.3,s[17,34]=1.2,s[17,35]=-0.6,s[17,36]=1.0,s[17,37]=-0.9,s[17,38]=0.5,s[17,39]=-0.6,s[17,40]=-1.1,s[17,41]=-1.1,s[17,42]=-0.1,s[17,43]=-0.4,s[17,44]=0.6,s[17,45]=0.1,s[17,46]=-0.2,s[17,47]=0.1,s[17,48]=-1.1,s[17,49]=-1.1,s[17,50]=-0.5,s[17,51]=0.6,s[17,52]=-0.3,s[17,53]=0.8,s[17,54]=0.2,s[17,55]=0.9,s[17,56]=-0.8,s[17,57]=1.1,s[17,58]=0.7,s[17,59]=0.0,s[17,60]=-0.3 s[18,1]=0.1,s[18,2]=-0.1,s[18,3]=0.8,s[18,4]=1.1,s[18,5]=0.9,s[18,6]=-0.7,s[18,7]=0.7,s[18,8]=1.0,s[18,9]=-0.5,s[18,10]=-0.2,s[18,11]=0.0,s[18,12]=-1.1,s[18,13]=-0.7,s[18,14]=0.5,s[18,15]=0.3,s[18,16]=-0.3,s[18,17]=-0.3,s[18,18]=0.2,s[18,19]=1.2,s[18,20]=0.9,s[18,21]=-0.8,s[18,22]=-0.7,s[18,23]=0.0,s[18,24]=-1.2,s[18,25]=-0.5,s[18,26]=-0.4,s[18,27]=0.2,s[18,28]=1.0,s[18,29]=1.0,s[18,30]=-1.1,s[18,31]=0.1,s[18,32]=0.6,s[18,33]=-0.7,s[18,34]=0.0,s[18,35]=-0.1,s[18,36]=1.1,s[18,37]=0.7,s[18,38]=0.7,s[18,39]=-1.1,s[18,40]=1.2,s[18,41]=-1.2,s[18,42]=0.5,s[18,43]=-0.6,s[18,44]=-0.6,s[18,45]=1.0,s[18,46]=0.0,s[18,47]=-0.2,s[18,48]=0.2,s[18,49]=0.6,s[18,50]=-0.2,s[18,51]=0.0,s[18,52]=0.4,s[18,53]=0.2,s[18,54]=0.3,s[18,55]=1.1,s[18,56]=0.7,s[18,57]=-0.7,s[18,58]=0.2,s[18,59]=0.1,s[18,60]=0.9 s[19,1]=0.6,s[19,2]=0.3,s[19,3]=-0.3,s[19,4]=0.2,s[19,5]=-0.4,s[19,6]=0.7,s[19,7]=0.7,s[19,8]=0.8,s[19,9]=0.6,s[19,10]=1.2,s[19,11]=-0.5,s[19,12]=-1.2,s[19,13]=0.7,s[19,14]=-0.9,s[19,15]=-0.8,s[19,16]=-0.4,s[19,17]=0.7,s[19,18]=0.4,s[19,19]=-0.2,s[19,20]=-0.2,s[19,21]=-0.5,s[19,22]=-0.4,s[19,23]=-0.3,s[19,24]=-0.7,s[19,25]=-0.6,s[19,26]=0.0,s[19,27]=0.1,s[19,28]=0.2,s[19,29]=0.7,s[19,30]=0.9,s[19,31]=0.4,s[19,32]=-0.1,s[19,33]=1.1,s[19,34]=-0.4,s[19,35]=0.3,s[19,36]=0.2,s[19,37]=0.6,s[19,38]=-0.3,s[19,39]=-0.5,s[19,40]=0.3,s[19,41]=0.1,s[19,42]=-0.2,s[19,43]=-0.5,s[19,44]=-0.8,s[19,45]=-0.4,s[19,46]=-0.1,s[19,47]=-0.6,s[19,48]=-0.4,s[19,49]=0.7,s[19,50]=1.1,s[19,51]=0.0,s[19,52]=-0.8,s[19,53]=0.1,s[19,54]=0.0,s[19,55]=-0.2,s[19,56]=0.7,s[19,57]=-1.0,s[19,58]=-0.8,s[19,59]=1.0,s[19,60]=-1.1 s[20,1]=0.3,s[20,2]=0.0,s[20,3]=0.7,s[20,4]=1.0,s[20,5]=-0.8,s[20,6]=0.6,s[20,7]=0.1,s[20,8]=-0.8,s[20,9]=-0.7,s[20,10]=0.7,s[20,11]=0.0,s[20,12]=0.6,s[20,13]=-0.1,s[20,14]=0.1,s[20,15]=-0.1,s[20,16]=-1.1,s[20,17]=0.5,s[20,18]=0.9,s[20,19]=-1.1,s[20,20]=-1.2,s[20,21]=0.6,s[20,22]=1.0,s[20,23]=0.9,s[20,24]=0.7,s[20,25]=-0.2,s[20,26]=-0.3,s[20,27]=1.0,s[20,28]=-0.2,s[20,29]=-0.7,s[20,30]=0.2,s[20,31]=0.2,s[20,32]=0.9,s[20,33]=0.2,s[20,34]=0.5,s[20,35]=1.1,s[20,36]=0.4,s[20,37]=-0.8,s[20,38]=-0.7,s[20,39]=1.2,s[20,40]=0.3,s[20,41]=0.5,s[20,42]=-0.9,s[20,43]=0.9,s[20,44]=0.4,s[20,45]=-0.3,s[20,46]=-1.1,s[20,47]=0.1,s[20,48]=0.9,s[20,49]=-0.1,s[20,50]=-0.9,s[20,51]=0.5,s[20,52]=0.3,s[20,53]=0.5,s[20,54]=-0.1,s[20,55]=-0.5,s[20,56]=-1.1,s[20,57]=-0.7,s[20,58]=-0.7,s[20,59]=-0.2,s[20,60]=0.2 s[21,1]=-0.2,s[21,2]=0.0,s[21,3]=0.9,s[21,4]=0.9,s[21,5]=-0.7,s[21,6]=-0.7,s[21,7]=1.2,s[21,8]=-0.2,s[21,9]=-1.0,s[21,10]=-0.7,s[21,11]=-0.4,s[21,12]=1.1,s[21,13]=1.1,s[21,14]=-1.2,s[21,15]=0.6,s[21,16]=0.3,s[21,17]=0.4,s[21,18]=-0.4,s[21,19]=-0.9,s[21,20]=1.0,s[21,21]=1.2,s[21,22]=0.3,s[21,23]=-1.2,s[21,24]=1.1,s[21,25]=0.8,s[21,26]=0.9,s[21,27]=-1.0,s[21,28]=0.6,s[21,29]=0.4,s[21,30]=-1.0,s[21,31]=0.1,s[21,32]=-0.3,s[21,33]=-0.1,s[21,34]=1.2,s[21,35]=-1.1,s[21,36]=-0.7,s[21,37]=1.0,s[21,38]=-1.1,s[21,39]=-0.5,s[21,40]=-1.2,s[21,41]=-0.9,s[21,42]=0.9,s[21,43]=0.1,s[21,44]=-0.6,s[21,45]=-1.2,s[21,46]=-0.1,s[21,47]=0.0,s[21,48]=-0.3,s[21,49]=1.0,s[21,50]=1.2,s[21,51]=-0.7,s[21,52]=0.0,s[21,53]=-0.1,s[21,54]=-0.8,s[21,55]=-0.9,s[21,56]=0.9,s[21,57]=-0.9,s[21,58]=1.2,s[21,59]=0.1,s[21,60]=-0.6 s[22,1]=-0.1,s[22,2]=-0.2,s[22,3]=-0.1,s[22,4]=-1.0,s[22,5]=0.6,s[22,6]=1.1,s[22,7]=0.1,s[22,8]=-0.5,s[22,9]=0.2,s[22,10]=0.5,s[22,11]=-0.1,s[22,12]=-1.1,s[22,13]=-0.3,s[22,14]=0.4,s[22,15]=0.5,s[22,16]=0.2,s[22,17]=-0.1,s[22,18]=1.0,s[22,19]=0.7,s[22,20]=-1.1,s[22,21]=-0.1,s[22,22]=0.9,s[22,23]=-0.7,s[22,24]=0.1,s[22,25]=-0.6,s[22,26]=-0.7,s[22,27]=-1.1,s[22,28]=-0.7,s[22,29]=-1.0,s[22,30]=-0.8,s[22,31]=0.0,s[22,32]=0.2,s[22,33]=1.2,s[22,34]=-0.8,s[22,35]=0.1,s[22,36]=-1.2,s[22,37]=0.5,s[22,38]=-0.1,s[22,39]=0.8,s[22,40]=0.3,s[22,41]=-0.6,s[22,42]=-1.2,s[22,43]=-0.1,s[22,44]=-0.2,s[22,45]=-0.8,s[22,46]=-0.2,s[22,47]=-0.7,s[22,48]=-0.1,s[22,49]=-0.6,s[22,50]=0.7,s[22,51]=-0.3,s[22,52]=0.6,s[22,53]=0.2,s[22,54]=1.1,s[22,55]=-1.2,s[22,56]=0.4,s[22,57]=0.6,s[22,58]=-0.3,s[22,59]=-0.4,s[22,60]=1.1 s[23,1]=-0.1,s[23,2]=0.0,s[23,3]=-0.8,s[23,4]=0.6,s[23,5]=-1.1,s[23,6]=-0.6,s[23,7]=-0.9,s[23,8]=-1.0,s[23,9]=1.2,s[23,10]=0.5,s[23,11]=-1.1,s[23,12]=-1.2,s[23,13]=-0.1,s[23,14]=-0.5,s[23,15]=0.0,s[23,16]=0.4,s[23,17]=0.3,s[23,18]=0.1,s[23,19]=0.9,s[23,20]=0.0,s[23,21]=-0.9,s[23,22]=-0.4,s[23,23]=1.2,s[23,24]=-0.7,s[23,25]=0.2,s[23,26]=0.4,s[23,27]=0.9,s[23,28]=-1.1,s[23,29]=0.1,s[23,30]=0.5,s[23,31]=-0.1,s[23,32]=-0.8,s[23,33]=-1.0,s[23,34]=0.8,s[23,35]=0.4,s[23,36]=1.2,s[23,37]=0.0,s[23,38]=-0.9,s[23,39]=0.5,s[23,40]=-1.0,s[23,41]=0.6,s[23,42]=1.1,s[23,43]=0.2,s[23,44]=1.0,s[23,45]=0.6,s[23,46]=-0.4,s[23,47]=0.1,s[23,48]=0.0,s[23,49]=-0.6,s[23,50]=-1.0,s[23,51]=0.4,s[23,52]=-0.2,s[23,53]=0.0,s[23,54]=-1.0,s[23,55]=-1.2,s[23,56]=-0.3,s[23,57]=0.3,s[23,58]=1.2,s[23,59]=0.3,s[23,60]=0.2 s[24,1]=-0.3,s[24,2]=0.1,s[24,3]=-0.1,s[24,4]=0.0,s[24,5]=-0.5,s[24,6]=-0.4,s[24,7]=-1.0,s[24,8]=0.0,s[24,9]=-1.0,s[24,10]=-0.9,s[24,11]=-0.6,s[24,12]=-0.3,s[24,13]=-0.8,s[24,14]=-0.3,s[24,15]=-1.0,s[24,16]=-0.1,s[24,17]=0.8,s[24,18]=-0.3,s[24,19]=0.9,s[24,20]=-0.4,s[24,21]=-0.1,s[24,22]=-0.4,s[24,23]=-0.4,s[24,24]=0.2,s[24,25]=-0.8,s[24,26]=0.0,s[24,27]=0.6,s[24,28]=0.8,s[24,29]=-0.7,s[24,30]=0.0,s[24,31]=0.3,s[24,32]=1.1,s[24,33]=-0.3,s[24,34]=-0.1,s[24,35]=-0.6,s[24,36]=-1.0,s[24,37]=-0.9,s[24,38]=-0.3,s[24,39]=-1.1,s[24,40]=-0.9,s[24,41]=0.2,s[24,42]=0.0,s[24,43]=-0.5,s[24,44]=0.5,s[24,45]=-0.5,s[24,46]=-0.5,s[24,47]=-0.3,s[24,48]=-0.4,s[24,49]=0.9,s[24,50]=1.1,s[24,51]=0.2,s[24,52]=-0.2,s[24,53]=-0.9,s[24,54]=0.2,s[24,55]=0.7,s[24,56]=-0.2,s[24,57]=0.0,s[24,58]=0.7,s[24,59]=-0.7,s[24,60]=0.1 s[25,1]=0.3,s[25,2]=0.8,s[25,3]=-1.2,s[25,4]=1.0,s[25,5]=-0.4,s[25,6]=-0.7,s[25,7]=-0.6,s[25,8]=1.1,s[25,9]=-0.3,s[25,10]=0.9,s[25,11]=-0.5,s[25,12]=-0.2,s[25,13]=-0.2,s[25,14]=-0.1,s[25,15]=-0.7,s[25,16]=0.5,s[25,17]=-0.3,s[25,18]=-0.4,s[25,19]=0.5,s[25,20]=-0.5,s[25,21]=0.3,s[25,22]=-0.3,s[25,23]=-0.9,s[25,24]=0.7,s[25,25]=0.5,s[25,26]=0.9,s[25,27]=0.5,s[25,28]=-0.2,s[25,29]=-0.6,s[25,30]=-1.0,s[25,31]=0.2,s[25,32]=0.9,s[25,33]=-0.4,s[25,34]=-0.7,s[25,35]=-0.6,s[25,36]=-1.2,s[25,37]=-0.3,s[25,38]=0.3,s[25,39]=-1.0,s[25,40]=1.0,s[25,41]=0.7,s[25,42]=0.4,s[25,43]=-0.4,s[25,44]=-0.6,s[25,45]=0.0,s[25,46]=0.0,s[25,47]=0.1,s[25,48]=0.9,s[25,49]=0.0,s[25,50]=0.1,s[25,51]=-0.3,s[25,52]=-0.4,s[25,53]=1.1,s[25,54]=-0.3,s[25,55]=-1.2,s[25,56]=-0.8,s[25,57]=0.7,s[25,58]=0.9,s[25,59]=-0.7,s[25,60]=0.7 s[26,1]=-0.1,s[26,2]=-1.0,s[26,3]=-0.9,s[26,4]=-1.1,s[26,5]=1.2,s[26,6]=-1.1,s[26,7]=-0.5,s[26,8]=-0.2,s[26,9]=0.4,s[26,10]=-0.1,s[26,11]=0.4,s[26,12]=-0.6,s[26,13]=0.9,s[26,14]=-1.2,s[26,15]=0.0,s[26,16]=-0.1,s[26,17]=0.0,s[26,18]=0.7,s[26,19]=-1.1,s[26,20]=-0.9,s[26,21]=-1.1,s[26,22]=-0.1,s[26,23]=-0.1,s[26,24]=0.7,s[26,25]=-0.6,s[26,26]=-0.7,s[26,27]=0.8,s[26,28]=0.0,s[26,29]=0.0,s[26,30]=1.1,s[26,31]=0.5,s[26,32]=-0.1,s[26,33]=0.9,s[26,34]=-0.8,s[26,35]=-1.0,s[26,36]=-0.1,s[26,37]=1.2,s[26,38]=0.4,s[26,39]=-1.1,s[26,40]=0.1,s[26,41]=0.0,s[26,42]=0.5,s[26,43]=0.7,s[26,44]=0.3,s[26,45]=-0.8,s[26,46]=0.1,s[26,47]=-0.3,s[26,48]=0.2,s[26,49]=1.2,s[26,50]=0.4,s[26,51]=0.5,s[26,52]=1.2,s[26,53]=0.8,s[26,54]=1.1,s[26,55]=0.6,s[26,56]=0.6,s[26,57]=-1.0,s[26,58]=-0.7,s[26,59]=0.0,s[26,60]=-0.7 s[27,1]=0.2,s[27,2]=-0.8,s[27,3]=0.3,s[27,4]=-0.7,s[27,5]=0.7,s[27,6]=-0.6,s[27,7]=0.0,s[27,8]=1.0,s[27,9]=-0.1,s[27,10]=1.1,s[27,11]=1.0,s[27,12]=0.9,s[27,13]=-0.4,s[27,14]=0.6,s[27,15]=-0.1,s[27,16]=-0.2,s[27,17]=-1.0,s[27,18]=0.2,s[27,19]=0.0,s[27,20]=-0.6,s[27,21]=0.9,s[27,22]=-1.1,s[27,23]=-1.2,s[27,24]=0.8,s[27,25]=-0.6,s[27,26]=0.3,s[27,27]=-0.6,s[27,28]=0.7,s[27,29]=0.2,s[27,30]=-1.1,s[27,31]=0.2,s[27,32]=-0.4,s[27,33]=0.7,s[27,34]=-0.5,s[27,35]=-0.5,s[27,36]=0.2,s[27,37]=0.2,s[27,38]=-0.5,s[27,39]=-0.3,s[27,40]=1.1,s[27,41]=0.1,s[27,42]=-0.3,s[27,43]=-1.1,s[27,44]=-0.2,s[27,45]=-0.2,s[27,46]=0.1,s[27,47]=-1.0,s[27,48]=0.8,s[27,49]=-0.5,s[27,50]=0.8,s[27,51]=0.5,s[27,52]=-0.8,s[27,53]=-0.4,s[27,54]=0.5,s[27,55]=1.0,s[27,56]=-0.1,s[27,57]=1.1,s[27,58]=-0.8,s[27,59]=-0.3,s[27,60]=0.3 s[28,1]=0.1,s[28,2]=0.7,s[28,3]=-0.9,s[28,4]=0.0,s[28,5]=0.0,s[28,6]=1.2,s[28,7]=-0.5,s[28,8]=0.8,s[28,9]=-0.4,s[28,10]=-0.6,s[28,11]=-1.1,s[28,12]=-0.1,s[28,13]=-0.7,s[28,14]=0.4,s[28,15]=0.6,s[28,16]=0.1,s[28,17]=-0.9,s[28,18]=1.1,s[28,19]=-1.0,s[28,20]=0.5,s[28,21]=0.2,s[28,22]=0.2,s[28,23]=0.3,s[28,24]=1.0,s[28,25]=-0.8,s[28,26]=-1.1,s[28,27]=0.7,s[28,28]=-1.1,s[28,29]=-0.3,s[28,30]=-0.4,s[28,31]=-0.2,s[28,32]=0.8,s[28,33]=1.2,s[28,34]=-0.7,s[28,35]=-0.2,s[28,36]=-0.3,s[28,37]=-1.0,s[28,38]=1.2,s[28,39]=0.8,s[28,40]=0.8,s[28,41]=0.7,s[28,42]=0.7,s[28,43]=-0.7,s[28,44]=0.0,s[28,45]=0.1,s[28,46]=-0.6,s[28,47]=0.4,s[28,48]=1.1,s[28,49]=-0.9,s[28,50]=-1.1,s[28,51]=-1.0,s[28,52]=0.5,s[28,53]=-1.1,s[28,54]=1.2,s[28,55]=-0.2,s[28,56]=0.1,s[28,57]=-0.7,s[28,58]=1.0,s[28,59]=0.2,s[28,60]=-0.2 s[29,1]=-0.4,s[29,2]=-0.7,s[29,3]=-0.4,s[29,4]=0.8,s[29,5]=-0.1,s[29,6]=0.6,s[29,7]=0.4,s[29,8]=-0.3,s[29,9]=0.2,s[29,10]=-0.8,s[29,11]=-0.2,s[29,12]=-0.9,s[29,13]=-1.2,s[29,14]=-0.4,s[29,15]=-0.8,s[29,16]=0.0,s[29,17]=0.0,s[29,18]=1.1,s[29,19]=0.8,s[29,20]=1.0,s[29,21]=0.6,s[29,22]=0.8,s[29,23]=0.0,s[29,24]=-1.0,s[29,25]=0.5,s[29,26]=1.2,s[29,27]=-1.2,s[29,28]=-0.8,s[29,29]=-0.6,s[29,30]=1.0,s[29,31]=-0.5,s[29,32]=0.6,s[29,33]=1.2,s[29,34]=0.1,s[29,35]=-0.8,s[29,36]=1.0,s[29,37]=0.0,s[29,38]=0.5,s[29,39]=1.2,s[29,40]=0.3,s[29,41]=-0.2,s[29,42]=0.9,s[29,43]=-0.2,s[29,44]=0.0,s[29,45]=-0.1,s[29,46]=-0.2,s[29,47]=0.1,s[29,48]=-0.2,s[29,49]=-0.6,s[29,50]=0.0,s[29,51]=-0.9,s[29,52]=-0.6,s[29,53]=0.3,s[29,54]=-0.4,s[29,55]=-1.0,s[29,56]=-1.1,s[29,57]=-1.1,s[29,58]=0.1,s[29,59]=-0.6,s[29,60]=-0.3 s[30,1]=-0.3,s[30,2]=-0.1,s[30,3]=1.0,s[30,4]=-0.8,s[30,5]=-1.2,s[30,6]=1.0,s[30,7]=-0.6,s[30,8]=0.0,s[30,9]=0.8,s[30,10]=-0.4,s[30,11]=-0.4,s[30,12]=0.9,s[30,13]=0.8,s[30,14]=-0.2,s[30,15]=0.5,s[30,16]=-0.2,s[30,17]=-0.9,s[30,18]=-0.4,s[30,19]=-0.1,s[30,20]=-0.9,s[30,21]=0.3,s[30,22]=0.7,s[30,23]=-0.6,s[30,24]=1.2,s[30,25]=0.2,s[30,26]=0.2,s[30,27]=-0.4,s[30,28]=-1.1,s[30,29]=1.0,s[30,30]=0.9,s[30,31]=0.2,s[30,32]=-0.5,s[30,33]=-0.4,s[30,34]=0.0,s[30,35]=1.0,s[30,36]=1.1,s[30,37]=0.0,s[30,38]=-0.4,s[30,39]=-0.2,s[30,40]=1.1,s[30,41]=0.3,s[30,42]=0.8,s[30,43]=-0.6,s[30,44]=-0.7,s[30,45]=0.1,s[30,46]=0.1,s[30,47]=0.7,s[30,48]=0.4,s[30,49]=0.8,s[30,50]=0.8,s[30,51]=0.5,s[30,52]=-0.9,s[30,53]=0.8,s[30,54]=0.3,s[30,55]=-1.0,s[30,56]=-0.1,s[30,57]=0.6,s[30,58]=0.8,s[30,59]=-1.0,s[30,60]=1.2 s[31,1]=0.0,s[31,2]=0.8,s[31,3]=0.2,s[31,4]=-0.2,s[31,5]=0.4,s[31,6]=-0.1,s[31,7]=0.0,s[31,8]=-1.0,s[31,9]=1.0,s[31,10]=0.2,s[31,11]=0.3,s[31,12]=-1.0,s[31,13]=0.0,s[31,14]=1.0,s[31,15]=1.2,s[31,16]=-0.2,s[31,17]=1.2,s[31,18]=1.2,s[31,19]=-0.9,s[31,20]=-0.2,s[31,21]=0.7,s[31,22]=0.2,s[31,23]=-0.1,s[31,24]=-0.7,s[31,25]=-0.9,s[31,26]=0.6,s[31,27]=-0.3,s[31,28]=1.1,s[31,29]=1.1,s[31,30]=0.9,s[31,31]=0.8,s[31,32]=0.4,s[31,33]=0.1,s[31,34]=0.8,s[31,35]=0.8,s[31,36]=0.1,s[31,37]=-1.1,s[31,38]=0.8,s[31,39]=0.5,s[31,40]=0.2,s[31,41]=-0.9,s[31,42]=0.1,s[31,43]=0.7,s[31,44]=-1.0,s[31,45]=-0.6,s[31,46]=-0.1,s[31,47]=-0.7,s[31,48]=-0.1,s[31,49]=1.1,s[31,50]=0.2,s[31,51]=0.6,s[31,52]=0.2,s[31,53]=1.1,s[31,54]=-1.1,s[31,55]=-0.4,s[31,56]=0.0,s[31,57]=0.8,s[31,58]=1.2,s[31,59]=0.2,s[31,60]=-1.0 s[32,1]=0.1,s[32,2]=1.2,s[32,3]=0.8,s[32,4]=-0.7,s[32,5]=-0.8,s[32,6]=0.1,s[32,7]=0.1,s[32,8]=0.2,s[32,9]=0.0,s[32,10]=0.9,s[32,11]=0.3,s[32,12]=-0.4,s[32,13]=1.2,s[32,14]=0.4,s[32,15]=0.6,s[32,16]=0.2,s[32,17]=0.3,s[32,18]=-0.3,s[32,19]=-1.0,s[32,20]=-0.6,s[32,21]=-0.8,s[32,22]=-0.3,s[32,23]=1.0,s[32,24]=-0.5,s[32,25]=0.1,s[32,26]=-0.8,s[32,27]=1.0,s[32,28]=-0.6,s[32,29]=-0.9,s[32,30]=-1.2,s[32,31]=-0.1,s[32,32]=-0.1,s[32,33]=0.8,s[32,34]=1.0,s[32,35]=0.2,s[32,36]=-0.1,s[32,37]=0.2,s[32,38]=-0.1,s[32,39]=-1.2,s[32,40]=1.1,s[32,41]=-0.7,s[32,42]=-0.2,s[32,43]=0.0,s[32,44]=-0.1,s[32,45]=0.8,s[32,46]=0.0,s[32,47]=-0.3,s[32,48]=-0.5,s[32,49]=-0.9,s[32,50]=0.7,s[32,51]=0.4,s[32,52]=0.1,s[32,53]=-0.4,s[32,54]=-0.1,s[32,55]=1.0,s[32,56]=0.5,s[32,57]=-0.5,s[32,58]=-0.7,s[32,59]=-0.1,s[32,60]=-0.7 s[33,1]=-0.3,s[33,2]=-0.1,s[33,3]=0.0,s[33,4]=-0.8,s[33,5]=0.6,s[33,6]=-1.0,s[33,7]=-0.7,s[33,8]=0.3,s[33,9]=-0.5,s[33,10]=-1.1,s[33,11]=0.0,s[33,12]=0.9,s[33,13]=-1.0,s[33,14]=-0.2,s[33,15]=-0.3,s[33,16]=-0.2,s[33,17]=-0.2,s[33,18]=0.6,s[33,19]=-0.1,s[33,20]=-1.2,s[33,21]=0.4,s[33,22]=-0.7,s[33,23]=0.5,s[33,24]=0.1,s[33,25]=-0.9,s[33,26]=0.2,s[33,27]=1.0,s[33,28]=-0.5,s[33,29]=-0.5,s[33,30]=-0.7,s[33,31]=-0.5,s[33,32]=0.5,s[33,33]=-0.9,s[33,34]=0.8,s[33,35]=0.8,s[33,36]=-0.7,s[33,37]=-0.9,s[33,38]=0.8,s[33,39]=-0.2,s[33,40]=-0.3,s[33,41]=-0.2,s[33,42]=0.0,s[33,43]=-0.1,s[33,44]=0.7,s[33,45]=1.0,s[33,46]=0.0,s[33,47]=0.5,s[33,48]=0.3,s[33,49]=-0.5,s[33,50]=-0.6,s[33,51]=0.9,s[33,52]=-0.1,s[33,53]=0.7,s[33,54]=-0.7,s[33,55]=-0.2,s[33,56]=-0.6,s[33,57]=-1.1,s[33,58]=-0.4,s[33,59]=-0.5,s[33,60]=0.6 s[34,1]=-0.1,s[34,2]=1.0,s[34,3]=0.3,s[34,4]=-0.5,s[34,5]=1.1,s[34,6]=-1.1,s[34,7]=1.1,s[34,8]=1.1,s[34,9]=-0.7,s[34,10]=1.0,s[34,11]=-0.4,s[34,12]=0.6,s[34,13]=-1.1,s[34,14]=0.0,s[34,15]=0.7,s[34,16]=0.1,s[34,17]=-0.1,s[34,18]=-0.9,s[34,19]=-0.4,s[34,20]=0.4,s[34,21]=-0.3,s[34,22]=-0.8,s[34,23]=1.0,s[34,24]=0.0,s[34,25]=-0.5,s[34,26]=0.7,s[34,27]=1.0,s[34,28]=-0.5,s[34,29]=-1.2,s[34,30]=0.2,s[34,31]=0.6,s[34,32]=1.1,s[34,33]=1.2,s[34,34]=-0.8,s[34,35]=-0.4,s[34,36]=0.6,s[34,37]=-0.3,s[34,38]=0.7,s[34,39]=-1.2,s[34,40]=0.5,s[34,41]=0.2,s[34,42]=0.4,s[34,43]=-1.2,s[34,44]=-1.0,s[34,45]=-0.9,s[34,46]=0.4,s[34,47]=0.3,s[34,48]=1.2,s[34,49]=0.9,s[34,50]=0.0,s[34,51]=0.5,s[34,52]=0.4,s[34,53]=-0.1,s[34,54]=-0.8,s[34,55]=0.8,s[34,56]=0.1,s[34,57]=-0.7,s[34,58]=-0.6,s[34,59]=-0.3,s[34,60]=1.1 s[35,1]=-0.7,s[35,2]=-0.7,s[35,3]=-0.2,s[35,4]=-1.1,s[35,5]=0.1,s[35,6]=-0.4,s[35,7]=1.0,s[35,8]=-1.0,s[35,9]=1.2,s[35,10]=-0.4,s[35,11]=-1.0,s[35,12]=-0.5,s[35,13]=-0.3,s[35,14]=-0.1,s[35,15]=0.9,s[35,16]=-0.1,s[35,17]=1.0,s[35,18]=0.9,s[35,19]=-1.0,s[35,20]=0.5,s[35,21]=1.1,s[35,22]=-0.4,s[35,23]=1.2,s[35,24]=-1.0,s[35,25]=-0.6,s[35,26]=-0.4,s[35,27]=-0.2,s[35,28]=-1.2,s[35,29]=-0.1,s[35,30]=-0.5,s[35,31]=0.0,s[35,32]=-1.0,s[35,33]=-0.9,s[35,34]=1.0,s[35,35]=0.3,s[35,36]=0.3,s[35,37]=-0.5,s[35,38]=0.3,s[35,39]=-0.6,s[35,40]=-0.9,s[35,41]=0.2,s[35,42]=-0.2,s[35,43]=0.4,s[35,44]=1.0,s[35,45]=0.7,s[35,46]=-0.6,s[35,47]=0.6,s[35,48]=-0.1,s[35,49]=-0.6,s[35,50]=0.5,s[35,51]=0.1,s[35,52]=0.7,s[35,53]=1.1,s[35,54]=-1.2,s[35,55]=-1.1,s[35,56]=0.8,s[35,57]=-1.1,s[35,58]=0.1,s[35,59]=-1.0,s[35,60]=0.1 s[36,1]=0.3,s[36,2]=-0.4,s[36,3]=0.5,s[36,4]=0.4,s[36,5]=0.8,s[36,6]=0.5,s[36,7]=0.4,s[36,8]=1.0,s[36,9]=0.7,s[36,10]=0.1,s[36,11]=0.9,s[36,12]=-0.9,s[36,13]=1.0,s[36,14]=-0.2,s[36,15]=-0.9,s[36,16]=-0.6,s[36,17]=-0.1,s[36,18]=-0.2,s[36,19]=-0.7,s[36,20]=-0.9,s[36,21]=-0.3,s[36,22]=-1.0,s[36,23]=-1.0,s[36,24]=0.9,s[36,25]=-0.8,s[36,26]=0.3,s[36,27]=-1.1,s[36,28]=1.0,s[36,29]=0.3,s[36,30]=0.5,s[36,31]=0.4,s[36,32]=-0.4,s[36,33]=0.2,s[36,34]=0.3,s[36,35]=-0.3,s[36,36]=0.9,s[36,37]=-0.7,s[36,38]=-1.0,s[36,39]=-0.2,s[36,40]=-0.1,s[36,41]=0.1,s[36,42]=-0.6,s[36,43]=-0.5,s[36,44]=0.2,s[36,45]=0.0,s[36,46]=0.2,s[36,47]=0.1,s[36,48]=0.5,s[36,49]=-0.3,s[36,50]=-0.3,s[36,51]=1.2,s[36,52]=1.1,s[36,53]=0.6,s[36,54]=0.3,s[36,55]=0.6,s[36,56]=0.2,s[36,57]=-0.8,s[36,58]=-0.5,s[36,59]=-0.3,s[36,60]=1.1 s[37,1]=0.2,s[37,2]=0.2,s[37,3]=-0.6,s[37,4]=0.3,s[37,5]=0.5,s[37,6]=1.1,s[37,7]=1.2,s[37,8]=-0.2,s[37,9]=-1.1,s[37,10]=-1.2,s[37,11]=0.5,s[37,12]=0.8,s[37,13]=0.5,s[37,14]=0.6,s[37,15]=-0.7,s[37,16]=-0.3,s[37,17]=1.0,s[37,18]=0.8,s[37,19]=-0.2,s[37,20]=1.0,s[37,21]=-0.3,s[37,22]=0.8,s[37,23]=-1.1,s[37,24]=-1.0,s[37,25]=0.4,s[37,26]=0.4,s[37,27]=-0.6,s[37,28]=-0.3,s[37,29]=1.0,s[37,30]=-0.8,s[37,31]=0.1,s[37,32]=-1.1,s[37,33]=0.7,s[37,34]=0.0,s[37,35]=0.5,s[37,36]=-1.1,s[37,37]=-0.4,s[37,38]=0.4,s[37,39]=-0.6,s[37,40]=0.4,s[37,41]=-0.9,s[37,42]=-0.6,s[37,43]=-0.3,s[37,44]=0.5,s[37,45]=-1.1,s[37,46]=0.2,s[37,47]=-0.8,s[37,48]=0.9,s[37,49]=1.2,s[37,50]=0.5,s[37,51]=-0.2,s[37,52]=-1.2,s[37,53]=-0.3,s[37,54]=0.4,s[37,55]=-0.3,s[37,56]=-0.1,s[37,57]=0.4,s[37,58]=0.7,s[37,59]=0.0,s[37,60]=-0.9 s[38,1]=0.4,s[38,2]=-0.4,s[38,3]=-0.3,s[38,4]=-1.1,s[38,5]=0.7,s[38,6]=0.0,s[38,7]=-0.1,s[38,8]=-0.6,s[38,9]=0.2,s[38,10]=0.3,s[38,11]=-0.8,s[38,12]=0.6,s[38,13]=-1.1,s[38,14]=0.7,s[38,15]=0.8,s[38,16]=0.1,s[38,17]=-0.3,s[38,18]=0.4,s[38,19]=1.2,s[38,20]=-0.8,s[38,21]=-0.7,s[38,22]=0.2,s[38,23]=0.3,s[38,24]=-0.7,s[38,25]=0.6,s[38,26]=-0.3,s[38,27]=0.7,s[38,28]=0.5,s[38,29]=-1.1,s[38,30]=1.0,s[38,31]=0.4,s[38,32]=1.1,s[38,33]=-0.2,s[38,34]=-1.0,s[38,35]=-0.4,s[38,36]=-0.3,s[38,37]=0.5,s[38,38]=-0.8,s[38,39]=0.0,s[38,40]=0.6,s[38,41]=-0.5,s[38,42]=0.9,s[38,43]=0.1,s[38,44]=0.5,s[38,45]=-1.2,s[38,46]=0.5,s[38,47]=0.0,s[38,48]=1.1,s[38,49]=0.7,s[38,50]=0.6,s[38,51]=0.3,s[38,52]=-0.2,s[38,53]=-1.2,s[38,54]=0.1,s[38,55]=-0.5,s[38,56]=-0.1,s[38,57]=-0.3,s[38,58]=-0.2,s[38,59]=0.3,s[38,60]=-1.2 s[39,1]=-0.7,s[39,2]=-0.6,s[39,3]=0.9,s[39,4]=-0.5,s[39,5]=-0.2,s[39,6]=0.9,s[39,7]=0.8,s[39,8]=0.4,s[39,9]=-0.8,s[39,10]=-0.8,s[39,11]=-0.6,s[39,12]=0.9,s[39,13]=-1.2,s[39,14]=0.0,s[39,15]=1.1,s[39,16]=0.2,s[39,17]=0.9,s[39,18]=1.0,s[39,19]=-0.6,s[39,20]=-0.5,s[39,21]=-0.3,s[39,22]=-1.0,s[39,23]=1.1,s[39,24]=0.4,s[39,25]=-0.7,s[39,26]=0.4,s[39,27]=-0.9,s[39,28]=0.1,s[39,29]=0.3,s[39,30]=-0.1,s[39,31]=0.1,s[39,32]=-0.6,s[39,33]=-0.1,s[39,34]=0.9,s[39,35]=1.2,s[39,36]=-0.7,s[39,37]=0.1,s[39,38]=0.5,s[39,39]=0.0,s[39,40]=-1.0,s[39,41]=1.0,s[39,42]=-0.5,s[39,43]=-1.0,s[39,44]=0.3,s[39,45]=-0.2,s[39,46]=0.6,s[39,47]=0.4,s[39,48]=0.6,s[39,49]=-0.4,s[39,50]=1.1,s[39,51]=0.8,s[39,52]=-1.2,s[39,53]=-1.2,s[39,54]=0.2,s[39,55]=-0.8,s[39,56]=-0.1,s[39,57]=-0.5,s[39,58]=-0.3,s[39,59]=0.6,s[39,60]=-0.5 s[40,1]=-0.3,s[40,2]=0.1,s[40,3]=0.0,s[40,4]=-0.5,s[40,5]=-1.0,s[40,6]=-1.0,s[40,7]=-1.0,s[40,8]=-0.4,s[40,9]=-0.8,s[40,10]=1.1,s[40,11]=-0.8,s[40,12]=0.6,s[40,13]=0.6,s[40,14]=-0.8,s[40,15]=0.7,s[40,16]=-0.3,s[40,17]=-0.2,s[40,18]=1.2,s[40,19]=-0.5,s[40,20]=-1.2,s[40,21]=1.1,s[40,22]=0.4,s[40,23]=-0.2,s[40,24]=1.0,s[40,25]=-0.8,s[40,26]=-0.6,s[40,27]=0.3,s[40,28]=-1.0,s[40,29]=-0.5,s[40,30]=0.9,s[40,31]=0.1,s[40,32]=-1.0,s[40,33]=0.9,s[40,34]=-0.8,s[40,35]=0.7,s[40,36]=1.0,s[40,37]=0.3,s[40,38]=-1.2,s[40,39]=0.2,s[40,40]=-1.1,s[40,41]=-0.3,s[40,42]=-0.7,s[40,43]=-0.9,s[40,44]=-0.1,s[40,45]=0.2,s[40,46]=0.7,s[40,47]=0.9,s[40,48]=-0.8,s[40,49]=-1.0,s[40,50]=-0.7,s[40,51]=-0.6,s[40,52]=-0.9,s[40,53]=-0.3,s[40,54]=1.1,s[40,55]=-0.7,s[40,56]=0.8,s[40,57]=-0.6,s[40,58]=-0.1,s[40,59]=-1.1,s[40,60]=0.4 s[41,1]=0.1,s[41,2]=0.5,s[41,3]=-0.3,s[41,4]=1.1,s[41,5]=-0.4,s[41,6]=-1.0,s[41,7]=-0.1,s[41,8]=0.3,s[41,9]=1.2,s[41,10]=0.9,s[41,11]=0.1,s[41,12]=-0.2,s[41,13]=-0.4,s[41,14]=0.6,s[41,15]=-0.3,s[41,16]=-1.0,s[41,17]=0.7,s[41,18]=0.2,s[41,19]=-0.4,s[41,20]=0.5,s[41,21]=0.6,s[41,22]=0.3,s[41,23]=0.7,s[41,24]=-0.1,s[41,25]=0.6,s[41,26]=0.8,s[41,27]=0.6,s[41,28]=-1.2,s[41,29]=-0.3,s[41,30]=0.3,s[41,31]=-0.3,s[41,32]=-0.6,s[41,33]=0.8,s[41,34]=0.0,s[41,35]=0.6,s[41,36]=-0.4,s[41,37]=0.1,s[41,38]=0.3,s[41,39]=-0.2,s[41,40]=0.0,s[41,41]=0.1,s[41,42]=0.7,s[41,43]=-0.6,s[41,44]=-0.3,s[41,45]=0.2,s[41,46]=-0.5,s[41,47]=0.3,s[41,48]=0.9,s[41,49]=-0.5,s[41,50]=-1.0,s[41,51]=-0.8,s[41,52]=0.2,s[41,53]=0.0,s[41,54]=-0.4,s[41,55]=0.8,s[41,56]=0.2,s[41,57]=0.9,s[41,58]=0.8,s[41,59]=0.9,s[41,60]=-0.6 s[42,1]=0.0,s[42,2]=-0.3,s[42,3]=-0.5,s[42,4]=-0.6,s[42,5]=-1.1,s[42,6]=0.6,s[42,7]=-0.6,s[42,8]=-0.1,s[42,9]=1.0,s[42,10]=-1.2,s[42,11]=0.2,s[42,12]=0.2,s[42,13]=0.1,s[42,14]=-1.2,s[42,15]=0.0,s[42,16]=-0.1,s[42,17]=0.4,s[42,18]=-1.1,s[42,19]=0.3,s[42,20]=0.9,s[42,21]=0.7,s[42,22]=-0.5,s[42,23]=-1.0,s[42,24]=0.4,s[42,25]=-0.2,s[42,26]=0.0,s[42,27]=0.4,s[42,28]=0.2,s[42,29]=-0.1,s[42,30]=0.9,s[42,31]=-0.4,s[42,32]=-0.4,s[42,33]=-0.7,s[42,34]=0.7,s[42,35]=0.5,s[42,36]=0.3,s[42,37]=-0.2,s[42,38]=0.9,s[42,39]=0.7,s[42,40]=-0.7,s[42,41]=-0.5,s[42,42]=-1.2,s[42,43]=0.9,s[42,44]=-0.9,s[42,45]=-1.2,s[42,46]=-0.1,s[42,47]=0.1,s[42,48]=-0.1,s[42,49]=1.1,s[42,50]=0.6,s[42,51]=0.2,s[42,52]=-0.5,s[42,53]=0.6,s[42,54]=-0.5,s[42,55]=-0.9,s[42,56]=0.3,s[42,57]=-1.2,s[42,58]=1.1,s[42,59]=-0.5,s[42,60]=0.1 s[43,1]=-0.1,s[43,2]=1.0,s[43,3]=-1.2,s[43,4]=0.9,s[43,5]=0.4,s[43,6]=0.3,s[43,7]=0.8,s[43,8]=-0.6,s[43,9]=0.4,s[43,10]=0.4,s[43,11]=-0.7,s[43,12]=1.0,s[43,13]=0.9,s[43,14]=-0.1,s[43,15]=1.2,s[43,16]=-0.1,s[43,17]=0.3,s[43,18]=-0.5,s[43,19]=-0.2,s[43,20]=1.2,s[43,21]=-1.0,s[43,22]=-0.5,s[43,23]=0.4,s[43,24]=-0.4,s[43,25]=-1.2,s[43,26]=-0.4,s[43,27]=0.9,s[43,28]=-1.0,s[43,29]=-1.0,s[43,30]=-0.8,s[43,31]=-0.5,s[43,32]=0.7,s[43,33]=-0.7,s[43,34]=-0.6,s[43,35]=0.0,s[43,36]=-0.9,s[43,37]=0.1,s[43,38]=1.0,s[43,39]=-0.6,s[43,40]=0.9,s[43,41]=-0.9,s[43,42]=1.0,s[43,43]=0.9,s[43,44]=0.5,s[43,45]=0.4,s[43,46]=0.6,s[43,47]=0.1,s[43,48]=-1.0,s[43,49]=-0.9,s[43,50]=-0.2,s[43,51]=-0.7,s[43,52]=-0.4,s[43,53]=-0.8,s[43,54]=0.2,s[43,55]=0.8,s[43,56]=0.0,s[43,57]=0.3,s[43,58]=0.9,s[43,59]=-0.3,s[43,60]=-0.3 s[44,1]=0.3,s[44,2]=-0.1,s[44,3]=0.2,s[44,4]=-1.1,s[44,5]=0.2,s[44,6]=-1.0,s[44,7]=0.2,s[44,8]=0.3,s[44,9]=0.2,s[44,10]=-1.2,s[44,11]=0.1,s[44,12]=-0.2,s[44,13]=-0.1,s[44,14]=0.5,s[44,15]=0.2,s[44,16]=0.1,s[44,17]=-1.2,s[44,18]=-1.1,s[44,19]=0.9,s[44,20]=0.5,s[44,21]=0.1,s[44,22]=-0.8,s[44,23]=1.2,s[44,24]=-0.3,s[44,25]=-0.3,s[44,26]=1.0,s[44,27]=0.2,s[44,28]=-1.2,s[44,29]=0.0,s[44,30]=0.9,s[44,31]=0.5,s[44,32]=-0.1,s[44,33]=1.1,s[44,34]=-1.2,s[44,35]=-1.2,s[44,36]=0.4,s[44,37]=-0.4,s[44,38]=-0.5,s[44,39]=1.0,s[44,40]=0.8,s[44,41]=0.5,s[44,42]=-0.4,s[44,43]=0.6,s[44,44]=-1.1,s[44,45]=0.5,s[44,46]=0.1,s[44,47]=0.4,s[44,48]=1.2,s[44,49]=0.8,s[44,50]=-1.1,s[44,51]=-0.9,s[44,52]=0.1,s[44,53]=0.0,s[44,54]=-0.9,s[44,55]=-1.0,s[44,56]=-0.7,s[44,57]=0.1,s[44,58]=-1.1,s[44,59]=0.7,s[44,60]=-0.6 s[45,1]=0.3,s[45,2]=-0.8,s[45,3]=0.7,s[45,4]=-0.1,s[45,5]=1.1,s[45,6]=-0.3,s[45,7]=0.6,s[45,8]=1.0,s[45,9]=1.0,s[45,10]=0.3,s[45,11]=0.4,s[45,12]=-0.5,s[45,13]=-1.1,s[45,14]=-0.1,s[45,15]=0.4,s[45,16]=0.0,s[45,17]=-0.7,s[45,18]=-1.0,s[45,19]=-0.8,s[45,20]=1.2,s[45,21]=0.1,s[45,22]=0.0,s[45,23]=-0.6,s[45,24]=-1.0,s[45,25]=0.8,s[45,26]=0.6,s[45,27]=0.1,s[45,28]=-0.3,s[45,29]=0.5,s[45,30]=0.3,s[45,31]=-0.1,s[45,32]=0.6,s[45,33]=0.3,s[45,34]=-0.4,s[45,35]=-0.4,s[45,36]=-0.3,s[45,37]=-0.8,s[45,38]=0.4,s[45,39]=1.0,s[45,40]=-0.6,s[45,41]=-0.1,s[45,42]=0.1,s[45,43]=1.0,s[45,44]=-0.1,s[45,45]=-0.7,s[45,46]=0.6,s[45,47]=-1.2,s[45,48]=-0.3,s[45,49]=0.1,s[45,50]=-0.4,s[45,51]=-0.4,s[45,52]=1.0,s[45,53]=-0.4,s[45,54]=1.1,s[45,55]=0.4,s[45,56]=-0.1,s[45,57]=-1.1,s[45,58]=-0.5,s[45,59]=0.6,s[45,60]=-0.6 s[46,1]=-0.3,s[46,2]=0.0,s[46,3]=1.1,s[46,4]=-0.1,s[46,5]=-1.2,s[46,6]=1.2,s[46,7]=0.5,s[46,8]=-1.0,s[46,9]=-1.0,s[46,10]=-0.1,s[46,11]=-0.4,s[46,12]=-0.3,s[46,13]=0.0,s[46,14]=-0.3,s[46,15]=0.7,s[46,16]=-0.1,s[46,17]=-0.2,s[46,18]=-0.8,s[46,19]=-0.8,s[46,20]=-0.5,s[46,21]=-0.6,s[46,22]=-0.1,s[46,23]=0.7,s[46,24]=-0.4,s[46,25]=-0.7,s[46,26]=-0.3,s[46,27]=-0.1,s[46,28]=0.1,s[46,29]=-0.7,s[46,30]=-0.5,s[46,31]=0.6,s[46,32]=0.7,s[46,33]=-0.7,s[46,34]=-0.7,s[46,35]=1.2,s[46,36]=1.1,s[46,37]=0.6,s[46,38]=-0.7,s[46,39]=-1.1,s[46,40]=-0.8,s[46,41]=0.1,s[46,42]=-0.4,s[46,43]=-0.9,s[46,44]=0.5,s[46,45]=0.2,s[46,46]=0.0,s[46,47]=-1.2,s[46,48]=-0.8,s[46,49]=-0.9,s[46,50]=-0.5,s[46,51]=1.2,s[46,52]=1.2,s[46,53]=-0.4,s[46,54]=-0.5,s[46,55]=-1.0,s[46,56]=-0.6,s[46,57]=1.2,s[46,58]=0.9,s[46,59]=-0.1,s[46,60]=-0.9 s[47,1]=-0.3,s[47,2]=-1.0,s[47,3]=0.1,s[47,4]=-0.2,s[47,5]=-0.6,s[47,6]=0.0,s[47,7]=1.0,s[47,8]=0.1,s[47,9]=-0.3,s[47,10]=-0.7,s[47,11]=0.1,s[47,12]=0.1,s[47,13]=0.8,s[47,14]=0.4,s[47,15]=1.1,s[47,16]=0.0,s[47,17]=-0.4,s[47,18]=0.1,s[47,19]=0.7,s[47,20]=-0.3,s[47,21]=-1.0,s[47,22]=1.1,s[47,23]=-0.1,s[47,24]=-1.0,s[47,25]=0.4,s[47,26]=-0.5,s[47,27]=-0.9,s[47,28]=-0.3,s[47,29]=0.3,s[47,30]=0.5,s[47,31]=-1.0,s[47,32]=0.9,s[47,33]=0.9,s[47,34]=1.1,s[47,35]=1.0,s[47,36]=-0.9,s[47,37]=-0.9,s[47,38]=0.6,s[47,39]=0.6,s[47,40]=-0.8,s[47,41]=0.3,s[47,42]=1.1,s[47,43]=-0.9,s[47,44]=-0.2,s[47,45]=0.3,s[47,46]=-0.2,s[47,47]=0.3,s[47,48]=0.6,s[47,49]=0.4,s[47,50]=-0.6,s[47,51]=0.3,s[47,52]=0.4,s[47,53]=-0.6,s[47,54]=-0.5,s[47,55]=0.8,s[47,56]=0.2,s[47,57]=-0.2,s[47,58]=0.0,s[47,59]=0.0,s[47,60]=-0.4 s[48,1]=0.1,s[48,2]=-0.4,s[48,3]=-0.8,s[48,4]=0.6,s[48,5]=0.7,s[48,6]=1.2,s[48,7]=-0.4,s[48,8]=-0.7,s[48,9]=-0.1,s[48,10]=-0.6,s[48,11]=0.9,s[48,12]=-1.2,s[48,13]=-0.6,s[48,14]=0.2,s[48,15]=-0.9,s[48,16]=0.2,s[48,17]=-0.2,s[48,18]=0.0,s[48,19]=-0.1,s[48,20]=-1.1,s[48,21]=-1.1,s[48,22]=0.4,s[48,23]=-0.9,s[48,24]=-0.2,s[48,25]=0.5,s[48,26]=-0.6,s[48,27]=-1.1,s[48,28]=-0.5,s[48,29]=-0.4,s[48,30]=-1.0 s[48,31]=0.2,s[48,32]=0.0,s[48,33]=-0.2,s[48,34]=-0.6,s[48,35]=0.6,s[48,36]=0.2,s[48,37]=0.7,s[48,38]=0.0,s[48,39]=0.1,s[48,40]=-0.3,s[48,41]=-0.3,s[48,42]=-1.0,s[48,43]=-0.4,s[48,44]=0.3,s[48,45]=-0.1,s[48,46]=-0.3,s[48,47]=-0.7,s[48,48]=0.6,s[48,49]=1.1,s[48,50]=-1.2,s[48,51]=-0.7,s[48,52]=-1.2,s[48,53]=-0.6,s[48,54]=0.2,s[48,55]=0.2,s[48,56]=-0.7,s[48,57]=-0.3,s[48,58]=0.2,s[48,59]=-1.0,s[48,60]=0.2 s[49,1]=-0.4,s[49,2]=0.3,s[49,3]=0.0,s[49,4]=-0.7,s[49,5]=0.5,s[49,6]=-0.9,s[49,7]=0.2,s[49,8]=0.6,s[49,9]=1.0,s[49,10]=-1.0,s[49,11]=-0.2,s[49,12]=-0.2,s[49,13]=0.0,s[49,14]=0.5,s[49,15]=1.0,s[49,16]=0.1,s[49,17]=-0.3,s[49,18]=-0.4,s[49,19]=-0.8,s[49,20]=0.3,s[49,21]=0.5,s[49,22]=0.2,s[49,23]=0.0,s[49,24]=-0.9,s[49,25]=1.2,s[49,26]=-0.3,s[49,27]=-1.2,s[49,28]=0.9,s[49,29]=0.2,s[49,30]=-1.2 s[49,31]=-0.2,s[49,32]=1.2,s[49,33]=0.5,s[49,34]=-0.8,s[49,35]=1.0,s[49,36]=0.5,s[49,37]=0.1,s[49,38]=0.6,s[49,39]=0.4,s[49,40]=0.2,s[49,41]=0.4,s[49,42]=0.0,s[49,43]=1.1,s[49,44]=1.2,s[49,45]=-1.2,s[49,46]=0.1,s[49,47]=0.7,s[49,48]=0.9,s[49,49]=1.0,s[49,50]=-0.1,s[49,51]=-0.2,s[49,52]=-0.7,s[49,53]=-0.9,s[49,54]=-1.0,s[49,55]=0.9,s[49,56]=-0.3,s[49,57]=0.8,s[49,58]=0.9,s[49,59]=0.3,s[49,60]=0.8 s[50,1]=0.1,s[50,2]=-1.1,s[50,3]=-0.3,s[50,4]=-0.9,s[50,5]=-0.5,s[50,6]=-0.3,s[50,7]=0.5,s[50,8]=0.3,s[50,9]=-0.5,s[50,10]=-1.1,s[50,11]=-0.8,s[50,12]=-0.9,s[50,13]=0.5,s[50,14]=0.8,s[50,15]=-0.2,s[50,16]=0.1,s[50,17]=-0.7,s[50,18]=0.0,s[50,19]=1.1,s[50,20]=0.2,s[50,21]=-1.0,s[50,22]=0.9,s[50,23]=-0.8,s[50,24]=-0.2,s[50,25]=1.0,s[50,26]=-0.9,s[50,27]=-0.8,s[50,28]=0.1,s[50,29]=-0.2,s[50,30]=-0.4 s[50,31]=-0.2,s[50,32]=-0.2,s[50,33]=0.8,s[50,34]=-0.9,s[50,35]=0.3,s[50,36]=-1.0,s[50,37]=-0.1,s[50,38]=0.1,s[50,39]=0.4,s[50,40]=0.7,s[50,41]=-0.8,s[50,42]=-1.0,s[50,43]=-0.1,s[50,44]=1.0,s[50,45]=1.2,s[50,46]=-0.3,s[50,47]=-0.6,s[50,48]=0.2,s[50,49]=-0.1,s[50,50]=-1.2,s[50,51]=0.2,s[50,52]=-1.0,s[50,53]=-0.7,s[50,54]=-0.6,s[50,55]=-0.4,s[50,56]=0.5,s[50,57]=-0.7,s[50,58]=0.2,s[50,59]=0.7,s[50,60]=0.8 s[51,1]=-0.6,s[51,2]=0.4,s[51,3]=-0.1,s[51,4]=0.3,s[51,5]=1.2,s[51,6]=-0.1,s[51,7]=-0.4,s[51,8]=-0.4,s[51,9]=0.5,s[51,10]=0.8,s[51,11]=0.0,s[51,12]=-0.4,s[51,13]=-1.2,s[51,14]=-0.1,s[51,15]=-0.9,s[51,16]=-0.4,s[51,17]=-0.1,s[51,18]=-0.7,s[51,19]=-0.8,s[51,20]=-1.1,s[51,21]=-0.1,s[51,22]=-1.2,s[51,23]=0.9,s[51,24]=0.3,s[51,25]=1.0,s[51,26]=0.0,s[51,27]=1.1,s[51,28]=-0.6,s[51,29]=-0.3,s[51,30]=0.4 s[51,31]=-0.8,s[51,32]=-0.2,s[51,33]=0.7,s[51,34]=0.0,s[51,35]=-0.4,s[51,36]=0.7,s[51,37]=0.8,s[51,38]=-1.2,s[51,39]=1.0,s[51,40]=-0.9,s[51,41]=-0.1,s[51,42]=0.3,s[51,43]=-0.4,s[51,44]=0.8,s[51,45]=-0.9,s[51,46]=1.1,s[51,47]=-0.2,s[51,48]=0.3,s[51,49]=0.6,s[51,50]=0.1,s[51,51]=1.1,s[51,52]=-0.4,s[51,53]=-0.8,s[51,54]=0.0,s[51,55]=0.7,s[51,56]=1.0,s[51,57]=-0.8,s[51,58]=-1.2,s[51,59]=-0.4,s[51,60]=0.8 s[52,1]=0.1,s[52,2]=-0.5,s[52,3]=0.2,s[52,4]=-0.1,s[52,5]=0.3,s[52,6]=-0.8,s[52,7]=0.4,s[52,8]=-1.1,s[52,9]=0.1,s[52,10]=0.1,s[52,11]=0.1,s[52,12]=-0.6,s[52,13]=-1.1,s[52,14]=0.9,s[52,15]=0.4,s[52,16]=-0.1,s[52,17]=0.5,s[52,18]=1.0,s[52,19]=-1.1,s[52,20]=0.4,s[52,21]=-0.3,s[52,22]=1.2,s[52,23]=1.1,s[52,24]=-0.3,s[52,25]=0.7,s[52,26]=-0.3,s[52,27]=-0.4,s[52,28]=-1.0,s[52,29]=0.2,s[52,30]=0.9 s[52,31]=-0.2,s[52,32]=0.3,s[52,33]=0.3,s[52,34]=0.0,s[52,35]=-0.9,s[52,36]=1.2,s[52,37]=-0.4,s[52,38]=-0.2,s[52,39]=0.7,s[52,40]=-1.2,s[52,41]=-0.4,s[52,42]=-0.1,s[52,43]=0.8,s[52,44]=0.9,s[52,45]=1.2,s[52,46]=-0.2,s[52,47]=-0.5,s[52,48]=-0.2,s[52,49]=0.9,s[52,50]=0.3,s[52,51]=-0.5,s[52,52]=0.7,s[52,53]=-0.1,s[52,54]=-0.4,s[52,55]=-0.9,s[52,56]=-0.7,s[52,57]=-0.6,s[52,58]=0.5,s[52,59]=0.5,s[52,60]=0.1 s[53,1]=0.5,s[53,2]=0.6,s[53,3]=-0.2,s[53,4]=0.6,s[53,5]=0.1,s[53,6]=1.1,s[53,7]=0.7,s[53,8]=0.7,s[53,9]=-1.0,s[53,10]=0.9,s[53,11]=-0.6,s[53,12]=-0.5,s[53,13]=0.0,s[53,14]=0.4,s[53,15]=-0.8,s[53,16]=-0.1,s[53,17]=1.0,s[53,18]=-0.3,s[53,19]=1.0,s[53,20]=-0.1,s[53,21]=0.2,s[53,22]=-0.4,s[53,23]=0.5,s[53,24]=0.1,s[53,25]=1.1,s[53,26]=-0.8,s[53,27]=0.3,s[53,28]=0.7,s[53,29]=-0.4,s[53,30]=0.6 s[53,31]=0.3,s[53,32]=0.0,s[53,33]=0.9,s[53,34]=-0.3,s[53,35]=-0.6,s[53,36]=-0.3,s[53,37]=0.1,s[53,38]=-0.3,s[53,39]=0.4,s[53,40]=0.4,s[53,41]=0.9,s[53,42]=-0.6,s[53,43]=1.2,s[53,44]=1.2,s[53,45]=0.3,s[53,46]=0.0,s[53,47]=-0.6,s[53,48]=0.7,s[53,49]=0.2,s[53,50]=0.9,s[53,51]=-0.4,s[53,52]=0.3,s[53,53]=1.2,s[53,54]=0.8,s[53,55]=0.2,s[53,56]=-0.4,s[53,57]=0.7,s[53,58]=-0.6,s[53,59]=-0.8,s[53,60]=0.6 s[54,1]=0.4,s[54,2]=0.7,s[54,3]=0.5,s[54,4]=-1.2,s[54,5]=0.1,s[54,6]=0.9,s[54,7]=-1.2,s[54,8]=1.1,s[54,9]=-1.1,s[54,10]=-1.2,s[54,11]=1.1,s[54,12]=0.8,s[54,13]=-0.1,s[54,14]=-0.4,s[54,15]=-0.4,s[54,16]=0.5,s[54,17]=-0.8,s[54,18]=-0.1,s[54,19]=1.2,s[54,20]=0.3,s[54,21]=-0.6,s[54,22]=-0.2,s[54,23]=-0.9,s[54,24]=0.3,s[54,25]=0.5,s[54,26]=0.0,s[54,27]=1.1,s[54,28]=-1.2,s[54,29]=-0.5,s[54,30]=-0.2 s[54,31]=-0.8,s[54,32]=1.2,s[54,33]=0.3,s[54,34]=-0.1,s[54,35]=-0.6,s[54,36]=0.6,s[54,37]=-0.4,s[54,38]=0.4,s[54,39]=-0.5,s[54,40]=0.8,s[54,41]=-0.8,s[54,42]=-0.9,s[54,43]=-0.8,s[54,44]=-0.8,s[54,45]=-0.3,s[54,46]=-0.3,s[54,47]=-0.7,s[54,48]=-0.4,s[54,49]=1.2,s[54,50]=0.5,s[54,51]=0.5,s[54,52]=-0.4,s[54,53]=1.0,s[54,54]=-0.5,s[54,55]=-1.0,s[54,56]=0.6,s[54,57]=0.9,s[54,58]=-0.5,s[54,59]=1.0,s[54,60]=1.1 s[55,1]=-0.3,s[55,2]=0.4,s[55,3]=-0.7,s[55,4]=0.3,s[55,5]=0.7,s[55,6]=0.9,s[55,7]=-0.1,s[55,8]=1.0,s[55,9]=0.5,s[55,10]=-1.0,s[55,11]=0.6,s[55,12]=0.6,s[55,13]=-0.3,s[55,14]=0.2,s[55,15]=1.1,s[55,16]=-0.4,s[55,17]=-0.1,s[55,18]=-0.8,s[55,19]=0.6,s[55,20]=-0.9,s[55,21]=-0.5,s[55,22]=0.6,s[55,23]=0.5,s[55,24]=-0.4,s[55,25]=0.4,s[55,26]=-1.0,s[55,27]=-1.0,s[55,28]=1.0,s[55,29]=1.1,s[55,30]=0.2 s[55,31]=-0.3,s[55,32]=0.6,s[55,33]=-1.1,s[55,34]=0.4,s[55,35]=0.5,s[55,36]=-1.1,s[55,37]=-0.8,s[55,38]=-1.2,s[55,39]=1.2,s[55,40]=-0.8,s[55,41]=0.7,s[55,42]=-0.2,s[55,43]=0.7,s[55,44]=0.0,s[55,45]=0.4,s[55,46]=0.0,s[55,47]=0.0,s[55,48]=-0.3,s[55,49]=-0.1,s[55,50]=-0.4,s[55,51]=0.7,s[55,52]=-0.2,s[55,53]=-0.1,s[55,54]=-1.0,s[55,55]=0.1,s[55,56]=0.2,s[55,57]=-0.2,s[55,58]=-0.5,s[55,59]=-1.2,s[55,60]=-0.5 s[56,1]=-0.3,s[56,2]=-0.1,s[56,3]=-0.8,s[56,4]=0.2,s[56,5]=-0.4,s[56,6]=0.6,s[56,7]=-0.5,s[56,8]=-0.1,s[56,9]=-0.1,s[56,10]=1.0,s[56,11]=-0.1,s[56,12]=-0.9,s[56,13]=-0.5,s[56,14]=-0.2,s[56,15]=0.0,s[56,16]=-0.2,s[56,17]=0.6,s[56,18]=0.9,s[56,19]=-1.2,s[56,20]=-0.9,s[56,21]=0.4,s[56,22]=-0.7,s[56,23]=0.2,s[56,24]=-0.2,s[56,25]=-1.1,s[56,26]=0.2,s[56,27]=1.2,s[56,28]=-1.1,s[56,29]=0.2,s[56,30]=0.5 s[56,31]=-0.1,s[56,32]=1.0,s[56,33]=1.1,s[56,34]=-0.8,s[56,35]=0.3,s[56,36]=0.8,s[56,37]=-1.0,s[56,38]=0.2,s[56,39]=0.8,s[56,40]=1.1,s[56,41]=-0.1,s[56,42]=-0.2,s[56,43]=1.2,s[56,44]=0.4,s[56,45]=1.1,s[56,46]=-0.1,s[56,47]=-0.1,s[56,48]=1.2,s[56,49]=0.8,s[56,50]=0.8,s[56,51]=-1.2,s[56,52]=0.9,s[56,53]=-0.6,s[56,54]=1.2,s[56,55]=0.7,s[56,56]=-0.1,s[56,57]=1.1,s[56,58]=0.1,s[56,59]=-0.8,s[56,60]=1.1 s[57,1]=0.2,s[57,2]=-0.1,s[57,3]=0.7,s[57,4]=0.9,s[57,5]=-0.7,s[57,6]=-0.5,s[57,7]=-0.1,s[57,8]=-0.9,s[57,9]=0.3,s[57,10]=-0.6,s[57,11]=-0.3,s[57,12]=-1.1,s[57,13]=0.7,s[57,14]=0.0,s[57,15]=-0.3,s[57,16]=-0.2,s[57,17]=0.5,s[57,18]=0.0,s[57,19]=-1.0,s[57,20]=-0.1,s[57,21]=-0.3,s[57,22]=1.1,s[57,23]=0.0,s[57,24]=0.5,s[57,25]=0.4,s[57,26]=0.3,s[57,27]=0.6,s[57,28]=1.2,s[57,29]=0.3,s[57,30]=0.0 s[57,31]=-0.6,s[57,32]=0.8,s[57,33]=0.4,s[57,34]=0.6,s[57,35]=0.6,s[57,36]=0.0,s[57,37]=0.6,s[57,38]=0.3,s[57,39]=-0.2,s[57,40]=-0.1,s[57,41]=-1.2,s[57,42]=-0.5,s[57,43]=-0.8,s[57,44]=0.6,s[57,45]=1.0,s[57,46]=-0.7,s[57,47]=-0.7,s[57,48]=-0.4,s[57,49]=0.0,s[57,50]=0.0,s[57,51]=0.3,s[57,52]=0.0,s[57,53]=-0.8,s[57,54]=0.3,s[57,55]=-0.7,s[57,56]=0.7,s[57,57]=0.5,s[57,58]=0.8,s[57,59]=0.3,s[57,60]=0.6 s[58,1]=-0.3,s[58,2]=0.5,s[58,3]=0.4,s[58,4]=0.5,s[58,5]=-0.9,s[58,6]=-0.7,s[58,7]=1.1,s[58,8]=1.0,s[58,9]=-0.2,s[58,10]=-0.8,s[58,11]=0.5,s[58,12]=1.0,s[58,13]=1.2,s[58,14]=0.1,s[58,15]=1.0,s[58,16]=-0.1,s[58,17]=-0.4,s[58,18]=0.5,s[58,19]=0.7,s[58,20]=0.1,s[58,21]=-0.4,s[58,22]=0.1,s[58,23]=1.2,s[58,24]=0.6,s[58,25]=-0.1,s[58,26]=1.1,s[58,27]=-0.1,s[58,28]=0.8,s[58,29]=-0.8,s[58,30]=-0.5 s[58,31]=-0.4,s[58,32]=0.4,s[58,33]=0.6,s[58,34]=-0.3,s[58,35]=-0.1,s[58,36]=0.0,s[58,37]=-0.2,s[58,38]=-0.2,s[58,39]=0.8,s[58,40]=0.5,s[58,41]=-0.4,s[58,42]=-0.1,s[58,43]=-0.8,s[58,44]=-0.2,s[58,45]=0.2,s[58,46]=-0.3,s[58,47]=-0.4,s[58,48]=0.0,s[58,49]=-1.0,s[58,50]=-1.0,s[58,51]=0.8,s[58,52]=-0.8,s[58,53]=-0.5,s[58,54]=-0.1,s[58,55]=-0.9,s[58,56]=-0.4,s[58,57]=0.6,s[58,58]=0.1,s[58,59]=-0.3,s[58,60]=-0.1 s[59,1]=0.3,s[59,2]=-1.1,s[59,3]=-0.3,s[59,4]=-0.4,s[59,5]=-0.4,s[59,6]=0.3,s[59,7]=-0.5,s[59,8]=-0.1,s[59,9]=0.5,s[59,10]=0.7,s[59,11]=1.0,s[59,12]=-0.3,s[59,13]=-1.1,s[59,14]=0.8,s[59,15]=0.0,s[59,16]=0.3,s[59,17]=-0.2,s[59,18]=-0.9,s[59,19]=-0.3,s[59,20]=-1.1,s[59,21]=-0.3,s[59,22]=0.9,s[59,23]=-0.3,s[59,24]=-0.3,s[59,25]=-1.2,s[59,26]=-0.3,s[59,27]=-0.1,s[59,28]=1.0,s[59,29]=0.0,s[59,30]=-1.1 s[59,31]=0.5,s[59,32]=-1.1,s[59,33]=-1.1,s[59,34]=0.8,s[59,35]=-0.1,s[59,36]=-0.6,s[59,37]=0.0,s[59,38]=0.7,s[59,39]=0.7,s[59,40]=0.3,s[59,41]=0.3,s[59,42]=-0.4,s[59,43]=0.0,s[59,44]=-0.2,s[59,45]=1.0,s[59,46]=0.1,s[59,47]=-0.2,s[59,48]=0.3,s[59,49]=0.4,s[59,50]=1.1,s[59,51]=-1.2,s[59,52]=-1.2,s[59,53]=1.2,s[59,54]=-1.1,s[59,55]=-0.5,s[59,56]=0.8,s[59,57]=-0.7,s[59,58]=-0.8,s[59,59]=-0.1,s[59,60]=1.1 s[60,1]=0.1,s[60,2]=0.1,s[60,3]=0.4,s[60,4]=0.9,s[60,5]=-0.2,s[60,6]=0.7,s[60,7]=-0.2,s[60,8]=0.8,s[60,9]=0.6,s[60,10]=-1.1,s[60,11]=-0.7,s[60,12]=1.0,s[60,13]=-0.4,s[60,14]=0.4,s[60,15]=-0.3,s[60,16]=0.6,s[60,17]=-1.1,s[60,18]=-0.5,s[60,19]=-0.9,s[60,20]=0.3,s[60,21]=0.9,s[60,22]=-0.7,s[60,23]=0.3,s[60,24]=0.8,s[60,25]=-1.1,s[60,26]=-0.9,s[60,27]=-0.2,s[60,28]=-0.8,s[60,29]=1.1,s[60,30]=-0.5 s[60,31]=-0.1,s[60,32]=0.2,s[60,33]=0.3,s[60,34]=-0.4,s[60,35]=0.5,s[60,36]=1.1,s[60,37]=0.7,s[60,38]=0.4,s[60,39]=-1.2,s[60,40]=0.5,s[60,41]=0.3,s[60,42]=1.1,s[60,43]=0.4,s[60,44]=-1.0,s[60,45]=1.1,s[60,46]=0.4,s[60,47]=0.0,s[60,48]=-0.2,s[60,49]=0.6,s[60,50]=-0.3,s[60,51]=-0.3,s[60,52]=-0.2,s[60,53]=0.6,s[60,54]=0.1,s[60,55]=0.0,s[60,56]=-0.2,s[60,57]=-0.9,s[60,58]=0.2,s[60,59]=-0.5,s[60,60]=-0.5 s[61,1]=0.0,s[61,2]=-0.9,s[61,3]=-0.2,s[61,4]=-1.2,s[61,5]=-1.1,s[61,6]=-0.1,s[61,7]=0.6,s[61,8]=-0.3,s[61,9]=0.2,s[61,10]=0.5,s[61,11]=0.3,s[61,12]=-1.2,s[61,13]=0.0,s[61,14]=-1.1,s[61,15]=-0.4,s[61,16]=-0.1,s[61,17]=-0.2,s[61,18]=0.3,s[61,19]=0.1,s[61,20]=-1.0,s[61,21]=0.1,s[61,22]=-0.3,s[61,23]=-0.8,s[61,24]=0.3,s[61,25]=-1.0,s[61,26]=0.8,s[61,27]=0.3,s[61,28]=-0.4,s[61,29]=0.0,s[61,30]=-0.8 s[61,31]=-0.1,s[61,32]=1.0,s[61,33]=-0.2,s[61,34]=0.7,s[61,35]=-0.7,s[61,36]=-0.3,s[61,37]=-0.8,s[61,38]=0.9,s[61,39]=0.7,s[61,40]=0.3,s[61,41]=0.6,s[61,42]=1.1,s[61,43]=1.0,s[61,44]=1.1,s[61,45]=0.2,s[61,46]=0.2,s[61,47]=-0.2,s[61,48]=0.4,s[61,49]=1.0,s[61,50]=0.7,s[61,51]=0.7,s[61,52]=0.3,s[61,53]=0.6,s[61,54]=0.0,s[61,55]=0.2,s[61,56]=0.2,s[61,57]=-0.1,s[61,58]=-1.1,s[61,59]=-0.9,s[61,60]=0.3 s[62,1]=0.1,s[62,2]=1.2,s[62,3]=-0.9,s[62,4]=-0.7,s[62,5]=-0.9,s[62,6]=0.4,s[62,7]=0.3,s[62,8]=-0.9,s[62,9]=0.3,s[62,10]=0.7,s[62,11]=-1.0,s[62,12]=1.0,s[62,13]=0.0,s[62,14]=0.0,s[62,15]=-0.1,s[62,16]=0.8,s[62,17]=0.0,s[62,18]=0.6,s[62,19]=-1.1,s[62,20]=-0.2,s[62,21]=0.1,s[62,22]=-0.8,s[62,23]=1.0,s[62,24]=-0.4,s[62,25]=0.7,s[62,26]=0.9,s[62,27]=0.2,s[62,28]=0.5,s[62,29]=-0.6,s[62,30]=0.6 s[62,31]=-0.2,s[62,32]=0.0,s[62,33]=0.5,s[62,34]=0.2,s[62,35]=0.1,s[62,36]=1.1,s[62,37]=-0.2,s[62,38]=0.5,s[62,39]=0.6,s[62,40]=-0.2,s[62,41]=-0.4,s[62,42]=-1.0,s[62,43]=-1.2,s[62,44]=0.7,s[62,45]=0.7,s[62,46]=-0.1,s[62,47]=0.5,s[62,48]=-0.9,s[62,49]=-0.4,s[62,50]=-0.4,s[62,51]=-0.9,s[62,52]=-0.4,s[62,53]=-0.2,s[62,54]=-0.7,s[62,55]=-0.7,s[62,56]=-0.1,s[62,57]=1.1,s[62,58]=-0.3,s[62,59]=-0.5,s[62,60]=0.2 s[63,1]=0.0,s[63,2]=0.4,s[63,3]=0.0,s[63,4]=-0.4,s[63,5]=0.3,s[63,6]=0.1,s[63,7]=0.5,s[63,8]=-0.2,s[63,9]=0.8,s[63,10]=1.1,s[63,11]=-0.6,s[63,12]=-0.6,s[63,13]=0.0,s[63,14]=-0.1,s[63,15]=-0.4,s[63,16]=0.1,s[63,17]=0.0,s[63,18]=-1.2,s[63,19]=-0.7,s[63,20]=-1.1,s[63,21]=1.0,s[63,22]=0.0,s[63,23]=-0.8,s[63,24]=-0.7,s[63,25]=-1.2,s[63,26]=-0.4,s[63,27]=1.1,s[63,28]=0.9,s[63,29]=0.5,s[63,30]=0.2 s[63,31]=-0.1,s[63,32]=-0.5,s[63,33]=-0.8,s[63,34]=-0.1,s[63,35]=-0.8,s[63,36]=-0.5,s[63,37]=-0.6,s[63,38]=0.8,s[63,39]=1.2,s[63,40]=-1.1,s[63,41]=-0.3,s[63,42]=1.0,s[63,43]=1.2,s[63,44]=0.4,s[63,45]=1.0,s[63,46]=0.0,s[63,47]=0.2,s[63,48]=1.2,s[63,49]=-0.6,s[63,50]=-0.2,s[63,51]=-1.0,s[63,52]=-1.1,s[63,53]=-0.2,s[63,54]=1.2,s[63,55]=0.3,s[63,56]=-0.9,s[63,57]=-0.9,s[63,58]=0.4,s[63,59]=-0.4,s[63,60]=1.0 s[64,1]=0.3,s[64,2]=-1.2,s[64,3]=1.0,s[64,4]=1.1,s[64,5]=0.4,s[64,6]=-0.7,s[64,7]=-1.2,s[64,8]=0.9,s[64,9]=1.2,s[64,10]=0.5,s[64,11]=-1.2,s[64,12]=0.1,s[64,13]=-0.7,s[64,14]=0.3,s[64,15]=-0.8,s[64,16]=0.3,s[64,17]=0.3,s[64,18]=-0.1,s[64,19]=-0.3,s[64,20]=-0.4,s[64,21]=-0.7,s[64,22]=0.0,s[64,23]=-0.2,s[64,24]=-0.3,s[64,25]=1.0,s[64,26]=0.8,s[64,27]=1.0,s[64,28]=1.0,s[64,29]=-0.6,s[64,30]=-0.3 s[64,31]=0.2,s[64,32]=0.4,s[64,33]=-0.5,s[64,34]=-0.3,s[64,35]=-0.9,s[64,36]=0.8,s[64,37]=-0.6,s[64,38]=-0.2,s[64,39]=0.9,s[64,40]=0.3,s[64,41]=0.7,s[64,42]=0.0,s[64,43]=1.1,s[64,44]=-0.9,s[64,45]=1.1,s[64,46]=0.3,s[64,47]=-0.8,s[64,48]=-1.1,s[64,49]=0.7,s[64,50]=-0.4,s[64,51]=-0.9,s[64,52]=-0.3,s[64,53]=-0.8,s[64,54]=0.4,s[64,55]=-0.4,s[64,56]=-0.9,s[64,57]=-1.0,s[64,58]=-0.1,s[64,59]=0.3,s[64,60]=0.2 s[65,1]=0.3,s[65,2]=-0.1,s[65,3]=-0.4,s[65,4]=1.2,s[65,5]=-0.6,s[65,6]=-0.7,s[65,7]=0.1,s[65,8]=0.2,s[65,9]=-0.8,s[65,10]=-0.6,s[65,11]=-0.2,s[65,12]=-0.8,s[65,13]=-0.6,s[65,14]=-0.7,s[65,15]=1.1,s[65,16]=0.0,s[65,17]=1.2,s[65,18]=-0.7,s[65,19]=0.8,s[65,20]=-0.3,s[65,21]=-0.6,s[65,22]=-0.5,s[65,23]=0.9,s[65,24]=1.2,s[65,25]=-1.1,s[65,26]=1.2,s[65,27]=0.5,s[65,28]=0.0,s[65,29]=0.7,s[65,30]=1.1 s[65,31]=0.0,s[65,32]=-0.6,s[65,33]=-1.0,s[65,34]=1.1,s[65,35]=-1.0,s[65,36]=-0.6,s[65,37]=-1.1,s[65,38]=0.4,s[65,39]=-0.8,s[65,40]=-0.9,s[65,41]=0.7,s[65,42]=0.5,s[65,43]=1.1,s[65,44]=1.2,s[65,45]=0.5,s[65,46]=0.3,s[65,47]=0.8,s[65,48]=-0.7,s[65,49]=-0.2,s[65,50]=-1.0,s[65,51]=1.0,s[65,52]=-0.1,s[65,53]=-0.3,s[65,54]=0.9,s[65,55]=1.1,s[65,56]=1.1,s[65,57]=-0.4,s[65,58]=0.5,s[65,59]=0.4,s[65,60]=-1.2 s[66,1]=0.0,s[66,2]=0.1,s[66,3]=0.6,s[66,4]=-0.2,s[66,5]=-0.5,s[66,6]=0.9,s[66,7]=0.5,s[66,8]=-0.3,s[66,9]=-0.6,s[66,10]=-0.9,s[66,11]=-0.2,s[66,12]=-1.1,s[66,13]=0.9,s[66,14]=0.2,s[66,15]=0.4,s[66,16]=0.6,s[66,17]=0.1,s[66,18]=-1.2,s[66,19]=0.6,s[66,20]=0.3,s[66,21]=0.2,s[66,22]=-0.3,s[66,23]=-0.1,s[66,24]=-0.5,s[66,25]=0.3,s[66,26]=-0.6,s[66,27]=-0.2,s[66,28]=-0.3,s[66,29]=-0.4,s[66,30]=-0.9 s[66,31]=0.0,s[66,32]=1.0,s[66,33]=0.0,s[66,34]=-1.0,s[66,35]=0.7,s[66,36]=-1.0,s[66,37]=0.7,s[66,38]=-0.7,s[66,39]=-0.6,s[66,40]=1.2,s[66,41]=0.6,s[66,42]=-1.1,s[66,43]=0.6,s[66,44]=-0.8,s[66,45]=-1.2,s[66,46]=-0.4,s[66,47]=0.9,s[66,48]=0.9,s[66,49]=0.5,s[66,50]=1.0,s[66,51]=0.9,s[66,52]=0.3,s[66,53]=-0.6,s[66,54]=0.6,s[66,55]=-0.2,s[66,56]=-0.6,s[66,57]=0.1,s[66,58]=-0.9,s[66,59]=-0.2,s[66,60]=1.0 s[67,1]=-0.3,s[67,2]=-0.7,s[67,3]=-0.4,s[67,4]=0.6,s[67,5]=0.9,s[67,6]=0.6,s[67,7]=0.5,s[67,8]=-0.4,s[67,9]=0.9,s[67,10]=-0.2,s[67,11]=0.5,s[67,12]=-0.7,s[67,13]=0.2,s[67,14]=1.1,s[67,15]=-1.0,s[67,16]=0.2,s[67,17]=0.2,s[67,18]=0.6,s[67,19]=-0.2,s[67,20]=-1.1,s[67,21]=-0.9,s[67,22]=0.7,s[67,23]=0.4,s[67,24]=0.1,s[67,25]=-0.9,s[67,26]=0.1,s[67,27]=-0.4,s[67,28]=-0.7,s[67,29]=-1.0,s[67,30]=0.8 s[67,31]=0.1,s[67,32]=0.0,s[67,33]=-0.7,s[67,34]=-0.1,s[67,35]=-0.5,s[67,36]=-0.4,s[67,37]=-0.2,s[67,38]=0.4,s[67,39]=0.0,s[67,40]=0.4,s[67,41]=0.8,s[67,42]=-0.1,s[67,43]=-1.0,s[67,44]=-0.7,s[67,45]=1.2,s[67,46]=0.3,s[67,47]=0.8,s[67,48]=-1.0,s[67,49]=-0.2,s[67,50]=-1.0,s[67,51]=0.0,s[67,52]=0.7,s[67,53]=-0.3,s[67,54]=0.7,s[67,55]=1.2,s[67,56]=-0.4,s[67,57]=1.0,s[67,58]=0.8,s[67,59]=-1.2,s[67,60]=0.7 s[68,1]=0.1,s[68,2]=1.2,s[68,3]=1.2,s[68,4]=0.2,s[68,5]=0.6,s[68,6]=-1.0,s[68,7]=-1.0,s[68,8]=-0.4,s[68,9]=-1.2,s[68,10]=-0.4,s[68,11]=0.5,s[68,12]=-0.3,s[68,13]=0.3,s[68,14]=-0.1,s[68,15]=0.6,s[68,16]=0.3,s[68,17]=0.6,s[68,18]=-1.2,s[68,19]=-0.5,s[68,20]=-1.1,s[68,21]=-0.6,s[68,22]=0.8,s[68,23]=-0.6,s[68,24]=0.4,s[68,25]=0.4,s[68,26]=0.1,s[68,27]=0.6,s[68,28]=-0.1,s[68,29]=-0.9,s[68,30]=1.1 s[68,31]=0.4,s[68,32]=-0.7,s[68,33]=-0.7,s[68,34]=-0.9,s[68,35]=0.5,s[68,36]=1.0,s[68,37]=-0.4,s[68,38]=0.1,s[68,39]=0.6,s[68,40]=0.9,s[68,41]=-0.7,s[68,42]=0.6,s[68,43]=1.2,s[68,44]=-0.8,s[68,45]=-0.9,s[68,46]=0.4,s[68,47]=0.6,s[68,48]=-0.4,s[68,49]=-0.1,s[68,50]=-0.9,s[68,51]=-0.7,s[68,52]=-1.2,s[68,53]=1.2,s[68,54]=0.3,s[68,55]=0.5,s[68,56]=0.5,s[68,57]=-1.0,s[68,58]=-0.4,s[68,59]=0.1,s[68,60]=0.3 endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float ppz = @ppz float ppw = @ppw float pxx = 0 float pyy = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x pyy = y float pzz = ppz x = s[@sel,1] + s[@sel,2]*x + s[@sel,3]*x*x + s[@sel,4]*x*y + s[@sel,5]*x*ppz + s[@sel,6]*x*ppw + s[@sel,7]*y + s[@sel,8]*y*y + \ s[@sel,9]*y*ppz + s[@sel,10]*y*ppw + s[@sel,11]*ppz + s[@sel,12]*ppz*ppz + s[@sel,13]*ppz*ppw + s[@sel,14]*ppw + s[@sel,15]*ppw*ppw y = s[@sel,16] + s[@sel,17]*pxx + s[@sel,18]*pxx*pxx + s[@sel,19]*pxx*y + s[@sel,20]*pxx*ppz + s[@sel,21]*pxx*ppw + s[@sel,22]*y + s[@sel,23]*y*y + \ s[@sel,24]*y*ppz + s[@sel,25]*y*ppw + s[@sel,26]*ppz + s[@sel,27]*ppz*ppz + s[@sel,28]*ppz*ppw + s[@sel,29]*ppw + s[@sel,30]*ppw*ppw ppz = s[@sel,31] + s[@sel,32]*pxx + s[@sel,33]*pxx*pxx + s[@sel,34]*pxx*pyy + s[@sel,35]*pxx*ppz + s[@sel,36]*pxx*ppw + s[@sel,37]*pyy + s[@sel,38]*pyy*pyy + \ s[@sel,39]*pyy*ppz + s[@sel,40]*pyy*ppw + s[@sel,41]*ppz + s[@sel,42]*ppz*ppz + s[@sel,43]*ppz*ppw + s[@sel,44]*ppw + s[@sel,45]*ppw*ppw ppw = s[@sel,46] + s[@sel,47]*pxx + s[@sel,48]*pxx*pxx + s[@sel,49]*pxx*pyy + s[@sel,50]*pxx*pzz + s[@sel,51]*pxx*ppw + s[@sel,52]*pyy + s[@sel,53]*pyy*pyy + \ s[@sel,54]*pyy*pzz + s[@sel,55]*pyy*ppw + s[@sel,56]*pzz + s[@sel,57]*pzz*pzz + s[@sel,58]*pzz*ppw + s[@sel,59]*ppw + s[@sel,60]*ppw*ppw att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y) + ppz*@pw + ppw*@p4) float d = @distscale*|pz-(x + sgn*flip(y) + ppz*@pw + ppw*@p4)| return d endfunc private: float s[69,61] default: title = "Sprott4D" heading text="Sprott 4D Quadratic attractors" endheading heading text=" x -> Quadratic in x, y, z and w" endheading heading text=" y -> Quadratic in x, y, z and w" endheading heading text=" z -> Quadratic in x, y, z and w" endheading heading text=" w -> Quadratic in x, y, z and w" endheading int param v_trapshapesprott4d caption = "Version (Trap Shape Sprott4D)" 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_trapshapesprott4D < 100 endparam param sel caption = "Sprott selector" default = 0 enum = "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" \ "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" \ "21" "22" "23" "24" "25" "26" "27" "28" "29" "30" \ "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" \ "41" "42" "43" "44" "45" "46" "47" "48" "49" "50" \ "51" "52" "53" "54" "55" "56" "57" "58" "59" "60" \ "61" "62" "63" "64" "65" "66" "67" "68" hint = "Each Sprott selector uses a different strange attractor." endparam heading text = "'Initialize Height' sets the starting z value for the attractor." endheading float param ppz caption = "Initialize Height" default = 0.0 endparam heading text = "'Initialize 4th dim' sets the starting w value for the attractor." endheading float param ppw caption = "Initialize 4th dim" default = 0.0 endparam heading text = "'Height weight' determines the weight of the final z value which is added \ to the trap distance." endheading complex param pw caption = "Height weight" default = (0.5,0) endparam heading text = "'4D weight' determines the weight of the final w value which is added \ to the trap distance." endheading complex param p4 caption = "4D weight" default = (0,0) endparam float param distscale caption = "Distance scale" default = 2 endparam float param s caption = "Attractor scale" default = 1 endparam int param max_att_iterations caption = "Attractor iterations" default = 20 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeSprott4D_ODE(common.ulb:TrapShape) { ; This shape uses a Sprott strange attractor.
;

; The Sprott attractors were developed by Julien C. Sprott, and are ; based upon polynomials and linear differential equations of polynomials. public: import "common.ulb" ; Constructor func REB_TrapShapeSprott4D_ODE(Generic pparent) TrapShape.TrapShape(pparent) s[0,1]=0.0,s[0,2]=-0.6,s[0,3]=0.0,s[0,4]=-0.8,s[0,5]=-0.8,s[0,6]=-0.6,s[0,7]=0.3,s[0,8]=0.1,s[0,9]=0.5,s[0,10]=-0.4,s[0,11]=0.0,s[0,12]=0.4,s[0,13]=0.7,s[0,14]=0.4,s[0,15]=1.2,s[0,16]=-0.6,s[0,17]=0.4,s[0,18]=-0.2,s[0,19]=-1.2,s[0,20]=0.2,s[0,21]=-1.0,s[0,22]=-0.6,s[0,23]=-0.9,s[0,24]=0.7,s[0,25]=-0.6,s[0,26]=1.2,s[0,27]=0.8,s[0,28]=-0.3,s[0,29]=0.3,s[0,30]=0.3 s[0,31]=-1.2,s[0,32]=0.6,s[0,33]=0.3,s[0,34]=0.6,s[0,35]=-0.5,s[0,36]=0.4,s[0,37]=-0.2,s[0,38]=-0.4,s[0,39]=-0.6,s[0,40]=-0.3,s[0,41]=-0.7,s[0,42]=0.0,s[0,43]=1.0,s[0,44]=0.8,s[0,45]=1.1,s[0,46]=0.7,s[0,47]=0.3,s[0,48]=-0.3,s[0,49]=-1.2,s[0,50]=-0.6,s[0,51]=-1.1,s[0,52]=-0.3,s[0,53]=-0.2,s[0,54]=-0.7,s[0,55]=-1.0,s[0,56]=1.2,s[0,57]=-1.2,s[0,58]=-0.7,s[0,59]=0.2,s[0,60]=-0.2 s[1,1]=0.7,s[1,2]=0.1,s[1,3]=0.1,s[1,4]=1.2,s[1,5]=-1.0,s[1,6]=0.4,s[1,7]=0.7,s[1,8]=-0.9,s[1,9]=-0.3,s[1,10]=-0.9,s[1,11]=-0.5,s[1,12]=-0.5,s[1,13]=-1.0,s[1,14]=0.0,s[1,15]=-0.4,s[1,16]=-0.2,s[1,17]=-0.5,s[1,18]=0.1,s[1,19]=-1.0,s[1,20]=0.3,s[1,21]=-0.4,s[1,22]=1.1,s[1,23]=1.1,s[1,24]=0.0,s[1,25]=-1.1,s[1,26]=-0.7,s[1,27]=0.0,s[1,28]=0.5,s[1,29]=0.7,s[1,30]=0.7,s[1,31]=-1.0,s[1,32]=0.7,s[1,33]=0.2,s[1,34]=-0.7,s[1,35]=-1.1,s[1,36]=0.7,s[1,37]=-0.7,s[1,38]=0.0,s[1,39]=-0.5,s[1,40]=0.2,s[1,41]=-0.1,s[1,42]=-0.6,s[1,43]=0.2,s[1,44]=-0.4,s[1,45]=-0.8,s[1,46]=0.8,s[1,47]=0.5,s[1,48]=-1.2,s[1,49]=-0.4,s[1,50]=-1.1,s[1,51]=-1.1,s[1,52]=-0.5,s[1,53]=0.2,s[1,54]=-0.8,s[1,55]=0.3,s[1,56]=0.2,s[1,57]=-0.5,s[1,58]=0.0,s[1,59]=-0.9,s[1,60]=-1.0 s[2,1]=0.0,s[2,2]=-0.9,s[2,3]=1.2,s[2,4]=0.3,s[2,5]=0.6,s[2,6]=0.6,s[2,7]=-0.7,s[2,8]=-0.1,s[2,9]=-0.1,s[2,10]=-0.9,s[2,11]=0.8,s[2,12]=0.5,s[2,13]=0.7,s[2,14]=0.8,s[2,15]=-1.2,s[2,16]=-1.0,s[2,17]=-0.2,s[2,18]=-1.1,s[2,19]=0.5,s[2,20]=-0.9,s[2,21]=0.6,s[2,22]=-0.1,s[2,23]=0.6,s[2,24]=0.2,s[2,25]=-0.3,s[2,26]=-0.5,s[2,27]=1.1,s[2,28]=-0.3,s[2,29]=-0.7,s[2,30]=-0.4,s[2,31]=-0.6,s[2,32]=0.9,s[2,33]=0.0,s[2,34]=-0.6,s[2,35]=1.2,s[2,36]=-0.4,s[2,37]=0.9,s[2,38]=0.7,s[2,39]=-0.2,s[2,40]=-0.1,s[2,41]=-0.8,s[2,42]=-0.8,s[2,43]=-1.2,s[2,44]=1.2,s[2,45]=0.2,s[2,46]=-0.7,s[2,47]=-0.9,s[2,48]=-0.4,s[2,49]=0.1,s[2,50]=0.7,s[2,51]=0.2,s[2,52]=1.1,s[2,53]=-0.1,s[2,54]=-1.2,s[2,55]=-0.5,s[2,56]=0.0,s[2,57]=1.0,s[2,58]=1.2,s[2,59]=-0.2,s[2,60]=-1.1 s[3,1]=0.0,s[3,2]=-0.7,s[3,3]=0.0,s[3,4]=-0.8,s[3,5]=-0.8,s[3,6]=-0.6,s[3,7]=0.3,s[3,8]=0.1,s[3,9]=0.5,s[3,10]=-0.4,s[3,11]=0.0,s[3,12]=0.4,s[3,13]=0.7,s[3,14]=0.4,s[3,15]=1.2,s[3,16]=-0.6,s[3,17]=0.4,s[3,18]=-0.2,s[3,19]=-1.2,s[3,20]=0.2,s[3,21]=-1.0,s[3,22]=-0.6,s[3,23]=-0.9,s[3,24]=0.7,s[3,25]=-0.6,s[3,26]=1.2,s[3,27]=0.8,s[3,28]=-0.3,s[3,29]=0.3,s[3,30]=0.3,s[3,31]=-1.2,s[3,32]=0.6,s[3,33]=0.3,s[3,34]=0.6,s[3,35]=-0.5,s[3,36]=0.4,s[3,37]=-0.2,s[3,38]=-0.4,s[3,39]=-0.6,s[3,40]=-0.3,s[3,41]=-0.7,s[3,42]=0.0,s[3,43]=1.0,s[3,44]=0.8,s[3,45]=1.1,s[3,46]=0.7,s[3,47]=0.3,s[3,48]=-0.3,s[3,49]=-1.2,s[3,50]=-0.6,s[3,51]=-1.1,s[3,52]=-0.3,s[3,53]=-0.2,s[3,54]=-0.7,s[3,55]=-1.0,s[3,56]=1.2,s[3,57]=-1.2,s[3,58]=-0.7,s[3,59]=0.2,s[3,60]=-0.2 s[4,1]=-0.7,s[4,2]=-1.1,s[4,3]=1.2,s[4,4]=-0.2,s[4,5]=-1.1,s[4,6]=0.8,s[4,7]=-1.1,s[4,8]=0.8,s[4,9]=0.3,s[4,10]=-0.9,s[4,11]=-0.5,s[4,12]=0.5,s[4,13]=-0.2,s[4,14]=-0.7,s[4,15]=0.3,s[4,16]=1.2,s[4,17]=-0.8,s[4,18]=0.0,s[4,19]=-1.0,s[4,20]=-1.0,s[4,21]=-1.0,s[4,22]=0.8,s[4,23]=-0.4,s[4,24]=0.6,s[4,25]=-1.1,s[4,26]=0.7,s[4,27]=-0.5,s[4,28]=-0.4,s[4,29]=-1.2,s[4,30]=0.7,s[4,31]=-0.9,s[4,32]=0.5,s[4,33]=0.9,s[4,34]=-0.6,s[4,35]=-1.1,s[4,36]=-0.5,s[4,37]=0.0,s[4,38]=-1.0,s[4,39]=0.1,s[4,40]=1.0,s[4,41]=-1.0,s[4,42]=-0.3,s[4,43]=-0.8,s[4,44]=1.2,s[4,45]=-0.3,s[4,46]=0.8,s[4,47]=0.8,s[4,48]=-1.2,s[4,49]=-0.3,s[4,50]=0.7,s[4,51]=1.1,s[4,52]=0.8,s[4,53]=0.1,s[4,54]=0.8,s[4,55]=0.3,s[4,56]=1.2,s[4,57]=1.0,s[4,58]=0.2,s[4,59]=0.6,s[4,60]=-0.6 s[5,1]=-0.2,s[5,2]=0.0,s[5,3]=-1.0,s[5,4]=1.0,s[5,5]=-0.3,s[5,6]=-0.7,s[5,7]=-1.2,s[5,8]=-0.6,s[5,9]=0.4,s[5,10]=0.5,s[5,11]=0.9,s[5,12]=1.1,s[5,13]=0.8,s[5,14]=1.2,s[5,15]=0.1,s[5,16]=1.1,s[5,17]=-0.5,s[5,18]=-0.4,s[5,19]=-0.4,s[5,20]=0.4,s[5,21]=-0.9,s[5,22]=-0.2,s[5,23]=0.0,s[5,24]=-0.9,s[5,25]=-0.8,s[5,26]=1.2,s[5,27]=-1.2,s[5,28]=0.2,s[5,29]=0.4,s[5,30]=-0.1,s[5,31]=0.3,s[5,32]=-0.6,s[5,33]=-0.1,s[5,34]=-1.1,s[5,35]=-0.5,s[5,36]=-1.0,s[5,37]=0.7,s[5,38]=0.0,s[5,39]=-1.0,s[5,40]=0.0,s[5,41]=0.3,s[5,42]=0.3,s[5,43]=1.0,s[5,44]=0.1,s[5,45]=1.0,s[5,46]=1.2,s[5,47]=-0.1,s[5,48]=-0.4,s[5,49]=-0.5,s[5,50]=0.1,s[5,51]=-0.4,s[5,52]=0.4,s[5,53]=-0.6,s[5,54]=-1.1,s[5,55]=-0.1,s[5,56]=0.0,s[5,57]=0.2,s[5,58]=0.0,s[5,59]=-0.1,s[5,60]=-0.9 s[6,1]=-0.3,s[6,2]=0.6,s[6,3]=0.0,s[6,4]=-0.7,s[6,5]=0.6,s[6,6]=1.2,s[6,7]=-0.1,s[6,8]=0.7,s[6,9]=-0.9,s[6,10]=-1.1,s[6,11]=1.2,s[6,12]=1.1,s[6,13]=-1.1,s[6,14]=-0.1,s[6,15]=0.3,s[6,16]=-0.1,s[6,17]=-0.9,s[6,18]=-0.4,s[6,19]=0.3,s[6,20]=0.1,s[6,21]=-1.2,s[6,22]=-0.6,s[6,23]=-0.3,s[6,24]=0.2,s[6,25]=-0.2,s[6,26]=-0.2,s[6,27]=0.3,s[6,28]=1.1,s[6,29]=-1.1,s[6,30]=-1.0,s[6,31]=-1.0,s[6,32]=0.3,s[6,33]=-0.3,s[6,34]=0.6,s[6,35]=-1.2,s[6,36]=0.1,s[6,37]=-0.2,s[6,38]=0.5,s[6,39]=1.2,s[6,40]=0.9,s[6,41]=-0.5,s[6,42]=1.1,s[6,43]=-0.3,s[6,44]=0.9,s[6,45]=-0.3,s[6,46]=1.0,s[6,47]=-0.5,s[6,48]=-0.2,s[6,49]=0.2,s[6,50]=0.9,s[6,51]=1.1,s[6,52]=0.5,s[6,53]=-1.0,s[6,54]=-0.5,s[6,55]=0.9,s[6,56]=-0.6,s[6,57]=-1.1,s[6,58]=-0.2,s[6,59]=-0.3,s[6,60]=0.5 s[7,1]=-0.8,s[7,2]=0.7,s[7,3]=-0.5,s[7,4]=-1.1,s[7,5]=-0.7,s[7,6]=0.7,s[7,7]=-1.1,s[7,8]=-0.3,s[7,9]=0.6,s[7,10]=-0.1,s[7,11]=-0.8,s[7,12]=0.6,s[7,13]=1.2,s[7,14]=-1.1,s[7,15]=0.6,s[7,16]=-0.1,s[7,17]=-0.3,s[7,18]=0.5,s[7,19]=0.1,s[7,20]=0.9,s[7,21]=0.8,s[7,22]=-0.6,s[7,23]=0.8,s[7,24]=1.2,s[7,25]=0.3,s[7,26]=-0.5,s[7,27]=0.7,s[7,28]=0.1,s[7,29]=1.2,s[7,30]=-1.1,s[7,31]=0.9,s[7,32]=-0.9,s[7,33]=0.6,s[7,34]=-0.4,s[7,35]=0.2,s[7,36]=-0.7,s[7,37]=-0.8,s[7,38]=-0.6,s[7,39]=-0.7,s[7,40]=-0.5,s[7,41]=0.8,s[7,42]=-1.2,s[7,43]=1.0,s[7,44]=-1.2,s[7,45]=0.1,s[7,46]=-0.4,s[7,47]=0.1,s[7,48]=-0.6,s[7,49]=-0.6,s[7,50]=0.2,s[7,51]=-0.4,s[7,52]=0.5,s[7,53]=-0.2,s[7,54]=-0.5,s[7,55]=0.9,s[7,56]=-0.1,s[7,57]=-1.1,s[7,58]=0.4,s[7,59]=-1.0,s[7,60]=-0.3 s[8,1]=1.1,s[8,2]=-1.0,s[8,3]=0.7,s[8,4]=0.9,s[8,5]=1.1,s[8,6]=-0.1,s[8,7]=0.3,s[8,8]=0.4,s[8,9]=-1.1,s[8,10]=-1.0,s[8,11]=-0.9,s[8,12]=-1.1,s[8,13]=-0.4,s[8,14]=-1.1,s[8,15]=-0.2,s[8,16]=-1.2,s[8,17]=-0.2,s[8,18]=0.1,s[8,19]=0.7,s[8,20]=0.7,s[8,21]=0.5,s[8,22]=-0.3,s[8,23]=-1.0,s[8,24]=0.1,s[8,25]=-0.7,s[8,26]=0.8,s[8,27]=-1.2,s[8,28]=-0.7,s[8,29]=0.5,s[8,30]=0.9,s[8,31]=-0.6,s[8,32]=-0.8,s[8,33]=-0.5,s[8,34]=0.3,s[8,35]=0.2,s[8,36]=0.8,s[8,37]=-0.6,s[8,38]=1.0,s[8,39]=-0.8,s[8,40]=-1.2,s[8,41]=0.5,s[8,42]=-0.2,s[8,43]=-1.1,s[8,44]=-0.4,s[8,45]=0.4,s[8,46]=0.9,s[8,47]=0.6,s[8,48]=0.6,s[8,49]=0.1,s[8,50]=1.0,s[8,51]=0.6,s[8,52]=-0.8,s[8,53]=0.6,s[8,54]=0.2,s[8,55]=0.7,s[8,56]=1.1,s[8,57]=0.8,s[8,58]=0.2,s[8,59]=-0.6,s[8,60]=-0.5 s[9,1]=0.8,s[9,2]=-0.1,s[9,3]=-0.2,s[9,4]=-0.4,s[9,5]=1.2,s[9,6]=-0.6,s[9,7]=-0.2,s[9,8]=0.7,s[9,9]=-0.9,s[9,10]=0.0,s[9,11]=-0.2,s[9,12]=-1.0,s[9,13]=0.9,s[9,14]=-1.1,s[9,15]=0.5,s[9,16]=0.0,s[9,17]=1.0,s[9,18]=-0.9,s[9,19]=-0.2,s[9,20]=-1.0,s[9,21]=1.0,s[9,22]=0.0,s[9,23]=0.8,s[9,24]=1.2,s[9,25]=1.2,s[9,26]=0.7,s[9,27]=0.0,s[9,28]=-0.5,s[9,29]=0.7,s[9,30]=-0.7,s[9,31]=0.1,s[9,32]=-0.9,s[9,33]=-0.9,s[9,34]=0.6,s[9,35]=-0.5,s[9,36]=0.0,s[9,37]=0.9,s[9,38]=-0.2,s[9,39]=0.6,s[9,40]=-1.1,s[9,41]=0.0,s[9,42]=1.2,s[9,43]=0.6,s[9,44]=-0.3,s[9,45]=-1.1,s[9,46]=-1.0,s[9,47]=-0.5,s[9,48]=-1.0,s[9,49]=0.5,s[9,50]=0.7,s[9,51]=-0.5,s[9,52]=-1.1,s[9,53]=0.7,s[9,54]=-0.8,s[9,55]=-0.7,s[9,56]=0.9,s[9,57]=1.1,s[9,58]=-0.6,s[9,59]=1.1,s[9,60]=1.2 s[10,1]=0.1,s[10,2]=0.3,s[10,3]=-1.0,s[10,4]=-0.3,s[10,5]=-0.7,s[10,6]=0.8,s[10,7]=0.5,s[10,8]=-0.5,s[10,9]=0.5,s[10,10]=-1.1,s[10,11]=-0.7,s[10,12]=0.9,s[10,13]=0.1,s[10,14]=-0.8,s[10,15]=0.0,s[10,16]=-0.6,s[10,17]=-0.8,s[10,18]=1.2,s[10,19]=-1.2,s[10,20]=0.9,s[10,21]=1.1,s[10,22]=-1.1,s[10,23]=-0.3,s[10,24]=0.8,s[10,25]=0.9,s[10,26]=1.2,s[10,27]=1.0,s[10,28]=0.6,s[10,29]=0.5,s[10,30]=-0.9,s[10,31]=-1.0,s[10,32]=1.2,s[10,33]=-0.2,s[10,34]=-0.3,s[10,35]=-1.2,s[10,36]=0.7,s[10,37]=-0.3,s[10,38]=-0.2,s[10,39]=-0.8,s[10,40]=-1.1,s[10,41]=-0.4,s[10,42]=1.2,s[10,43]=1.1,s[10,44]=0.3,s[10,45]=-1.1,s[10,46]=1.0,s[10,47]=-1.0,s[10,48]=-0.3,s[10,49]=0.3,s[10,50]=-0.7,s[10,51]=-0.9,s[10,52]=0.2,s[10,53]=0.2,s[10,54]=0.1,s[10,55]=-0.4,s[10,56]=0.6,s[10,57]=-1.1,s[10,58]=0.6,s[10,59]=-0.1,s[10,60]=-0.9 s[11,1]=0.0,s[11,2]=0.8,s[11,3]=-0.3,s[11,4]=-0.5,s[11,5]=-0.4,s[11,6]=0.3,s[11,7]=0.8,s[11,8]=-0.3,s[11,9]=-0.5,s[11,10]=-0.6,s[11,11]=0.6,s[11,12]=1.1,s[11,13]=-0.6,s[11,14]=-0.1,s[11,15]=0.0,s[11,16]=-0.1,s[11,17]=0.5,s[11,18]=0.0,s[11,19]=0.8,s[11,20]=0.7,s[11,21]=0.4,s[11,22]=-0.9,s[11,23]=-0.1,s[11,24]=0.3,s[11,25]=-0.6,s[11,26]=0.7,s[11,27]=-0.7,s[11,28]=1.1,s[11,29]=0.3,s[11,30]=-0.9,s[11,31]=0.6,s[11,32]=-0.9,s[11,33]=0.7,s[11,34]=-0.5,s[11,35]=0.7,s[11,36]=1.1,s[11,37]=-1.2,s[11,38]=1.2,s[11,39]=-0.9,s[11,40]=-1.0,s[11,41]=-1.2,s[11,42]=1.0,s[11,43]=-0.6,s[11,44]=0.2,s[11,45]=-0.6,s[11,46]=1.2,s[11,47]=0.3,s[11,48]=-0.3,s[11,49]=-0.6,s[11,50]=0.8,s[11,51]=-0.4,s[11,52]=0.7,s[11,53]=-0.4,s[11,54]=0.0,s[11,55]=0.2,s[11,56]=-0.1,s[11,57]=0.1,s[11,58]=0.3,s[11,59]=-0.6,s[11,60]=-0.7 s[12,1]=-0.7,s[12,2]=-1.1,s[12,3]=-0.1,s[12,4]=-0.8,s[12,5]=1.2,s[12,6]=-0.6,s[12,7]=0.6,s[12,8]=-0.7,s[12,9]=0.5,s[12,10]=1.2,s[12,11]=0.1,s[12,12]=0.5,s[12,13]=0.9,s[12,14]=1.1,s[12,15]=-1.0,s[12,16]=0.8,s[12,17]=0.4,s[12,18]=-1.0,s[12,19]=-0.4,s[12,20]=0.0,s[12,21]=-0.2,s[12,22]=0.3,s[12,23]=0.0,s[12,24]=-1.1,s[12,25]=-0.1,s[12,26]=-0.7,s[12,27]=-1.2,s[12,28]=0.1,s[12,29]=0.9,s[12,30]=1.0,s[12,31]=-0.6,s[12,32]=-1.0,s[12,33]=0.7,s[12,34]=-1.0,s[12,35]=0.3,s[12,36]=-1.1,s[12,37]=-1.1,s[12,38]=1.0,s[12,39]=0.1,s[12,40]=0.8,s[12,41]=0.4,s[12,42]=-0.4,s[12,43]=-0.3,s[12,44]=-0.1,s[12,45]=0.2,s[12,46]=-0.3,s[12,47]=-0.4,s[12,48]=0.5,s[12,49]=-1.0,s[12,50]=-0.9,s[12,51]=1.1,s[12,52]=1.2,s[12,53]=0.5,s[12,54]=0.0,s[12,55]=-0.1,s[12,56]=-0.9,s[12,57]=0.4,s[12,58]=1.0,s[12,59]=-0.4,s[12,60]=-1.2 s[13,1]=0.7,s[13,2]=1.1,s[13,3]=-0.1,s[13,4]=-0.3,s[13,5]=0.6,s[13,6]=0.8,s[13,7]=0.3,s[13,8]=-0.3,s[13,9]=-1.2,s[13,10]=0.7,s[13,11]=-0.2,s[13,12]=1.0,s[13,13]=0.4,s[13,14]=0.2,s[13,15]=-0.3,s[13,16]=0.6,s[13,17]=0.9,s[13,18]=0.3,s[13,19]=-1.0,s[13,20]=0.8,s[13,21]=-0.6,s[13,22]=-0.8,s[13,23]=-0.7,s[13,24]=-0.3,s[13,25]=-0.1,s[13,26]=-0.4,s[13,27]=0.1,s[13,28]=1.1,s[13,29]=0.6,s[13,30]=0.9,s[13,31]=-0.7,s[13,32]=0.7,s[13,33]=0.0,s[13,34]=0.6,s[13,35]=0.8,s[13,36]=-0.9,s[13,37]=0.8,s[13,38]=0.7,s[13,39]=-0.6,s[13,40]=0.9,s[13,41]=-1.1,s[13,42]=-0.7,s[13,43]=0.5,s[13,44]=0.0,s[13,45]=0.8,s[13,46]=1.0,s[13,47]=0.3,s[13,48]=-0.9,s[13,49]=-0.7,s[13,50]=-0.1,s[13,51]=0.4,s[13,52]=0.2,s[13,53]=-0.9,s[13,54]=-1.2,s[13,55]=-0.4,s[13,56]=0.3,s[13,57]=-0.8,s[13,58]=-0.5,s[13,59]=-0.5,s[13,60]=1.1 s[14,1]=-0.2,s[14,2]=1.1,s[14,3]=-1.1,s[14,4]=1.2,s[14,5]=1.2,s[14,6]=1.0,s[14,7]=0.2,s[14,8]=1.0,s[14,9]=-0.3,s[14,10]=0.6,s[14,11]=0.5,s[14,12]=0.8,s[14,13]=-0.6,s[14,14]=-0.6,s[14,15]=-0.3,s[14,16]=-1.0,s[14,17]=-0.6,s[14,18]=0.8,s[14,19]=0.6,s[14,20]=0.5,s[14,21]=1.0,s[14,22]=-0.3,s[14,23]=1.1,s[14,24]=-0.7,s[14,25]=-0.7,s[14,26]=1.0,s[14,27]=-0.8,s[14,28]=0.5,s[14,29]=0.5,s[14,30]=1.2,s[14,31]=0.1,s[14,32]=-0.3,s[14,33]=-1.2,s[14,34]=-0.4,s[14,35]=0.7,s[14,36]=0.3,s[14,37]=0.3,s[14,38]=0.9,s[14,39]=-0.9,s[14,40]=0.8,s[14,41]=0.9,s[14,42]=0.0,s[14,43]=0.8,s[14,44]=-0.3,s[14,45]=-0.4,s[14,46]=-1.2,s[14,47]=1.1,s[14,48]=1.0,s[14,49]=1.0,s[14,50]=-1.2,s[14,51]=-1.2,s[14,52]=0.8,s[14,53]=-0.3,s[14,54]=0.5,s[14,55]=-0.5,s[14,56]=0.9,s[14,57]=0.0,s[14,58]=0.6,s[14,59]=-1.0,s[14,60]=-0.1 s[15,1]=0.3,s[15,2]=0.1,s[15,3]=0.2,s[15,4]=0.7,s[15,5]=0.6,s[15,6]=-0.6,s[15,7]=-0.1,s[15,8]=-0.7,s[15,9]=0.3,s[15,10]=-0.5,s[15,11]=0.3,s[15,12]=-0.2,s[15,13]=0.0,s[15,14]=0.6,s[15,15]=-0.3,s[15,16]=-0.1,s[15,17]=0.4,s[15,18]=0.1,s[15,19]=0.7,s[15,20]=-1.0,s[15,21]=0.9,s[15,22]=0.4,s[15,23]=-0.5,s[15,24]=1.1,s[15,25]=1.1,s[15,26]=-0.6,s[15,27]=0.6,s[15,28]=0.6,s[15,29]=-0.3,s[15,30]=-0.9,s[15,31]=0.8,s[15,32]=0.1,s[15,33]=0.0,s[15,34]=0.4,s[15,35]=1.2,s[15,36]=1.0,s[15,37]=1.2,s[15,38]=-1.1,s[15,39]=-0.3,s[15,40]=-0.3,s[15,41]=-0.3,s[15,42]=0.2,s[15,43]=0.6,s[15,44]=-0.8,s[15,45]=0.3,s[15,46]=1.2,s[15,47]=0.8,s[15,48]=0.6,s[15,49]=1.0,s[15,50]=0.0,s[15,51]=0.0,s[15,52]=1.1,s[15,53]=-1.0,s[15,54]=1.1,s[15,55]=0.6,s[15,56]=0.1,s[15,57]=-1.2,s[15,58]=1.2,s[15,59]=-0.9,s[15,60]=0.3 s[16,1]=-0.5,s[16,2]=0.5,s[16,3]=0.8,s[16,4]=0.4,s[16,5]=0.1,s[16,6]=-0.3,s[16,7]=-0.3,s[16,8]=0.9,s[16,9]=-0.9,s[16,10]=-0.6,s[16,11]=1.2,s[16,12]=-0.9,s[16,13]=-0.3,s[16,14]=0.4,s[16,15]=0.2,s[16,16]=-0.3,s[16,17]=-0.1,s[16,18]=0.7,s[16,19]=1.2,s[16,20]=0.3,s[16,21]=-0.5,s[16,22]=-0.2,s[16,23]=0.7,s[16,24]=-0.8,s[16,25]=0.9,s[16,26]=0.9,s[16,27]=0.2,s[16,28]=-0.4,s[16,29]=1.2,s[16,30]=0.5,s[16,31]=-0.3,s[16,32]=-0.2,s[16,33]=0.5,s[16,34]=-0.2,s[16,35]=-0.6,s[16,36]=0.9,s[16,37]=-0.5,s[16,38]=1.2,s[16,39]=0.7,s[16,40]=0.9,s[16,41]=0.4,s[16,42]=-0.9,s[16,43]=0.4,s[16,44]=0.6,s[16,45]=-0.6,s[16,46]=0.9,s[16,47]=-0.4,s[16,48]=-0.6,s[16,49]=-0.5,s[16,50]=-0.6,s[16,51]=-0.1,s[16,52]=-0.8,s[16,53]=-1.2,s[16,54]=-0.8,s[16,55]=1.2,s[16,56]=0.1,s[16,57]=-0.8,s[16,58]=0.8,s[16,59]=-1.1,s[16,60]=0.4 s[17,1]=0.5,s[17,2]=0.0,s[17,3]=-1.2,s[17,4]=0.7,s[17,5]=0.3,s[17,6]=0.8,s[17,7]=0.5,s[17,8]=1.1,s[17,9]=-0.5,s[17,10]=-1.0,s[17,11]=-1.2,s[17,12]=-0.3,s[17,13]=0.0,s[17,14]=1.2,s[17,15]=0.5,s[17,16]=1.2,s[17,17]=-0.6,s[17,18]=0.7,s[17,19]=0.2,s[17,20]=0.7,s[17,21]=1.2,s[17,22]=-0.3,s[17,23]=-0.8,s[17,24]=0.7,s[17,25]=-1.0,s[17,26]=0.6,s[17,27]=0.3,s[17,28]=-0.5,s[17,29]=1.2,s[17,30]=-0.7,s[17,31]=1.0,s[17,32]=0.0,s[17,33]=-0.7,s[17,34]=0.7,s[17,35]=0.3,s[17,36]=-0.5,s[17,37]=-0.3,s[17,38]=-0.7,s[17,39]=0.0,s[17,40]=-0.6,s[17,41]=0.7,s[17,42]=0.9,s[17,43]=-1.2,s[17,44]=0.3,s[17,45]=0.2,s[17,46]=-0.1,s[17,47]=-1.1,s[17,48]=-1.1,s[17,49]=1.0,s[17,50]=-0.5,s[17,51]=-0.3,s[17,52]=0.3,s[17,53]=-0.5,s[17,54]=0.7,s[17,55]=-1.2,s[17,56]=0.9,s[17,57]=1.1,s[17,58]=0.9,s[17,59]=1.0,s[17,60]=0.4 s[18,1]=-1.0,s[18,2]=-0.3,s[18,3]=1.2,s[18,4]=-0.9,s[18,5]=-0.6,s[18,6]=1.0,s[18,7]=0.5,s[18,8]=-1.2,s[18,9]=-1.0,s[18,10]=-0.9,s[18,11]=0.8,s[18,12]=-1.1,s[18,13]=0.2,s[18,14]=-0.6,s[18,15]=-0.2,s[18,16]=-0.7,s[18,17]=0.6,s[18,18]=0.4,s[18,19]=0.6,s[18,20]=0.3,s[18,21]=-0.4,s[18,22]=-0.1,s[18,23]=0.5,s[18,24]=0.1,s[18,25]=-0.3,s[18,26]=-0.7,s[18,27]=-0.4,s[18,28]=-0.2,s[18,29]=0.5,s[18,30]=0.7,s[18,31]=-0.9,s[18,32]=0.2,s[18,33]=0.4,s[18,34]=0.0,s[18,35]=-0.4,s[18,36]=0.2,s[18,37]=-0.4,s[18,38]=0.0,s[18,39]=1.2,s[18,40]=-1.2,s[18,41]=-1.1,s[18,42]=-0.1,s[18,43]=-1.1,s[18,44]=0.6,s[18,45]=1.1,s[18,46]=0.3,s[18,47]=1.0,s[18,48]=-1.1,s[18,49]=-0.8,s[18,50]=-0.8,s[18,51]=0.2,s[18,52]=0.2,s[18,53]=-1.2,s[18,54]=-1.0,s[18,55]=-1.1,s[18,56]=-0.5,s[18,57]=0.8,s[18,58]=-1.2,s[18,59]=-1.1,s[18,60]=0.0 s[19,1]=-0.2,s[19,2]=-1.0,s[19,3]=0.9,s[19,4]=0.3,s[19,5]=-0.6,s[19,6]=1.2,s[19,7]=0.1,s[19,8]=-1.2,s[19,9]=0.9,s[19,10]=0.1,s[19,11]=0.6,s[19,12]=-1.1,s[19,13]=-1.0,s[19,14]=0.1,s[19,15]=0.6,s[19,16]=0.6,s[19,17]=-1.1,s[19,18]=-0.5,s[19,19]=1.2,s[19,20]=-0.2,s[19,21]=0.5,s[19,22]=-0.8,s[19,23]=0.5,s[19,24]=-0.7,s[19,25]=-1.1,s[19,26]=0.9,s[19,27]=-0.3,s[19,28]=0.4,s[19,29]=0.0,s[19,30]=-1.0,s[19,31]=1.0,s[19,32]=-1.1,s[19,33]=-0.9,s[19,34]=0.7,s[19,35]=0.8,s[19,36]=-0.4,s[19,37]=-0.5,s[19,38]=0.3,s[19,39]=0.2,s[19,40]=-0.8,s[19,41]=-0.6,s[19,42]=0.4,s[19,43]=0.5,s[19,44]=-0.4,s[19,45]=-0.9,s[19,46]=-0.9,s[19,47]=-0.5,s[19,48]=1.0,s[19,49]=0.9,s[19,50]=-0.8,s[19,51]=-0.6,s[19,52]=-1.2,s[19,53]=-0.2,s[19,54]=-0.6,s[19,55]=-0.6,s[19,56]=-0.1,s[19,57]=-1.2,s[19,58]=1.0,s[19,59]=-1.0,s[19,60]=-0.2 s[20,1]=0.9,s[20,2]=0.5,s[20,3]=-0.6,s[20,4]=0.8,s[20,5]=-0.4,s[20,6]=0.9,s[20,7]=-1.0,s[20,8]=0.0,s[20,9]=-0.1,s[20,10]=0.5,s[20,11]=0.8,s[20,12]=-0.6,s[20,13]=0.8,s[20,14]=-0.8,s[20,15]=0.2,s[20,16]=-0.2,s[20,17]=-1.0,s[20,18]=0.0,s[20,19]=-1.2,s[20,20]=0.8,s[20,21]=0.8,s[20,22]=1.2,s[20,23]=-0.9,s[20,24]=1.1,s[20,25]=1.0,s[20,26]=-0.4,s[20,27]=0.9,s[20,28]=0.8,s[20,29]=-1.2,s[20,30]=-0.2,s[20,31]=-0.6,s[20,32]=1.2,s[20,33]=-0.5,s[20,34]=-0.3,s[20,35]=-1.0,s[20,36]=-0.1,s[20,37]=-0.7,s[20,38]=-0.1,s[20,39]=0.8,s[20,40]=0.1,s[20,41]=-0.1,s[20,42]=1.0,s[20,43]=1.2,s[20,44]=0.6,s[20,45]=-0.8,s[20,46]=-1.1,s[20,47]=0.2,s[20,48]=-0.1,s[20,49]=-1.2,s[20,50]=-1.2,s[20,51]=-0.8,s[20,52]=-1.2,s[20,53]=-1.1,s[20,54]=1.0,s[20,55]=0.9,s[20,56]=0.3,s[20,57]=-0.6,s[20,58]=-0.4,s[20,59]=-1.1,s[20,60]=-0.9 s[21,1]=-0.1,s[21,2]=-0.6,s[21,3]=-0.7,s[21,4]=0.3,s[21,5]=0.3,s[21,6]=-0.7,s[21,7]=-0.7,s[21,8]=-0.6,s[21,9]=1.2,s[21,10]=-0.1,s[21,11]=0.1,s[21,12]=0.5,s[21,13]=-0.3,s[21,14]=1.2,s[21,15]=1.1,s[21,16]=0.7,s[21,17]=-0.8,s[21,18]=-1.1,s[21,19]=0.0,s[21,20]=-0.6,s[21,21]=-1.2,s[21,22]=-0.8,s[21,23]=0.7,s[21,24]=0.9,s[21,25]=0.5,s[21,26]=-0.9,s[21,27]=-0.6,s[21,28]=0.1,s[21,29]=0.5,s[21,30]=-0.9,s[21,31]=0.0,s[21,32]=0.5,s[21,33]=-1.2,s[21,34]=1.0,s[21,35]=-0.4,s[21,36]=0.1,s[21,37]=1.1,s[21,38]=-0.1,s[21,39]=-0.3,s[21,40]=-0.9,s[21,41]=-0.6,s[21,42]=-0.2,s[21,43]=0.7,s[21,44]=-1.0,s[21,45]=-0.1,s[21,46]=-1.2,s[21,47]=-0.1,s[21,48]=1.2,s[21,49]=-1.0,s[21,50]=-0.7,s[21,51]=-0.1,s[21,52]=-0.7,s[21,53]=1.2,s[21,54]=-1.2,s[21,55]=-0.1,s[21,56]=-1.1,s[21,57]=-0.4,s[21,58]=1.2,s[21,59]=-0.4,s[21,60]=-0.3 s[22,1]=1.2,s[22,2]=0.5,s[22,3]=-0.7,s[22,4]=0.4,s[22,5]=-1.0,s[22,6]=0.7,s[22,7]=-0.3,s[22,8]=1.1,s[22,9]=-0.6,s[22,10]=-0.5,s[22,11]=1.2,s[22,12]=-1.1,s[22,13]=-0.8,s[22,14]=0.3,s[22,15]=0.5,s[22,16]=0.8,s[22,17]=-1.2,s[22,18]=-0.4,s[22,19]=0.1,s[22,20]=-0.4,s[22,21]=-1.2,s[22,22]=0.6,s[22,23]=0.8,s[22,24]=0.9,s[22,25]=0.1,s[22,26]=-0.2,s[22,27]=-0.1,s[22,28]=0.5,s[22,29]=0.5,s[22,30]=0.9,s[22,31]=0.8,s[22,32]=0.0,s[22,33]=0.3,s[22,34]=1.0,s[22,35]=-0.6,s[22,36]=-0.3,s[22,37]=0.0,s[22,38]=0.9,s[22,39]=1.1,s[22,40]=0.8,s[22,41]=0.6,s[22,42]=-0.8,s[22,43]=0.1,s[22,44]=-0.9,s[22,45]=0.9,s[22,46]=0.5,s[22,47]=-1.0,s[22,48]=-0.4,s[22,49]=0.7,s[22,50]=0.6,s[22,51]=0.4,s[22,52]=1.1,s[22,53]=-1.2,s[22,54]=-0.9,s[22,55]=1.2,s[22,56]=-0.8,s[22,57]=0.8,s[22,58]=-1.0,s[22,59]=0.0,s[22,60]=0.9 s[23,1]=-1.1,s[23,2]=-0.5,s[23,3]=-0.9,s[23,4]=0.8,s[23,5]=-0.3,s[23,6]=-0.2,s[23,7]=1.2,s[23,8]=0.2,s[23,9]=-1.0,s[23,10]=0.1,s[23,11]=0.2,s[23,12]=0.8,s[23,13]=-1.0,s[23,14]=-1.1,s[23,15]=0.6,s[23,16]=0.7,s[23,17]=-0.3,s[23,18]=-0.6,s[23,19]=0.8,s[23,20]=0.1,s[23,21]=0.2,s[23,22]=-0.3,s[23,23]=-0.8,s[23,24]=-0.9,s[23,25]=-0.9,s[23,26]=0.9,s[23,27]=-1.1,s[23,28]=1.1,s[23,29]=-0.6,s[23,30]=0.6,s[23,31]=-0.2,s[23,32]=-0.4,s[23,33]=0.6,s[23,34]=-0.5,s[23,35]=-0.4,s[23,36]=-0.4,s[23,37]=-0.3,s[23,38]=0.8,s[23,39]=0.9,s[23,40]=0.9,s[23,41]=-0.1,s[23,42]=-0.7,s[23,43]=0.6,s[23,44]=0.9,s[23,45]=-0.6,s[23,46]=1.1,s[23,47]=-0.5,s[23,48]=0.9,s[23,49]=-1.0,s[23,50]=1.1,s[23,51]=0.8,s[23,52]=1.2,s[23,53]=1.2,s[23,54]=0.0,s[23,55]=-0.7,s[23,56]=-0.9,s[23,57]=-0.2,s[23,58]=-0.7,s[23,59]=-0.6,s[23,60]=-0.3 s[24,1]=1.1,s[24,2]=0.4,s[24,3]=-0.4,s[24,4]=-1.0,s[24,5]=0.3,s[24,6]=0.4,s[24,7]=0.5,s[24,8]=-0.6,s[24,9]=0.9,s[24,10]=-0.5,s[24,11]=-0.8,s[24,12]=-0.7,s[24,13]=0.5,s[24,14]=0.3,s[24,15]=-1.2,s[24,16]=0.8,s[24,17]=-0.4,s[24,18]=-0.9,s[24,19]=-0.4,s[24,20]=-0.9,s[24,21]=1.1,s[24,22]=-0.6,s[24,23]=0.2,s[24,24]=-0.7,s[24,25]=-1.1,s[24,26]=-0.5,s[24,27]=1.1,s[24,28]=-1.1,s[24,29]=0.6,s[24,30]=0.2,s[24,31]=1.2,s[24,32]=-0.5,s[24,33]=1.2,s[24,34]=0.7,s[24,35]=0.9,s[24,36]=1.0,s[24,37]=0.3,s[24,38]=-1.0,s[24,39]=-0.5,s[24,40]=-0.9,s[24,41]=-0.5,s[24,42]=0.4,s[24,43]=-1.1,s[24,44]=0.7,s[24,45]=0.2,s[24,46]=-0.5,s[24,47]=0.5,s[24,48]=-0.8,s[24,49]=0.4,s[24,50]=-0.2,s[24,51]=1.1,s[24,52]=0.9,s[24,53]=1.0,s[24,54]=0.2,s[24,55]=-0.8,s[24,56]=0.9,s[24,57]=0.2,s[24,58]=-1.2,s[24,59]=0.3,s[24,60]=0.6 s[25,1]=-0.2,s[25,2]=0.9,s[25,3]=-0.5,s[25,4]=-0.8,s[25,5]=-0.5,s[25,6]=0.3,s[25,7]=0.2,s[25,8]=0.7,s[25,9]=0.7,s[25,10]=0.2,s[25,11]=-0.3,s[25,12]=-0.4,s[25,13]=-0.9,s[25,14]=-1.2,s[25,15]=0.9,s[25,16]=0.5,s[25,17]=0.5,s[25,18]=0.1,s[25,19]=-0.1,s[25,20]=0.6,s[25,21]=-0.4,s[25,22]=0.0,s[25,23]=0.0,s[25,24]=0.6,s[25,25]=0.0,s[25,26]=-1.1,s[25,27]=-0.7,s[25,28]=-1.2,s[25,29]=0.8,s[25,30]=0.9,s[25,31]=-0.3,s[25,32]=1.0,s[25,33]=1.0,s[25,34]=0.2,s[25,35]=0.1,s[25,36]=0.3,s[25,37]=-0.8,s[25,38]=-0.9,s[25,39]=0.3,s[25,40]=1.1,s[25,41]=-0.1,s[25,42]=0.1,s[25,43]=-0.1,s[25,44]=-0.5,s[25,45]=-0.7,s[25,46]=-1.2,s[25,47]=-0.1,s[25,48]=0.9,s[25,49]=-0.6,s[25,50]=0.5,s[25,51]=-0.9,s[25,52]=1.1,s[25,53]=-0.2,s[25,54]=-0.3,s[25,55]=-0.7,s[25,56]=0.1,s[25,57]=0.2,s[25,58]=1.0,s[25,59]=1.2,s[25,60]=0.9 s[26,1]=-1.2,s[26,2]=0.2,s[26,3]=-0.4,s[26,4]=1.0,s[26,5]=0.8,s[26,6]=0.0,s[26,7]=1.1,s[26,8]=-0.4,s[26,9]=1.1,s[26,10]=0.5,s[26,11]=0.7,s[26,12]=0.3,s[26,13]=0.8,s[26,14]=-0.7,s[26,15]=1.2,s[26,16]=-0.8,s[26,17]=-1.0,s[26,18]=-0.9,s[26,19]=0.6,s[26,20]=-0.9,s[26,21]=-0.6,s[26,22]=-0.7,s[26,23]=-0.4,s[26,24]=0.7,s[26,25]=0.6,s[26,26]=-1.1,s[26,27]=0.4,s[26,28]=0.7,s[26,29]=1.1,s[26,30]=-0.4,s[26,31]=-0.4,s[26,32]=0.8,s[26,33]=-0.6,s[26,34]=-0.7,s[26,35]=-0.2,s[26,36]=-1.1,s[26,37]=0.6,s[26,38]=0.2,s[26,39]=0.3,s[26,40]=-0.9,s[26,41]=0.7,s[26,42]=0.3,s[26,43]=1.0,s[26,44]=-0.6,s[26,45]=0.4,s[26,46]=0.2,s[26,47]=-0.6,s[26,48]=-0.9,s[26,49]=-0.4,s[26,50]=0.4,s[26,51]=0.5,s[26,52]=0.8,s[26,53]=0.1,s[26,54]=-0.1,s[26,55]=0.9,s[26,56]=-1.1,s[26,57]=-0.7,s[26,58]=-0.1,s[26,59]=-0.9,s[26,60]=0.0 s[27,1]=0.7,s[27,2]=-0.8,s[27,3]=0.3,s[27,4]=-0.5,s[27,5]=-0.1,s[27,6]=-0.2,s[27,7]=-0.9,s[27,8]=0.6,s[27,9]=-0.8,s[27,10]=-0.6,s[27,11]=-1.1,s[27,12]=1.0,s[27,13]=-0.4,s[27,14]=-0.6,s[27,15]=0.6,s[27,16]=-1.0,s[27,17]=0.1,s[27,18]=1.2,s[27,19]=0.6,s[27,20]=0.7,s[27,21]=-1.2,s[27,22]=-1.0,s[27,23]=-0.6,s[27,24]=0.9,s[27,25]=0.8,s[27,26]=-0.6,s[27,27]=-1.2,s[27,28]=0.0,s[27,29]=0.0,s[27,30]=0.3,s[27,31]=-0.2,s[27,32]=0.7,s[27,33]=0.0,s[27,34]=0.5,s[27,35]=0.5,s[27,36]=1.2,s[27,37]=-0.3,s[27,38]=-1.1,s[27,39]=-0.7,s[27,40]=0.2,s[27,41]=-0.5,s[27,42]=0.0,s[27,43]=-0.7,s[27,44]=-0.7,s[27,45]=1.1,s[27,46]=0.5,s[27,47]=0.6,s[27,48]=-1.0,s[27,49]=1.1,s[27,50]=-0.4,s[27,51]=0.2,s[27,52]=-0.7,s[27,53]=1.1,s[27,54]=-0.3,s[27,55]=-0.7,s[27,56]=-0.4,s[27,57]=0.7,s[27,58]=-0.8,s[27,59]=-1.2,s[27,60]=-0.9 s[28,1]=0.5,s[28,2]=-0.8,s[28,3]=-0.1,s[28,4]=-0.3,s[28,5]=0.1,s[28,6]=0.6,s[28,7]=0.2,s[28,8]=0.7,s[28,9]=-1.0,s[28,10]=0.8,s[28,11]=-1.1,s[28,12]=-1.0,s[28,13]=0.9,s[28,14]=0.1,s[28,15]=1.2,s[28,16]=-1.2,s[28,17]=1.2,s[28,18]=-0.9,s[28,19]=-1.0,s[28,20]=0.5,s[28,21]=-1.2,s[28,22]=-0.4,s[28,23]=-0.9,s[28,24]=0.4,s[28,25]=-0.5,s[28,26]=-1.1,s[28,27]=0.4,s[28,28]=0.9,s[28,29]=-1.0,s[28,30]=0.1,s[28,31]=0.3,s[28,32]=-0.4,s[28,33]=0.1,s[28,34]=0.2,s[28,35]=-1.1,s[28,36]=-0.1,s[28,37]=-0.9,s[28,38]=-0.4,s[28,39]=-1.0,s[28,40]=-0.9,s[28,41]=-0.3,s[28,42]=0.5,s[28,43]=0.4,s[28,44]=-1.0,s[28,45]=-0.8,s[28,46]=0.0,s[28,47]=0.9,s[28,48]=-0.2,s[28,49]=0.8,s[28,50]=0.0,s[28,51]=0.4,s[28,52]=0.3,s[28,53]=-0.6,s[28,54]=-0.7,s[28,55]=-0.7,s[28,56]=0.3,s[28,57]=0.7,s[28,58]=-0.1,s[28,59]=-0.8,s[28,60]=1.0 s[29,1]=1.1,s[29,2]=0.0,s[29,3]=-0.8,s[29,4]=0.7,s[29,5]=0.8,s[29,6]=1.2,s[29,7]=0.8,s[29,8]=0.8,s[29,9]=-0.7,s[29,10]=0.9,s[29,11]=0.3,s[29,12]=0.9,s[29,13]=1.0,s[29,14]=0.7,s[29,15]=-0.3,s[29,16]=-0.7,s[29,17]=0.7,s[29,18]=-0.9,s[29,19]=0.0,s[29,20]=-1.1,s[29,21]=0.0,s[29,22]=0.0,s[29,23]=0.8,s[29,24]=-1.2,s[29,25]=0.0,s[29,26]=-0.8,s[29,27]=0.3,s[29,28]=1.1,s[29,29]=-0.7,s[29,30]=0.8,s[29,31]=0.3,s[29,32]=-0.9,s[29,33]=-0.6,s[29,34]=-0.7,s[29,35]=0.7,s[29,36]=-0.9,s[29,37]=-0.9,s[29,38]=0.3,s[29,39]=1.0,s[29,40]=-1.0,s[29,41]=1.2,s[29,42]=0.1,s[29,43]=0.3,s[29,44]=0.3,s[29,45]=-0.4,s[29,46]=1.0,s[29,47]=-0.2,s[29,48]=-1.1,s[29,49]=0.1,s[29,50]=0.4,s[29,51]=-0.8,s[29,52]=-0.1,s[29,53]=-0.9,s[29,54]=-0.7,s[29,55]=0.1,s[29,56]=-0.3,s[29,57]=-0.9,s[29,58]=-0.9,s[29,59]=-0.6,s[29,60]=-0.4 s[30,1]=0.8,s[30,2]=0.6,s[30,3]=-0.2,s[30,4]=-1.2,s[30,5]=-0.7,s[30,6]=0.9,s[30,7]=0.6,s[30,8]=-1.2,s[30,9]=-0.1,s[30,10]=0.3,s[30,11]=-0.8,s[30,12]=0.0,s[30,13]=1.0,s[30,14]=0.8,s[30,15]=-1.0,s[30,16]=-0.3,s[30,17]=0.9,s[30,18]=0.6,s[30,19]=-0.2,s[30,20]=1.1,s[30,21]=-1.2,s[30,22]=0.0,s[30,23]=0.5,s[30,24]=0.5,s[30,25]=0.1,s[30,26]=0.8,s[30,27]=0.0,s[30,28]=0.0,s[30,29]=-0.4,s[30,30]=-0.9,s[30,31]=-1.1,s[30,32]=0.5,s[30,33]=-0.4,s[30,34]=0.6,s[30,35]=-0.2,s[30,36]=0.4,s[30,37]=0.4,s[30,38]=-0.9,s[30,39]=0.8,s[30,40]=-0.8,s[30,41]=-1.1,s[30,42]=1.2,s[30,43]=0.5,s[30,44]=0.2,s[30,45]=-0.7,s[30,46]=-1.0,s[30,47]=1.0,s[30,48]=0.3,s[30,49]=1.0,s[30,50]=1.2,s[30,51]=-0.3,s[30,52]=0.7,s[30,53]=-1.2,s[30,54]=-1.0,s[30,55]=0.9,s[30,56]=-0.2,s[30,57]=-0.9,s[30,58]=0.6,s[30,59]=-1.0,s[30,60]=-0.2 s[31,1]=-0.3,s[31,2]=-0.7,s[31,3]=1.1,s[31,4]=0.1,s[31,5]=0.2,s[31,6]=1.1,s[31,7]=0.6,s[31,8]=-1.1,s[31,9]=0.6,s[31,10]=0.7,s[31,11]=-0.4,s[31,12]=-0.9,s[31,13]=0.2,s[31,14]=-1.2,s[31,15]=-1.0,s[31,16]=0.8,s[31,17]=-0.2,s[31,18]=-1.2,s[31,19]=0.8,s[31,20]=0.9,s[31,21]=-1.1,s[31,22]=-0.5,s[31,23]=1.2,s[31,24]=-1.0,s[31,25]=0.2,s[31,26]=-0.7,s[31,27]=-0.7,s[31,28]=0.4,s[31,29]=0.0,s[31,30]=-0.6,s[31,31]=-0.8,s[31,32]=-0.4,s[31,33]=-0.3,s[31,34]=0.0,s[31,35]=0.4,s[31,36]=-1.1,s[31,37]=0.0,s[31,38]=0.7,s[31,39]=0.5,s[31,40]=0.7,s[31,41]=-0.5,s[31,42]=1.2,s[31,43]=0.3,s[31,44]=0.2,s[31,45]=-1.2,s[31,46]=-0.6,s[31,47]=0.3,s[31,48]=0.7,s[31,49]=0.2,s[31,50]=-0.6,s[31,51]=0.5,s[31,52]=-0.9,s[31,53]=-0.8,s[31,54]=-1.1,s[31,55]=-0.1,s[31,56]=-0.5,s[31,57]=0.7,s[31,58]=0.8,s[31,59]=1.0,s[31,60]=-1.1 s[32,1]=0.6,s[32,2]=0.0,s[32,3]=-1.1,s[32,4]=0.9,s[32,5]=0.7,s[32,6]=-0.7,s[32,7]=-1.2,s[32,8]=0.9,s[32,9]=-0.5,s[32,10]=-0.6,s[32,11]=-0.4,s[32,12]=1.0,s[32,13]=0.8,s[32,14]=0.8,s[32,15]=-1.0,s[32,16]=1.2,s[32,17]=0.2,s[32,18]=0.9,s[32,19]=0.6,s[32,20]=1.2,s[32,21]=-0.9,s[32,22]=0.8,s[32,23]=-0.1,s[32,24]=-0.9,s[32,25]=-0.9,s[32,26]=-1.0,s[32,27]=-1.1,s[32,28]=0.4,s[32,29]=0.2,s[32,30]=0.0,s[32,31]=-0.9,s[32,32]=0.2,s[32,33]=-0.5,s[32,34]=-0.6,s[32,35]=-0.7,s[32,36]=0.1,s[32,37]=-0.3,s[32,38]=0.4,s[32,39]=-0.8,s[32,40]=0.0,s[32,41]=-0.3,s[32,42]=0.1,s[32,43]=-0.2,s[32,44]=-0.5,s[32,45]=0.0,s[32,46]=0.6,s[32,47]=-0.7,s[32,48]=1.2,s[32,49]=1.0,s[32,50]=-0.7,s[32,51]=-0.7,s[32,52]=-1.2,s[32,53]=-0.3,s[32,54]=1.0,s[32,55]=-1.1,s[32,56]=-0.4,s[32,57]=0.5,s[32,58]=1.2,s[32,59]=0.7,s[32,60]=0.5 s[33,1]=-0.8,s[33,2]=-1.0,s[33,3]=0.8,s[33,4]=0.9,s[33,5]=0.1,s[33,6]=-0.1,s[33,7]=0.5,s[33,8]=-0.2,s[33,9]=-0.5,s[33,10]=-1.1,s[33,11]=-0.1,s[33,12]=1.1,s[33,13]=0.7,s[33,14]=-0.9,s[33,15]=-0.5,s[33,16]=-0.6,s[33,17]=0.1,s[33,18]=0.6,s[33,19]=-0.1,s[33,20]=-0.8,s[33,21]=1.0,s[33,22]=-1.2,s[33,23]=-0.1,s[33,24]=-0.1,s[33,25]=0.1,s[33,26]=-0.9,s[33,27]=1.1,s[33,28]=-1.0,s[33,29]=-0.5,s[33,30]=-0.9,s[33,31]=1.1,s[33,32]=-0.1,s[33,33]=-1.0,s[33,34]=0.4,s[33,35]=0.0,s[33,36]=0.0,s[33,37]=-0.5,s[33,38]=-1.2,s[33,39]=0.8,s[33,40]=-1.2,s[33,41]=0.0,s[33,42]=0.0,s[33,43]=0.7,s[33,44]=-0.9,s[33,45]=0.0,s[33,46]=-1.1,s[33,47]=0.3,s[33,48]=0.6,s[33,49]=-0.2,s[33,50]=-0.7,s[33,51]=0.3,s[33,52]=-0.2,s[33,53]=-0.2,s[33,54]=-0.2,s[33,55]=0.4,s[33,56]=0.7,s[33,57]=-1.1,s[33,58]=1.1,s[33,59]=1.0,s[33,60]=0.3 s[34,1]=-0.7,s[34,2]=-0.8,s[34,3]=-0.4,s[34,4]=-0.1,s[34,5]=1.2,s[34,6]=-0.4,s[34,7]=0.5,s[34,8]=0.1,s[34,9]=0.5,s[34,10]=0.3,s[34,11]=-1.0,s[34,12]=1.0,s[34,13]=0.5,s[34,14]=0.6,s[34,15]=0.9,s[34,16]=-0.6,s[34,17]=1.1,s[34,18]=0.1,s[34,19]=0.0,s[34,20]=-0.6,s[34,21]=-0.8,s[34,22]=-0.1,s[34,23]=0.1,s[34,24]=-0.1,s[34,25]=0.1,s[34,26]=-1.2,s[34,27]=-1.2,s[34,28]=-0.4,s[34,29]=0.6,s[34,30]=0.7,s[34,31]=-0.8,s[34,32]=-0.6,s[34,33]=0.6,s[34,34]=-0.1,s[34,35]=-1.2,s[34,36]=-1.2,s[34,37]=0.8,s[34,38]=0.7,s[34,39]=1.0,s[34,40]=0.8,s[34,41]=0.0,s[34,42]=0.0,s[34,43]=0.5,s[34,44]=0.4,s[34,45]=-0.5,s[34,46]=-0.8,s[34,47]=0.2,s[34,48]=0.6,s[34,49]=-0.7,s[34,50]=0.8,s[34,51]=-0.9,s[34,52]=-1.1,s[34,53]=1.0,s[34,54]=0.3,s[34,55]=-0.8,s[34,56]=1.1,s[34,57]=0.5,s[34,58]=0.0,s[34,59]=-0.4,s[34,60]=-0.2 s[35,1]=-0.9,s[35,2]=-1.0,s[35,3]=0.9,s[35,4]=0.1,s[35,5]=-0.1,s[35,6]=0.3,s[35,7]=-0.9,s[35,8]=-1.1,s[35,9]=0.5,s[35,10]=0.7,s[35,11]=-0.9,s[35,12]=-0.5,s[35,13]=-0.4,s[35,14]=0.1,s[35,15]=-0.9,s[35,16]=0.0,s[35,17]=-0.1,s[35,18]=0.2,s[35,19]=-0.1,s[35,20]=-0.1,s[35,21]=1.2,s[35,22]=1.0,s[35,23]=0.1,s[35,24]=0.9,s[35,25]=-0.3,s[35,26]=-0.5,s[35,27]=1.2,s[35,28]=0.5,s[35,29]=-0.8,s[35,30]=0.2,s[35,31]=-0.2,s[35,32]=0.7,s[35,33]=-0.6,s[35,34]=-0.4,s[35,35]=1.1,s[35,36]=-0.8,s[35,37]=0.6,s[35,38]=-0.2,s[35,39]=0.1,s[35,40]=0.8,s[35,41]=-0.5,s[35,42]=-0.7,s[35,43]=0.5,s[35,44]=-0.3,s[35,45]=0.9,s[35,46]=-0.3,s[35,47]=0.1,s[35,48]=-0.6,s[35,49]=-0.9,s[35,50]=0.9,s[35,51]=1.2,s[35,52]=1.2,s[35,53]=-0.1,s[35,54]=-1.2,s[35,55]=-0.9,s[35,56]=-1.2,s[35,57]=-0.2,s[35,58]=-0.7,s[35,59]=1.1,s[35,60]=-1.0 s[36,1]=-0.6,s[36,2]=0.2,s[36,3]=0.8,s[36,4]=0.3,s[36,5]=-0.7,s[36,6]=0.5,s[36,7]=0.2,s[36,8]=-1.0,s[36,9]=-0.4,s[36,10]=-0.6,s[36,11]=-0.2,s[36,12]=0.6,s[36,13]=1.1,s[36,14]=-0.9,s[36,15]=0.2,s[36,16]=0.1,s[36,17]=0.0,s[36,18]=-0.6,s[36,19]=0.4,s[36,20]=-0.2,s[36,21]=-0.7,s[36,22]=-0.7,s[36,23]=0.6,s[36,24]=0.0,s[36,25]=-0.2,s[36,26]=1.2,s[36,27]=-0.8,s[36,28]=-0.8,s[36,29]=-0.6,s[36,30]=0.4,s[36,31]=0.7,s[36,32]=-0.9,s[36,33]=1.1,s[36,34]=0.4,s[36,35]=0.3,s[36,36]=-0.1,s[36,37]=-0.9,s[36,38]=-0.5,s[36,39]=1.1,s[36,40]=0.1,s[36,41]=0.8,s[36,42]=0.4,s[36,43]=0.2,s[36,44]=1.0,s[36,45]=-0.7,s[36,46]=0.7,s[36,47]=0.6,s[36,48]=1.0,s[36,49]=0.9,s[36,50]=0.2,s[36,51]=0.0,s[36,52]=-0.2,s[36,53]=-1.0,s[36,54]=-1.0,s[36,55]=-0.7,s[36,56]=-0.3,s[36,57]=-0.6,s[36,58]=-1.2,s[36,59]=0.8,s[36,60]=1.0 s[37,1]=-1.2,s[37,2]=-0.7,s[37,3]=0.2,s[37,4]=-1.2,s[37,5]=0.7,s[37,6]=0.7,s[37,7]=0.1,s[37,8]=-0.4,s[37,9]=0.1,s[37,10]=0.6,s[37,11]=0.2,s[37,12]=0.9,s[37,13]=0.8,s[37,14]=-1.2,s[37,15]=1.1,s[37,16]=0.2,s[37,17]=-0.2,s[37,18]=-1.1,s[37,19]=-1.2,s[37,20]=-0.1,s[37,21]=0.4,s[37,22]=0.7,s[37,23]=-0.2,s[37,24]=-0.3,s[37,25]=0.1,s[37,26]=1.2,s[37,27]=0.5,s[37,28]=-0.1,s[37,29]=0.1,s[37,30]=0.7,s[37,31]=1.2,s[37,32]=-1.1,s[37,33]=0.5,s[37,34]=-1.0,s[37,35]=0.5,s[37,36]=0.0,s[37,37]=-0.8,s[37,38]=0.2,s[37,39]=0.1,s[37,40]=0.1,s[37,41]=-1.0,s[37,42]=-1.0,s[37,43]=-1.0,s[37,44]=0.6,s[37,45]=1.1,s[37,46]=-0.8,s[37,47]=1.2,s[37,48]=0.8,s[37,49]=0.0,s[37,50]=0.8,s[37,51]=-1.0,s[37,52]=-0.3,s[37,53]=-0.4,s[37,54]=0.7,s[37,55]=0.0,s[37,56]=-0.7,s[37,57]=0.3,s[37,58]=0.1,s[37,59]=-0.8,s[37,60]=0.2 s[38,1]=-0.8,s[38,2]=1.0,s[38,3]=-0.2,s[38,4]=0.9,s[38,5]=-0.9,s[38,6]=1.0,s[38,7]=-0.2,s[38,8]=0.9,s[38,9]=-0.3,s[38,10]=-1.1,s[38,11]=0.7,s[38,12]=-0.8,s[38,13]=0.9,s[38,14]=0.8,s[38,15]=-0.8,s[38,16]=-0.4,s[38,17]=0.6,s[38,18]=-0.1,s[38,19]=-0.1,s[38,20]=0.4,s[38,21]=0.7,s[38,22]=-1.2,s[38,23]=-0.7,s[38,24]=0.0,s[38,25]=-0.9,s[38,26]=-0.9,s[38,27]=-0.9,s[38,28]=0.8,s[38,29]=1.0,s[38,30]=1.2,s[38,31]=0.7,s[38,32]=-1.2,s[38,33]=0.8,s[38,34]=-0.7,s[38,35]=-0.6,s[38,36]=-0.2,s[38,37]=0.0,s[38,38]=-0.9,s[38,39]=1.1,s[38,40]=0.2,s[38,41]=-0.7,s[38,42]=-0.9,s[38,43]=1.2,s[38,44]=-1.2,s[38,45]=-0.5,s[38,46]=0.6,s[38,47]=0.1,s[38,48]=1.0,s[38,49]=-0.2,s[38,50]=0.3,s[38,51]=0.7,s[38,52]=-0.7,s[38,53]=0.6,s[38,54]=-0.5,s[38,55]=1.1,s[38,56]=0.7,s[38,57]=-1.0,s[38,58]=1.2,s[38,59]=-1.2,s[38,60]=-0.6 s[39,1]=-0.3,s[39,2]=-0.9,s[39,3]=-0.8,s[39,4]=1.2,s[39,5]=-0.6,s[39,6]=-0.6,s[39,7]=0.4,s[39,8]=0.3,s[39,9]=-0.5,s[39,10]=-0.7,s[39,11]=0.2,s[39,12]=-1.1,s[39,13]=1.2,s[39,14]=0.3,s[39,15]=-1.0,s[39,16]=-0.9,s[39,17]=0.8,s[39,18]=-1.2,s[39,19]=-1.0,s[39,20]=-0.8,s[39,21]=0.9,s[39,22]=-0.2,s[39,23]=0.3,s[39,24]=0.4,s[39,25]=0.4,s[39,26]=-0.7,s[39,27]=-1.2,s[39,28]=1.2,s[39,29]=-0.1,s[39,30]=0.4,s[39,31]=0.3,s[39,32]=0.4,s[39,33]=0.2,s[39,34]=-0.4,s[39,35]=-0.9,s[39,36]=-0.7,s[39,37]=-1.0,s[39,38]=-0.4,s[39,39]=0.0,s[39,40]=1.1,s[39,41]=1.2,s[39,42]=0.3,s[39,43]=-0.6,s[39,44]=-0.6,s[39,45]=0.0,s[39,46]=-1.2,s[39,47]=-0.7,s[39,48]=0.2,s[39,49]=0.4,s[39,50]=-0.9,s[39,51]=-0.3,s[39,52]=0.9,s[39,53]=0.2,s[39,54]=0.1,s[39,55]=1.0,s[39,56]=-0.7,s[39,57]=-0.2,s[39,58]=-0.4,s[39,59]=0.8,s[39,60]=0.0 s[40,1]=1.0,s[40,2]=0.9,s[40,3]=-1.2,s[40,4]=0.8,s[40,5]=-0.2,s[40,6]=-0.2,s[40,7]=-0.9,s[40,8]=-0.9,s[40,9]=-0.3,s[40,10]=-0.9,s[40,11]=-1.0,s[40,12]=1.0,s[40,13]=0.3,s[40,14]=0.6,s[40,15]=0.4,s[40,16]=-0.7,s[40,17]=-0.3,s[40,18]=-0.9,s[40,19]=1.2,s[40,20]=1.0,s[40,21]=0.2,s[40,22]=0.0,s[40,23]=1.0,s[40,24]=-0.7,s[40,25]=-0.8,s[40,26]=-1.2,s[40,27]=-0.2,s[40,28]=0.8,s[40,29]=-0.9,s[40,30]=0.8,s[40,31]=0.3,s[40,32]=0.0,s[40,33]=0.2,s[40,34]=-0.1,s[40,35]=-1.1,s[40,36]=0.6,s[40,37]=-1.0,s[40,38]=-0.3,s[40,39]=1.2,s[40,40]=-1.2,s[40,41]=-1.0,s[40,42]=0.9,s[40,43]=0.0,s[40,44]=1.2,s[40,45]=0.9,s[40,46]=-0.3,s[40,47]=0.5,s[40,48]=-1.0,s[40,49]=-0.5,s[40,50]=-1.0,s[40,51]=1.0,s[40,52]=0.8,s[40,53]=1.0,s[40,54]=-0.7,s[40,55]=-0.5,s[40,56]=0.0,s[40,57]=-1.1,s[40,58]=0.8,s[40,59]=-1.0,s[40,60]=0.8 s[41,1]=0.1,s[41,2]=0.5,s[41,3]=-0.3,s[41,4]=-1.1,s[41,5]=-1.2,s[41,6]=0.7,s[41,7]=-1.2,s[41,8]=0.6,s[41,9]=-1.1,s[41,10]=0.3,s[41,11]=0.2,s[41,12]=-1.0,s[41,13]=-1.2,s[41,14]=-0.7,s[41,15]=0.9,s[41,16]=0.9,s[41,17]=0.4,s[41,18]=0.2,s[41,19]=-0.8,s[41,20]=0.1,s[41,21]=1.1,s[41,22]=0.6,s[41,23]=-0.4,s[41,24]=-0.4,s[41,25]=1.0,s[41,26]=0.5,s[41,27]=-0.8,s[41,28]=0.7,s[41,29]=-0.7,s[41,30]=1.1,s[41,31]=-0.8,s[41,32]=0.7,s[41,33]=-0.2,s[41,34]=-0.1,s[41,35]=-0.8,s[41,36]=-0.6,s[41,37]=0.3,s[41,38]=-0.2,s[41,39]=-0.7,s[41,40]=-1.1,s[41,41]=-1.2,s[41,42]=0.1,s[41,43]=-0.3,s[41,44]=0.7,s[41,45]=0.9,s[41,46]=-0.3,s[41,47]=-0.6,s[41,48]=0.1,s[41,49]=-0.2,s[41,50]=-1.2,s[41,51]=-1.2,s[41,52]=0.7,s[41,53]=-1.1,s[41,54]=1.0,s[41,55]=0.2,s[41,56]=-0.9,s[41,57]=0.8,s[41,58]=-0.3,s[41,59]=-0.4,s[41,60]=0.0 s[42,1]=-1.2,s[42,2]=0.5,s[42,3]=-0.6,s[42,4]=0.3,s[42,5]=0.1,s[42,6]=-1.1,s[42,7]=0.6,s[42,8]=-0.3,s[42,9]=0.7,s[42,10]=-0.6,s[42,11]=1.1,s[42,12]=-0.4,s[42,13]=0.2,s[42,14]=0.1,s[42,15]=0.3,s[42,16]=1.0,s[42,17]=0.0,s[42,18]=-1.0,s[42,19]=1.2,s[42,20]=-0.6,s[42,21]=-0.3,s[42,22]=-1.1,s[42,23]=-0.1,s[42,24]=0.2,s[42,25]=0.1,s[42,26]=-0.2,s[42,27]=0.9,s[42,28]=-0.7,s[42,29]=0.6,s[42,30]=-1.1,s[42,31]=-1.2,s[42,32]=0.6,s[42,33]=0.2,s[42,34]=0.2,s[42,35]=0.5,s[42,36]=0.1,s[42,37]=-0.3,s[42,38]=-0.1,s[42,39]=-0.8,s[42,40]=0.0,s[42,41]=-1.2,s[42,42]=0.5,s[42,43]=-0.6,s[42,44]=0.2,s[42,45]=-0.9,s[42,46]=-0.7,s[42,47]=-0.5,s[42,48]=0.5,s[42,49]=1.2,s[42,50]=-0.7,s[42,51]=1.0,s[42,52]=-0.4,s[42,53]=-0.9,s[42,54]=0.7,s[42,55]=0.0,s[42,56]=1.2,s[42,57]=1.2,s[42,58]=1.2,s[42,59]=-0.7,s[42,60]=0.6 s[43,1]=0.7,s[43,2]=0.1,s[43,3]=0.3,s[43,4]=1.1,s[43,5]=-0.3,s[43,6]=0.9,s[43,7]=0.9,s[43,8]=0.5,s[43,9]=-0.2,s[43,10]=0.1,s[43,11]=-1.2,s[43,12]=1.0,s[43,13]=-0.3,s[43,14]=-0.3,s[43,15]=-0.8,s[43,16]=-1.0,s[43,17]=0.4,s[43,18]=0.2,s[43,19]=-0.5,s[43,20]=-0.1,s[43,21]=1.0,s[43,22]=0.9,s[43,23]=0.6,s[43,24]=-1.1,s[43,25]=0.5,s[43,26]=0.5,s[43,27]=0.1,s[43,28]=0.7,s[43,29]=0.5,s[43,30]=-1.2,s[43,31]=0.8,s[43,32]=0.6,s[43,33]=-0.2,s[43,34]=-1.2,s[43,35]=0.3,s[43,36]=-0.9,s[43,37]=1.1,s[43,38]=0.2,s[43,39]=0.4,s[43,40]=-0.2,s[43,41]=-0.4,s[43,42]=-0.7,s[43,43]=0.5,s[43,44]=-0.7,s[43,45]=-0.1,s[43,46]=1.2,s[43,47]=-0.7,s[43,48]=-1.2,s[43,49]=-0.2,s[43,50]=-1.0,s[43,51]=0.5,s[43,52]=0.5,s[43,53]=1.1,s[43,54]=-0.4,s[43,55]=1.0,s[43,56]=0.4,s[43,57]=-1.2,s[43,58]=-0.7,s[43,59]=0.8,s[43,60]=-0.8 s[44,1]=0.8,s[44,2]=0.8,s[44,3]=-0.6,s[44,4]=-0.8,s[44,5]=0.0,s[44,6]=0.0,s[44,7]=-0.6,s[44,8]=0.4,s[44,9]=0.7,s[44,10]=-0.6,s[44,11]=1.1,s[44,12]=0.3,s[44,13]=0.6,s[44,14]=0.4,s[44,15]=-1.0,s[44,16]=0.6,s[44,17]=-0.6,s[44,18]=-0.4,s[44,19]=-0.7,s[44,20]=0.5,s[44,21]=-0.4,s[44,22]=-1.1,s[44,23]=0.5,s[44,24]=-0.4,s[44,25]=-0.5,s[44,26]=0.7,s[44,27]=-0.2,s[44,28]=0.2,s[44,29]=0.4,s[44,30]=-0.9,s[44,31]=0.5,s[44,32]=-1.2,s[44,33]=-0.1,s[44,34]=-0.6,s[44,35]=1.0,s[44,36]=-0.2,s[44,37]=-1.0,s[44,38]=0.6,s[44,39]=0.2,s[44,40]=1.1,s[44,41]=0.6,s[44,42]=-1.1,s[44,43]=-0.7,s[44,44]=0.4,s[44,45]=0.7,s[44,46]=-0.4,s[44,47]=0.3,s[44,48]=-1.2,s[44,49]=-0.6,s[44,50]=-0.1,s[44,51]=0.7,s[44,52]=-0.4,s[44,53]=0.1,s[44,54]=0.9,s[44,55]=1.1,s[44,56]=0.3,s[44,57]=1.0,s[44,58]=0.0,s[44,59]=0.2,s[44,60]=0.2 s[45,1]=-0.5,s[45,2]=0.2,s[45,3]=1.0,s[45,4]=-0.6,s[45,5]=1.0,s[45,6]=1.2,s[45,7]=0.7,s[45,8]=-0.1,s[45,9]=-0.7,s[45,10]=-0.6,s[45,11]=-0.1,s[45,12]=-0.8,s[45,13]=-0.9,s[45,14]=1.1,s[45,15]=-1.1,s[45,16]=-0.1,s[45,17]=0.0,s[45,18]=0.3,s[45,19]=0.9,s[45,20]=1.2,s[45,21]=-0.5,s[45,22]=-0.7,s[45,23]=-0.9,s[45,24]=-0.6,s[45,25]=0.2,s[45,26]=1.2,s[45,27]=0.7,s[45,28]=0.9,s[45,29]=-0.1,s[45,30]=-0.1,s[45,31]=1.2,s[45,32]=0.3,s[45,33]=-0.3,s[45,34]=-0.5,s[45,35]=-0.1,s[45,36]=0.0,s[45,37]=-0.7,s[45,38]=0.0,s[45,39]=-0.1,s[45,40]=-1.2,s[45,41]=-1.0,s[45,42]=0.1,s[45,43]=-0.3,s[45,44]=1.1,s[45,45]=-1.2,s[45,46]=0.4,s[45,47]=0.9,s[45,48]=-1.1,s[45,49]=0.6,s[45,50]=-0.6,s[45,51]=0.5,s[45,52]=0.0,s[45,53]=1.1,s[45,54]=-0.9,s[45,55]=0.1,s[45,56]=0.6,s[45,57]=-1.1,s[45,58]=0.4,s[45,59]=0.2,s[45,60]=0.8 s[46,1]=-0.7,s[46,2]=0.0,s[46,3]=0.6,s[46,4]=0.3,s[46,5]=-0.3,s[46,6]=-1.0,s[46,7]=1.2,s[46,8]=-0.9,s[46,9]=-0.9,s[46,10]=-0.5,s[46,11]=-0.4,s[46,12]=-0.1,s[46,13]=-0.9,s[46,14]=-0.7,s[46,15]=-0.9,s[46,16]=0.9,s[46,17]=0.4,s[46,18]=-0.1,s[46,19]=1.1,s[46,20]=1.1,s[46,21]=-0.3,s[46,22]=0.0,s[46,23]=-0.3,s[46,24]=-0.6,s[46,25]=0.0,s[46,26]=-0.2,s[46,27]=-0.5,s[46,28]=0.4,s[46,29]=0.6,s[46,30]=-1.1,s[46,31]=-0.3,s[46,32]=-0.8,s[46,33]=0.4,s[46,34]=0.5,s[46,35]=0.1,s[46,36]=1.1,s[46,37]=1.2,s[46,38]=-0.9,s[46,39]=0.2,s[46,40]=1.2,s[46,41]=-1.2,s[46,42]=0.5,s[46,43]=1.0,s[46,44]=-0.7,s[46,45]=-1.2,s[46,46]=0.9,s[46,47]=1.2,s[46,48]=0.7,s[46,49]=0.0,s[46,50]=-0.6,s[46,51]=0.6,s[46,52]=-0.7,s[46,53]=1.1,s[46,54]=0.2,s[46,55]=-0.3,s[46,56]=-1.2,s[46,57]=-1.1,s[46,58]=0.9,s[46,59]=0.7,s[46,60]=0.7 s[47,1]=-0.3,s[47,2]=-0.7,s[47,3]=-0.7,s[47,4]=0.5,s[47,5]=-1.1,s[47,6]=-0.5,s[47,7]=0.0,s[47,8]=1.0,s[47,9]=0.6,s[47,10]=1.1,s[47,11]=0.5,s[47,12]=0.0,s[47,13]=-0.7,s[47,14]=-0.3,s[47,15]=1.0,s[47,16]=-1.1,s[47,17]=0.3,s[47,18]=-0.2,s[47,19]=1.1,s[47,20]=-1.0,s[47,21]=1.2,s[47,22]=-0.5,s[47,23]=-0.7,s[47,24]=-1.0,s[47,25]=-0.4,s[47,26]=1.2,s[47,27]=1.1,s[47,28]=0.6,s[47,29]=-0.1,s[47,30]=1.1,s[47,31]=0.5,s[47,32]=-1.1,s[47,33]=-0.4,s[47,34]=1.2,s[47,35]=-0.9,s[47,36]=0.7,s[47,37]=0.1,s[47,38]=0.9,s[47,39]=-0.7,s[47,40]=-0.4,s[47,41]=-1.1,s[47,42]=0.7,s[47,43]=-0.1,s[47,44]=-0.8,s[47,45]=-0.1,s[47,46]=0.0,s[47,47]=-0.2,s[47,48]=-0.2,s[47,49]=0.1,s[47,50]=-0.2,s[47,51]=0.3,s[47,52]=0.6,s[47,53]=-0.8,s[47,54]=-0.1,s[47,55]=0.4,s[47,56]=1.0,s[47,57]=-0.7,s[47,58]=0.5,s[47,59]=-0.9,s[47,60]=0.7 s[48,1]=0.1,s[48,2]=-0.6,s[48,3]=1.2,s[48,4]=-0.8,s[48,5]=0.2,s[48,6]=-0.8,s[48,7]=-1.0,s[48,8]=0.8,s[48,9]=0.4,s[48,10]=-0.2,s[48,11]=1.0,s[48,12]=-0.4,s[48,13]=0.3,s[48,14]=-0.1,s[48,15]=0.0,s[48,16]=-0.3,s[48,17]=0.5,s[48,18]=-0.9,s[48,19]=0.7,s[48,20]=0.8,s[48,21]=0.5,s[48,22]=0.3,s[48,23]=0.3,s[48,24]=0.4,s[48,25]=0.2,s[48,26]=-0.1,s[48,27]=1.2,s[48,28]=-0.5,s[48,29]=-0.2,s[48,30]=-0.9,s[48,31]=-1.1,s[48,32]=-1.1,s[48,33]=0.8,s[48,34]=-1.1,s[48,35]=1.1,s[48,36]=-0.2,s[48,37]=-0.7,s[48,38]=-0.4,s[48,39]=-0.7,s[48,40]=0.0,s[48,41]=-1.1,s[48,42]=0.4,s[48,43]=-0.8,s[48,44]=-0.6,s[48,45]=-0.8,s[48,46]=-1.1,s[48,47]=-0.7,s[48,48]=-1.1,s[48,49]=0.9,s[48,50]=-0.6,s[48,51]=0.3,s[48,52]=0.8,s[48,53]=-0.5,s[48,54]=-1.0,s[48,55]=0.3,s[48,56]=-0.1,s[48,57]=0.7,s[48,58]=-0.1,s[48,59]=0.1,s[48,60]=0.4 s[49,1]=-1.0,s[49,2]=0.2,s[49,3]=0.4,s[49,4]=-0.6,s[49,5]=0.2,s[49,6]=-0.7,s[49,7]=-0.8,s[49,8]=0.4,s[49,9]=0.9,s[49,10]=0.5,s[49,11]=0.4,s[49,12]=0.6,s[49,13]=0.1,s[49,14]=-0.6,s[49,15]=-0.8,s[49,16]=-0.6,s[49,17]=0.1,s[49,18]=0.2,s[49,19]=-0.8,s[49,20]=-1.1,s[49,21]=0.4,s[49,22]=0.1,s[49,23]=-0.6,s[49,24]=-0.8,s[49,25]=-1.2,s[49,26]=0.7,s[49,27]=0.4,s[49,28]=0.3,s[49,29]=0.7,s[49,30]=0.7,s[49,31]=0.5,s[49,32]=0.7,s[49,33]=0.0,s[49,34]=1.2,s[49,35]=0.8,s[49,36]=0.8,s[49,37]=-0.9,s[49,38]=-1.0,s[49,39]=0.8,s[49,40]=-0.7,s[49,41]=0.0,s[49,42]=-1.2,s[49,43]=-1.2,s[49,44]=0.2,s[49,45]=0.7,s[49,46]=-0.2,s[49,47]=-1.1,s[49,48]=0.5,s[49,49]=0.9,s[49,50]=-1.1,s[49,51]=-1.1,s[49,52]=-1.2,s[49,53]=-0.7,s[49,54]=1.0,s[49,55]=-0.3,s[49,56]=-0.2,s[49,57]=1.2,s[49,58]=0.1,s[49,59]=-0.3,s[49,60]=-1.2 s[50,1]=-1.0,s[50,2]=-0.1,s[50,3]=0.8,s[50,4]=-0.1,s[50,5]=0.2,s[50,6]=1.0,s[50,7]=1.0,s[50,8]=0.1,s[50,9]=0.4,s[50,10]=0.6,s[50,11]=0.2,s[50,12]=0.5,s[50,13]=-1.1,s[50,14]=0.9,s[50,15]=0.9,s[50,16]=-1.0,s[50,17]=0.3,s[50,18]=-0.4,s[50,19]=0.9,s[50,20]=1.0,s[50,21]=0.3,s[50,22]=0.5,s[50,23]=0.6,s[50,24]=-0.5,s[50,25]=1.1,s[50,26]=0.9,s[50,27]=-0.2,s[50,28]=-0.3,s[50,29]=0.3,s[50,30]=-1.1,s[50,31]=1.1,s[50,32]=-0.4,s[50,33]=0.9,s[50,34]=-0.2,s[50,35]=1.1,s[50,36]=0.9,s[50,37]=-0.9,s[50,38]=0.5,s[50,39]=0.6,s[50,40]=1.0,s[50,41]=-0.3,s[50,42]=-0.7,s[50,43]=-0.2,s[50,44]=-0.1,s[50,45]=0.3,s[50,46]=0.7,s[50,47]=0.4,s[50,48]=-0.5,s[50,49]=0.0,s[50,50]=1.2,s[50,51]=-0.5,s[50,52]=-1.1,s[50,53]=-1.2,s[50,54]=-0.5,s[50,55]=1.0,s[50,56]=0.1,s[50,57]=0.9,s[50,58]=0.5,s[50,59]=0.4,s[50,60]=-0.7 s[51,1]=-1.1,s[51,2]=0.9,s[51,3]=0.9,s[51,4]=0.6,s[51,5]=-1.2,s[51,6]=-1.1,s[51,7]=0.1,s[51,8]=1.2,s[51,9]=-0.1,s[51,10]=0.9,s[51,11]=-0.4,s[51,12]=-0.2,s[51,13]=0.1,s[51,14]=-0.6,s[51,15]=-0.2,s[51,16]=-0.5,s[51,17]=1.2,s[51,18]=0.0,s[51,19]=0.9,s[51,20]=0.8,s[51,21]=0.7,s[51,22]=0.8,s[51,23]=0.3,s[51,24]=0.4,s[51,25]=0.1,s[51,26]=0.6,s[51,27]=0.4,s[51,28]=-0.3,s[51,29]=0.1,s[51,30]=-0.6,s[51,31]=0.9,s[51,32]=0.4,s[51,33]=0.3,s[51,34]=0.3,s[51,35]=-0.5,s[51,36]=-0.1,s[51,37]=0.2,s[51,38]=-0.3,s[51,39]=-1.1,s[51,40]=-0.5,s[51,41]=0.3,s[51,42]=-0.9,s[51,43]=-0.7,s[51,44]=0.8,s[51,45]=-0.7,s[51,46]=0.9,s[51,47]=0.3,s[51,48]=0.9,s[51,49]=-0.9,s[51,50]=0.2,s[51,51]=0.5,s[51,52]=-1.2,s[51,53]=-0.7,s[51,54]=0.3,s[51,55]=0.3,s[51,56]=-0.9,s[51,57]=-1.2,s[51,58]=-0.6,s[51,59]=-0.8,s[51,60]=0.6 s[52,1]=0.2,s[52,2]=-0.9,s[52,3]=0.9,s[52,4]=-1.0,s[52,5]=0.3,s[52,6]=-0.4,s[52,7]=1.0,s[52,8]=1.2,s[52,9]=-0.4,s[52,10]=-0.5,s[52,11]=0.0,s[52,12]=-0.4,s[52,13]=-0.1,s[52,14]=0.4,s[52,15]=1.0,s[52,16]=-0.5,s[52,17]=-0.8,s[52,18]=0.8,s[52,19]=-0.3,s[52,20]=0.9,s[52,21]=0.8,s[52,22]=-0.8,s[52,23]=-0.9,s[52,24]=1.1,s[52,25]=0.3,s[52,26]=-0.2,s[52,27]=0.0,s[52,28]=-0.3,s[52,29]=0.9,s[52,30]=-0.4,s[52,31]=-0.8,s[52,32]=-0.6,s[52,33]=1.1,s[52,34]=-0.3,s[52,35]=-0.7,s[52,36]=1.1,s[52,37]=0.8,s[52,38]=-0.5,s[52,39]=0.3,s[52,40]=1.2,s[52,41]=1.1,s[52,42]=0.8,s[52,43]=0.8,s[52,44]=0.3,s[52,45]=-0.4,s[52,46]=-1.2,s[52,47]=0.1,s[52,48]=-0.8,s[52,49]=-0.1,s[52,50]=0.7,s[52,51]=-0.3,s[52,52]=-0.7,s[52,53]=1.1,s[52,54]=1.1,s[52,55]=1.2,s[52,56]=-0.3,s[52,57]=0.2,s[52,58]=0.1,s[52,59]=0.7,s[52,60]=-0.3 s[53,1]=-0.1,s[53,2]=0.3,s[53,3]=0.0,s[53,4]=0.1,s[53,5]=0.1,s[53,6]=0.5,s[53,7]=1.1,s[53,8]=0.2,s[53,9]=-1.1,s[53,10]=-0.8,s[53,11]=0.0,s[53,12]=0.4,s[53,13]=-1.0,s[53,14]=-0.7,s[53,15]=0.7,s[53,16]=0.3,s[53,17]=-0.1,s[53,18]=-0.3,s[53,19]=0.5,s[53,20]=0.3,s[53,21]=1.1,s[53,22]=1.1,s[53,23]=0.0,s[53,24]=-0.4,s[53,25]=0.5,s[53,26]=1.2,s[53,27]=0.4,s[53,28]=-0.7,s[53,29]=-0.8,s[53,30]=-0.8,s[53,31]=-0.4,s[53,32]=-0.9,s[53,33]=0.2,s[53,34]=-1.2,s[53,35]=0.8,s[53,36]=0.0,s[53,37]=1.1,s[53,38]=0.5,s[53,39]=-0.3,s[53,40]=1.0,s[53,41]=-1.1,s[53,42]=0.5,s[53,43]=0.4,s[53,44]=0.6,s[53,45]=-0.1,s[53,46]=-1.0,s[53,47]=-1.1,s[53,48]=-0.9,s[53,49]=-0.5,s[53,50]=0.8,s[53,51]=-0.5,s[53,52]=1.1,s[53,53]=0.0,s[53,54]=1.1,s[53,55]=0.9,s[53,56]=-1.1,s[53,57]=1.1,s[53,58]=-0.8,s[53,59]=-0.8,s[53,60]=1.0 s[54,1]=-1.1,s[54,2]=0.1,s[54,3]=0.8,s[54,4]=0.5,s[54,5]=-0.4,s[54,6]=1.0,s[54,7]=0.1,s[54,8]=-0.5,s[54,9]=1.1,s[54,10]=1.1,s[54,11]=0.5,s[54,12]=0.2,s[54,13]=-1.1,s[54,14]=-0.9,s[54,15]=-0.2,s[54,16]=0.4,s[54,17]=1.1,s[54,18]=0.5,s[54,19]=0.0,s[54,20]=0.9,s[54,21]=-0.5,s[54,22]=-1.2,s[54,23]=-0.5,s[54,24]=-0.2,s[54,25]=-0.6,s[54,26]=-1.1,s[54,27]=0.5,s[54,28]=0.2,s[54,29]=-0.6,s[54,30]=0.8,s[54,31]=-1.2,s[54,32]=-0.9,s[54,33]=-0.1,s[54,34]=-1.2,s[54,35]=-0.8,s[54,36]=0.0,s[54,37]=1.1,s[54,38]=1.0,s[54,39]=-1.1,s[54,40]=0.3,s[54,41]=0.4,s[54,42]=-1.1,s[54,43]=1.2,s[54,44]=-1.0,s[54,45]=-0.7,s[54,46]=0.6,s[54,47]=0.1,s[54,48]=-0.4,s[54,49]=1.0,s[54,50]=1.2,s[54,51]=0.6,s[54,52]=0.7,s[54,53]=0.7,s[54,54]=0.3,s[54,55]=-0.4,s[54,56]=0.2,s[54,57]=-0.5,s[54,58]=0.9,s[54,59]=-0.4,s[54,60]=-0.1 s[55,1]=0.6,s[55,2]=-0.6,s[55,3]=-0.4,s[55,4]=1.0,s[55,5]=1.2,s[55,6]=0.4,s[55,7]=0.2,s[55,8]=0.9,s[55,9]=-0.1,s[55,10]=0.3,s[55,11]=1.2,s[55,12]=0.6,s[55,13]=0.0,s[55,14]=-1.1,s[55,15]=0.2,s[55,16]=0.8,s[55,17]=0.0,s[55,18]=-1.1,s[55,19]=-0.4,s[55,20]=-1.1,s[55,21]=-0.6,s[55,22]=-0.1,s[55,23]=-0.3,s[55,24]=0.5,s[55,25]=0.7,s[55,26]=1.2,s[55,27]=0.3,s[55,28]=0.3,s[55,29]=0.5,s[55,30]=0.7,s[55,31]=-0.1,s[55,32]=0.0,s[55,33]=-1.1,s[55,34]=0.1,s[55,35]=0.3,s[55,36]=-0.2,s[55,37]=0.7,s[55,38]=0.1,s[55,39]=-0.1,s[55,40]=0.9,s[55,41]=0.1,s[55,42]=0.8,s[55,43]=-0.4,s[55,44]=0.6,s[55,45]=0.0,s[55,46]=1.0,s[55,47]=-0.2,s[55,48]=0.8,s[55,49]=0.7,s[55,50]=0.3,s[55,51]=0.6,s[55,52]=0.1,s[55,53]=-1.2,s[55,54]=-1.0,s[55,55]=-0.8,s[55,56]=0.5,s[55,57]=0.3,s[55,58]=0.4,s[55,59]=-0.4,s[55,60]=-0.8 s[56,1]=-0.1,s[56,2]=0.0,s[56,3]=0.2,s[56,4]=0.9,s[56,5]=-0.5,s[56,6]=-0.4,s[56,7]=0.3,s[56,8]=0.6,s[56,9]=-0.7,s[56,10]=-0.5,s[56,11]=-1.2,s[56,12]=-0.9,s[56,13]=0.5,s[56,14]=0.0,s[56,15]=0.6,s[56,16]=0.5,s[56,17]=0.3,s[56,18]=-0.4,s[56,19]=-0.4,s[56,20]=-1.2,s[56,21]=1.2,s[56,22]=-1.1,s[56,23]=0.2,s[56,24]=0.1,s[56,25]=0.2,s[56,26]=-0.3,s[56,27]=0.6,s[56,28]=-0.2,s[56,29]=0.5,s[56,30]=0.3,s[56,31]=0.6,s[56,32]=0.7,s[56,33]=-0.2,s[56,34]=1.2,s[56,35]=1.2,s[56,36]=-1.1,s[56,37]=-0.1,s[56,38]=-1.2,s[56,39]=-0.9,s[56,40]=1.1,s[56,41]=1.2,s[56,42]=0.7,s[56,43]=-0.9,s[56,44]=0.1,s[56,45]=0.8,s[56,46]=1.2,s[56,47]=0.9,s[56,48]=-0.6,s[56,49]=0.3,s[56,50]=0.5,s[56,51]=0.3,s[56,52]=1.2,s[56,53]=0.9,s[56,54]=0.8,s[56,55]=-0.8,s[56,56]=-0.3,s[56,57]=1.2,s[56,58]=0.3,s[56,59]=-0.9,s[56,60]=-0.8 s[57,1]=0.4,s[57,2]=1.1,s[57,3]=-0.5,s[57,4]=-1.1,s[57,5]=-0.4,s[57,6]=0.7,s[57,7]=0.4,s[57,8]=0.7,s[57,9]=1.1,s[57,10]=-0.4,s[57,11]=-0.9,s[57,12]=-0.7,s[57,13]=-0.2,s[57,14]=-0.4,s[57,15]=-0.5,s[57,16]=0.9,s[57,17]=0.1,s[57,18]=0.9,s[57,19]=-0.3,s[57,20]=-1.0,s[57,21]=0.9,s[57,22]=-1.1,s[57,23]=-0.5,s[57,24]=-0.1,s[57,25]=-0.2,s[57,26]=0.2,s[57,27]=-0.7,s[57,28]=0.0,s[57,29]=-1.1,s[57,30]=-0.3,s[57,31]=0.7,s[57,32]=0.8,s[57,33]=0.4,s[57,34]=1.0,s[57,35]=1.2,s[57,36]=-0.4,s[57,37]=-0.9,s[57,38]=-0.7,s[57,39]=-0.9,s[57,40]=0.4,s[57,41]=-0.8,s[57,42]=1.0,s[57,43]=0.5,s[57,44]=-0.3,s[57,45]=0.4,s[57,46]=0.0,s[57,47]=-0.8,s[57,48]=-1.0,s[57,49]=0.2,s[57,50]=-0.6,s[57,51]=0.4,s[57,52]=0.9,s[57,53]=0.0,s[57,54]=0.1,s[57,55]=-0.9,s[57,56]=0.5,s[57,57]=-0.4,s[57,58]=0.7,s[57,59]=0.1,s[57,60]=1.1 s[58,1]=0.1,s[58,2]=-0.9,s[58,3]=-0.7,s[58,4]=0.8,s[58,5]=1.0,s[58,6]=0.6,s[58,7]=0.0,s[58,8]=1.1,s[58,9]=-1.1,s[58,10]=-0.9,s[58,11]=-0.6,s[58,12]=0.4,s[58,13]=1.0,s[58,14]=-0.5,s[58,15]=-0.6,s[58,16]=0.0,s[58,17]=-0.3,s[58,18]=-0.4,s[58,19]=-0.4,s[58,20]=-0.1,s[58,21]=0.1,s[58,22]=-0.6,s[58,23]=-0.6,s[58,24]=-0.4,s[58,25]=0.1,s[58,26]=0.0,s[58,27]=1.2,s[58,28]=0.3,s[58,29]=0.9,s[58,30]=-1.2,s[58,31]=-0.7,s[58,32]=0.9,s[58,33]=-0.8,s[58,34]=-1.1,s[58,35]=1.1,s[58,36]=-0.3,s[58,37]=-0.5,s[58,38]=0.0,s[58,39]=1.0,s[58,40]=-1.1,s[58,41]=0.2,s[58,42]=-0.5,s[58,43]=0.7,s[58,44]=-0.8,s[58,45]=0.0,s[58,46]=-0.9,s[58,47]=0.7,s[58,48]=-0.3,s[58,49]=-0.9,s[58,50]=-0.6,s[58,51]=-0.5,s[58,52]=-0.4,s[58,53]=0.2,s[58,54]=1.0,s[58,55]=0.2,s[58,56]=1.1,s[58,57]=-1.2,s[58,58]=-0.8,s[58,59]=-0.2,s[58,60]=1.1 s[59,1]=-0.6,s[59,2]=-1.0,s[59,3]=0.8,s[59,4]=-1.1,s[59,5]=-0.5,s[59,6]=-0.2,s[59,7]=-0.5,s[59,8]=-0.7,s[59,9]=0.9,s[59,10]=-0.8,s[59,11]=-0.7,s[59,12]=1.1,s[59,13]=-1.0,s[59,14]=0.5,s[59,15]=0.3,s[59,16]=0.7,s[59,17]=-1.1,s[59,18]=0.9,s[59,19]=0.8,s[59,20]=0.2,s[59,21]=-1.1,s[59,22]=1.0,s[59,23]=0.0,s[59,24]=1.0,s[59,25]=0.2,s[59,26]=1.0,s[59,27]=1.1,s[59,28]=-0.4,s[59,29]=0.8,s[59,30]=0.3,s[59,31]=-0.8,s[59,32]=-0.7,s[59,33]=0.0,s[59,34]=1.1,s[59,35]=-1.1,s[59,36]=0.4,s[59,37]=-0.9,s[59,38]=-0.4,s[59,39]=-1.1,s[59,40]=0.3,s[59,41]=0.0,s[59,42]=0.0,s[59,43]=-0.5,s[59,44]=0.6,s[59,45]=0.9,s[59,46]=-1.1,s[59,47]=-0.6,s[59,48]=0.5,s[59,49]=0.1,s[59,50]=1.2,s[59,51]=-0.2,s[59,52]=-0.9,s[59,53]=-0.5,s[59,54]=-0.3,s[59,55]=-0.3,s[59,56]=-1.1,s[59,57]=-0.5,s[59,58]=-0.9,s[59,59]=1.2,s[59,60]=1.1 s[60,1]=-0.3,s[60,2]=0.3,s[60,3]=0.1,s[60,4]=0.7,s[60,5]=1.2,s[60,6]=-0.4,s[60,7]=0.2,s[60,8]=1.1,s[60,9]=-0.4,s[60,10]=-1.2,s[60,11]=0.0,s[60,12]=1.2,s[60,13]=0.8,s[60,14]=-0.9,s[60,15]=-0.9,s[60,16]=-0.8,s[60,17]=0.2,s[60,18]=-0.8,s[60,19]=0.6,s[60,20]=-0.7,s[60,21]=-1.1,s[60,22]=-0.9,s[60,23]=0.2,s[60,24]=1.1,s[60,25]=0.3,s[60,26]=-1.1,s[60,27]=0.6,s[60,28]=-0.4,s[60,29]=0.1,s[60,30]=0.0,s[60,31]=-0.7,s[60,32]=-0.2,s[60,33]=1.1,s[60,34]=0.9,s[60,35]=-0.2,s[60,36]=-0.6,s[60,37]=0.9,s[60,38]=-0.2,s[60,39]=-0.7,s[60,40]=0.1,s[60,41]=-0.9,s[60,42]=0.6,s[60,43]=0.4,s[60,44]=-1.1,s[60,45]=1.0,s[60,46]=-0.5,s[60,47]=0.7,s[60,48]=0.0,s[60,49]=0.6,s[60,50]=-0.2,s[60,51]=0.7,s[60,52]=0.0,s[60,53]=1.2,s[60,54]=-1.1,s[60,55]=0.9,s[60,56]=0.3,s[60,57]=1.2,s[60,58]=-1.1,s[60,59]=-0.1,s[60,60]=-0.4 s[61,1]=0.2,s[61,2]=-0.7,s[61,3]=0.4,s[61,4]=-1.0,s[61,5]=0.0,s[61,6]=-0.9,s[61,7]=1.2,s[61,8]=0.6,s[61,9]=-0.3,s[61,10]=-0.8,s[61,11]=1.2,s[61,12]=0.2,s[61,13]=-0.9,s[61,14]=-0.5,s[61,15]=0.9,s[61,16]=0.8,s[61,17]=-1.1,s[61,18]=-0.8,s[61,19]=0.6,s[61,20]=0.9,s[61,21]=-0.6,s[61,22]=-1.0,s[61,23]=0.6,s[61,24]=0.3,s[61,25]=0.6,s[61,26]=0.2,s[61,27]=-0.9,s[61,28]=1.0,s[61,29]=-0.7,s[61,30]=0.7,s[61,31]=0.3,s[61,32]=-1.2,s[61,33]=0.2,s[61,34]=0.1,s[61,35]=1.0,s[61,36]=-0.3,s[61,37]=1.2,s[61,38]=-0.7,s[61,39]=1.0,s[61,40]=0.3,s[61,41]=-1.2,s[61,42]=-0.9,s[61,43]=0.2,s[61,44]=0.7,s[61,45]=1.2,s[61,46]=0.0,s[61,47]=0.8,s[61,48]=-1.1,s[61,49]=0.8,s[61,50]=-1.1,s[61,51]=-0.7,s[61,52]=0.6,s[61,53]=0.8,s[61,54]=-0.6,s[61,55]=0.0,s[61,56]=0.3,s[61,57]=-0.8,s[61,58]=0.3,s[61,59]=-0.9,s[61,60]=0.5 s[62,1]=-0.7,s[62,2]=1.2,s[62,3]=0.6,s[62,4]=0.9,s[62,5]=-1.0,s[62,6]=0.4,s[62,7]=-1.0,s[62,8]=-0.3,s[62,9]=-0.9,s[62,10]=-1.2,s[62,11]=0.6,s[62,12]=-1.1,s[62,13]=1.0,s[62,14]=-0.9,s[62,15]=0.6,s[62,16]=0.9,s[62,17]=0.0,s[62,18]=0.0,s[62,19]=0.8,s[62,20]=-0.4,s[62,21]=-0.4,s[62,22]=-0.3,s[62,23]=0.4,s[62,24]=1.1,s[62,25]=-0.9,s[62,26]=1.2,s[62,27]=0.8,s[62,28]=0.0,s[62,29]=-0.3,s[62,30]=-0.6,s[62,31]=0.3,s[62,32]=-0.1,s[62,33]=0.3,s[62,34]=0.5,s[62,35]=0.2,s[62,36]=0.9,s[62,37]=-0.3,s[62,38]=-0.4,s[62,39]=1.2,s[62,40]=0.5,s[62,41]=0.0,s[62,42]=-1.0,s[62,43]=-0.7,s[62,44]=1.2,s[62,45]=-0.7,s[62,46]=-0.3,s[62,47]=-0.5,s[62,48]=-0.2,s[62,49]=0.5,s[62,50]=-1.2,s[62,51]=0.2,s[62,52]=-0.7,s[62,53]=1.2,s[62,54]=0.7,s[62,55]=-0.8,s[62,56]=-0.4,s[62,57]=0.0,s[62,58]=-0.9,s[62,59]=0.9,s[62,60]=0.2 s[63,1]=1.2,s[63,2]=-0.2,s[63,3]=-1.2,s[63,4]=-0.4,s[63,5]=-0.5,s[63,6]=-0.7,s[63,7]=0.1,s[63,8]=0.9,s[63,9]=0.5,s[63,10]=-1.2,s[63,11]=-1.1,s[63,12]=-0.8,s[63,13]=0.0,s[63,14]=0.5,s[63,15]=1.1,s[63,16]=-1.2,s[63,17]=-0.5,s[63,18]=-0.1,s[63,19]=0.4,s[63,20]=0.9,s[63,21]=-0.1,s[63,22]=-1.2,s[63,23]=0.1,s[63,24]=-1.2,s[63,25]=0.0,s[63,26]=-0.4,s[63,27]=0.1,s[63,28]=0.4,s[63,29]=-0.2,s[63,30]=-0.6,s[63,31]=-1.2,s[63,32]=0.1,s[63,33]=1.1,s[63,34]=-0.7,s[63,35]=0.6,s[63,36]=-0.3,s[63,37]=-0.8,s[63,38]=0.5,s[63,39]=-1.0,s[63,40]=0.6,s[63,41]=-0.7,s[63,42]=-0.9,s[63,43]=-0.1,s[63,44]=-0.9,s[63,45]=0.6,s[63,46]=0.1,s[63,47]=-0.7,s[63,48]=1.1,s[63,49]=-0.8,s[63,50]=-1.2,s[63,51]=1.2,s[63,52]=1.2,s[63,53]=-0.6,s[63,54]=1.2,s[63,55]=0.6,s[63,56]=-0.6,s[63,57]=0.7,s[63,58]=-0.9,s[63,59]=-0.1,s[63,60]=1.0 s[64,1]=1.1,s[64,2]=0.8,s[64,3]=0.4,s[64,4]=0.8,s[64,5]=1.2,s[64,6]=0.5,s[64,7]=0.5,s[64,8]=-0.4,s[64,9]=0.0,s[64,10]=-0.2,s[64,11]=0.9,s[64,12]=-0.3,s[64,13]=-0.5,s[64,14]=0.0,s[64,15]=0.9,s[64,16]=-0.9,s[64,17]=-1.2,s[64,18]=-0.6,s[64,19]=-0.1,s[64,20]=0.9,s[64,21]=0.0,s[64,22]=-0.6,s[64,23]=-0.1,s[64,24]=0.3,s[64,25]=-0.6,s[64,26]=-0.9,s[64,27]=0.6,s[64,28]=1.2,s[64,29]=-1.1,s[64,30]=0.5,s[64,31]=0.8,s[64,32]=-0.8,s[64,33]=-0.7,s[64,34]=0.7,s[64,35]=0.1,s[64,36]=-0.6,s[64,37]=0.0,s[64,38]=-0.7,s[64,39]=-1.0,s[64,40]=0.3,s[64,41]=0.1,s[64,42]=1.0,s[64,43]=0.2,s[64,44]=1.0,s[64,45]=-1.0,s[64,46]=0.5,s[64,47]=-1.2,s[64,48]=0.3,s[64,49]=0.1,s[64,50]=1.2,s[64,51]=-0.9,s[64,52]=-0.3,s[64,53]=0.5,s[64,54]=0.1,s[64,55]=-0.8,s[64,56]=-0.6,s[64,57]=-1.1,s[64,58]=0.8,s[64,59]=-0.1,s[64,60]=-1.0 s[65,1]=0.9,s[65,2]=-1.1,s[65,3]=0.9,s[65,4]=0.8,s[65,5]=-0.7,s[65,6]=-0.1,s[65,7]=0.2,s[65,8]=0.5,s[65,9]=-0.6,s[65,10]=-1.0,s[65,11]=0.9,s[65,12]=-0.8,s[65,13]=0.5,s[65,14]=0.7,s[65,15]=-0.4,s[65,16]=0.0,s[65,17]=-1.0,s[65,18]=-1.1,s[65,19]=-0.5,s[65,20]=0.4,s[65,21]=-1.2,s[65,22]=-1.1,s[65,23]=1.2,s[65,24]=-0.9,s[65,25]=-0.7,s[65,26]=-0.5,s[65,27]=0.1,s[65,28]=-0.6,s[65,29]=0.1,s[65,30]=-0.7,s[65,31]=0.3,s[65,32]=-1.0,s[65,33]=0.6,s[65,34]=1.0,s[65,35]=0.7,s[65,36]=-0.1,s[65,37]=1.1,s[65,38]=-0.9,s[65,39]=0.5,s[65,40]=1.2,s[65,41]=0.0,s[65,42]=-0.1,s[65,43]=0.4,s[65,44]=0.3,s[65,45]=0.6,s[65,46]=0.5,s[65,47]=1.2,s[65,48]=-0.2,s[65,49]=-0.2,s[65,50]=-0.3,s[65,51]=0.9,s[65,52]=-0.6,s[65,53]=0.5,s[65,54]=-0.8,s[65,55]=0.4,s[65,56]=1.2,s[65,57]=0.6,s[65,58]=0.9,s[65,59]=0.7,s[65,60]=-1.0 s[66,1]=-0.8,s[66,2]=-0.9,s[66,3]=0.2,s[66,4]=0.8,s[66,5]=-1.2,s[66,6]=-0.8,s[66,7]=0.2,s[66,8]=-0.9,s[66,9]=-1.1,s[66,10]=-0.5,s[66,11]=-0.7,s[66,12]=1.0,s[66,13]=0.0,s[66,14]=0.8,s[66,15]=-1.0,s[66,16]=-1.2,s[66,17]=-0.4,s[66,18]=0.0,s[66,19]=0.7,s[66,20]=-1.2,s[66,21]=-0.4,s[66,22]=-1.1,s[66,23]=1.0,s[66,24]=0.2,s[66,25]=0.4,s[66,26]=0.0,s[66,27]=0.4,s[66,28]=0.0,s[66,29]=-0.3,s[66,30]=-0.2,s[66,31]=1.0,s[66,32]=0.9,s[66,33]=-0.8,s[66,34]=0.8,s[66,35]=0.8,s[66,36]=-0.8,s[66,37]=-0.6,s[66,38]=-0.5,s[66,39]=0.0,s[66,40]=0.0,s[66,41]=0.4,s[66,42]=0.3,s[66,43]=-0.2,s[66,44]=0.0,s[66,45]=-0.5,s[66,46]=0.0,s[66,47]=-0.5,s[66,48]=0.2,s[66,49]=1.2,s[66,50]=-0.3,s[66,51]=0.1,s[66,52]=0.4,s[66,53]=-0.8,s[66,54]=0.5,s[66,55]=1.1,s[66,56]=-0.6,s[66,57]=-0.8,s[66,58]=0.8,s[66,59]=-0.2,s[66,60]=0.0 s[67,1]=-1.0,s[67,2]=0.2,s[67,3]=0.5,s[67,4]=-0.5,s[67,5]=1.1,s[67,6]=-0.7,s[67,7]=0.2,s[67,8]=-0.3,s[67,9]=0.2,s[67,10]=0.7,s[67,11]=-0.8,s[67,12]=0.5,s[67,13]=1.2,s[67,14]=0.4,s[67,15]=-1.0,s[67,16]=0.9,s[67,17]=-0.8,s[67,18]=0.9,s[67,19]=0.5,s[67,20]=0.7,s[67,21]=0.1,s[67,22]=-1.1,s[67,23]=-0.9,s[67,24]=0.7,s[67,25]=0.2,s[67,26]=0.2,s[67,27]=0.8,s[67,28]=1.1,s[67,29]=-0.7,s[67,30]=0.6,s[67,31]=1.0,s[67,32]=-0.7,s[67,33]=-1.2,s[67,34]=0.6,s[67,35]=0.4,s[67,36]=-0.2,s[67,37]=-1.1,s[67,38]=-1.2,s[67,39]=0.2,s[67,40]=1.1,s[67,41]=1.1,s[67,42]=0.9,s[67,43]=0.1,s[67,44]=0.2,s[67,45]=0.7,s[67,46]=-0.7,s[67,47]=0.5,s[67,48]=0.5,s[67,49]=1.0,s[67,50]=0.0,s[67,51]=0.1,s[67,52]=-1.1,s[67,53]=1.0,s[67,54]=0.5,s[67,55]=-0.4,s[67,56]=0.8,s[67,57]=1.1,s[67,58]=-1.2,s[67,59]=-1.1,s[67,60]=-0.8 s[68,1]=0.4,s[68,2]=-0.4,s[68,3]=0.7,s[68,4]=0.4,s[68,5]=-0.6,s[68,6]=0.6,s[68,7]=-0.2,s[68,8]=-0.3,s[68,9]=0.3,s[68,10]=1.1,s[68,11]=0.0,s[68,12]=0.5,s[68,13]=-1.2,s[68,14]=-0.9,s[68,15]=-0.7,s[68,16]=-0.4,s[68,17]=-1.0,s[68,18]=-0.3,s[68,19]=0.7,s[68,20]=-0.9,s[68,21]=0.3,s[68,22]=1.2,s[68,23]=0.0,s[68,24]=1.2,s[68,25]=0.3,s[68,26]=-0.4,s[68,27]=0.5,s[68,28]=0.7,s[68,29]=-0.9,s[68,30]=0.1,s[68,31]=0.4,s[68,32]=0.3,s[68,33]=-1.0,s[68,34]=-1.2,s[68,35]=-0.9,s[68,36]=0.6,s[68,37]=1.0,s[68,38]=-1.1,s[68,39]=0.4,s[68,40]=-0.6,s[68,41]=-1.1,s[68,42]=0.8,s[68,43]=-0.5,s[68,44]=0.3,s[68,45]=-1.0,s[68,46]=0.7,s[68,47]=-0.7,s[68,48]=-1.1,s[68,49]=-0.4,s[68,50]=1.0,s[68,51]=-0.7,s[68,52]=1.1,s[68,53]=-1.0,s[68,54]=-0.6,s[68,55]=-1.2,s[68,56]=-0.4,s[68,57]=-0.6,s[68,58]=1.1,s[68,59]=1.1,s[68,60]=-0.7 s[69,1]=0.4,s[69,2]=0.7,s[69,3]=-0.5,s[69,4]=1.1,s[69,5]=-0.6,s[69,6]=-0.8,s[69,7]=-1.1,s[69,8]=0.4,s[69,9]=0.8,s[69,10]=-0.9,s[69,11]=-0.3,s[69,12]=0.2,s[69,13]=0.4,s[69,14]=-0.7,s[69,15]=0.7,s[69,16]=1.1,s[69,17]=-0.5,s[69,18]=0.4,s[69,19]=0.0,s[69,20]=-0.5,s[69,21]=1.2,s[69,22]=0.0,s[69,23]=0.7,s[69,24]=-0.6,s[69,25]=-0.7,s[69,26]=-0.6,s[69,27]=-0.2,s[69,28]=0.5,s[69,29]=-1.2,s[69,30]=0.3,s[69,31]=-0.8,s[69,32]=0.5,s[69,33]=-0.1,s[69,34]=-0.5,s[69,35]=1.1,s[69,36]=-0.7,s[69,37]=-0.4,s[69,38]=0.6,s[69,39]=-0.9,s[69,40]=0.1,s[69,41]=-1.1,s[69,42]=-0.5,s[69,43]=-1.2,s[69,44]=-0.2,s[69,45]=0.3,s[69,46]=-0.1,s[69,47]=0.8,s[69,48]=0.4,s[69,49]=-0.1,s[69,50]=0.5,s[69,51]=-0.9,s[69,52]=1.1,s[69,53]=1.0,s[69,54]=0.9,s[69,55]=1.2,s[69,56]=0.9,s[69,57]=-0.4,s[69,58]=-1.2,s[69,59]=-0.3,s[69,60]=-1.0 s[70,1]=0.7,s[70,2]=0.8,s[70,3]=-0.2,s[70,4]=0.3,s[70,5]=1.0,s[70,6]=-0.8,s[70,7]=0.8,s[70,8]=-0.9,s[70,9]=-0.6,s[70,10]=-0.8,s[70,11]=0.8,s[70,12]=-0.9,s[70,13]=-0.5,s[70,14]=0.9,s[70,15]=0.6,s[70,16]=-0.2,s[70,17]=0.5,s[70,18]=-0.6,s[70,19]=0.3,s[70,20]=0.5,s[70,21]=-1.0,s[70,22]=0.0,s[70,23]=0.6,s[70,24]=0.9,s[70,25]=-1.1,s[70,26]=0.9,s[70,27]=-0.9,s[70,28]=0.8,s[70,29]=-0.8,s[70,30]=-0.3,s[70,31]=0.4,s[70,32]=-1.1,s[70,33]=-0.8,s[70,34]=-0.4,s[70,35]=0.7,s[70,36]=-1.2,s[70,37]=-0.6,s[70,38]=-0.9,s[70,39]=0.3,s[70,40]=-1.0,s[70,41]=0.6,s[70,42]=0.9,s[70,43]=0.9,s[70,44]=-1.1,s[70,45]=-0.9,s[70,46]=-0.9,s[70,47]=0.8,s[70,48]=1.0,s[70,49]=-1.2,s[70,50]=0.4,s[70,51]=-0.6,s[70,52]=-0.4,s[70,53]=0.3,s[70,54]=1.0,s[70,55]=0.3,s[70,56]=0.1,s[70,57]=0.0,s[70,58]=0.6,s[70,59]=0.3,s[70,60]=-0.8 s[71,1]=-1.0,s[71,2]=0.5,s[71,3]=0.6,s[71,4]=-1.2,s[71,5]=-1.1,s[71,6]=0.0,s[71,7]=-0.4,s[71,8]=0.6,s[71,9]=0.6,s[71,10]=0.9,s[71,11]=-0.9,s[71,12]=0.5,s[71,13]=-1.2,s[71,14]=-0.9,s[71,15]=0.3,s[71,16]=1.1,s[71,17]=-0.2,s[71,18]=-0.8,s[71,19]=0.4,s[71,20]=0.9,s[71,21]=0.2,s[71,22]=-0.8,s[71,23]=-0.5,s[71,24]=-1.1,s[71,25]=-0.7,s[71,26]=0.7,s[71,27]=1.1,s[71,28]=-0.3,s[71,29]=0.4,s[71,30]=0.8,s[71,31]=0.1,s[71,32]=0.4,s[71,33]=0.3,s[71,34]=-1.1,s[71,35]=0.5,s[71,36]=-1.2,s[71,37]=0.0,s[71,38]=0.8,s[71,39]=-1.1,s[71,40]=1.2,s[71,41]=0.6,s[71,42]=-0.6,s[71,43]=0.1,s[71,44]=0.9,s[71,45]=-0.8,s[71,46]=0.5,s[71,47]=1.0,s[71,48]=-1.0,s[71,49]=0.6,s[71,50]=-0.2,s[71,51]=0.2,s[71,52]=-0.1,s[71,53]=1.2,s[71,54]=-0.6,s[71,55]=-1.1,s[71,56]=-1.2,s[71,57]=-1.2,s[71,58]=-0.6,s[71,59]=0.4,s[71,60]=-0.7 s[72,1]=-0.3,s[72,2]=-0.9,s[72,3]=-0.4,s[72,4]=-0.8,s[72,5]=-1.1,s[72,6]=0.8,s[72,7]=-0.6,s[72,8]=0.1,s[72,9]=-0.7,s[72,10]=1.2,s[72,11]=0.4,s[72,12]=-0.7,s[72,13]=0.8,s[72,14]=-0.7,s[72,15]=1.1,s[72,16]=0.9,s[72,17]=0.7,s[72,18]=-0.7,s[72,19]=-1.2,s[72,20]=-0.9,s[72,21]=1.1,s[72,22]=-0.6,s[72,23]=0.1,s[72,24]=-0.5,s[72,25]=0.9,s[72,26]=-1.1,s[72,27]=1.2,s[72,28]=0.5,s[72,29]=0.2,s[72,30]=-0.9,s[72,31]=-0.9,s[72,32]=0.3,s[72,33]=-0.2,s[72,34]=0.5,s[72,35]=-1.0,s[72,36]=0.1,s[72,37]=0.7,s[72,38]=0.6,s[72,39]=0.7,s[72,40]=1.1,s[72,41]=0.0,s[72,42]=-0.9,s[72,43]=1.0,s[72,44]=0.5,s[72,45]=1.1,s[72,46]=-1.2,s[72,47]=1.1,s[72,48]=0.0,s[72,49]=0.4,s[72,50]=-0.6,s[72,51]=-1.0,s[72,52]=-0.6,s[72,53]=-0.3,s[72,54]=-0.6,s[72,55]=0.7,s[72,56]=-0.7,s[72,57]=0.5,s[72,58]=-0.7,s[72,59]=-0.3,s[72,60]=-1.1 s[73,1]=-0.3,s[73,2]=0.7,s[73,3]=-0.8,s[73,4]=0.8,s[73,5]=1.2,s[73,6]=0.9,s[73,7]=-0.7,s[73,8]=0.4,s[73,9]=-0.2,s[73,10]=0.4,s[73,11]=0.6,s[73,12]=-0.2,s[73,13]=-0.9,s[73,14]=0.7,s[73,15]=1.2,s[73,16]=-0.8,s[73,17]=0.5,s[73,18]=0.4,s[73,19]=-0.7,s[73,20]=0.6,s[73,21]=0.7,s[73,22]=-1.1,s[73,23]=-0.6,s[73,24]=-0.8,s[73,25]=-0.6,s[73,26]=0.5,s[73,27]=0.3,s[73,28]=0.4,s[73,29]=0.4,s[73,30]=0.7 s[73,31]=-0.5,s[73,32]=-0.2,s[73,33]=-0.9,s[73,34]=0.1,s[73,35]=0.9,s[73,36]=-1.0,s[73,37]=0.3,s[73,38]=0.8,s[73,39]=0.1,s[73,40]=0.4,s[73,41]=-1.0,s[73,42]=0.1,s[73,43]=0.6,s[73,44]=1.1,s[73,45]=0.0,s[73,46]=0.4,s[73,47]=-0.6,s[73,48]=0.7,s[73,49]=0.7,s[73,50]=1.2,s[73,51]=0.0,s[73,52]=0.0,s[73,53]=-1.2,s[73,54]=-0.1,s[73,55]=-0.6,s[73,56]=-0.8,s[73,57]=-0.8,s[73,58]=0.6,s[73,59]=-0.9,s[73,60]=0.3 s[74,1]=-0.4,s[74,2]=1.0,s[74,3]=1.1,s[74,4]=0.8,s[74,5]=0.9,s[74,6]=1.1,s[74,7]=0.8,s[74,8]=1.1,s[74,9]=-0.6,s[74,10]=-0.9,s[74,11]=1.1,s[74,12]=-1.0,s[74,13]=-1.2,s[74,14]=0.2,s[74,15]=1.2,s[74,16]=0.2,s[74,17]=-0.4,s[74,18]=0.5,s[74,19]=1.2,s[74,20]=1.0,s[74,21]=1.2,s[74,22]=-0.5,s[74,23]=0.1,s[74,24]=0.8,s[74,25]=-1.1,s[74,26]=-0.6,s[74,27]=-0.6,s[74,28]=0.2,s[74,29]=-0.1,s[74,30]=-0.8 s[74,31]=-0.7,s[74,32]=-0.6,s[74,33]=1.0,s[74,34]=0.6,s[74,35]=1.1,s[74,36]=0.3,s[74,37]=1.0,s[74,38]=-1.2,s[74,39]=0.4,s[74,40]=-1.0,s[74,41]=0.1,s[74,42]=-0.7,s[74,43]=-0.9,s[74,44]=-0.4,s[74,45]=0.8,s[74,46]=-0.2,s[74,47]=-1.1,s[74,48]=-0.2,s[74,49]=0.9,s[74,50]=0.7,s[74,51]=-0.4,s[74,52]=-0.1,s[74,53]=0.4,s[74,54]=-1.0,s[74,55]=0.8,s[74,56]=-0.3,s[74,57]=-1.2,s[74,58]=-0.2,s[74,59]=-1.0,s[74,60]=-0.2 s[75,1]=0.9,s[75,2]=0.6,s[75,3]=0.8,s[75,4]=-1.1,s[75,5]=-0.1,s[75,6]=0.6,s[75,7]=0.0,s[75,8]=-0.9,s[75,9]=0.7,s[75,10]=-1.1,s[75,11]=-1.2,s[75,12]=0.3,s[75,13]=1.0,s[75,14]=-0.7,s[75,15]=-0.3,s[75,16]=0.6,s[75,17]=0.4,s[75,18]=1.2,s[75,19]=1.2,s[75,20]=-0.5,s[75,21]=-1.0,s[75,22]=-0.6,s[75,23]=-0.2,s[75,24]=-0.6,s[75,25]=-0.4,s[75,26]=0.2,s[75,27]=0.8,s[75,28]=0.9,s[75,29]=-0.3,s[75,30]=-1.0 s[75,31]=-0.1,s[75,32]=0.3,s[75,33]=0.8,s[75,34]=0.5,s[75,35]=0.3,s[75,36]=-1.2,s[75,37]=0.6,s[75,38]=0.4,s[75,39]=-0.3,s[75,40]=-1.1,s[75,41]=-0.3,s[75,42]=-0.5,s[75,43]=-0.6,s[75,44]=-0.7,s[75,45]=-1.0,s[75,46]=0.6,s[75,47]=1.1,s[75,48]=-1.2,s[75,49]=-0.5,s[75,50]=-0.2,s[75,51]=-0.8,s[75,52]=0.5,s[75,53]=-1.2,s[75,54]=1.0,s[75,55]=1.2,s[75,56]=1.1,s[75,57]=-0.2,s[75,58]=0.2,s[75,59]=-0.9,s[75,60]=-0.4 s[76,1]=0.2,s[76,2]=-0.5,s[76,3]=0.1,s[76,4]=-0.1,s[76,5]=-0.5,s[76,6]=0.4,s[76,7]=0.5,s[76,8]=-0.3,s[76,9]=0.1,s[76,10]=0.9,s[76,11]=-0.9,s[76,12]=1.2,s[76,13]=1.2,s[76,14]=0.4,s[76,15]=-0.5,s[76,16]=0.7,s[76,17]=0.5,s[76,18]=0.7,s[76,19]=-0.9,s[76,20]=0.6,s[76,21]=0.5,s[76,22]=0.1,s[76,23]=0.4,s[76,24]=-0.4,s[76,25]=1.1,s[76,26]=0.2,s[76,27]=-0.2,s[76,28]=-0.3,s[76,29]=-0.9,s[76,30]=-1.1 s[76,31]=-0.2,s[76,32]=0.1,s[76,33]=0.3,s[76,34]=0.3,s[76,35]=-0.7,s[76,36]=-1.2,s[76,37]=1.1,s[76,38]=0.6,s[76,39]=0.4,s[76,40]=1.1,s[76,41]=-0.5,s[76,42]=-0.7,s[76,43]=0.5,s[76,44]=0.5,s[76,45]=1.1,s[76,46]=-0.4,s[76,47]=0.9,s[76,48]=1.1,s[76,49]=-0.6,s[76,50]=-0.9,s[76,51]=1.1,s[76,52]=-1.2,s[76,53]=0.5,s[76,54]=-1.1,s[76,55]=-0.9,s[76,56]=-1.2,s[76,57]=-1.1,s[76,58]=-0.9,s[76,59]=0.2,s[76,60]=-0.4 s[77,1]=0.6,s[77,2]=-0.9,s[77,3]=0.9,s[77,4]=-0.6,s[77,5]=-0.6,s[77,6]=-0.3,s[77,7]=-0.1,s[77,8]=-1.2,s[77,9]=-1.1,s[77,10]=0.5,s[77,11]=0.6,s[77,12]=-0.2,s[77,13]=0.3,s[77,14]=0.1,s[77,15]=-0.6,s[77,16]=1.1,s[77,17]=-1.2,s[77,18]=-1.1,s[77,19]=-0.7,s[77,20]=0.9,s[77,21]=-0.6,s[77,22]=-1.1,s[77,23]=1.2,s[77,24]=0.0,s[77,25]=0.2,s[77,26]=-0.3,s[77,27]=-0.1,s[77,28]=-1.0,s[77,29]=1.2,s[77,30]=0.7 s[77,31]=0.4,s[77,32]=0.2,s[77,33]=-0.4,s[77,34]=-1.1,s[77,35]=1.0,s[77,36]=0.0,s[77,37]=-0.4,s[77,38]=0.4,s[77,39]=0.1,s[77,40]=-0.7,s[77,41]=1.0,s[77,42]=-0.2,s[77,43]=-0.8,s[77,44]=-1.0,s[77,45]=-0.2,s[77,46]=-0.7,s[77,47]=-0.8,s[77,48]=-0.2,s[77,49]=-1.0,s[77,50]=-0.8,s[77,51]=0.6,s[77,52]=-0.5,s[77,53]=-0.9,s[77,54]=-0.4,s[77,55]=0.3,s[77,56]=-1.2,s[77,57]=0.2,s[77,58]=1.2,s[77,59]=0.4,s[77,60]=0.9 s[78,1]=1.1,s[78,2]=-0.6,s[78,3]=1.2,s[78,4]=1.0,s[78,5]=0.9,s[78,6]=0.7,s[78,7]=0.5,s[78,8]=-1.1,s[78,9]=-1.2,s[78,10]=0.0,s[78,11]=-1.2,s[78,12]=-1.1,s[78,13]=-0.2,s[78,14]=0.4,s[78,15]=-0.1,s[78,16]=-0.9,s[78,17]=0.6,s[78,18]=-0.4,s[78,19]=1.2,s[78,20]=-0.3,s[78,21]=-1.1,s[78,22]=-0.1,s[78,23]=0.2,s[78,24]=-0.6,s[78,25]=0.6,s[78,26]=0.2,s[78,27]=-1.0,s[78,28]=-0.4,s[78,29]=-1.1,s[78,30]=1.0 s[78,31]=0.7,s[78,32]=-0.6,s[78,33]=-0.8,s[78,34]=0.5,s[78,35]=0.9,s[78,36]=0.7,s[78,37]=-0.6,s[78,38]=0.7,s[78,39]=-0.2,s[78,40]=0.7,s[78,41]=0.0,s[78,42]=0.5,s[78,43]=0.3,s[78,44]=0.2,s[78,45]=0.1,s[78,46]=-1.2,s[78,47]=-1.1,s[78,48]=0.8,s[78,49]=0.0,s[78,50]=-0.4,s[78,51]=1.1,s[78,52]=0.3,s[78,53]=-0.5,s[78,54]=-1.2,s[78,55]=-1.0,s[78,56]=-0.1,s[78,57]=-0.5,s[78,58]=-0.8,s[78,59]=-0.8,s[78,60]=-0.6 s[79,1]=0.4,s[79,2]=-1.0,s[79,3]=-0.9,s[79,4]=1.1,s[79,5]=0.4,s[79,6]=0.0,s[79,7]=0.1,s[79,8]=1.2,s[79,9]=-0.6,s[79,10]=0.4,s[79,11]=1.1,s[79,12]=-1.2,s[79,13]=0.4,s[79,14]=0.7,s[79,15]=1.1,s[79,16]=-0.6,s[79,17]=-0.5,s[79,18]=-1.1,s[79,19]=-1.0,s[79,20]=-0.4,s[79,21]=0.8,s[79,22]=-0.8,s[79,23]=1.1,s[79,24]=1.2,s[79,25]=0.4,s[79,26]=-0.8,s[79,27]=-0.3,s[79,28]=1.1,s[79,29]=-0.1,s[79,30]=0.1 s[79,31]=1.2,s[79,32]=-1.0,s[79,33]=-0.6,s[79,34]=0.4,s[79,35]=0.0,s[79,36]=0.1,s[79,37]=-0.1,s[79,38]=0.2,s[79,39]=0.0,s[79,40]=1.2,s[79,41]=0.2,s[79,42]=0.1,s[79,43]=-0.9,s[79,44]=-0.6,s[79,45]=-0.7,s[79,46]=-0.9,s[79,47]=-0.7,s[79,48]=0.5,s[79,49]=-0.3,s[79,50]=-0.2,s[79,51]=-0.8,s[79,52]=0.9,s[79,53]=0.8,s[79,54]=-0.6,s[79,55]=0.7,s[79,56]=-0.2,s[79,57]=-0.1,s[79,58]=-0.8,s[79,59]=-1.2,s[79,60]=0.1 s[80,1]=-0.8,s[80,2]=1.0,s[80,3]=-0.9,s[80,4]=0.2,s[80,5]=-0.3,s[80,6]=-0.9,s[80,7]=0.8,s[80,8]=0.4,s[80,9]=0.4,s[80,10]=0.3,s[80,11]=-1.0,s[80,12]=0.0,s[80,13]=-1.2,s[80,14]=1.2,s[80,15]=0.3,s[80,16]=1.1,s[80,17]=-1.1,s[80,18]=-0.2,s[80,19]=-1.2,s[80,20]=-1.0,s[80,21]=0.9,s[80,22]=-0.1,s[80,23]=0.8,s[80,24]=-1.1,s[80,25]=-0.2,s[80,26]=-0.5,s[80,27]=0.8,s[80,28]=-0.1,s[80,29]=-0.4,s[80,30]=-0.2 s[80,31]=0.8,s[80,32]=0.4,s[80,33]=-1.2,s[80,34]=-1.0,s[80,35]=0.9,s[80,36]=0.6,s[80,37]=0.8,s[80,38]=-0.5,s[80,39]=-0.9,s[80,40]=0.8,s[80,41]=0.8,s[80,42]=0.6,s[80,43]=-1.0,s[80,44]=1.0,s[80,45]=0.0,s[80,46]=-0.2,s[80,47]=0.4,s[80,48]=0.0,s[80,49]=1.0,s[80,50]=-0.6,s[80,51]=-1.1,s[80,52]=1.2,s[80,53]=0.4,s[80,54]=0.8,s[80,55]=0.2,s[80,56]=0.8,s[80,57]=0.6,s[80,58]=0.2,s[80,59]=-0.9,s[80,60]=0.0 s[81,1]=1.0,s[81,2]=-0.3,s[81,3]=-0.5,s[81,4]=-0.9,s[81,5]=1.1,s[81,6]=-0.3,s[81,7]=-0.1,s[81,8]=0.1,s[81,9]=1.0,s[81,10]=-1.0,s[81,11]=0.5,s[81,12]=-0.5,s[81,13]=1.2,s[81,14]=0.9,s[81,15]=-0.5,s[81,16]=-0.6,s[81,17]=1.0,s[81,18]=1.1,s[81,19]=-0.4,s[81,20]=-0.9,s[81,21]=0.9,s[81,22]=0.0,s[81,23]=-0.9,s[81,24]=-0.4,s[81,25]=1.0,s[81,26]=-1.0,s[81,27]=-0.3,s[81,28]=-1.2,s[81,29]=-0.1,s[81,30]=-0.6 s[81,31]=-0.3,s[81,32]=-0.6,s[81,33]=0.9,s[81,34]=1.1,s[81,35]=-0.5,s[81,36]=-1.0,s[81,37]=0.7,s[81,38]=0.2,s[81,39]=0.8,s[81,40]=-1.1,s[81,41]=-1.1,s[81,42]=0.3,s[81,43]=0.0,s[81,44]=-0.6,s[81,45]=-0.6,s[81,46]=1.0,s[81,47]=0.1,s[81,48]=-1.0,s[81,49]=-0.9,s[81,50]=-1.1,s[81,51]=-0.1,s[81,52]=-1.1,s[81,53]=-1.2,s[81,54]=1.1,s[81,55]=0.8,s[81,56]=0.3,s[81,57]=-1.1,s[81,58]=-0.4,s[81,59]=-0.5,s[81,60]=0.2 s[82,1]=-0.1,s[82,2]=0.5,s[82,3]=-0.3,s[82,4]=0.7,s[82,5]=-0.6,s[82,6]=-0.8,s[82,7]=-1.2,s[82,8]=-1.2,s[82,9]=0.8,s[82,10]=1.1,s[82,11]=1.0,s[82,12]=-0.4,s[82,13]=-0.1,s[82,14]=-0.3,s[82,15]=0.6,s[82,16]=-0.9,s[82,17]=0.2,s[82,18]=-1.2,s[82,19]=-0.2,s[82,20]=-1.2,s[82,21]=0.0,s[82,22]=0.4,s[82,23]=0.4,s[82,24]=-0.9,s[82,25]=0.2,s[82,26]=-0.1,s[82,27]=1.0,s[82,28]=1.1,s[82,29]=-1.1,s[82,30]=0.3 s[82,31]=0.5,s[82,32]=-0.8,s[82,33]=-0.2,s[82,34]=0.1,s[82,35]=0.7,s[82,36]=-0.6,s[82,37]=-0.3,s[82,38]=-0.6,s[82,39]=0.7,s[82,40]=0.5,s[82,41]=-0.2,s[82,42]=0.5,s[82,43]=-0.7,s[82,44]=0.7,s[82,45]=0.7,s[82,46]=0.6,s[82,47]=0.9,s[82,48]=-0.4,s[82,49]=-1.1,s[82,50]=0.8,s[82,51]=0.0,s[82,52]=1.0,s[82,53]=-0.6,s[82,54]=1.0,s[82,55]=0.3,s[82,56]=-0.6,s[82,57]=1.0,s[82,58]=0.5,s[82,59]=-0.2,s[82,60]=0.9 s[83,1]=-0.1,s[83,2]=0.0,s[83,3]=-0.8,s[83,4]=0.7,s[83,5]=0.2,s[83,6]=1.2,s[83,7]=-0.5,s[83,8]=0.7,s[83,9]=1.1,s[83,10]=1.2,s[83,11]=0.0,s[83,12]=0.1,s[83,13]=0.5,s[83,14]=-0.2,s[83,15]=0.5,s[83,16]=1.1,s[83,17]=-0.1,s[83,18]=-0.5,s[83,19]=-1.1,s[83,20]=0.7,s[83,21]=0.6,s[83,22]=-1.1,s[83,23]=0.4,s[83,24]=-0.5,s[83,25]=0.1,s[83,26]=-1.0,s[83,27]=-1.2,s[83,28]=0.1,s[83,29]=0.5,s[83,30]=0.8 s[83,31]=-0.6,s[83,32]=1.1,s[83,33]=-0.8,s[83,34]=-1.1,s[83,35]=-0.9,s[83,36]=0.8,s[83,37]=1.1,s[83,38]=-0.4,s[83,39]=-0.4,s[83,40]=-0.5,s[83,41]=-0.2,s[83,42]=1.2,s[83,43]=0.5,s[83,44]=1.1,s[83,45]=-0.8,s[83,46]=0.3,s[83,47]=0.0,s[83,48]=1.2,s[83,49]=0.4,s[83,50]=0.7,s[83,51]=-1.2,s[83,52]=0.6,s[83,53]=-0.5,s[83,54]=-0.4,s[83,55]=1.1,s[83,56]=-0.9,s[83,57]=0.2,s[83,58]=1.0,s[83,59]=0.9,s[83,60]=-0.1 s[84,1]=0.7,s[84,2]=-0.5,s[84,3]=-0.6,s[84,4]=-0.1,s[84,5]=-0.8,s[84,6]=0.2,s[84,7]=1.0,s[84,8]=0.1,s[84,9]=-0.2,s[84,10]=0.9,s[84,11]=0.4,s[84,12]=1.0,s[84,13]=1.1,s[84,14]=0.8,s[84,15]=0.3,s[84,16]=-0.5,s[84,17]=0.8,s[84,18]=-0.2,s[84,19]=0.6,s[84,20]=0.8,s[84,21]=-0.8,s[84,22]=0.3,s[84,23]=0.5,s[84,24]=-0.8,s[84,25]=0.1,s[84,26]=1.1,s[84,27]=-1.2,s[84,28]=-0.3,s[84,29]=-0.6,s[84,30]=0.1 s[84,31]=-1.0,s[84,32]=-0.5,s[84,33]=0.4,s[84,34]=0.0,s[84,35]=-0.8,s[84,36]=-0.7,s[84,37]=0.2,s[84,38]=0.5,s[84,39]=-0.2,s[84,40]=-0.4,s[84,41]=0.7,s[84,42]=-0.3,s[84,43]=-0.1,s[84,44]=0.2,s[84,45]=-0.7,s[84,46]=-0.8,s[84,47]=0.8,s[84,48]=-0.1,s[84,49]=-1.2,s[84,50]=0.6,s[84,51]=-0.5,s[84,52]=-0.6,s[84,53]=-0.9,s[84,54]=-0.4,s[84,55]=0.1,s[84,56]=-0.1,s[84,57]=0.5,s[84,58]=0.1,s[84,59]=-0.4,s[84,60]=-0.1 s[85,1]=0.4,s[85,2]=1.2,s[85,3]=-0.7,s[85,4]=-1.2,s[85,5]=-1.0,s[85,6]=0.2,s[85,7]=0.5,s[85,8]=1.0,s[85,9]=-1.2,s[85,10]=0.0,s[85,11]=0.1,s[85,12]=1.0,s[85,13]=0.3,s[85,14]=0.1,s[85,15]=-1.2,s[85,16]=-1.0,s[85,17]=-0.7,s[85,18]=1.1,s[85,19]=-0.8,s[85,20]=1.0,s[85,21]=-0.2,s[85,22]=-1.0,s[85,23]=-1.0,s[85,24]=0.7,s[85,25]=0.1,s[85,26]=-0.6,s[85,27]=-0.3,s[85,28]=1.2,s[85,29]=0.7,s[85,30]=0.4 s[85,31]=0.8,s[85,32]=0.2,s[85,33]=0.2,s[85,34]=0.3,s[85,35]=-0.1,s[85,36]=1.1,s[85,37]=-0.8,s[85,38]=0.0,s[85,39]=-0.4,s[85,40]=-0.7,s[85,41]=-0.7,s[85,42]=-0.2,s[85,43]=0.0,s[85,44]=1.1,s[85,45]=-0.1,s[85,46]=-1.1,s[85,47]=0.9,s[85,48]=0.3,s[85,49]=-0.7,s[85,50]=-0.6,s[85,51]=0.6,s[85,52]=-0.6,s[85,53]=-1.0,s[85,54]=0.3,s[85,55]=0.5,s[85,56]=-0.1,s[85,57]=-0.7,s[85,58]=-0.3,s[85,59]=0.6,s[85,60]=1.2 s[86,1]=-1.0,s[86,2]=0.5,s[86,3]=0.0,s[86,4]=-1.0,s[86,5]=0.1,s[86,6]=0.1,s[86,7]=-0.8,s[86,8]=-1.2,s[86,9]=1.0,s[86,10]=-0.4,s[86,11]=-0.3,s[86,12]=0.9,s[86,13]=1.0,s[86,14]=-0.4,s[86,15]=-1.2,s[86,16]=1.0,s[86,17]=-0.5,s[86,18]=-0.3,s[86,19]=1.0,s[86,20]=-0.9,s[86,21]=-0.5,s[86,22]=1.1,s[86,23]=0.3,s[86,24]=-0.5,s[86,25]=0.8,s[86,26]=0.8,s[86,27]=-0.1,s[86,28]=-0.2,s[86,29]=0.2,s[86,30]=0.0 s[86,31]=1.1,s[86,32]=-0.4,s[86,33]=1.1,s[86,34]=-1.1,s[86,35]=-0.7,s[86,36]=-0.5,s[86,37]=-1.0,s[86,38]=-0.1,s[86,39]=-0.8,s[86,40]=-0.1,s[86,41]=0.2,s[86,42]=-0.1,s[86,43]=-0.9,s[86,44]=-0.1,s[86,45]=-1.1,s[86,46]=0.1,s[86,47]=0.3,s[86,48]=-0.4,s[86,49]=-1.1,s[86,50]=0.5,s[86,51]=1.0,s[86,52]=-0.9,s[86,53]=-0.3,s[86,54]=-0.2,s[86,55]=0.2,s[86,56]=-0.8,s[86,57]=-0.2,s[86,58]=-1.2,s[86,59]=-1.0,s[86,60]=0.3 s[87,1]=1.0,s[87,2]=-0.1,s[87,3]=0.0,s[87,4]=-1.0,s[87,5]=1.1,s[87,6]=0.3,s[87,7]=-1.2,s[87,8]=-0.1,s[87,9]=1.0,s[87,10]=0.0,s[87,11]=0.2,s[87,12]=0.3,s[87,13]=1.1,s[87,14]=-0.6,s[87,15]=0.0,s[87,16]=-0.5,s[87,17]=0.0,s[87,18]=0.8,s[87,19]=-1.2,s[87,20]=0.3,s[87,21]=-0.1,s[87,22]=-0.9,s[87,23]=0.7,s[87,24]=1.2,s[87,25]=-0.3,s[87,26]=1.1,s[87,27]=0.8,s[87,28]=1.0,s[87,29]=1.0,s[87,30]=0.0 s[87,31]=-0.5,s[87,32]=1.0,s[87,33]=-0.2,s[87,34]=-0.1,s[87,35]=0.1,s[87,36]=-0.1,s[87,37]=-0.9,s[87,38]=0.0,s[87,39]=-0.2,s[87,40]=-0.4,s[87,41]=0.5,s[87,42]=-0.5,s[87,43]=-0.5,s[87,44]=-0.3,s[87,45]=-1.2,s[87,46]=-0.1,s[87,47]=-0.8,s[87,48]=-0.5,s[87,49]=0.8,s[87,50]=0.4,s[87,51]=-0.9,s[87,52]=-0.1,s[87,53]=0.7,s[87,54]=0.3,s[87,55]=-0.6,s[87,56]=-1.2,s[87,57]=-0.7,s[87,58]=1.0,s[87,59]=-1.2,s[87,60]=0.8 s[88,1]=-0.2,s[88,2]=-0.5,s[88,3]=1.1,s[88,4]=-0.1,s[88,5]=0.8,s[88,6]=0.6,s[88,7]=0.0,s[88,8]=0.6,s[88,9]=-0.7,s[88,10]=1.2,s[88,11]=0.3,s[88,12]=1.2,s[88,13]=0.8,s[88,14]=-0.7,s[88,15]=-0.2,s[88,16]=1.1,s[88,17]=-0.9,s[88,18]=-1.2,s[88,19]=0.0,s[88,20]=0.5,s[88,21]=-0.9,s[88,22]=0.3,s[88,23]=0.5,s[88,24]=-0.5,s[88,25]=0.7,s[88,26]=0.1,s[88,27]=0.2,s[88,28]=1.1,s[88,29]=-0.7,s[88,30]=0.2 s[88,31]=-1.1,s[88,32]=-0.5,s[88,33]=-0.4,s[88,34]=0.5,s[88,35]=0.2,s[88,36]=0.1,s[88,37]=-0.1,s[88,38]=0.3,s[88,39]=-0.1,s[88,40]=-0.4,s[88,41]=-0.8,s[88,42]=-0.9,s[88,43]=-0.6,s[88,44]=0.5,s[88,45]=0.0,s[88,46]=-0.4,s[88,47]=0.2,s[88,48]=-0.6,s[88,49]=-0.5,s[88,50]=0.2,s[88,51]=1.0,s[88,52]=-0.8,s[88,53]=-1.0,s[88,54]=-0.1,s[88,55]=-1.1,s[88,56]=-0.3,s[88,57]=-0.7,s[88,58]=0.0,s[88,59]=0.5,s[88,60]=0.4 s[89,1]=0.3,s[89,2]=-0.9,s[89,3]=0.7,s[89,4]=0.9,s[89,5]=1.0,s[89,6]=-0.3,s[89,7]=-0.2,s[89,8]=-1.1,s[89,9]=-1.1,s[89,10]=-1.0,s[89,11]=1.2,s[89,12]=1.2,s[89,13]=0.8,s[89,14]=0.4,s[89,15]=1.1,s[89,16]=0.5,s[89,17]=-1.0,s[89,18]=-0.8,s[89,19]=-0.1,s[89,20]=-0.9,s[89,21]=0.1,s[89,22]=-0.5,s[89,23]=0.1,s[89,24]=-0.5,s[89,25]=0.8,s[89,26]=1.2,s[89,27]=-0.9,s[89,28]=-0.8,s[89,29]=-0.9,s[89,30]=0.8 s[89,31]=-0.9,s[89,32]=-0.1,s[89,33]=-0.3,s[89,34]=-0.9,s[89,35]=-1.0,s[89,36]=0.5,s[89,37]=-0.7,s[89,38]=1.0,s[89,39]=0.9,s[89,40]=0.6,s[89,41]=-0.9,s[89,42]=-0.9,s[89,43]=0.2,s[89,44]=0.9,s[89,45]=-0.2,s[89,46]=-0.3,s[89,47]=-1.0,s[89,48]=1.2,s[89,49]=1.2,s[89,50]=0.9,s[89,51]=0.1,s[89,52]=1.2,s[89,53]=0.5,s[89,54]=0.5,s[89,55]=-1.1,s[89,56]=-0.2,s[89,57]=0.7,s[89,58]=0.3,s[89,59]=-0.3,s[89,60]=1.0 s[90,1]=0.8,s[90,2]=0.1,s[90,3]=-0.7,s[90,4]=-0.9,s[90,5]=0.4,s[90,6]=1.2,s[90,7]=0.8,s[90,8]=1.2,s[90,9]=-1.1,s[90,10]=0.4,s[90,11]=0.8,s[90,12]=-0.3,s[90,13]=-0.1,s[90,14]=1.2,s[90,15]=-1.1,s[90,16]=-0.6,s[90,17]=-0.3,s[90,18]=0.9,s[90,19]=-0.5,s[90,20]=0.3,s[90,21]=-1.1,s[90,22]=-0.6,s[90,23]=-0.2,s[90,24]=-0.9,s[90,25]=-0.6,s[90,26]=-1.1,s[90,27]=-0.9,s[90,28]=0.7,s[90,29]=-0.2,s[90,30]=-0.8 s[90,31]=-0.7,s[90,32]=-0.8,s[90,33]=0.2,s[90,34]=-1.2,s[90,35]=0.4,s[90,36]=0.9,s[90,37]=-0.3,s[90,38]=-1.2,s[90,39]=-0.3,s[90,40]=-1.2,s[90,41]=-0.7,s[90,42]=0.5,s[90,43]=0.0,s[90,44]=-0.7,s[90,45]=0.9,s[90,46]=0.3,s[90,47]=0.0,s[90,48]=-0.2,s[90,49]=0.6,s[90,50]=1.2,s[90,51]=0.4,s[90,52]=0.7,s[90,53]=0.3,s[90,54]=0.1,s[90,55]=-0.6,s[90,56]=1.0,s[90,57]=0.4,s[90,58]=0.5,s[90,59]=-1.2,s[90,60]=0.4 endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float ppz = @ppz float ppw = @ppw float pxx = 0 float pyy = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x pyy = y float pzz = ppz x = x+0.1*(s[@sel,1] + s[@sel,2]*x + s[@sel,3]*x*x + s[@sel,4]*x*y + s[@sel,5]*x*ppz + s[@sel,6]*x*ppw + s[@sel,7]*y + s[@sel,8]*y*y + \ s[@sel,9]*y*ppz + s[@sel,10]*y*ppw + s[@sel,11]*ppz + s[@sel,12]*ppz*ppz + s[@sel,13]*ppz*ppw + s[@sel,14]*ppw + s[@sel,15]*ppw*ppw) y = y+0.1*(s[@sel,16] + s[@sel,17]*pxx + s[@sel,18]*pxx*pxx + s[@sel,19]*pxx*y + s[@sel,20]*pxx*ppz + s[@sel,21]*pxx*ppw + s[@sel,22]*y + s[@sel,23]*y*y + \ s[@sel,24]*y*ppz + s[@sel,25]*y*ppw + s[@sel,26]*ppz + s[@sel,27]*ppz*ppz + s[@sel,28]*ppz*ppw + s[@sel,29]*ppw + s[@sel,30]*ppw*ppw) ppz = ppz+0.1*(s[@sel,31] + s[@sel,32]*pxx + s[@sel,33]*pxx*pxx + s[@sel,34]*pxx*pyy + s[@sel,35]*pxx*ppz + s[@sel,36]*pxx*ppw + s[@sel,37]*pyy + s[@sel,38]*pyy*pyy + \ s[@sel,39]*pyy*ppz + s[@sel,40]*pyy*ppw + s[@sel,41]*ppz + s[@sel,42]*ppz*ppz + s[@sel,43]*ppz*ppw + s[@sel,44]*ppw + s[@sel,45]*ppw*ppw) ppw = ppw+0.1*(s[@sel,46] + s[@sel,47]*pxx + s[@sel,48]*pxx*pxx + s[@sel,49]*pxx*pyy + s[@sel,50]*pxx*pzz + s[@sel,51]*pxx*ppw + s[@sel,52]*pyy + s[@sel,53]*pyy*pyy + \ s[@sel,54]*pyy*pzz + s[@sel,55]*pyy*ppw + s[@sel,56]*pzz + s[@sel,57]*pzz*pzz + s[@sel,58]*pzz*ppw + s[@sel,59]*ppw + s[@sel,60]*ppw*ppw) att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y) + ppz*@pw + ppw*@p4) float d = @distscale*|pz-(x + sgn*flip(y) + ppz*@pw + ppw*@p4)| return d endfunc private: float s[91,61] default: title = "Sprott4D_ODE" heading text="Strange attractors from simultaneous ordinary differential \ equations using Euler's finite difference method to calculate." endheading heading text="Sprott 4D ODE quadratic attractors" endheading heading text=" x -> x + 0.1*(Quadratic in x, y, z and w)" endheading heading text=" y -> y + 0.1*(Quadratic in x, y, z and w)" endheading heading text=" z -> z + 0.1*(Quadratic in x, y, z and w)" endheading heading text=" w -> w + 0.1*(Quadratic in x, y, z and w)" endheading int param v_trapshapesprott4d_ode caption = "Version (Trap Shape Sprott4D_ODE)" 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_trapshapesprott4D_ode < 100 endparam param sel caption = "Sprott selector" default = 0 enum = "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" \ "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" \ "21" "22" "23" "24" "25" "26" "27" "28" "29" "30" \ "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" \ "41" "42" "43" "44" "45" "46" "47" "48" "49" "50" \ "51" "52" "53" "54" "55" "56" "57" "58" "59" "60" \ "61" "62" "63" "64" "65" "66" "67" "68" "69" "70" \ "71" "72" "73" "74" "75" "76" "77" "78" "79" "80" \ "81" "82" "83" "84" "85" "86" "87" "88" "89" "90" hint = "Each Sprott selector uses a different strange attractor." endparam heading text = "'Initialize Height' sets the starting z value for the attractor." endheading float param ppz caption = "Initialize Height" default = 0.0 endparam heading text = "'Initialize 4th dim' sets the starting w value for the attractor." endheading float param ppw caption = "Initialize 4th dim" default = 0.0 endparam heading text = "'Height weight' determines the weight of the final z value which is added \ to the trap distance." endheading complex param pw caption = "Height weight" default = (0,0) endparam heading text = "'4D weight' determines the weight of the final w value which is added \ to the trap distance." endheading complex param p4 caption = "4D weight" default = (0,0) endparam float param distscale caption = "Distance scale" default = 1 endparam float param s caption = "Attractor scale" default = 0.5 endparam int param max_att_iterations caption = "Attractor iterations" default = 100 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeSprott3D_ODE(common.ulb:TrapShape) { ; This shape uses a Sprott strange attractor.
;

; The Sprott attractors were developed by Julien C. Sprott, and are ; based upon polynomials and linear differential equations of polynomials. public: import "common.ulb" ; Constructor func REB_TrapShapeSprott3D_ODE(Generic pparent) TrapShape.TrapShape(pparent) so[0,1]=-1.2,so[0,2]=-0.7,so[0,3]=0.9,so[0,4]=0.5,so[0,5]=0.9,so[0,6]=-0.1,so[0,7]=-0.2,so[0,8]=-0.5,so[0,9]=-1.1,so[0,10]=0.5,so[0,11]=-1.0,so[0,12]=1.0,so[0,13]=-0.8,so[0,14]=0.6 so[0,15]=0.6,so[0,16]=1.2,so[0,17]=-0.1,so[0,18]=1.1,so[0,19]=1.1,so[0,20]=0.6,so[0,21]=0.3,so[0,22]=0.6,so[0,23]=-1.1,so[0,24]=-0.7,so[0,25]=-0.1,so[0,26]=-1.0,so[0,27]=-0.2,so[0,28]=-0.2,so[0,29]=-0.1,so[0,30]=0.1 so[1,1]=1.0,so[1,2]=-1.1,so[1,3]=-0.6,so[1,4]=-1.0,so[1,5]=0.2,so[1,6]=0.4,so[1,7]=1.0,so[1,8]=0.8,so[1,9]=0.5,so[1,10]=-0.8,so[1,11]=0.1,so[1,12]=-0.1,so[1,13]=-1.2,so[1,14]=-0.9 so[1,15]=0.3,so[1,16]=1.0,so[1,17]=-0.9,so[1,18]=-0.5,so[1,19]=1.1,so[1,20]=1.0,so[1,21]=0.1,so[1,22]=-1.0,so[1,23]=1.0,so[1,24]=-0.9,so[1,25]=-0.4,so[1,26]=-0.6,so[1,27]=0.3,so[1,28]=-0.6,so[1,29]=0.1,so[1,30]=0.7 so[2,1]=-1.0,so[2,2]=-0.3,so[2,3]=0.2,so[2,4]=-0.9,so[2,5]=0.7,so[2,6]=-0.1,so[2,7]=0.3,so[2,8]=1.1,so[2,9]=-0.8,so[2,10]=-0.5,so[2,11]=-1.1,so[2,12]=1.2,so[2,13]=-1.0,so[2,14]=-0.6 so[2,15]=0.6,so[2,16]=1.2,so[2,17]=-0.1,so[2,18]=0.5,so[2,19]=0.5,so[2,20]=0.8,so[2,21]=-1.2,so[2,22]=-0.8,so[2,23]=-1.1,so[2,24]=1.1,so[2,25]=0.7,so[2,26]=0.5,so[2,27]=0.0,so[2,28]=-1.1,so[2,29]=-0.5,so[2,30]=0.6 so[3,1]=-0.8,so[3,2]=-0.5,so[3,3]=0.5,so[3,4]=0.2,so[3,5]=0.2,so[3,6]=-1.1,so[3,7]=-0.8,so[3,8]=-1.0,so[3,9]=-1.1,so[3,10]=0.4,so[3,11]=-1.0,so[3,12]=-0.3,so[3,13]=0.6,so[3,14]=1.1 so[3,15]=0.7,so[3,16]=0.4,so[3,17]=0.1,so[3,18]=1.0,so[3,19]=1.0,so[3,20]=-0.7,so[3,21]=1.1,so[3,22]=-1.0,so[3,23]=-0.9,so[3,24]=-0.9,so[3,25]=-0.7,so[3,26]=-0.3,so[3,27]=-0.2,so[3,28]=-0.3,so[3,29]=-1.0,so[3,30]=0.1 so[4,1]=-0.3,so[4,2]=-0.9,so[4,3]=1.2,so[4,4]=0.1,so[4,5]=1.1,so[4,6]=-1.1,so[4,7]=-0.1,so[4,8]=0.4,so[4,9]=0.4,so[4,10]=-0.6,so[4,11]=0.8,so[4,12]=-0.2,so[4,13]=-0.1,so[4,14]=1.0 so[4,15]=-1.1,so[4,16]=0.3,so[4,17]=-0.5,so[4,18]=-1.0,so[4,19]=1.2,so[4,20]=0.1,so[4,21]=-0.7,so[4,22]=0.1,so[4,23]=-0.3,so[4,24]=0.1,so[4,25]=0.6,so[4,26]=0.6,so[4,27]=0.7,so[4,28]=1.1,so[4,29]=-0.8,so[4,30]=-0.4 so[5,1]=-1.1,so[5,2]=0.1,so[5,3]=0.9,so[5,4]=0.1,so[5,5]=0.2,so[5,6]=0.6,so[5,7]=0.2,so[5,8]=0.0,so[5,9]=-0.2,so[5,10]=-0.2,so[5,11]=-0.3,so[5,12]=-1.1,so[5,13]=0.6,so[5,14]=0.8 so[5,15]=-0.1,so[5,16]=-0.1,so[5,17]=0.3,so[5,18]=0.2,so[5,19]=0.8,so[5,20]=-0.7,so[5,21]=0.6,so[5,22]=-1.1,so[5,23]=0.8,so[5,24]=-0.9,so[5,25]=0.1,so[5,26]=0.1,so[5,27]=-0.4,so[5,28]=0.8,so[5,29]=-0.7,so[5,30]=0.6 so[6,1]=0.7,so[6,2]=-0.2,so[6,3]=-1.2,so[6,4]=0.4,so[6,5]=0.3,so[6,6]=-1.0,so[6,7]=0.2,so[6,8]=-1.0,so[6,9]=-1.2,so[6,10]=1.2,so[6,11]=0.5,so[6,12]=0.8,so[6,13]=-1.1,so[6,14]=-0.6 so[6,15]=-0.3,so[6,16]=0.4,so[6,17]=-0.2,so[6,18]=-0.1,so[6,19]=-1.2,so[6,20]=0.1,so[6,21]=0.1,so[6,22]=0.8,so[6,23]=1.1,so[6,24]=0.5,so[6,25]=1.0,so[6,26]=0.0,so[6,27]=-0.8,so[6,28]=-0.3,so[6,29]=-0.6,so[6,30]=0.4 so[7,1]=0.3,so[7,2]=0.1,so[7,3]=0.6,so[7,4]=-0.5,so[7,5]=0.2,so[7,6]=0.5,so[7,7]=1.2,so[7,8]=0.0,so[7,9]=-0.1,so[7,10]=-1.1,so[7,11]=0.9,so[7,12]=-0.9,so[7,13]=-1.0,so[7,14]=0.0 so[7,15]=0.3,so[7,16]=-1.2,so[7,17]=0.7,so[7,18]=1.0,so[7,19]=0.9,so[7,20]=0.2,so[7,21]=-0.5,so[7,22]=-0.1,so[7,23]=0.6,so[7,24]=0.0,so[7,25]=1.1,so[7,26]=-1.2,so[7,27]=-0.8,so[7,28]=0.9,so[7,29]=1.2,so[7,30]=-0.4 so[8,1]=-0.3,so[8,2]=0.4,so[8,3]=0.3,so[8,4]=-1.1,so[8,5]=1.0,so[8,6]=0.7,so[8,7]=0.8,so[8,8]=0.2,so[8,9]=0.4,so[8,10]=-0.9,so[8,11]=0.1,so[8,12]=-0.6,so[8,13]=1.1,so[8,14]=-0.3 so[8,15]=0.2,so[8,16]=0.2,so[8,17]=-0.4,so[8,18]=0.5,so[8,19]=0.9,so[8,20]=-0.3,so[8,21]=1.0,so[8,22]=-0.7,so[8,23]=1.0,so[8,24]=-0.5,so[8,25]=0.0,so[8,26]=-1.2,so[8,27]=-0.6,so[8,28]=0.5,so[8,29]=-0.8,so[8,30]=0.5 so[9,1]=0.7,so[9,2]=0.2,so[9,3]=0.5,so[9,4]=-0.6,so[9,5]=0.4,so[9,6]=0.8,so[9,7]=1.1,so[9,8]=-0.8,so[9,9]=-1.2,so[9,10]=-1.0,so[9,11]=-0.5,so[9,12]=0.4,so[9,13]=0.8,so[9,14]=-0.1 so[9,15]=-0.2,so[9,16]=-0.5,so[9,17]=-0.6,so[9,18]=-0.4,so[9,19]=-0.3,so[9,20]=0.7,so[9,21]=0.6,so[9,22]=1.1,so[9,23]=0.3,so[9,24]=0.6,so[9,25]=0.0,so[9,26]=-1.2,so[9,27]=-0.5,so[9,28]=-0.9,so[9,29]=-1.1,so[9,30]=0.8 so[10,1]=-0.1,so[10,2]=-1.0,so[10,3]=-0.4,so[10,4]=-0.5,so[10,5]=1.0,so[10,6]=-0.6,so[10,7]=1.1,so[10,8]=1.2,so[10,9]=-0.9,so[10,10]=-0.4,so[10,11]=-1.2,so[10,12]=0.7,so[10,13]=-0.1,so[10,14]=0.8 so[10,15]=-0.5,so[10,16]=-0.8,so[10,17]=-0.9,so[10,18]=-0.9,so[10,19]=0.6,so[10,20]=1.1,so[10,21]=0.0,so[10,22]=1.0,so[10,23]=0.3,so[10,24]=-0.9,so[10,25]=0.5,so[10,26]=-1.1,so[10,27]=-0.3,so[10,28]=-0.8,so[10,29]=-0.9,so[10,30]=-0.6 so[11,1]=0.4,so[11,2]=-1.0,so[11,3]=0.8,so[11,4]=1.0,so[11,5]=1.1,so[11,6]=-0.5,so[11,7]=-0.1,so[11,8]=-0.8,so[11,9]=-1.1,so[11,10]=-0.4,so[11,11]=0.5,so[11,12]=-0.6,so[11,13]=-0.2,so[11,14]=-0.5 so[11,15]=-0.3,so[11,16]=-0.7,so[11,17]=0.3,so[11,18]=1.2,so[11,19]=1.2,so[11,20]=0.1,so[11,21]=1.2,so[11,22]=0.1,so[11,23]=-0.5,so[11,24]=0.3,so[11,25]=-0.9,so[11,26]=0.2,so[11,27]=-1.2,so[11,28]=-0.8,so[11,29]=0.3,so[11,30]=1.0 so[12,1]=-0.3,so[12,2]=-0.4,so[12,3]=-0.2,so[12,4]=-0.8,so[12,5]=-0.2,so[12,6]=-0.1,so[12,7]=-0.4,so[12,8]=0.2,so[12,9]=0.3,so[12,10]=0.4,so[12,11]=0.8,so[12,12]=1.0,so[12,13]=-0.5,so[12,14]=-0.5,so[12,15]=-0.7 so[12,16]=-1.1,so[12,17]=-0.1,so[12,18]=-0.1,so[12,19]=-1.1,so[12,20]=0.5,so[12,21]=-0.2,so[12,22]=0.0,so[12,23]=-0.5,so[12,24]=-1.0,so[12,25]=-0.6,so[12,26]=1.1,so[12,27]=0.2,so[12,28]=-0.1,so[12,29]=-0.6,so[12,30]=0.3 so[13,1]=-0.5,so[13,2]=0.2,so[13,3]=0.3,so[13,4]=0.2,so[13,5]=-0.5,so[13,6]=-1.0,so[13,7]=1.1,so[13,8]=0.6,so[13,9]=-0.1,so[13,10]=-1.2,so[13,11]=0.3,so[13,12]=-0.9,so[13,13]=-1.2,so[13,14]=-1.2,so[13,15]=0.7 so[13,16]=0.1,so[13,17]=1.1,so[13,18]=0.3,so[13,19]=1.1,so[13,20]=-0.9,so[13,21]=-0.3,so[13,22]=1.0,so[13,23]=0.4,so[13,24]=1.0,so[13,25]=0.8,so[13,26]=-0.4,so[13,27]=0.7,so[13,28]=0.1,so[13,29]=-0.2,so[13,30]=-0.5 so[14,1]=0.4,so[14,2]=0.7,so[14,3]=0.9,so[14,4]=0.3,so[14,5]=-1.1,so[14,6]=0.9,so[14,7]=0.5,so[14,8]=0.7,so[14,9]=0.9,so[14,10]=-1.2,so[14,11]=-0.2,so[14,12]=-0.8,so[14,13]=-0.9,so[14,14]=0.7,so[14,15]=0.6 so[14,16]=0.1,so[14,17]=-1.1,so[14,18]=-0.5,so[14,19]=-0.3,so[14,20]=0.6,so[14,21]=0.5,so[14,22]=1.2,so[14,23]=-1.0,so[14,24]=0.0,so[14,25]=0.9,so[14,26]=-1.1,so[14,27]=-0.2,so[14,28]=0.2,so[14,29]=-0.7,so[14,30]=0.9 so[15,1]=0.4,so[15,2]=0.5,so[15,3]=-0.6,so[15,4]=0.3,so[15,5]=-0.1,so[15,6]=-0.6,so[15,7]=1.0,so[15,8]=0.2,so[15,9]=0.7,so[15,10]=-0.3,so[15,11]=-0.9,so[15,12]=1.1,so[15,13]=1.2,so[15,14]=0.5,so[15,15]=0.1 so[15,16]=-0.7,so[15,17]=0.6,so[15,18]=0.4,so[15,19]=-1.1,so[15,20]=-1.1,so[15,21]=1.0,so[15,22]=-0.8,so[15,23]=-0.8,so[15,24]=0.6,so[15,25]=-0.5,so[15,26]=-0.7,so[15,27]=-0.6,so[15,28]=0.9,so[15,29]=0.9,so[15,30]=0.4 so[16,1]=0.3,so[16,2]=-1.1,so[16,3]=0.4,so[16,4]=0.2,so[16,5]=-0.5,so[16,6]=0.9,so[16,7]=-0.2,so[16,8]=-1.1,so[16,9]=0.9,so[16,10]=-0.7,so[16,11]=-1.0,so[16,12]=-1.0,so[16,13]=1.2,so[16,14]=0.6,so[16,15]=0.9 so[16,16]=0.0,so[16,17]=-0.9,so[16,18]=-0.9,so[16,19]=0.0,so[16,20]=-0.3,so[16,21]=-1.1,so[16,22]=1.1,so[16,23]=0.2,so[16,24]=0.1,so[16,25]=0.2,so[16,26]=-0.7,so[16,27]=-0.1,so[16,28]=-1.0,so[16,29]=0.3,so[16,30]=-0.7 so[17,1]=-1.1,so[17,2]=-0.2,so[17,3]=-0.5,so[17,4]=1.0,so[17,5]=0.6,so[17,6]=0.0,so[17,7]=0.4,so[17,8]=-1.2,so[17,9]=-1.1,so[17,10]=0.1,so[17,11]=0.4,so[17,12]=1.2,so[17,13]=-1.0,so[17,14]=-0.1,so[17,15]=0.8 so[17,16]=0.1,so[17,17]=0.4,so[17,18]=-0.2,so[17,19]=0.7,so[17,20]=-0.8,so[17,21]=-0.9,so[17,22]=0.9,so[17,23]=-0.6,so[17,24]=0.8,so[17,25]=-0.5,so[17,26]=0.4,so[17,27]=0.9,so[17,28]=-0.5,so[17,29]=0.3,so[17,30]=-0.1 so[18,1]=-0.4,so[18,2]=-0.2,so[18,3]=0.7,so[18,4]=1.2,so[18,5]=0.8,so[18,6]=-1.2,so[18,7]=1.0,so[18,8]=-0.9,so[18,9]=-0.9,so[18,10]=-1.1,so[18,11]=-0.7,so[18,12]=0.0,so[18,13]=0.2,so[18,14]=-0.5,so[18,15]=0.8 so[18,16]=-1.0,so[18,17]=-0.9,so[18,18]=0.3,so[18,19]=-0.4,so[18,20]=1.2,so[18,21]=1.2,so[18,22]=1.2,so[18,23]=-0.3,so[18,24]=0.3,so[18,25]=0.5,so[18,26]=-0.5,so[18,27]=1.0,so[18,28]=0.5,so[18,29]=-0.9,so[18,30]=0.1 so[19,1]=-0.8,so[19,2]=0.9,so[19,3]=0.2,so[19,4]=-0.8,so[19,5]=0.4,so[19,6]=-0.8,so[19,7]=0.6,so[19,8]=0.1,so[19,9]=1.1,so[19,10]=0.6,so[19,11]=0.4,so[19,12]=0.8,so[19,13]=-0.2,so[19,14]=-0.6,so[19,15]=0.3 so[19,16]=-1.0,so[19,17]=-0.9,so[19,18]=-1.1,so[19,19]=-0.5,so[19,20]=0.9,so[19,21]=-0.8,so[19,22]=-1.2,so[19,23]=-1.2,so[19,24]=-0.9,so[19,25]=-1.2,so[19,26]=-0.2,so[19,27]=1.2,so[19,28]=0.8,so[19,29]=0.5,so[19,30]=0.7 so[20,1]=0.7,so[20,2]=-1.0,so[20,3]=-0.3,so[20,4]=0.5,so[20,5]=0.1,so[20,6]=0.3,so[20,7]=-0.7,so[20,8]=1.1,so[20,9]=-1.2,so[20,10]=-0.3,so[20,11]=1.2,so[20,12]=1.2,so[20,13]=-0.7,so[20,14]=1.0,so[20,15]=0.8 so[20,16]=-0.5,so[20,17]=1.0,so[20,18]=-0.6,so[20,19]=0.4,so[20,20]=-1.1,so[20,21]=-0.4,so[20,22]=1.1,so[20,23]=-1.2,so[20,24]=0.7,so[20,25]=0.9,so[20,26]=1.2,so[20,27]=1.0,so[20,28]=0.1,so[20,29]=0.3,so[20,30]=-0.6 so[21,1]=-0.7,so[21,2]=0.7,so[21,3]=0.8,so[21,4]=0.2,so[21,5]=1.0,so[21,6]=-0.8,so[21,7]=0.6,so[21,8]=-1.1,so[21,9]=-0.8,so[21,10]=1.1,so[21,11]=0.0,so[21,12]=1.1,so[21,13]=0.9,so[21,14]=0.9,so[21,15]=0.9 so[21,16]=0.1,so[21,17]=-0.6,so[21,18]=0.9,so[21,19]=0.1,so[21,20]=1.2,so[21,21]=0.5,so[21,22]=1.0,so[21,23]=1.2,so[21,24]=0.4,so[21,25]=-0.5,so[21,26]=0.9,so[21,27]=-0.5,so[21,28]=-1.0,so[21,29]=-0.3,so[21,30]=0.0 so[22,1]=0.2,so[22,2]=-0.3,so[22,3]=-0.8,so[22,4]=-0.4,so[22,5]=-0.1,so[22,6]=1.1,so[22,7]=0.1,so[22,8]=1.0,so[22,9]=0.1,so[22,10]=-1.1,so[22,11]=-1.1,so[22,12]=0.0,so[22,13]=0.8,so[22,14]=-0.3,so[22,15]=-0.8 so[22,16]=-0.9,so[22,17]=-0.1,so[22,18]=-0.5,so[22,19]=-1.1,so[22,20]=1.0,so[22,21]=-0.7,so[22,22]=0.0,so[22,23]=0.3,so[22,24]=-0.6,so[22,25]=0.0,so[22,26]=0.6,so[22,27]=-0.1,so[22,28]=-1.1,so[22,29]=-0.8,so[22,30]=-0.4 so[23,1]=-1.2,so[23,2]=0.5,so[23,3]=-0.5,so[23,4]=0.0,so[23,5]=0.4,so[23,6]=0.7,so[23,7]=0.3,so[23,8]=-0.3,so[23,9]=0.5,so[23,10]=1.0,so[23,11]=-0.7,so[23,12]=0.5,so[23,13]=0.1,so[23,14]=-1.2,so[23,15]=0.2 so[23,16]=-0.3,so[23,17]=0.8,so[23,18]=0.4,so[23,19]=-0.3,so[23,20]=-0.6,so[23,21]=1.1,so[23,22]=-1.0,so[23,23]=0.2,so[23,24]=0.9,so[23,25]=-0.4,so[23,26]=1.2,so[23,27]=-0.6,so[23,28]=1.2,so[23,29]=0.5,so[23,30]=0.8 so[24,1]=-1.1,so[24,2]=0.3,so[24,3]=0.4,so[24,4]=0.5,so[24,5]=0.7,so[24,6]=0.4,so[24,7]=0.8,so[24,8]=0.4,so[24,9]=0.4,so[24,10]=-0.7,so[24,11]=-0.7,so[24,12]=0.5,so[24,13]=-1.1,so[24,14]=0.3,so[24,15]=0.6 so[24,16]=-0.6,so[24,17]=-0.2,so[24,18]=0.9,so[24,19]=-1.2,so[24,20]=-0.6,so[24,21]=0.5,so[24,22]=-0.8,so[24,23]=1.1,so[24,24]=0.3,so[24,25]=0.9,so[24,26]=1.2,so[24,27]=-0.1,so[24,28]=0.9,so[24,29]=-0.6,so[24,30]=-0.9 so[25,1]=-0.3,so[25,2]=-0.1,so[25,3]=0.2,so[25,4]=0.9,so[25,5]=1.1,so[25,6]=1.1,so[25,7]=0.0,so[25,8]=0.2,so[25,9]=0.3,so[25,10]=0.3,so[25,11]=0.6,so[25,12]=-0.9,so[25,13]=0.1,so[25,14]=-1.0,so[25,15]=0.2 so[25,16]=0.6,so[25,17]=-0.3,so[25,18]=1.2,so[25,19]=0.8,so[25,20]=0.7,so[25,21]=0.3,so[25,22]=1.2,so[25,23]=-0.6,so[25,24]=-1.2,so[25,25]=-0.1,so[25,26]=0.6,so[25,27]=0.9,so[25,28]=-1.0,so[25,29]=-1.1,so[25,30]=0.0 so[26,1]=1.1,so[26,2]=-0.1,so[26,3]=-0.4,so[26,4]=-1.2,so[26,5]=0.6,so[26,6]=0.9,so[26,7]=-1.1,so[26,8]=-1.0,so[26,9]=-0.9,so[26,10]=0.6,so[26,11]=1.1,so[26,12]=0.9,so[26,13]=0.0,so[26,14]=1.2,so[26,15]=1.2 so[26,16]=0.2,so[26,17]=-0.1,so[26,18]=0.9,so[26,19]=0.3,so[26,20]=-1.0,so[26,21]=0.0,so[26,22]=1.1,so[26,23]=-0.2,so[26,24]=0.9,so[26,25]=-1.2,so[26,26]=0.2,so[26,27]=0.8,so[26,28]=-1.2,so[26,29]=-0.9,so[26,30]=0.7 so[27,1]=-0.6,so[27,2]=-1.2,so[27,3]=0.5,so[27,4]=-0.9,so[27,5]=-1.0,so[27,6]=-0.8,so[27,7]=-0.4,so[27,8]=-0.9,so[27,9]=0.0,so[27,10]=-1.0,so[27,11]=-0.8,so[27,12]=-0.6,so[27,13]=0.3,so[27,14]=1.0,so[27,15]=-1.2 so[27,16]=-0.4,so[27,17]=-1.1,so[27,18]=-0.1,so[27,19]=1.1,so[27,20]=0.7,so[27,21]=-0.2,so[27,22]=1.0,so[27,23]=0.2,so[27,24]=0.8,so[27,25]=0.7,so[27,26]=-1.1,so[27,27]=1.2,so[27,28]=-1.0,so[27,29]=0.9,so[27,30]=-0.4 so[28,1]=-0.2,so[28,2]=-1.0,so[28,3]=0.8,so[28,4]=0.5,so[28,5]=-1.0,so[28,6]=0.6,so[28,7]=0.9,so[28,8]=-0.2,so[28,9]=0.1,so[28,10]=-1.1,so[28,11]=-1.2,so[28,12]=-0.5,so[28,13]=0.7,so[28,14]=-0.1,so[28,15]=-0.4 so[28,16]=-0.4,so[28,17]=-0.4,so[28,18]=-0.7,so[28,19]=0.9,so[28,20]=0.3,so[28,21]=-1.2,so[28,22]=-0.4,so[28,23]=-0.1,so[28,24]=1.2,so[28,25]=1.0,so[28,26]=-1.2,so[28,27]=1.2,so[28,28]=-0.8,so[28,29]=-0.5,so[28,30]=0.4 so[29,1]=-1.0,so[29,2]=-1.1,so[29,3]=0.5,so[29,4]=-0.2,so[29,5]=1.0,so[29,6]=0.0,so[29,7]=0.1,so[29,8]=1.0,so[29,9]=-0.9,so[29,10]=0.4,so[29,11]=-0.6,so[29,12]=-1.2,so[29,13]=-0.9,so[29,14]=-1.2,so[29,15]=0.9 so[29,16]=1.1,so[29,17]=0.9,so[29,18]=-0.5,so[29,19]=-0.3,so[29,20]=-1.0,so[29,21]=-0.3,so[29,22]=0.9,so[29,23]=-0.5,so[29,24]=-1.1,so[29,25]=-1.2,so[29,26]=-0.7,so[29,27]=0.7,so[29,28]=1.2,so[29,29]=1.0,so[29,30]=-0.7 so[30,1]=-1.0,so[30,2]=0.9,so[30,3]=0.4,so[30,4]=1.1,so[30,5]=-1.1,so[30,6]=-0.9,so[30,7]=0.8,so[30,8]=0.4,so[30,9]=1.1,so[30,10]=0.0,so[30,11]=-0.5,so[30,12]=-0.5,so[30,13]=-0.3,so[30,14]=-1.2,so[30,15]=0.9 so[30,16]=-1.2,so[30,17]=-0.8,so[30,18]=1.1,so[30,19]=-1.0,so[30,20]=0.7,so[30,21]=-1.0,so[30,22]=1.0,so[30,23]=0.5,so[30,24]=-0.8,so[30,25]=1.1,so[30,26]=1.2,so[30,27]=-0.1,so[30,28]=0.8,so[30,29]=-1.2,so[30,30]=-0.8 so[31,1]=0.1,so[31,2]=0.7,so[31,3]=-0.8,so[31,4]=-1.2,so[31,5]=1.2,so[31,6]=0.8,so[31,7]=-0.3,so[31,8]=0.6,so[31,9]=0.8,so[31,10]=-0.2,so[31,11]=0.9,so[31,12]=-1.1,so[31,13]=-1.0,so[31,14]=0.4,so[31,15]=1.0 so[31,16]=-0.3,so[31,17]=-0.1,so[31,18]=-1.0,so[31,19]=0.0,so[31,20]=0.8,so[31,21]=-0.9,so[31,22]=-0.4,so[31,23]=-0.5,so[31,24]=-0.1,so[31,25]=0.7,so[31,26]=0.1,so[31,27]=0.7,so[31,28]=-0.5,so[31,29]=-0.3,so[31,30]=-1.0 so[32,1]=1.1,so[32,2]=-0.6,so[32,3]=-1.1,so[32,4]=-0.2,so[32,5]=-0.7,so[32,6]=0.7,so[32,7]=0.3,so[32,8]=0.9,so[32,9]=-0.4,so[32,10]=-0.4,so[32,11]=-0.3,so[32,12]=-0.7,so[32,13]=0.7,so[32,14]=0.0,so[32,15]=-0.8 so[32,16]=0.7,so[32,17]=0.1,so[32,18]=-1.0,so[32,19]=-0.5,so[32,20]=0.2,so[32,21]=-0.6,so[32,22]=0.3,so[32,23]=0.8,so[32,24]=-0.3,so[32,25]=0.7,so[32,26]=-0.1,so[32,27]=1.1,so[32,28]=0.8,so[32,29]=0.7,so[32,30]=-0.2 so[33,1]=0.9,so[33,2]=1.1,so[33,3]=0.8,so[33,4]=-0.7,so[33,5]=-0.5,so[33,6]=0.6,so[33,7]=-0.8,so[33,8]=0.3,so[33,9]=1.0,so[33,10]=-0.7,so[33,11]=0.5,so[33,12]=0.7,so[33,13]=0.6,so[33,14]=0.5,so[33,15]=0.5,so[33,16]=-1.0,so[33,17]=0.5,so[33,18]=-0.5,so[33,19]=-1.1,so[33,20]=-0.5,so[33,21]=0.7,so[33,22]=0.9,so[33,23]=-0.2,so[33,24]=-1.0,so[33,25]=1.2,so[33,26]=1.2,so[33,27]=1.2,so[33,28]=0.7,so[33,29]=-0.4,so[33,30]=-1.0 so[34,1]=-0.9,so[34,2]=-0.6,so[34,3]=-0.9,so[34,4]=1.0,so[34,5]=-0.9,so[34,6]=0.8,so[34,7]=1.1,so[34,8]=-1.2,so[34,9]=0.4,so[34,10]=-0.8,so[34,11]=1.0,so[34,12]=-0.4,so[34,13]=-1.1,so[34,14]=-1.1,so[34,15]=0.4,so[34,16]=-0.3,so[34,17]=0.3,so[34,18]=-0.7,so[34,19]=0.1,so[34,20]=0.0,so[34,21]=0.0,so[34,22]=-0.2,so[34,23]=0.6,so[34,24]=0.3,so[34,25]=0.9,so[34,26]=1.0,so[34,27]=0.8,so[34,28]=1.1,so[34,29]=-1.1,so[34,30]=0.2 so[35,1]=-0.3,so[35,2]=-1.1,so[35,3]=0.1,so[35,4]=0.9,so[35,5]=0.0,so[35,6]=-0.2,so[35,7]=-1.1,so[35,8]=-0.4,so[35,9]=0.9,so[35,10]=0.8,so[35,11]=0.3,so[35,12]=1.2,so[35,13]=0.5,so[35,14]=0.4,so[35,15]=0.1,so[35,16]=0.1,so[35,17]=-0.1,so[35,18]=-0.9,so[35,19]=1.1,so[35,20]=0.3,so[35,21]=0.1,so[35,22]=0.1,so[35,23]=0.4,so[35,24]=0.8,so[35,25]=-0.4,so[35,26]=-1.0,so[35,27]=0.0,so[35,28]=1.0,so[35,29]=0.0,so[35,30]=-0.4 so[36,1]=0.3,so[36,2]=0.6,so[36,3]=0.5,so[36,4]=-0.9,so[36,5]=-0.6,so[36,6]=-1.0,so[36,7]=0.6,so[36,8]=1.1,so[36,9]=-1.2,so[36,10]=-1.1,so[36,11]=-0.1,so[36,12]=0.9,so[36,13]=0.8,so[36,14]=1.1,so[36,15]=0.3,so[36,16]=0.0,so[36,17]=-0.2,so[36,18]=0.8,so[36,19]=0.0,so[36,20]=1.0,so[36,21]=0.1,so[36,22]=0.0,so[36,23]=0.1,so[36,24]=-0.9,so[36,25]=1.0,so[36,26]=-0.1,so[36,27]=-0.6,so[36,28]=-0.7,so[36,29]=-0.2,so[36,30]=1.2 so[37,1]=0.1,so[37,2]=-0.4,so[37,3]=-0.3,so[37,4]=0.7,so[37,5]=-0.7,so[37,6]=-0.2,so[37,7]=0.3,so[37,8]=-1.2,so[37,9]=1.0,so[37,10]=-0.3,so[37,11]=0.4,so[37,12]=-0.3,so[37,13]=-0.7,so[37,14]=0.0,so[37,15]=0.4,so[37,16]=0.5,so[37,17]=0.9,so[37,18]=-0.7,so[37,19]=0.8,so[37,20]=-0.8,so[37,21]=-0.4,so[37,22]=-0.4,so[37,23]=-0.4,so[37,24]=0.8,so[37,25]=1.2,so[37,26]=-1.1,so[37,27]=-0.4,so[37,28]=0.6,so[37,29]=-0.4,so[37,30]=-0.7 so[38,1]=-0.3,so[38,2]=0.7,so[38,3]=0.0,so[38,4]=-0.1,so[38,5]=0.3,so[38,6]=0.3,so[38,7]=0.8,so[38,8]=-0.9,so[38,9]=0.4,so[38,10]=-0.8,so[38,11]=0.4,so[38,12]=-0.3,so[38,13]=-0.2,so[38,14]=-0.7,so[38,15]=0.5,so[38,16]=0.8,so[38,17]=-1.2,so[38,18]=-0.9,so[38,19]=1.0,so[38,20]=0.9,so[38,21]=-0.3,so[38,22]=0.4,so[38,23]=1.1,so[38,24]=-1.2,so[38,25]=-1.0,so[38,26]=0.2,so[38,27]=-1.0,so[38,28]=0.2,so[38,29]=-0.5,so[38,30]=1.1 so[39,1]=-1.1,so[39,2]=0.8,so[39,3]=0.8,so[39,4]=-0.4,so[39,5]=-0.6,so[39,6]=0.6,so[39,7]=-1.2,so[39,8]=-1.2,so[39,9]=0.6,so[39,10]=0.8,so[39,11]=-0.8,so[39,12]=-0.9,so[39,13]=0.0,so[39,14]=1.0,so[39,15]=0.3,so[39,16]=-0.1,so[39,17]=0.2,so[39,18]=1.2,so[39,19]=0.5,so[39,20]=0.9,so[39,21]=0.3,so[39,22]=0.6,so[39,23]=-0.2,so[39,24]=0.8,so[39,25]=-1.2,so[39,26]=-0.9,so[39,27]=-0.1,so[39,28]=-0.9,so[39,29]=-0.2,so[39,30]=0.6 so[40,1]=0.0,so[40,2]=0.3,so[40,3]=-1.0,so[40,4]=1.1,so[40,5]=-0.7,so[40,6]=-1.0,so[40,7]=-0.3,so[40,8]=0.3,so[40,9]=0.2,so[40,10]=-1.2,so[40,11]=-0.1,so[40,12]=0.0,so[40,13]=0.9,so[40,14]=0.7,so[40,15]=0.9,so[40,16]=-0.4,so[40,17]=0.1,so[40,18]=-0.5,so[40,19]=-1.0,so[40,20]=-0.7,so[40,21]=0.1,so[40,22]=-1.1,so[40,23]=-0.8,so[40,24]=-1.0,so[40,25]=-0.8,so[40,26]=1.2,so[40,27]=0.2,so[40,28]=1.0,so[40,29]=-0.6,so[40,30]=-1.0 so[41,1]=0.8,so[41,2]=-0.5,so[41,3]=0.9,so[41,4]=-1.1,so[41,5]=1.1,so[41,6]=-1.2,so[41,7]=-1.1,so[41,8]=-0.8,so[41,9]=0.1,so[41,10]=-0.4,so[41,11]=0.0,so[41,12]=0.5,so[41,13]=0.2,so[41,14]=-0.5,so[41,15]=-0.5,so[41,16]=1.0,so[41,17]=-0.7,so[41,18]=0.4,so[41,19]=1.2,so[41,20]=0.1,so[41,21]=0.8,so[41,22]=-0.8,so[41,23]=-0.4,so[41,24]=1.0,so[41,25]=-0.9,so[41,26]=-0.4,so[41,27]=-0.6,so[41,28]=0.3,so[41,29]=-0.8,so[41,30]=-0.3 so[42,1]=1.2,so[42,2]=-0.9,so[42,3]=0.0,so[42,4]=-0.4,so[42,5]=-1.1,so[42,6]=0.3,so[42,7]=-0.5,so[42,8]=0.4,so[42,9]=0.5,so[42,10]=0.3,so[42,11]=-1.0,so[42,12]=1.0,so[42,13]=0.4,so[42,14]=1.0,so[42,15]=0.7,so[42,16]=-0.7,so[42,17]=0.5,so[42,18]=0.6,so[42,19]=0.4,so[42,20]=0.6,so[42,21]=-0.2,so[42,22]=-0.9,so[42,23]=1.1,so[42,24]=-0.4,so[42,25]=-0.9,so[42,26]=0.5,so[42,27]=-0.4,so[42,28]=-0.5,so[42,29]=0.3,so[42,30]=-0.1 so[43,1]=1.0,so[43,2]=0.5,so[43,3]=-0.4,so[43,4]=-0.9,so[43,5]=0.8,so[43,6]=1.1,so[43,7]=-1.1,so[43,8]=-0.2,so[43,9]=0.6,so[43,10]=0.9,so[43,11]=-0.3,so[43,12]=0.4,so[43,13]=1.1,so[43,14]=1.0,so[43,15]=0.2,so[43,16]=-0.7,so[43,17]=-0.2,so[43,18]=0.8,so[43,19]=-1.0,so[43,20]=0.5,so[43,21]=1.1,so[43,22]=0.6,so[43,23]=0.1,so[43,24]=0.6,so[43,25]=-0.3,so[43,26]=1.0,so[43,27]=-0.2,so[43,28]=-1.0,so[43,29]=0.7,so[43,30]=-0.8 so[44,1]=-0.5,so[44,2]=-1.2,so[44,3]=0.3,so[44,4]=-1.2,so[44,5]=0.3,so[44,6]=-0.5,so[44,7]=1.2,so[44,8]=-1.0,so[44,9]=-0.4,so[44,10]=-0.5,so[44,11]=-1.2,so[44,12]=0.8,so[44,13]=1.2,so[44,14]=-0.5,so[44,15]=1.1,so[44,16]=0.4,so[44,17]=0.7,so[44,18]=0.9,so[44,19]=-0.9,so[44,20]=-0.9,so[44,21]=0.5,so[44,22]=-1.1,so[44,23]=0.4,so[44,24]=0.4,so[44,25]=0.5,so[44,26]=-0.1,so[44,27]=-1.2,so[44,28]=0.2,so[44,29]=-0.8,so[44,30]=-0.6 so[45,1]=0.0,so[45,2]=0.1,so[45,3]=1.2,so[45,4]=-0.4,so[45,5]=0.5,so[45,6]=0.4,so[45,7]=-1.1,so[45,8]=0.1,so[45,9]=-0.2,so[45,10]=0.0,so[45,11]=-1.1,so[45,12]=0.4,so[45,13]=0.7,so[45,14]=0.3,so[45,15]=-1.1,so[45,16]=0.5,so[45,17]=-1.2,so[45,18]=-1.0,so[45,19]=-1.1,so[45,20]=-1.2,so[45,21]=0.2,so[45,22]=0.8,so[45,23]=0.1,so[45,24]=0.0,so[45,25]=0.3,so[45,26]=0.5,so[45,27]=0.6,so[45,28]=0.2,so[45,29]=-0.7,so[45,30]=0.4 so[46,1]=1.2,so[46,2]=0.0,so[46,3]=0.7,so[46,4]=-0.7,so[46,5]=-0.9,so[46,6]=0.3,so[46,7]=-1.1,so[46,8]=1.1,so[46,9]=-0.2,so[46,10]=-0.4,so[46,11]=0.0,so[46,12]=-0.5,so[46,13]=0.8,so[46,14]=-1.2,so[46,15]=-1.1,so[46,16]=-0.2,so[46,17]=-0.5,so[46,18]=-0.1,so[46,19]=0.6,so[46,20]=-0.6,so[46,21]=-0.5,so[46,22]=0.7,so[46,23]=1.2,so[46,24]=0.8,so[46,25]=0.5,so[46,26]=0.0,so[46,27]=1.1,so[46,28]=0.8,so[46,29]=0.4,so[46,30]=-0.9 so[47,1]=-0.1,so[47,2]=-0.8,so[47,3]=0.4,so[47,4]=0.6,so[47,5]=-0.4,so[47,6]=1.1,so[47,7]=0.2,so[47,8]=-0.1,so[47,9]=-0.1,so[47,10]=1.2,so[47,11]=0.2,so[47,12]=-1.2,so[47,13]=1.1,so[47,14]=-1.2,so[47,15]=1.2,so[47,16]=-0.2,so[47,17]=0.7,so[47,18]=-0.3,so[47,19]=0.4,so[47,20]=-0.8,so[47,21]=-0.5,so[47,22]=0.4,so[47,23]=0.7,so[47,24]=0.4,so[47,25]=1.2,so[47,26]=-0.2,so[47,27]=1.0,so[47,28]=0.6,so[47,29]=0.4,so[47,30]=-0.3 so[48,1]=1.1,so[48,2]=-0.4,so[48,3]=0.4,so[48,4]=0.8,so[48,5]=0.0,so[48,6]=-0.4,so[48,7]=-1.1,so[48,8]=-1.1,so[48,9]=-0.2,so[48,10]=-1.2,so[48,11]=-0.3,so[48,12]=-0.7,so[48,13]=1.2,so[48,14]=0.4,so[48,15]=0.2,so[48,16]=0.0,so[48,17]=0.5,so[48,18]=-0.5,so[48,19]=0.9,so[48,20]=-0.9,so[48,21]=-0.5,so[48,22]=0.7,so[48,23]=0.7,so[48,24]=-1.0,so[48,25]=0.3,so[48,26]=-0.2,so[48,27]=0.2,so[48,28]=-1.0,so[48,29]=0.3,so[48,30]=-0.3 so[49,1]=1.2,so[49,2]=0.5,so[49,3]=-0.2,so[49,4]=-1.0,so[49,5]=-0.1,so[49,6]=-0.6,so[49,7]=0.3,so[49,8]=-0.1,so[49,9]=0.6,so[49,10]=-0.9,so[49,11]=-0.5,so[49,12]=-0.7,so[49,13]=0.7,so[49,14]=0.7,so[49,15]=1.1,so[49,16]=-1.2,so[49,17]=0.4,so[49,18]=-0.2,so[49,19]=-0.9,so[49,20]=0.4,so[49,21]=-0.4,so[49,22]=-0.7,so[49,23]=-0.5,so[49,24]=-1.1,so[49,25]=0.8,so[49,26]=-0.3,so[49,27]=0.9,so[49,28]=-1.1,so[49,29]=-0.4,so[49,30]=0.4 so[50,1]=-0.1,so[50,2]=0.3,so[50,3]=-0.1,so[50,4]=-0.5,so[50,5]=0.0,so[50,6]=0.9,so[50,7]=-0.7,so[50,8]=-0.5,so[50,9]=-1.2,so[50,10]=-0.2,so[50,11]=-1.0,so[50,12]=1.2,so[50,13]=0.9,so[50,14]=0.4,so[50,15]=0.2,so[50,16]=-0.9,so[50,17]=0.3,so[50,18]=0.7,so[50,19]=-0.4,so[50,20]=0.7,so[50,21]=-0.4,so[50,22]=1.2,so[50,23]=-0.2,so[50,24]=-1.2,so[50,25]=0.4,so[50,26]=-0.4,so[50,27]=0.4,so[50,28]=-1.0,so[50,29]=-0.3,so[50,30]=0.6 endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float ppz = @ppz float pxx = 0 float pyy = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x pyy = y x = x + 0.1*(so[@sd,1] + so[@sd,2]*x + so[@sd,3]*x*x + so[@sd,4]*x*y \ + so[@sd,5]*x*ppz + so[@sd,6]*y + so[@sd,7]*y*y + \ so[@sd,8]*y*ppz + so[@sd,9]*ppz + so[@sd,10]*ppz*ppz) y = y + 0.1*(so[@sd,11] + so[@sd,12]*pxx + so[@sd,13]*pxx*pxx + so[@sd,14]*pxx*y \ + so[@sd,15]*pxx*ppz + so[@sd,16]*y + so[@sd,17]*y*y + \ so[@sd,18]*y*ppz + so[@sd,19]*ppz + so[@sd,20]*ppz*ppz) ppz = ppz + 0.1*(so[@sd,21] + so[@sd,22]*pxx + so[@sd,23]*pxx*pxx + so[@sd,24]*pxx*pyy + \ so[@sd,25]*pxx*ppz + so[@sd,26]*pyy + so[@sd,27]*pyy*pyy + \ so[@sd,28]*pyy*ppz + so[@sd,29]*ppz + so[@sd,30]*ppz*ppz) att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y) + ppz*@pw) float d = @distscale*|pz-(x + sgn*flip(y) + ppz*@pw)| return d endfunc private: float so[51,31] default: title = "Sprott3D_ODE" heading text="Strange attractors from simultaneous ordinary differential \ equations using Euler's finite difference method to calculate." endheading heading text="Sprott 3D ODE quadratic attractors" endheading heading text=" x -> x + 0.1*(Quadratic in x, y and z)" endheading heading text=" y -> y + 0.1*(Quadratic in x, y and z)" endheading heading text=" z -> z + 0.1*(Quadratic in x, y and z)" endheading int param v_trapshapesprott3d_ode caption = "Version (Trap Shape Sprott3D_ODE)" default = 101 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_trapshapesprott3d_ode < 101 endparam param sd caption = "Sprott selector" default = 0 enum = "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" \ "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" \ "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" \ "45" "46" "47" "48" "49" "50" hint = "Each Sprott selector uses a different strange attractor." endparam heading text = "'Initialize Height' sets the starting z value for the attractor." endheading float param ppz caption = "Initialize Height" default = 0.5 endparam heading text = "'Height weight' determines the weight of the final z value which is added \ to the trap distance." endheading complex param pw caption = "Height weight" default = (0.5,0) endparam float param distscale caption = "Distance scale" default = 0.1 endparam float param s caption = "Attractor scale" default = 2.0 endparam int param max_att_iterations caption = "Attractor iterations" default = 50 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeSprottQuad(common.ulb:TrapShape) { ; This shape uses a Sprott strange attractor.
;

; The Sprott attractors were developed by Julien C. Sprott, and are ; based upon polynomials and linear differential equations of polynomials. public: import "common.ulb" ; Constructor func REB_TrapShapeSprottQuad(Generic pparent) TrapShape.TrapShape(pparent) qd[0,1]=1,qd[0,2]=-1.1,qd[0,3]=-0.2,qd[0,4]=-0.1,qd[0,5]=-0.4,qd[0,6]=0.1,qd[0,7]=-0.3,qd[0,8]=0.8,qd[0,9]=-0.1,qd[0,10]=0.3,qd[0,11]=-1,qd[0,12]=-0.9 qd[1,1]=0.9,qd[1,2]=-0.1,qd[1,3]=0.2,qd[1,4]=0.5,qd[1,5]=-0.6,qd[1,6]=-1.0,qd[1,7]=-0.9,qd[1,8]=-0.8,qd[1,9]=1.0,qd[1,10]=-0.2,qd[1,11]=0.4,qd[1,12]=-0.2 qd[2,1]=-0.8,qd[2,2]=1.1,qd[2,3]=0.5,qd[2,4]=1.1,qd[2,5]=1.1,qd[2,6]=1.1,qd[2,7]=-0.6,qd[2,8]=-0.1,qd[2,9]=-0.6,qd[2,10]=-0.1,qd[2,11]=0.2,qd[2,12]=0.5 qd[3,1]=-0.8,qd[3,2]=-0.7,qd[3,3]=0.4,qd[3,4]=0.8,qd[3,5]=0.4,qd[3,6]=1.1,qd[3,7]=0.9,qd[3,8]=0.9,qd[3,9]=0.4,qd[3,10]=0.6,qd[3,11]=0.9,qd[3,12]=0.1 qd[4,1]=0.9,qd[4,2]=0.5,qd[4,3]=-1.2,qd[4,4]=0.0,qd[4,5]=-0.3,qd[4,6]=0.0,qd[4,7]=0.2,qd[4,8]=0.4,qd[4,9]=0.9,qd[4,10]=-0.1,qd[4,11]=-1.1,qd[4,12]=-0.1 qd[5,1]=0.6,qd[5,2]=-0.1,qd[5,3]=-0.5,qd[5,4]=-1.2,qd[5,5]=-0.3,qd[5,6]=-0.6,qd[5,7]=0.8,qd[5,8]=0.4,qd[5,9]=-0.1,qd[5,10]=1.0,qd[5,11]=-0.8,qd[5,12]=-1.0 qd[6,1]=-0.8,qd[6,2]=0.5,qd[6,3]=0.5,qd[6,4]=-0.7,qd[6,5]=-0.9,qd[6,6]=1.0,qd[6,7]=-0.1,qd[6,8]=-0.4,qd[6,9]=1.1,qd[6,10]=-0.4,qd[6,11]=0.0,qd[6,12]=-0.3 qd[7,1]=-0.6,qd[7,2]=0.8,qd[7,3]=0.4,qd[7,4]=-0.8,qd[7,5]=-1.0,qd[7,6]=-1.1,qd[7,7]=-0.8,qd[7,8]=1.0,qd[7,9]=0.3,qd[7,10]=1.0,qd[7,11]=0.8,qd[7,12]=0.4 qd[8,1]=-0.9,qd[8,2]=-0.4,qd[8,3]=-1.1,qd[8,4]=-0.4,qd[8,5]=0.8,qd[8,6]=0.9,qd[8,7]=0.9,qd[8,8]=-0.2,qd[8,9]=-1.1,qd[8,10]=-0.7,qd[8,11]=-0.2,qd[8,12]=0.1 qd[9,1]=-0.2,qd[9,2]=0.8,qd[9,3]=-0.4,qd[9,4]=-0.3,qd[9,5]=-0.8,qd[9,6]=1.0,qd[9,7]=0.5,qd[9,8]=-0.9,qd[9,9]=0.9,qd[9,10]=-0.6,qd[9,11]=0.4,qd[9,12]=-0.3 qd[10,1]=0.7,qd[10,2]=-0.3,qd[10,3]=-1.1,qd[10,4]=0.5,qd[10,5]=0.3,qd[10,6]=-0.7,qd[10,7]=0.0,qd[10,8]=0.9,qd[10,9]=-0.4,qd[10,10]=0.3,qd[10,11]=0.7,qd[10,12]=0.2 qd[11,1]=1.1,qd[11,2]=-0.4,qd[11,3]=-0.1,qd[11,4]=-1.1,qd[11,5]=-0.8,qd[11,6]=-0.9,qd[11,7]=-0.7,qd[11,8]=-0.7,qd[11,9]=0.7,qd[11,10]=0.4,qd[11,11]=0.0,qd[11,12]=-0.1 qd[12,1]=-1.2,qd[12,2]=-0.1,qd[12,3]=-0.5,qd[12,4]=0.6,qd[12,5]=-1.0,qd[12,6]=-0.3,qd[12,7]=-0.6,qd[12,8]=-0.2,qd[12,9]=-0.8,qd[12,10]=-0.7,qd[12,11]=-0.4,qd[12,12]=0.1 qd[13,1]=0.2,qd[13,2]=1.0,qd[13,3]=-0.3,qd[13,4]=0.9,qd[13,5]=0.6,qd[13,6]=-0.5,qd[13,7]=0.6,qd[13,8]=1.0,qd[13,9]=-1.0,qd[13,10]=-0.1,qd[13,11]=-1.2,qd[13,12]=0.8 qd[14,1]=-0.6,qd[14,2]=-0.5,qd[14,3]=0.7,qd[14,4]=0.4,qd[14,5]=-0.7,qd[14,6]=-0.1,qd[14,7]=0.7,qd[14,8]=0.4,qd[14,9]=-0.7,qd[14,10]=1.0,qd[14,11]=0.1,qd[14,12]=-0.1 qd[15,1]=0.6,qd[15,2]=-0.3,qd[15,3]=-0.1,qd[15,4]=-1.1,qd[15,5]=-1.1,qd[15,6]=0.5,qd[15,7]=-0.1,qd[15,8]=0.1,qd[15,9]=0.7,qd[15,10]=0.9,qd[15,11]=-0.8,qd[15,12]=1.0 qd[16,1]=-0.4,qd[16,2]=-1.0,qd[16,3]=-0.7,qd[16,4]=-0.7,qd[16,5]=-1.1,qd[16,6]=-0.1,qd[16,7]=1.2,qd[16,8]=-0.5,qd[16,9]=-0.7,qd[16,10]=0.3,qd[16,11]=0.5,qd[16,12]=-0.6 qd[17,1]=-0.7,qd[17,2]=0.7,qd[17,3]=1.0,qd[17,4]=-0.5,qd[17,5]=0.7,qd[17,6]=0.3,qd[17,7]=0.8,qd[17,8]=-0.9,qd[17,9]=-0.8,qd[17,10]=-1.0,qd[17,11]=-0.6,qd[17,12]=-1.1 qd[18,1]=0.8,qd[18,2]=0.3,qd[18,3]=0.0,qd[18,4]=0.2,qd[18,5]=0.3,qd[18,6]=-0.8,qd[18,7]=-0.4,qd[18,8]=-1.2,qd[18,9]=-0.9,qd[18,10]=-1.1,qd[18,11]=-0.2,qd[18,12]=0.2 qd[19,1]=0.3,qd[19,2]=1.0,qd[19,3]=-0.4,qd[19,4]=0.9,qd[19,5]=0.3,qd[19,6]=-0.5,qd[19,7]=0.0,qd[19,8]=-1.0,qd[19,9]=-1.2,qd[19,10]=0.1,qd[19,11]=-0.9,qd[19,12]=0.0 qd[20,1]=1.2,qd[20,2]=-0.2,qd[20,3]=-0.9,qd[20,4]=1.1,qd[20,5]=0.5,qd[20,6]=-0.5,qd[20,7]=0.3,qd[20,8]=-0.5,qd[20,9]=-1.2,qd[20,10]=0.6,qd[20,11]=-0.1,qd[20,12]=-0.4 qd[21,1]=0.2,qd[21,2]=0.3,qd[21,3]=0.4,qd[21,4]=-0.1,qd[21,5]=1.2,qd[21,6]=-0.5,qd[21,7]=-0.4,qd[21,8]=-1.1,qd[21,9]=0.5,qd[21,10]=-1.2,qd[21,11]=1.2,qd[21,12]=0.3 qd[22,1]=1.1,qd[22,2]=0.4,qd[22,3]=-0.3,qd[22,4]=-0.2,qd[22,5]=0.4,qd[22,6]=-1.0,qd[22,7]=0.6,qd[22,8]=-0.4,qd[22,9]=-0.5,qd[22,10]=1.2,qd[22,11]=-0.9,qd[22,12]=1.0 qd[23,1]=-1.1,qd[23,2]=0.9,qd[23,3]=1.1,qd[23,4]=0.4,qd[23,5]=-1.2,qd[23,6]=1.0,qd[23,7]=0.3,qd[23,8]=0.3,qd[23,9]=0.3,qd[23,10]=-0.7,qd[23,11]=0.6,qd[23,12]=-0.9 qd[24,1]=-0.1,qd[24,2]=-0.4,qd[24,3]=-0.8,qd[24,4]=-0.8,qd[24,5]=0.9,qd[24,6]=-0.2,qd[24,7]=0.9,qd[24,8]=-0.2,qd[24,9]=-0.9,qd[24,10]=-0.9,qd[24,11]=-0.4,qd[24,12]=-1.2 qd[25,1]=-0.7,qd[25,2]=-0.2,qd[25,3]=-0.4,qd[25,4]=0.4,qd[25,5]=-0.9,qd[25,6]=0.9,qd[25,7]=0.3,qd[25,8]=-0.3,qd[25,9]=-1.1,qd[25,10]=-0.2,qd[25,11]=0.0,qd[25,12]=-0.4 qd[26,1]=-0.6,qd[26,2]=1.1,qd[26,3]=-0.2,qd[26,4]=0.7,qd[26,5]=-0.1,qd[26,6]=1.1,qd[26,7]=-1.2,qd[26,8]=0.0,qd[26,9]=1.1,qd[26,10]=0.3,qd[26,11]=0.7,qd[26,12]=0.8 qd[27,1]=0.1,qd[27,2]=-0.7,qd[27,3]=0.2,qd[27,4]=-0.2,qd[27,5]=0.1,qd[27,6]=1.2,qd[27,7]=-0.5,qd[27,8]=-0.9,qd[27,9]=0.5,qd[27,10]=0.4,qd[27,11]=-1.0,qd[27,12]=0.2 qd[28,1]=0.7,qd[28,2]=-0.6,qd[28,3]=-0.2,qd[28,4]=0.1,qd[28,5]=0.2,qd[28,6]=-0.2,qd[28,7]=-0.8,qd[28,8]=-0.7,qd[28,9]=0.6,qd[28,10]=1.2,qd[28,11]=0.4,qd[28,12]=1.2 qd[29,1]=-0.4,qd[29,2]=-0.1,qd[29,3]=-0.2,qd[29,4]=-0.4,qd[29,5]=-1.2,qd[29,6]=0.8,qd[29,7]=-0.7,qd[29,8]=-0.1,qd[29,9]=0.6,qd[29,10]=0.5,qd[29,11]=-0.9,qd[29,12]=0.7 qd[30,1]=-0.9,qd[30,2]=0.4,qd[30,3]=-0.6,qd[30,4]=-0.7,qd[30,5]=1.1,qd[30,6]=0.9,qd[30,7]=0.2,qd[30,8]=-1.0,qd[30,9]=0.3,qd[30,10]=1.1,qd[30,11]=0.3,qd[30,12]=0.0 qd[31,1]=-0.6,qd[31,2]=-0.4,qd[31,3]=1.1,qd[31,4]=-1.0,qd[31,5]=-0.6,qd[31,6]=1.2,qd[31,7]=0.4,qd[31,8]=0.3,qd[31,9]=-0.1,qd[31,10]=-0.8,qd[31,11]=0.9,qd[31,12]=0.1, qd[32,1]=0.2,qd[32,2]=-0.2,qd[32,3]=-0.3,qd[32,4]=-1.1,qd[32,5]=-0.3,qd[32,6]=-0.9,qd[32,7]=0.4,qd[32,8]=1.0,qd[32,9]=0.5,qd[32,10]=1.1,qd[32,11]=-0.7,qd[32,12]=-1.2 qd[33,1]=1.0,qd[33,2]=-0.8,qd[33,3]=-0.9,qd[33,4]=-0.3,qd[33,5]=-0.8,qd[33,6]=-0.1,qd[33,7]=0.3,qd[33,8]=-0.3,qd[33,9]=0.1,qd[33,10]=-0.1,qd[33,11]=0.1,qd[33,12]=-1.1 qd[34,1]=0.0,qd[34,2]=-0.9,qd[34,3]=0.0,qd[34,4]=-0.8,qd[34,5]=0.6,qd[34,6]=0.9,qd[34,7]=0.2,qd[34,8]=-0.9,qd[34,9]=-1.0,qd[34,10]=-1.2,qd[34,11]=-0.8,qd[34,12]=-1.2 qd[35,1]=0.2,qd[35,2]=0.4,qd[35,3]=-1.2,qd[35,4]=-0.6,qd[35,5]=-1.2,qd[35,6]=0.6,qd[35,7]=0.4,qd[35,8]=-1.1,qd[35,9]=1.2,qd[35,10]=-0.9,qd[35,11]=-0.4,qd[35,12]=-0.1 qd[36,1]=0.7,qd[36,2]=0.5,qd[36,3]=-1.2,qd[36,4]=-0.6,qd[36,5]=0.3,qd[36,6]=0.2,qd[36,7]=-1.2,qd[36,8]=-0.6,qd[36,9]=0.2,qd[36,10]=-0.7,qd[36,11]=-0.1,qd[36,12]=0.8 qd[37,1]=0.3,qd[37,2]=-0.3,qd[37,3]=-1.1,qd[37,4]=-1.0,qd[37,5]=0.5,qd[37,6]=-0.8,qd[37,7]=0.8,qd[37,8]=1.1,qd[37,9]=0.8,qd[37,10]=0.1,qd[37,11]=-0.9,qd[37,12]=0.1 qd[38,1]=-0.8,qd[38,2]=-1.1,qd[38,3]=-0.1,qd[38,4]=-0.5,qd[38,5]=-0.2,qd[38,6]=0.6,qd[38,7]=0.0,qd[38,8]=-0.8,qd[38,9]=-0.3,qd[38,10]=1.2,qd[38,11]=-1.0,qd[38,12]=1.1 qd[39,1]=0.5,qd[39,2]=0.3,qd[39,3]=-0.7,qd[39,4]=-0.2,qd[39,5]=-0.3,qd[39,6]=1.1,qd[39,7]=0.8,qd[39,8]=1.1,qd[39,9]=-1.0,qd[39,10]=-0.1,qd[39,11]=0.4,qd[39,12]=-0.6 qd[40,1]=-0.5,qd[40,2]=0.4,qd[40,3]=0.6,qd[40,4]=0.8,qd[40,5]=-0.3,qd[40,6]=-1.2,qd[40,7]=0.7,qd[40,8]=-0.5,qd[40,9]=-0.7,qd[40,10]=-1.0,qd[40,11]=0.1,qd[40,12]=-0.5 qd[41,1]=1.1,qd[41,2]=0.3,qd[41,3]=-1.2,qd[41,4]=1.0,qd[41,5]=0.7,qd[41,6]=-1.2,qd[41,7]=0.8,qd[41,8]=-0.7,qd[41,9]=0.1,qd[41,10]=-0.2,qd[41,11]=-1.0,qd[41,12]=1.0 qd[42,1]=-0.6,qd[42,2]=-0.2,qd[42,3]=1.0,qd[42,4]=0.9,qd[42,5]=-1.1,qd[42,6]=-0.6,qd[42,7]=0.3,qd[42,8]=0.7,qd[42,9]=-0.7,qd[42,10]=0.0,qd[42,11]=0.1,qd[42,12]=-0.6 qd[43,1]=0.6,qd[43,2]=-0.6,qd[43,3]=-0.5,qd[43,4]=0.2,qd[43,5]=-0.7,qd[43,6]=0.3,qd[43,7]=-0.5,qd[43,8]=0.8,qd[43,9]=-0.5,qd[43,10]=-1.1,qd[43,11]=-0.2,qd[43,12]=1.2 qd[44,1]=0.0,qd[44,2]=0.2,qd[44,3]=0.1,qd[44,4]=-0.9,qd[44,5]=-0.9,qd[44,6]=-1.2,qd[44,7]=-0.8,qd[44,8]=-1.0,qd[44,9]=0.4,qd[44,10]=0.1,qd[44,11]=0.6,qd[44,12]=0.4 qd[45,1]=-1.2,qd[45,2]=1.0,qd[45,3]=1.2,qd[45,4]=-0.8,qd[45,5]=-1.1,qd[45,6]=0.4,qd[45,7]=-0.2,qd[45,8]=0.6,qd[45,9]=-0.2,qd[45,10]=0.5,qd[45,11]=-1.0,qd[45,12]=-0.2 qd[46,1]=-0.2,qd[46,2]=-1.1,qd[46,3]=-0.5,qd[46,4]=0.1,qd[46,5]=0.9,qd[46,6]=0.3,qd[46,7]=0.5,qd[46,8]=-0.6,qd[46,9]=-1.0,qd[46,10]=0.8,qd[46,11]=-0.7,qd[46,12]=-0.7 qd[47,1]=-0.3,qd[47,2]=-0.3,qd[47,3]=0.7,qd[47,4]=-0.9,qd[47,5]=1.0,qd[47,6]=0.8,qd[47,7]=-0.7,qd[47,8]=-0.9,qd[47,9]=0.5,qd[47,10]=0.8,qd[47,11]=0.1,qd[47,12]=0.2 qd[48,1]=-0.8,qd[48,2]=-0.8,qd[48,3]=1.2,qd[48,4]=0.7,qd[48,5]=-0.7,qd[48,6]=0.1,qd[48,7]=1.0,qd[48,8]=-0.8,qd[48,9]=-0.6,qd[48,10]=0.5,qd[48,11]=1.0,qd[48,12]=-0.5 qd[49,1]=-0.3,qd[49,2]=-0.9,qd[49,3]=0.6,qd[49,4]=-0.2,qd[49,5]=-0.1,qd[49,6]=0.4,qd[49,7]=0.5,qd[49,8]=-1.1,qd[49,9]=1.0,qd[49,10]=-1.2,qd[49,11]=0.0,qd[49,12]=-1.0 qd[50,1]=-0.9,qd[50,2]=-0.2,qd[50,3]=1.1,qd[50,4]=0.5,qd[50,5]=0.5,qd[50,6]=-0.8,qd[50,7]=0.3,qd[50,8]=0.2,qd[50,9]=0.0,qd[50,10]=0.3,qd[50,11]=-0.6,qd[50,12]=-1.1 qd[51,1]=-1.1,qd[51,2]=0.0,qd[51,3]=1.0,qd[51,4]=0.0,qd[51,5]=0.4,qd[51,6]=0.1,qd[51,7]=-0.3,qd[51,8]=-0.7,qd[51,9]=-0.6,qd[51,10]=0.7,qd[51,11]=-0.8,qd[51,12]=0.9 qd[52,1]=0.0,qd[52,2]=-0.5,qd[52,3]=-0.2,qd[52,4]=-1.0,qd[52,5]=-1.2,qd[52,6]=-1.0,qd[52,7]=0.7,qd[52,8]=-0.3,qd[52,9]=-0.8,qd[52,10]=0.4,qd[52,11]=0.0,qd[52,12]=-0.5 qd[53,1]=-0.1,qd[53,2]=0.5,qd[53,3]=-0.1,qd[53,4]=-1.0,qd[53,5]=-0.6,qd[53,6]=-0.5,qd[53,7]=-0.6,qd[53,8]=-0.4,qd[53,9]=0.4,qd[53,10]=-0.8,qd[53,11]=-1.2,qd[53,12]=0.5 qd[54,1]=0.1,qd[54,2]=-0.8,qd[54,3]=0.6,qd[54,4]=0.1,qd[54,5]=1.1,qd[54,6]=0.6,qd[54,7]=0.3,qd[54,8]=-0.8,qd[54,9]=-1.0,qd[54,10]=-0.5,qd[54,11]=-0.5,qd[54,12]=-1.1 qd[55,1]=-1.1,qd[55,2]=0.1,qd[55,3]=1.1,qd[55,4]=0.9,qd[55,5]=0.3,qd[55,6]=-0.3,qd[55,7]=0.9,qd[55,8]=-1.1,qd[55,9]=-0.5,qd[55,10]=0.7,qd[55,11]=0.6,qd[55,12]=-0.2 qd[56,1]=-0.9,qd[56,2]=0.4,qd[56,3]=1.2,qd[56,4]=-1.2,qd[56,5]=0.8,qd[56,6]=0.5,qd[56,7]=-0.5,qd[56,8]=0.5,qd[56,9]=0.8,qd[56,10]=-0.4,qd[56,11]=-1.0,qd[56,12]=-1.1 qd[57,1]=0.8,qd[57,2]=-0.3,qd[57,3]=0.4,qd[57,4]=-1.0,qd[57,5]=-0.5,qd[57,6]=0.3,qd[57,7]=-1.1,qd[57,8]=0.0,qd[57,9]=0.3,qd[57,10]=0.1,qd[57,11]=-0.8,qd[57,12]=0.7 qd[58,1]=-0.2,qd[58,2]=-1.2,qd[58,3]=1.2,qd[58,4]=1.1,qd[58,5]=-1.0,qd[58,6]=0.9,qd[58,7]=0.1,qd[58,8]=-0.5,qd[58,9]=0.7,qd[58,10]=-1.2,qd[58,11]=-0.6,qd[58,12]=1.2 qd[59,1]=-0.1,qd[59,2]=-1.0,qd[59,3]=-0.7,qd[59,4]=0.9,qd[59,5]=0.4,qd[59,6]=-0.1,qd[59,7]=-0.6,qd[59,8]=0.4,qd[59,9]=0.6,qd[59,10]=1.0,qd[59,11]=-0.7,qd[59,12]=1.1 qd[60,1]=-0.4,qd[60,2]=-0.3,qd[60,3]=0.1,qd[60,4]=0.7,qd[60,5]=1.0,qd[60,6]=0.6,qd[60,7]=-0.3,qd[60,8]=1.0,qd[60,9]=-0.8,qd[60,10]=-0.5,qd[60,11]=0.5,qd[60,12]=0.8 qd[61,1]=0.4,qd[61,2]=-0.7,qd[61,3]=0.7,qd[61,4]=0.0,qd[61,5]=1.1,qd[61,6]=0.9,qd[61,7]=0.2,qd[61,8]=-0.9,qd[61,9]=-1.1,qd[61,10]=-0.4,qd[61,11]=-0.1,qd[61,12]=0.1 qd[62,1]=0.7,qd[62,2]=-0.2,qd[62,3]=-0.6,qd[62,4]=0.9,qd[62,5]=0.0,qd[62,6]=0.3,qd[62,7]=1.2,qd[62,8]=0.3,qd[62,9]=-0.6,qd[62,10]=-0.6,qd[62,11]=0.3,qd[62,12]=-1.0 qd[63,1]=1.0,qd[63,2]=0.7,qd[63,3]=-0.7,qd[63,4]=-0.2,qd[63,5]=0.9,qd[63,6]=0.1,qd[63,7]=0.9,qd[63,8]=1.0,qd[63,9]=-0.9,qd[63,10]=1.0,qd[63,11]=-0.2,qd[63,12]=-0.3 qd[64,1]=-0.7,qd[64,2]=1.1,qd[64,3]=0.9,qd[64,4]=1.1,qd[64,5]=0.3,qd[64,6]=-0.2,qd[64,7]=0.3,qd[64,8]=-1.1,qd[64,9]=-1.0,qd[64,10]=0.4,qd[64,11]=-0.6,qd[64,12]=-0.5 qd[65,1]=0.5,qd[65,2]=-0.2,qd[65,3]=-0.1,qd[65,4]=-0.6,qd[65,5]=0.3,qd[65,6]=0.7,qd[65,7]=1.0,qd[65,8]=0.6,qd[65,9]=-0.2,qd[65,10]=-1.2,qd[65,11]=0.3,qd[65,12]=-0.6 qd[66,1]=1.0,qd[66,2]=-0.8,qd[66,3]=-0.5,qd[66,4]=0.2,qd[66,5]=0.1,qd[66,6]=-0.4,qd[66,7]=-0.7,qd[66,8]=-0.4,qd[66,9]=1.1,qd[66,10]=-1.1,qd[66,11]=-0.5,qd[66,12]=-0.5 qd[67,1]=1.1,qd[67,2]=-0.4,qd[67,3]=-0.2,qd[67,4]=-0.6,qd[67,5]=0.4,qd[67,6]=-0.8,qd[67,7]=0.5,qd[67,8]=-0.9,qd[67,9]=-0.6,qd[67,10]=0.1,qd[67,11]=1.2,qd[67,12]=0.7 qd[68,1]=-0.2,qd[68,2]=-0.5,qd[68,3]=-0.1,qd[68,4]=-0.1,qd[68,5]=0.7,qd[68,6]=0.3,qd[68,7]=1.1,qd[68,8]=0.9,qd[68,9]=-0.8,qd[68,10]=0.2,qd[68,11]=0.2,qd[68,12]=-0.5 qd[69,1]=1.1,qd[69,2]=-0.9,qd[69,3]=0.4,qd[69,4]=-0.7,qd[69,5]=0.2,qd[69,6]=0.0,qd[69,7]=0.4,qd[69,8]=1.2,qd[69,9]=0.8,qd[69,10]=-0.7,qd[69,11]=-0.8,qd[69,12]=0.1 qd[70,1]=-0.8,qd[70,2]=0.3,qd[70,3]=0.4,qd[70,4]=-1.1,qd[70,5]=-0.1,qd[70,6]=1.2,qd[70,7]=-0.9,qd[70,8]=-0.7,qd[70,9]=1.2,qd[70,10]=-1.1,qd[70,11]=-0.2,qd[70,12]=0.3 qd[71,1]=-0.3,qd[71,2]=-1.2,qd[71,3]=0.5,qd[71,4]=-0.8,qd[71,5]=0.2,qd[71,6]=1.1,qd[71,7]=1.2,qd[71,8]=-0.8,qd[71,9]=0.9,qd[71,10]=-1.1,qd[71,11]=-1.1,qd[71,12]=1.2, qd[72,1]=-0.3,qd[72,2]=-1.2,qd[72,3]=0.7,qd[72,4]=0.3,qd[72,5]=0.4,qd[72,6]=0.6,qd[72,7]=0.1,qd[72,8]=0.7,qd[72,9]=-0.6,qd[72,10]=-0.6,qd[72,11]=0.7,qd[72,12]=0.8 qd[73,1]=-1.1,qd[73,2]=0.2,qd[73,3]=0.2,qd[73,4]=-1.1,qd[73,5]=-0.6,qd[73,6]=1.1,qd[73,7]=-0.1,qd[73,8]=0.5,qd[73,9]=1.2,qd[73,10]=0.9,qd[73,11]=0.8,qd[73,12]=-0.7 qd[74,1]=0.9,qd[74,2]=0.5,qd[74,3]=-1.1,qd[74,4]=-0.5,qd[74,5]=0.0,qd[74,6]=-1.2,qd[74,7]=0.2,qd[74,8]=1.2,qd[74,9]=-0.5,qd[74,10]=-0.3,qd[74,11]=-0.3,qd[74,12]=-0.8 qd[75,1]=0.8,qd[75,2]=0.7,qd[75,3]=-1.2,qd[75,4]=0.4,qd[75,5]=-0.1,qd[75,6]=-1.2,qd[75,7]=-0.7,qd[75,8]=-0.1,qd[75,9]=-1.0,qd[75,10]=0.0,qd[75,11]=-1.0,qd[75,12]=-0.3 qd[76,1]=-0.8,qd[76,2]=1.0,qd[76,3]=0.9,qd[76,4]=-1.1,qd[76,5]=-0.9,qd[76,6]=0.4,qd[76,7]=0.6,qd[76,8]=-0.1,qd[76,9]=0.8,qd[76,10]=-0.5,qd[76,11]=-0.2,qd[76,12]=-0.3 qd[77,1]=-0.7,qd[77,2]=-1.1,qd[77,3]=0.5,qd[77,4]=0.1,qd[77,5]=-0.6,qd[77,6]=0.6,qd[77,7]=-0.1,qd[77,8]=1.1,qd[77,9]=0.0,qd[77,10]=-1.2,qd[77,11]=-0.1,qd[77,12]=0.4 qd[78,1]=0.5,qd[78,2]=-1.1,qd[78,3]=-1.1,qd[78,4]=0.0,qd[78,5]=-0.5,qd[78,6]=0.0,qd[78,7]=0.7,qd[78,8]=1.2,qd[78,9]=-0.9,qd[78,10]=-0.2,qd[78,11]=0.5,qd[78,12]=-1.0 qd[79,1]=-0.4,qd[79,2]=-0.3,qd[79,3]=0.3,qd[79,4]=-0.1,qd[79,5]=-1.0,qd[79,6]=1.0,qd[79,7]=-0.7,qd[79,8]=-0.7,qd[79,9]=1.0,qd[79,10]=-1.2,qd[79,11]=0.5,qd[79,12]=0.8 qd[80,1]=0.6,qd[80,2]=-0.3,qd[80,3]=0.0,qd[80,4]=0.4,qd[80,5]=-0.8,qd[80,6]=-0.3,qd[80,7]=-0.7,qd[80,8]=-0.9,qd[80,9]=-0.3,qd[80,10]=0.2,qd[80,11]=1.1,qd[80,12]=1.1 qd[81,1]=-0.3,qd[81,2]=-0.7,qd[81,3]=0.2,qd[81,4]=-0.7,qd[81,5]=-0.3,qd[81,6]=0.5,qd[81,7]=1.2,qd[81,8]=-0.1,qd[81,9]=-0.8,qd[81,10]=-1.1,qd[81,11]=-0.1,qd[81,12]=-0.8 qd[82,1]=0.2,qd[82,2]=-0.4,qd[82,3]=-0.9,qd[82,4]=-0.2,qd[82,5]=1.2,qd[82,6]=1.2,qd[82,7]=0.3,qd[82,8]=-0.7,qd[82,9]=-1.1,qd[82,10]=-0.2,qd[82,11]=-0.2,qd[82,12]=-0.7 qd[83,1]=1.2,qd[83,2]=-0.7,qd[83,3]=-0.5,qd[83,4]=0.1,qd[83,5]=0.2,qd[83,6]=-1.1,qd[83,7]=0.3,qd[83,8]=-1.0,qd[83,9]=0.6,qd[83,10]=-0.3,qd[83,11]=0.2,qd[83,12]=-1.1 qd[84,1]=0.7,qd[84,2]=-1.2,qd[84,3]=0.9,qd[84,4]=0.0,qd[84,5]=-0.7,qd[84,6]=0.2,qd[84,7]=-0.7,qd[84,8]=1.2,qd[84,9]=0.5,qd[84,10]=1.0,qd[84,11]=-0.4,qd[84,12]=1.2 qd[85,1]=1.1,qd[85,2]=-0.4,qd[85,3]=-0.7,qd[85,4]=0.4,qd[85,5]=0.7,qd[85,6]=-0.4,qd[85,7]=-0.3,qd[85,8]=0.5,qd[85,9]=-0.2,qd[85,10]=0.6,qd[85,11]=0.0,qd[85,12]=0.8 qd[86,1]=1.2,qd[86,2]=-0.3,qd[86,3]=-0.1,qd[86,4]=-0.9,qd[86,5]=0.6,qd[86,6]=0.0,qd[86,7]=0.6,qd[86,8]=0.6,qd[86,9]=0.9,qd[86,10]=-0.6,qd[86,11]=-1.2,qd[86,12]=0.4 qd[87,1]=0.3,qd[87,2]=-1.0,qd[87,3]=0.3,qd[87,4]=-0.1,qd[87,5]=-1.0,qd[87,6]=1.1,qd[87,7]=-0.8,qd[87,8]=-0.4,qd[87,9]=0.6,qd[87,10]=0.0,qd[87,11]=0.6,qd[87,12]=1.0 qd[88,1]=-0.3,qd[88,2]=0.0,qd[88,3]=-0.3,qd[88,4]=0.8,qd[88,5]=-0.8,qd[88,6]=0.8,qd[88,7]=0.7,qd[88,8]=1.1,qd[88,9]=-0.5,qd[88,10]=0.0,qd[88,11]=0.6,qd[88,12]=-1.0 qd[89,1]=0.4,qd[89,2]=0.8,qd[89,3]=-0.3,qd[89,4]=-0.2,qd[89,5]=-1.2,qd[89,6]=-0.2,qd[89,7]=0.0,qd[89,8]=0.0,qd[89,9]=1.2,qd[89,10]=1.2,qd[89,11]=0.5,qd[89,12]=-1.1 qd[90,1]=0.5,qd[90,2]=-0.4,qd[90,3]=-0.8,qd[90,4]=-1.0,qd[90,5]=0.0,qd[90,6]=-0.7,qd[90,7]=0.0,qd[90,8]=-0.5,qd[90,9]=-1.1,qd[90,10]=1.0,qd[90,11]=0.8,qd[90,12]=0.1 qd[91,1]=-0.6,qd[91,2]=0.1,qd[91,3]=-0.3,qd[91,4]=-0.8,qd[91,5]=-0.5,qd[91,6]=0.2,qd[91,7]=-1.1,qd[91,8]=0.3,qd[91,9]=0.6,qd[91,10]=1.0,qd[91,11]=-0.2,qd[91,12]=0.9 qd[92,1]=1.0,qd[92,2]=0.3,qd[92,3]=-0.5,qd[92,4]=0.6,qd[92,5]=-1.2,qd[92,6]=-0.1,qd[92,7]=-1.0,qd[92,8]=-0.3,qd[92,9]=0.0,qd[92,10]=-1.2,qd[92,11]=0.4,qd[92,12]=0.1, qd[93,1]=-0.1,qd[93,2]=-1.2,qd[93,3]=-1.1,qd[93,4]=-0.3,qd[93,5]=0.9,qd[93,6]=-0.7,qd[93,7]=1.0,qd[93,8]=0.1,qd[93,9]=0.3,qd[93,10]=-0.6,qd[93,11]=0.4,qd[93,12]=-0.5 qd[94,1]=-1.2,qd[94,2]=0.8,qd[94,3]=0.1,qd[94,4]=1.1,qd[94,5]=-0.7,qd[94,6]=1.2,qd[94,7]=-0.5,qd[94,8]=0.7,qd[94,9]=-0.4,qd[94,10]=0.9,qd[94,11]=-1.2,qd[94,12]=-0.3 qd[95,1]=0.2,qd[95,2]=-0.4,qd[95,3]=-0.9,qd[95,4]=0.0,qd[95,5]=0.6,qd[95,6]=0.4,qd[95,7]=0.5,qd[95,8]=0.7,qd[95,9]=-1.1,qd[95,10]=0.4,qd[95,11]=-0.2,qd[95,12]=-1.1 qd[96,1]=0.8,qd[96,2]=0.2,qd[96,3]=-1.1,qd[96,4]=0.7,qd[96,5]=-1.2,qd[96,6]=-1.0,qd[96,7]=0.0,qd[96,8]=-0.3,qd[96,9]=1.1,qd[96,10]=-0.8,qd[96,11]=-0.5,qd[96,12]=0.9 qd[97,1]=0.7,qd[97,2]=-0.7,qd[97,3]=1.2,qd[97,4]=0.1,qd[97,5]=-1.0,qd[97,6]=0.1,qd[97,7]=0.5,qd[97,8]=1.1,qd[97,9]=-0.9,qd[97,10]=0.9,qd[97,11]=0.6,qd[97,12]=-1.2 qd[98,1]=1.0,qd[98,2]=-0.1,qd[98,3]=-0.8,qd[98,4]=0.0,qd[98,5]=0.7,qd[98,6]=-0.6,qd[98,7]=0.6,qd[98,8]=0.2,qd[98,9]=-0.2,qd[98,10]=0.8,qd[98,11]=1.0,qd[98,12]=-0.4 qd[99,1]=0.2,qd[99,2]=-0.9,qd[99,3]=0.1,qd[99,4]=0.5,qd[99,5]=0.0,qd[99,6]=0.8,qd[99,7]=-1.0,qd[99,8]=-0.4,qd[99,9]=0.9,qd[99,10]=-0.2,qd[99,11]=0.6,qd[99,12]=0.0 qd[100,1]=-1.0,qd[100,2]=-0.4,qd[100,3]=-0.3,qd[100,4]=0.9,qd[100,5]=0.8,qd[100,6]=1.0,qd[100,7]=-1.2,qd[100,8]=0.5,qd[100,9]=0.3,qd[100,10]=-0.4,qd[100,11]=0.1,qd[100,12]=0.1 qd[101,1]=0.1,qd[101,2]=1.2,qd[101,3]=0.7,qd[101,4]=-0.3,qd[101,5]=0.8,qd[101,6]=-0.7,qd[101,7]=-0.6,qd[101,8]=-0.9,qd[101,9]=1.0,qd[101,10]=-0.7,qd[101,11]=-0.1,qd[101,12]=1.2 qd[102,1]=-0.6,qd[102,2]=-0.2,qd[102,3]=0.1,qd[102,4]=0.2,qd[102,5]=-0.4,qd[102,6]=1.1,qd[102,7]=0.8,qd[102,8]=-1.1,qd[102,9]=-0.2,qd[102,10]=-0.6,qd[102,11]=-0.3,qd[102,12]=-0.9 qd[103,1]=0.7,qd[103,2]=-0.1,qd[103,3]=-0.9,qd[103,4]=0.2,qd[103,5]=0.8,qd[103,6]=-0.6,qd[103,7]=-0.4,qd[103,8]=-1.2,qd[103,9]=1.0,qd[103,10]=0.8,qd[103,11]=0.3,qd[103,12]=0.4 qd[104,1]=0.1,qd[104,2]=-1.2,qd[104,3]=-0.6,qd[104,4]=0.9,qd[104,5]=1.1,qd[104,6]=-0.6,qd[104,7]=0.3,qd[104,8]=-0.7,qd[104,9]=-0.8,qd[104,10]=-0.7,qd[104,11]=0.0,qd[104,12]=-0.8 qd[105,1]=1.0,qd[105,2]=0.0,qd[105,3]=-0.1,qd[105,4]=0.0,qd[105,5]=-0.3,qd[105,6]=-0.2,qd[105,7]=0.7,qd[105,8]=0.3,qd[105,9]=0.4,qd[105,10]=1.1,qd[105,11]=0.3,qd[105,12]=-0.3 qd[106,1]=-0.4,qd[106,2]=-1.2,qd[106,3]=-0.1,qd[106,4]=-0.5,qd[106,5]=-0.6,qd[106,6]=0.0,qd[106,7]=-0.3,qd[106,8]=1.1,qd[106,9]=0.7,qd[106,10]=0.3,qd[106,11]=-0.6,qd[106,12]=0.5 qd[107,1]=0.1,qd[107,2]=0.2,qd[107,3]=-0.3,qd[107,4]=1.2,qd[107,5]=1.1,qd[107,6]=0.5,qd[107,7]=0.7,qd[107,8]=0.5,qd[107,9]=-1.1,qd[107,10]=0.4,qd[107,11]=-0.2,qd[107,12]=-1.2 qd[108,1]=0.2,qd[108,2]=-0.1,qd[108,3]=-0.2,qd[108,4]=0.3,qd[108,5]=0.4,qd[108,6]=-0.8,qd[108,7]=-0.7,qd[108,8]=-1.2,qd[108,9]=-0.1,qd[108,10]=-0.6,qd[108,11]=-0.7,qd[108,12]=1.0 qd[109,1]=0.3,qd[109,2]=0.5,qd[109,3]=-0.5,qd[109,4]=-1.0,qd[109,5]=0.4,qd[109,6]=1.2,qd[109,7]=-0.8,qd[109,8]=-1.0,qd[109,9]=0.5,qd[109,10]=0.2,qd[109,11]=-0.3,qd[109,12]=0.5 qd[110,1]=0.2,qd[110,2]=-0.1,qd[110,3]=-0.3,qd[110,4]=1.0,qd[110,5]=0.9,qd[110,6]=-1.1,qd[110,7]=1.2,qd[110,8]=0.6,qd[110,9]=-0.3,qd[110,10]=-0.3,qd[110,11]=-0.6,qd[110,12]=-0.7 endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x x = qd[@sd,1] + qd[@sd,2]*x + qd[@sd,3]*x*x + qd[@sd,4]*x*y \ + qd[@sd,5]*y + qd[@sd,6]*y*y y = qd[@sd,7] + qd[@sd,8]*pxx + qd[@sd,9]*pxx*pxx + qd[@sd,10]*pxx*y \ + qd[@sd,11]*y + qd[@sd,12]*y*y att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y)) float d = @distscale*|pz-(x + sgn*flip(y))| return d endfunc private: float qd[111,13] default: title = "SprottQuad" heading text="Sprott 2D Quadratic Attractors" endheading heading text=" x -> Quadratic in x and y" endheading heading text=" y -> Quadratic in x and y" endheading int param v_trapshapesprottquad caption = "Version (Trap Shape SprottQuad)" default = 101 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_trapshapesprottquad < 101 endparam param sd caption = "Sprott selector" default = 0 enum = "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" \ "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" \ "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" \ "45" "46" "47" "48" "49" "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" \ "60" "61" "62" "63" "64" "65" "66" "67" "69" "69" "70" "71" "72" "73" "74" \ "75" "76" "77" "78" "79" "80" "81" "82" "83" "84" "85" "86" "87" "88" "89" \ "90" "91" "92" "93" "94" "95" "96" "97" "98" "99" "100" "101" "102" "103" \ "104" "105" "106" "107" "108" "109" "110" hint = "Each Sprott selector uses a different strange attractor." endparam float param distscale caption = "Distance scale" default = 1.0 endparam float param s caption = "Attractor scale" default = 0.5 endparam int param max_att_iterations caption = "Attractor iterations" default = 20 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeThreeply(common.ulb:TrapShape) { ; This shape is the Threeply strange attractor. public: import "common.ulb" ; Constructor func REB_TrapShapeThreeply(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x if x != 0 x = y - x/abs(x)*(abs(sin(x)*cos(@h2) + @h3 \ - x*sin(@h1 + @h2 + @h3))) else x = y - (abs(sin(x)*cos(@h2) + @h3 \ - x*sin(@h1 + @h2 + @h3))) endif y = @h1 - pxx att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y)) float d = @distscale*|pz-(x + sgn*flip(y))| return d endfunc default: title = "Threeply" heading text = "Threeply attractor" endheading heading text = "x->y-sign(x)*(abs(sin(x)*cos(h2)+\ h3-x*sin(h1+h2+h3)))" endheading heading text = "y->h1-x" endheading int param v_trapshapethreeply caption = "Version (Trap Shape Threeply)" default = 101 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_trapshapethreeply < 101 endparam float param h1 caption = "Threeply param 1" default = -55 endparam float param h2 caption = "Threeply param 2" default = -1 endparam float param h3 caption = "Threeply param 3" default = 0.8 endparam float param distscale caption = "Distance scale" default = 0.0002 endparam float param s caption = "Attractor scale" default = 100 endparam int param max_att_iterations caption = "Attractor iterations" default = 100 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_TrapShapeZito(common.ulb:TrapShape) { ; This shape uses the Zito strange attractor. public: import "common.ulb" ; Constructor func REB_TrapShapeZito(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float x = real(pz)*@s float y = imag(pz)*@s float pxx = 0 int att_iter = 0 while att_iter < @max_att_iterations && x < 1e100 && x > -1e100 pxx = x x = x*y +@h1*x - y y= pxx + y att_iter = att_iter + 1 endwhile m_LastZ = (x + sgn*flip(y)) float d = @distscale*|pz-(x + sgn*flip(y))| return d endfunc default: title = "Zito" heading text = "Zito attractor" endheading heading text = "x -> x*y + a*x - y" endheading heading text = "y -> x + y" endheading int param v_trapshapezito caption = "Version (Trap Shape Zito)" default = 101 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_trapshapezito < 101 endparam float param h1 caption = "Zito param" default = 0.357 endparam float param distscale caption = "Distance scale" default = 1 endparam float param s caption = "Attractor scale" default = 2 endparam int param max_att_iterations caption = "Attractor iterations" default = 10 endparam bool param sgn caption = "Conjugate transform" default = false endparam } class REB_SpokesNRings(common.ulb:TrapShape) { ; This trap creates rings and spokes shapes.
; It can also be used as a texture ; public: import "common.ulb" ; constructor func REB_SpokesNRings(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; call for each iterated point float func Iterate(complex pz) TrapShape.Iterate(pz) float dist = cabs(pz) float theta = atan2(pz) if theta < 0 theta = theta + 2*#pi endif if theta > 2*#pi theta = 2*#pi endif float wedge = 2*#pi/@spokes float swidth = @swidth if swidth >= wedge swidth = wedge endif if @type == "Spokes" if @spiralize if (theta+@twist*dist) % wedge < (theta+@twist*dist+swidth) % wedge dist = 1e20 pz = (1e20,1e20) endif else if theta % wedge < (theta+swidth) % wedge dist = 1e20 pz = (1e20,1e20) endif endif elseif @type == "Rings" if dist % (1/@dens) < (dist+0.5*@rwidth/@dens) % (1/@dens) dist = 1e20 pz = (1e20,1e20) endif endif m_lastZ = pz return dist endfunc protected: default: title = "Spokes N Rings" int param v_spokesnrings caption = "Version (Trap Shape Spokes N Rings)" 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_spokesnrings < 100 endparam param type caption = "Trap Type" default = 0 enum = "Spokes" "Rings" endparam int param spokes caption = "# of Spokes" default = 5 visible = @type == "Spokes" endparam float param swidth caption = "Spoke thickness" default = 1 visible = @type == "Spokes" endparam bool param spiralize caption = "Spiral spokes" default = false visible = @type == "Spokes" endparam float param twist caption = "Amount of twist" default = 1 visible = @type == "Spokes" && @spiralize endparam float param dens caption = "Ring density" default = 20 visible = @type == "Rings" endparam float param rwidth caption = "Ring thickness" default = 1 visible = @type == "Rings" endparam } class REB_TrapShapeAmpersand(common.ulb:TrapShape) { ; This shape uses the ampersand function.
;

; This variant of the ampersand function involves taking a square root ; so there are two solutions. A signed and absolute value version of ; the distance is also available. The transformed value is the ; complex return value of the function. public: import "common.ulb" $define debug ; Constructor func REB_TrapShapeAmpersand(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale if !@cmplx x = real(@fn1(pz)) y = imag(@fn2(pz)) else x = real(@fn1(pz)) y = imag(@fn1(pz)) endif if @ref == "pz" d = (y^2-x^2)*(x-@a1)*(@a2*x-@a3)-@a4*(x^2+y^2-@a5*x)^2+cabs(pz)*@offset else d = (y^2-x^2)*(x-@a1)*(@a2*x-@a3)-@a4*(x^2+y^2-@a5*x)^2+@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else int sgn = 1 if @sgn sgn = -1 endif float x = real(pz) float qy = 0 float qb = 6*x^2 - 3*x - 3 float qc = 6*x^4 - 13*x^3 + 19*x^2 if @negroot qy = ((-qb - (qb^2 - 16*qc)^0.5)/(8))^0.5 else qy = ((-qb + (qb^2 - 16*qc)^0.5)/(8))^0.5 endif m_LastZ = @a*(x + sgn*flip(qy)) if @absval d = abs(cabs(pz) - cabs(@a*(x + sgn*flip(qy)))) else d = cabs(pz - @a*(x + sgn*flip(qy))) endif endif return d endfunc default: title = "Ampersand" int param v_trapshapeampersand caption = "Version (Trap Shape Ampersand)" default = 101 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_trapshapeampersand < 101 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam bool param adv caption = "advanced" default = false visible = @altformula endparam float param a1 caption = "parameter a1" default = 1 visible = @adv && @altformula endparam float param a2 caption = "parameter a2" default = 2 visible = @adv && @altformula endparam float param a3 caption = "parameter a3" default = 3 visible = @adv endparam float param a4 caption = "parameter a4" default = 4 visible = @adv && @altformula endparam float param a5 caption = "parameter a5" default = 2 visible = @adv && @altformula endparam bool param cmplx caption = "Apply to complex" default = false visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = !@cmplx && @altformula endfunc float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@altformula endparam param negroot caption = "Quad Neg Root" default = true visible = !@altformula endparam } class REB_TrapShapeSpiricOfPerseus(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeSpiricOfPerseus(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float d = 0 float x = real(pz) complex qy = 0 if @negroot qy = -(2*(x^2+@c^2)^0.5 -x^2 - 1 + @b^2 - @c^2)^0.5 else qy = (2*(x^2+@c^2)^0.5 -x^2 - 1 + @b^2 - @c^2)^0.5 endif m_LastZ = 3*@a*(x + sgn*flip(qy)) if @absval d = abs(cabs(pz) - cabs(3*@a*(x + sgn*flip(qy)))) else d = cabs(pz - 3*@a*(x + sgn*flip(qy))) endif return d endfunc default: title = "Spiric Of Perseus" int param v_SpiricOfPerseus caption = "Version (Spiric Of Perseus)" 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_SpiricOfPerseus < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "Spiric 1 parameter" default = 0.3 endparam float param c caption = "Spiric 2 parameter" default = 0.6 endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam param negroot caption = "Quad Neg Root" default = true endparam } class REB_TrapShapeGranvillesEgg(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeGranvillesEgg(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float d = 0 float x = real(pz) complex qy = 0 if @negroot qy = -((x-@b)*(1-x)/x^2)^0.5 else qy = ((x-@b)*(1-x)/x^2)^0.5 endif m_LastZ = @a*(x + sgn*flip(qy))/2 if @absval d = abs(cabs(pz) - cabs(@a*(x + sgn*flip(qy)))/2) else d = cabs(pz - @a*(x + sgn*flip(qy))/2) endif return d endfunc default: title = "Granville's Egg" int param v_GranvillesEgg caption = "Version (Granville's Egg)" 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_GranvillesEgg < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "Granville parameter" default = 0.1 endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam param negroot caption = "Quad Neg Root" default = true endparam } class REB_TrapShapeGudermannian(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeGudermannian(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float d = 0 float x = real(pz) float qy = atan(exp(x)) m_LastZ = 5*@a*(x + sgn*flip(qy))/2 if @absval d = abs(cabs(pz) - cabs(5*@a*(x + sgn*flip(qy)))/2) else d = cabs(pz - 5*@a*(x + sgn*flip(qy))/2) endif return d endfunc default: title = "Gudermannian" int param v_Gudermannian caption = "Version (Gudermannian)" 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_Gudermannian < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeHeatCapacity(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeHeatCapacity(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float d = 0 float x = real(pz) float qy = x + @b/x^2 m_LastZ = @a*(x + sgn*flip(qy))/2 if @absval d = abs(cabs(pz) - cabs(@a*(x + sgn*flip(qy)))/2) else d = cabs(pz - @a*(x + sgn*flip(qy))/2) endif return d endfunc default: title = "Heat Capacity" int param v_HeatCapacity caption = "Version (Heat Capacity)" 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_HeatCapacity < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "Heat Capacity parameter" default = 0.01 endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeHoerlFunction(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeHoerlFunction(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float d = 0 float x = real(pz) float qy = x^@b*exp(x) m_LastZ = 2.5*@a*(x + sgn*flip(qy)) if @absval d = abs(cabs(pz) - cabs(2.5*@a*(x + sgn*flip(qy)))) else d = cabs(pz - 2.5*@a*(x + sgn*flip(qy))) endif return d endfunc default: title = "Hoerl Function" int param v_HoerlFunction caption = "Version (Hoerl Function)" 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_HoerlFunction < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "Hoerl parameter" default = 0.5 endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeBesace(common.ulb:TrapShape) { public: import "common.ulb" $define debug ; Constructor func REB_TrapShapeBesace(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = (y+@aa*x^2)^2-x^2+x^4-cabs(pz)*@offset else d = (y+@aa*x^2)^2-x^2+x^4-@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else int sgn = 1 if @sgn sgn = -1 endif d = 0 x = real(pz) complex qy = 0 if @negroot qy = -sqrt(x^2-x^4) - @b*x^2 else qy = sqrt(x^2-x^4) - @b*x^2 endif m_LastZ = @a*(x + sgn*flip(qy))/2 if @absval d = abs(cabs(pz) - cabs(@a*(x + sgn*flip(qy)))/2) else d = cabs(pz - @a*(x + sgn*flip(qy))/2) endif endif return d endfunc default: title = "Besace" int param v_Besace caption = "Version (Besace)" 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_besace < 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 0.2 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "Besace parameter" default = 2 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param b caption = "Besace parameter" default = 100 visible = !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@altformula endparam param negroot caption = "Quad Neg Root" default = true visible = !@altformula endparam } class REB_TrapShapeKulpsQuartic(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeKulpsQuartic(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float d = 0 float x = real(pz) float qy = 0 if @negroot qy = -sqrt(1/(1+x^2)) else qy = sqrt(1/(1+x^2)) endif m_LastZ = 2.5*@a*(x + sgn*flip(qy)) if @absval d = abs(cabs(pz) - cabs(2.5*@a*(x + sgn*flip(qy)))) else d = cabs(pz - 2.5*@a*(x + sgn*flip(qy))) endif return d endfunc default: title = "Kulp's Quartic" int param v_KulpsQuartic caption = "Version (Kulp's Quartic)" default = 101 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_KulpsQuartic < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam param negroot caption = "Quad Neg Root" default = true endparam } class REB_TrapShapeKiepertsCurve(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeKiepertsCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float d = 0 float x = real(pz) complex qy = 0 if @negroot qy = -sqrt((1-x^2)^3) else qy = sqrt((1-x^2)^3) endif m_LastZ = 3*@a*(x + sgn*flip(qy)) if @absval d = abs(cabs(pz) - cabs(3*@a*(x + sgn*flip(qy)))) else d = cabs(pz - 3*@a*(x + sgn*flip(qy))) endif return d endfunc default: title = "Kiepert's Curve" int param v_KiepertsCurve caption = "Version (Kiepert's Curve)" 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_KiepertsCurve < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam param negroot caption = "Quad Neg Root" default = true endparam } class REB_TrapShapeLennardJones(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeLennardJones(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float d = 0 float x = real(pz) float qy = 0 qy = x^(-12) - x^(-6) m_LastZ = 5*@a*(x + sgn*flip(qy)) if @absval d = abs(cabs(pz) - cabs(5*@a*(x + sgn*flip(qy)))) else d = cabs(pz - 5*@a*(x + sgn*flip(qy))) endif return d endfunc default: title = "Lennard-Jones Potential" int param v_LennardJones caption = "Version (Lennard-Jones Potential)" 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_LennardJones < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeFunction(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeFunction(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float d = 0 float x = real(pz) float qy = 0 qy = real(@fn(x)) m_LastZ = 5*@a*(x + sgn*flip(qy)) if @absval d = abs(cabs(pz) - cabs(5*@a*(x + sgn*flip(qy)))) else d = cabs(pz - 5*@a*(x + sgn*flip(qy))) endif return d endfunc default: title = "Function" int param v_Function caption = "Version (Function)" 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_Function < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam func fn caption = "Function" default = sin() endfunc } class REB_TrapShapeCubicSpiral(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeCubicspiral(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float d = 0 float x = real(pz) float qy = 0 qy = x^3 m_LastZ = 4*@a*(x + sgn*flip(qy)) if @absval d = abs(cabs(pz) - cabs(4*@a*(x + sgn*flip(qy)))) else d = cabs(pz - 4*@a*(x + sgn*flip(qy))) endif return d endfunc default: title = "Cubic Spiral" int param v_CubicSpiral caption = "Version (Cubic Spiral)" 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_CubicSpiral < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeGauss(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeGauss(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float d = 0 float x = real(pz) float qy = 0 qy = (1/(@sigma*sqrt(2*#pi)))*exp(-x^2/(2*@sigma^2)) m_LastZ = 4*@a*(x + sgn*flip(qy)) if @absval d = abs(cabs(pz) - cabs(4*@a*(x + sgn*flip(qy)))) else d = cabs(pz - 4*@a*(x + sgn*flip(qy))) endif return d endfunc default: title = "Gauss Curve" int param v_Gauss caption = "Version (Gauss Curve)" 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_Gauss < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param sigma caption = "Sigma" default = 1 endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeOphiuride(common.ulb:TrapShape) { ; This shape uses the ophiuride function.
;

; This variant of the ophuiride function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeOphiuride(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = (0.01*@b*sin(theta)-@a*cos(theta))*tan(theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Ophiuride" int param v_trapshapeophiuride caption = "Version (Trap Shape Ophiuride)" default = 101 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_trapshapeophiuride < 101 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects shape and scale of trap." endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeREBAstroid(common.ulb:TrapShape) { ; This shape uses the astroid function.
;

; This variant of the astoid function is different from that used by Damien ; Jones. It has signed and absolute value version of the distance. The function ; also has a complex conjugate variant. The transformed value is the complex ; return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeREBAstroid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 complex as = 0 complex af1 = 0 complex af2 = 0 float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale if !@cmplx x = real(@fn1(pz)) y = imag(@fn2(pz)) else x = real(@fn1(pz)) y = imag(@fn1(pz)) endif if @ref == "pz" d = x^(2/3)+y^(2/3)-@a^(2/3)+cabs(pz)*@offset else d = x^(2/3)+y^(2/3)-@a^(2/3)+@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif af1 = @afn1(theta)^real(@pwr) af2 = @afn2(theta)^imag(@pwr) as = @ar*(af1+sgn*flip(af2)) m_LastZ = as if @absval d = abs(cabs(pz) - cabs(as)) else d = cabs(pz - (as)) endif endif return d endfunc default: title = "Astroid REB" int param v_trapshapeastroidreb caption = "Version (Trap Shape Astroid REB)" default = 102 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_trapshapeastroidreb < 102 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 0.2 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param a caption = "parameter a" default = 1 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam bool param cmplx caption = "Apply to complex" default = false visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula && !@cmplx endfunc float param ar caption = "Radius" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam complex param pwr caption = "Power" default = (3,3) hint = "Affects shape and scale of trap." visible = !@altformula endparam func afn1 caption = "Function #1" default = cos() visible = !@altformula endfunc func afn2 caption = "Function #2" default = sin() visible = !@altformula endfunc bool param sgn caption = "Conjugate transform" default = false visible = !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@altformula endparam bool param alttheta caption = "Alternate theta" default = false visible = !@altformula endparam } class REB_TrapShapeBean(common.ulb:TrapShape) { ; This shape uses the bean function.
;

; It has signed and absolute value version of the distance. The function ; also has a complex conjugate variant. The transformed value is the complex ; return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeBean(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) float theta = 0 TrapShape.Iterate(pz) float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = (x^2+y^2)^2-x^3-y^3-cabs(pz)*@offset else d = (x^2+y^2)^2-x^3-y^3-@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else complex af1 = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif af1 = @a*(@afn1(theta)^real(@pwr)+@afn2(theta)^imag(@pwr)) if @absval d = abs(cabs(pz) - cabs(af1*cos(theta) + sgn*flip(af1*sin(theta)))) else d = cabs(pz - (af1*cos(theta) + sgn*flip(af1*sin(theta)))) endif m_LastZ = (af1*cos(theta) + sgn*flip(af1*sin(theta))) endif return d endfunc default: title = "Bean" int param v_trapshapebean caption = "Version (Trap Shape Bean)" default = 101 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_trapshapebean < 101 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 0.2 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam complex param pwr caption = "Power" default = (3,3) hint = "Affects shape and scale of trap." visible = !@altformula endparam func afn1 caption = "Function #1" default = cos() visible = !@altformula endfunc func afn2 caption = "Function #2" default = sin() visible = !@altformula endfunc bool param sgn caption = "Conjugate transform" default = false visible = !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@altformula endparam } class REB_TrapShapeCircle(common.ulb:TrapShape) { ; This shape uses the circle function.
;

; This variant of the circle function has a signed and absolute value ; version of the distance. The function also has a complex conjugate. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeCircle(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = @a*sin(theta)^2 + 0.2*@b*cos(theta)^2 if @absval d = abs(cabs(pz) - cabs(rr*cos(theta) + sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) return d endfunc default: title = "Circle" int param v_trapshapecircle caption = "Version (Trap Shape Circle)" default = 102 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_trapshapecircle < 102 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_AstroidalEllipsoid(common.ulb:TrapShape) { ; This shape uses the 3D Astroidal Ellipsoid function.
;

public: import "common.ulb" ; Constructor func REB_AstroidalEllipsoid(Generic pparent) TrapShape.TrapShape(pparent) xrot = (0,1)^(@xang/90) yrot = (0,1)^(@yang/90) temp = 0 endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float x = (@aa*cos(real(pz))*cos(imag(pz)))^3*@scale2 float y = (@ab*sin(real(pz))*cos(imag(pz)))^3*@scale2 float z = (@ac*sin(imag(pz)))^3*@scale2 ; ; Y axis rotation ; temp = x + flip(z) temp = temp*yrot x = real(temp) z = imag(temp) ; ; X axis rotation ; temp = y + flip(z) temp = temp*xrot y = real(temp) z = imag(temp) ; calculate 3D distance float d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +z^2)*@scale if @usez if @tz == "cabs(z)" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*cabs(pz)-z)^2)*@scale elseif @tz == "real+imag z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz)+imag(pz))-z)^2)*@scale elseif @tz == "real z" d = sqrt((imag(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz))-z)^2)*@scale elseif @tz == "real z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(imag(pz))-z)^2)*@scale elseif @tz == "angle pz" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*atan2(pz)-z)^2)*@scale endif endif m_lastZ = x + flip(y) return d endfunc protected: complex xrot complex yrot complex temp default: title = "Astroidal Ellipsoid" heading text = "This is a 3D parametric surface." endheading int param v_AstroidalEllipsoid caption = "Version (Trap Shape AstroidalEllipsoid)" 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_AstroidalEllipsoid < 100 endparam float param xang caption = "X rotation" default = -40 endparam float param yang caption = "Y rotation" default = 30 endparam float param scale2 caption = "prescale" default = 1.0 endparam float param scale caption = "Scale" default = 0.2 endparam bool param usez caption = "fractal z for z value" default = false endparam param tz caption = "fractal z type" enum = "cabs(z)" "real+imag z" "real z" "imag z" "angle pz" default = 0 visible = @usez endparam float param sz caption = "fractal z scale" default = 1 visible = @usez endparam float param aa caption = "param a" default = 1.0 endparam float param ab caption = "param b" default = 1.0 endparam float param ac caption = "param c" default = 1.0 endparam } class REB_AppleSurface(common.ulb:TrapShape) { ; This shape uses the 3D Apple Surface function.
;

public: import "common.ulb" ; Constructor func REB_AppleSurface(Generic pparent) TrapShape.TrapShape(pparent) xrot = (0,1)^(@xang/90) yrot = (0,1)^(@yang/90) temp = 0 endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float x = (cos(real(pz))*(4 + 3.8*cos(imag(pz))))*@ap*@scale2 float y = (sin(real(pz))*(4 + 3.8*cos(imag(pz))))*@ap*@scale2 float z = ((cos(imag(pz)) + sin(imag(pz)) - 1)+\ (1 + sin(imag(pz)))*log(1 - #pi*imag(pz) / 10) +\ 7.5*sin(imag(pz)))*@ap*@scale2 ; ; Y axis rotation ; temp = x + flip(z) temp = temp*yrot x = real(temp) z = imag(temp) ; ; X axis rotation ; temp = y + flip(z) temp = temp*xrot y = real(temp) z = imag(temp) ; calculate 3D distance float d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +z^2)*@scale if @usez if @tz == "cabs(z)" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*cabs(pz)-z)^2)*@scale elseif @tz == "real+imag z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz)+imag(pz))-z)^2)*@scale elseif @tz == "real z" d = sqrt((imag(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz))-z)^2)*@scale elseif @tz == "real z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(imag(pz))-z)^2)*@scale elseif @tz == "angle pz" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*atan2(pz)-z)^2)*@scale endif endif m_lastZ = x + flip(y) return d endfunc protected: complex xrot complex yrot complex temp default: title = "Apple Surface" heading text = "This is a 3D parametric surface." endheading int param v_AppleSurface caption = "Version (Trap Shape AppleSurface)" 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_AppleSurface < 100 endparam float param xang caption = "X rotation" default = -75 endparam float param yang caption = "Y rotation" default = 20 endparam float param scale2 caption = "Precale" default = 1.0 endparam float param scale caption = "Scale" default = 0.2 endparam bool param usez caption = "fractal z for z value" default = false endparam param tz caption = "fractal z type" enum = "cabs(z)" "real+imag z" "real z" "imag z" "angle pz" default = 0 visible = @usez endparam float param sz caption = "fractal z scale" default = 1 visible = @usez endparam float param ap caption = "param" default = 0.1 endparam } class REB_BowTie(common.ulb:TrapShape) { ; This shape uses the 3D Bow Tie Surface function.
;

public: import "common.ulb" ; Constructor func REB_BowTie(Generic pparent) TrapShape.TrapShape(pparent) xrot = (0,1)^(@xang/90) yrot = (0,1)^(@yang/90) temp = 0 endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float x = sin(real(pz))/(sqrt(2)+sin(imag(pz)))*@scale2 float y = sin(real(pz))/(sqrt(2)+cos(imag(pz)))*@scale2 float z = cos(real(pz))/(sqrt(2)+1)*@scale2 ; ; Y axis rotation ; temp = x + flip(z) temp = temp*yrot x = real(temp) z = imag(temp) ; ; X axis rotation ; temp = y + flip(z) temp = temp*xrot y = real(temp) z = imag(temp) ; calculate 3D distance float d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +z^2)*@scale if @usez if @tz == "cabs(z)" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*cabs(pz)-z)^2)*@scale elseif @tz == "real+imag z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz)+imag(pz))-z)^2)*@scale elseif @tz == "real z" d = sqrt((imag(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz))-z)^2)*@scale elseif @tz == "real z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(imag(pz))-z)^2)*@scale elseif @tz == "angle pz" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*atan2(pz)-z)^2)*@scale endif endif m_lastZ = x + flip(y) return d endfunc protected: complex xrot complex yrot complex temp default: title = "Bow Tie Surface" heading text = "This is a 3D parametric surface." endheading int param v_BowTieSurface caption = "Version (Trap Shape BowTieSurface)" 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_BowTieSurface < 100 endparam float param xang caption = "X rotation" default = -45 endparam float param yang caption = "Y rotation" default = 90 endparam float param scale2 caption = "Prescale" default = 1 endparam float param scale caption = "Scale" default = 0.2 endparam bool param usez caption = "fractal z for z value" default = false endparam param tz caption = "fractal z type" enum = "cabs(z)" "real+imag z" "real z" "imag z" "angle pz" default = 0 visible = @usez endparam float param sz caption = "fractal z scale" default = 1 visible = @usez endparam } class REB_BowSurface(common.ulb:TrapShape) { ; This shape uses the 3D Bow Surface function.
;

public: import "common.ulb" ; Constructor func REB_BowSurface(Generic pparent) TrapShape.TrapShape(pparent) xrot = (0,1)^(@xang/90) yrot = (0,1)^(@yang/90) temp = 0 endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float x = ((2 + @T*sin(2*#pi*real(pz)))*sin(4*#pi*imag(pz)))*@scale2 float y = (2 + @T*sin(2*#pi*real(pz)))*cos(4*#pi*imag(pz))*@scale2 float z = (@T*cos(2*#pi*real(pz)) + 3*cos(2*#pi*imag(pz))*@scale2) ; ; Y axis rotation ; temp = x + flip(z) temp = temp*yrot x = real(temp) z = imag(temp) ; ; X axis rotation ; temp = y + flip(z) temp = temp*xrot y = real(temp) z = imag(temp) ; calculate 3D distance float d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +z^2)*@scale if @usez if @tz == "cabs(z)" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*cabs(pz)-z)^2)*@scale elseif @tz == "real+imag z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz)+imag(pz))-z)^2)*@scale elseif @tz == "real z" d = sqrt((imag(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz))-z)^2)*@scale elseif @tz == "real z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(imag(pz))-z)^2)*@scale elseif @tz == "angle pz" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*atan2(pz)-z)^2)*@scale endif endif m_lastZ = x + flip(y) return d endfunc protected: complex xrot complex yrot complex temp default: title = "Bow Surface" heading text = "This is a 3D parametric surface." endheading int param v_BowSurface caption = "Version (Trap Shape BowSurface)" 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_BowSurface < 100 endparam float param xang caption = "X rotation" default = -100 endparam float param yang caption = "Y rotation" default = 30 endparam float param scale2 caption = "Prescale" default = 0.5 endparam float param scale caption = "Scale" default = 0.2 endparam float param T caption = "Bow thickness" default = 1 endparam bool param usez caption = "fractal z for z value" default = false endparam param tz caption = "fractal z type" enum = "cabs(z)" "real+imag z" "real z" "imag z" "angle pz" default = 0 visible = @usez endparam float param sz caption = "fractal z scale" default = 1 visible = @usez endparam } class REB_BoySurface(common.ulb:TrapShape) { ; This shape uses the 3D Boy Surface function.
;

public: import "common.ulb" ; Constructor func REB_BoySurface(Generic pparent) TrapShape.TrapShape(pparent) xrot = (0,1)^(@xang/90) yrot = (0,1)^(@yang/90) temp = 0 endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float x = (((2/3)*(cos(real(pz))*cos(2*imag(pz))+sqrt(2)*sin(real(pz))*cos(imag(pz)))*cos(real(pz)) \ /(sqrt(2) - sin(2*real(pz))*sin(3*imag(pz)))))*@scale2 float y = (((2/3)*(cos(real(pz))*sin(2*imag(pz))-sqrt(2)*sin(real(pz))*sin(imag(pz)))*cos(real(pz)) \ /(sqrt(2)-sin(2*real(pz))*sin(3*imag(pz)))))*@scale2 float z = ((sqrt(2)*cos(real(pz))^2 / (sqrt(2) - sin(2*real(pz))*sin(2*imag(pz)))))*@scale2 ; ; Y axis rotation ; temp = x + flip(z) temp = temp*yrot x = real(temp) z = imag(temp) ; ; X axis rotation ; temp = y + flip(z) temp = temp*xrot y = real(temp) z = imag(temp) ; calculate 3D distance float d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +z^2)*@scale if @usez if @tz == "cabs(z)" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*cabs(pz)-z)^2)*@scale elseif @tz == "real+imag z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz)+imag(pz))-z)^2)*@scale elseif @tz == "real z" d = sqrt((imag(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz))-z)^2)*@scale elseif @tz == "real z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(imag(pz))-z)^2)*@scale elseif @tz == "angle pz" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*atan2(pz)-z)^2)*@scale endif endif m_lastZ = x + flip(y) return d endfunc protected: complex xrot complex yrot complex temp default: title = "Boy Surface" heading text = "This is a 3D parametric surface." endheading int param v_BoySurface caption = "Version (Trap Shape BowSurface)" 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_BoySurface < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 0 endparam float param scale2 caption = "Prescale" default = 1.0 endparam float param scale caption = "Scale" default = 0.2 endparam bool param usez caption = "fractal z for z value" default = false endparam param tz caption = "fractal z type" enum = "cabs(z)" "real+imag z" "real z" "imag z" "angle pz" default = 0 visible = @usez endparam float param sz caption = "fractal z scale" default = 1 visible = @usez endparam } class REB_BourMinimalSurface(common.ulb:TrapShape) { ; This shape uses the 3D Bour Minimal Surface function.
;

public: import "common.ulb" ; Constructor func REB_BourMinimalSurface(Generic pparent) TrapShape.TrapShape(pparent) xrot = (0,1)^(@xang/90) yrot = (0,1)^(@yang/90) temp = 0 endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float x = ((real(pz)^(@n-1)* cos((@n-1)*imag(pz))/(2*(@n-1)) - real(pz)^(@n+1)* cos((@n+1)*imag(pz))/(2*(@n+1))))*@scale2 float y = ((real(pz)^(@n-1)* sin((@n-1)*imag(pz))/(2*(@n-1)) + real(pz)^(@n+1)* sin((@n+1)*imag(pz))/(2*(@n+1))))*@scale2 float z = ((real(pz)^@n*cos(@n*imag(pz)) / @n))*@scale2 ; ; Y axis rotation ; temp = x + flip(z) temp = temp*yrot x = real(temp) z = imag(temp) ; ; X axis rotation ; temp = y + flip(z) temp = temp*xrot y = real(temp) z = imag(temp) ; calculate 3D distance float d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +z^2)*@scale if @usez if @tz == "cabs(z)" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*cabs(pz)-z)^2)*@scale elseif @tz == "real+imag z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz)+imag(pz))-z)^2)*@scale elseif @tz == "real z" d = sqrt((imag(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz))-z)^2)*@scale elseif @tz == "real z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(imag(pz))-z)^2)*@scale elseif @tz == "angle pz" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*atan2(pz)-z)^2)*@scale endif endif m_lastZ = x + flip(y) return d endfunc protected: complex xrot complex yrot complex temp default: title = "Bour Minimal Surface" heading text = "This is a 3D parametric surface." endheading int param v_BourMinimalSurface caption = "Version (Trap Shape BourMinimalSurface)" 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_BourMinimalSurface < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param scale2 caption = "Prescale" default = 1.0 endparam float param scale caption = "Scale" default = 0.2 endparam int param n caption = "Integer parameter" default = 3 min = 2 endparam bool param usez caption = "fractal z for z value" default = false endparam param tz caption = "fractal z type" enum = "cabs(z)" "real+imag z" "real z" "imag z" "angle pz" default = 0 visible = @usez endparam float param sz caption = "fractal z scale" default = 1 visible = @usez endparam } class REB_BohemianDome(common.ulb:TrapShape) { ; This shape uses the 3D Bohemian Dome Surface function.
;

public: import "common.ulb" ; Constructor func REB_BohemianDome(Generic pparent) TrapShape.TrapShape(pparent) xrot = (0,1)^(@xang/90) yrot = (0,1)^(@yang/90) temp = 0 endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float x = (@ba*cos(real(pz)))*@scale2 float y = (@bb*cos(imag(pz)) + @ba*sin(real(pz)))*@scale2 float z = (@bc*sin(imag(pz)))*@scale2 ; ; Y axis rotation ; temp = x + flip(z) temp = temp*yrot x = real(temp) z = imag(temp) ; ; X axis rotation ; temp = y + flip(z) temp = temp*xrot y = real(temp) z = imag(temp) ; calculate 3D distance float d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +z^2)*@scale if @usez if @tz == "cabs(z)" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*cabs(pz)-z)^2)*@scale elseif @tz == "real+imag z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz)+imag(pz))-z)^2)*@scale elseif @tz == "real z" d = sqrt((imag(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz))-z)^2)*@scale elseif @tz == "real z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(imag(pz))-z)^2)*@scale elseif @tz == "angle pz" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*atan2(pz)-z)^2)*@scale endif endif m_lastZ = x + flip(y) return d endfunc protected: complex xrot complex yrot complex temp default: title = "Bohemian Dome" heading text = "This is a 3D parametric surface." endheading int param v_BohemianDome caption = "Version (Trap Shape Bohemian Dome)" 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_BohemianDome < 100 endparam float param xang caption = "X rotation" default = -30 endparam float param yang caption = "Y rotation" default = 60 endparam float param scale2 caption = "Precale" default = 1.0 endparam float param scale caption = "Scale" default = 0.2 endparam float param ba caption = "param a" default = 0.5 endparam float param bb caption = "param b" default = 1.5 endparam float param bc caption = "param c" default = 1.0 endparam bool param usez caption = "fractal z for z value" default = false endparam param tz caption = "fractal z type" enum = "cabs(z)" "real+imag z" "real z" "imag z" "angle pz" default = 0 visible = @usez endparam float param sz caption = "fractal z scale" default = 1 visible = @usez endparam } class REB_BanchoffKleinBottle(common.ulb:TrapShape) { ; This shape uses the 3D Banchoff Klein Bottle Surface function.
;

public: import "common.ulb" ; Constructor func REB_BanchoffKleinBottle(Generic pparent) TrapShape.TrapShape(pparent) xrot = (0,1)^(@xang/90) yrot = (0,1)^(@yang/90) temp = 0 endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float x = (cos(real(pz)/@banc)*(cos(real(pz)/@banb)*(@bana+cos(imag(pz)))+ \ (sin(real(pz)/@banb)*sin(imag(pz))*cos(imag(pz)))))*@bc float y = (sin(real(pz)/@banc)*(cos(real(pz)/@banb)*(@bana+cos(imag(pz)))+ \ (sin(real(pz)/@banb)*sin(imag(pz))*cos(imag(pz)))))*@bc float z = (-sin(real(pz)/@banb)*(@bana+cos(imag(pz)))+cos(real(pz)/@banb)*sin(imag(pz))*cos(imag(pz)))*@bc ; ; Y axis rotation ; temp = x + flip(z) temp = temp*yrot x = real(temp) z = imag(temp) ; ; X axis rotation ; temp = y + flip(z) temp = temp*xrot y = real(temp) z = imag(temp) ; calculate 3D distance float d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +z^2)*@scale if @usez if @tz == "cabs(z)" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*cabs(pz)-z)^2)*@scale elseif @tz == "real+imag z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz)+imag(pz))-z)^2)*@scale elseif @tz == "real z" d = sqrt((imag(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz))-z)^2)*@scale elseif @tz == "real z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(imag(pz))-z)^2)*@scale elseif @tz == "angle pz" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*atan2(pz)-z)^2)*@scale endif endif m_lastZ = x + flip(y) return d endfunc protected: complex xrot complex yrot complex temp default: title = "Banchoff Klein Bottle" heading text = "This is a 3D parametric surface." endheading int param v_BanchoffKleinBottle caption = "Version (Banchoff Klein Bottle)" 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_BanchoffKleinBottle < 100 endparam float param xang caption = "X rotation" default = -90 endparam float param yang caption = "Y rotation" default = 90 endparam float param scale caption = "scale" default = 0.2 endparam bool param usez caption = "fractal z for z value" default = false endparam param tz caption = "fractal z type" enum = "cabs(z)" "real+imag z" "real z" "imag z" "angle pz" default = 0 visible = @usez endparam float param sz caption = "fractal z scale" default = 1 visible = @usez endparam float param bc caption = "Banchoff scale" default = 0.5 endparam float param bana caption = "Parameter a" default = 1.414213 endparam float param banb caption = "Parameter b" default = 2.0 endparam float param banc caption = "Parameter c" default = 1.0 endparam } class REB_TrapShapeConvexPolygons(common.ulb:TrapShape) { ; This shape uses the Convex Polygons.
$define debug public: import "common.ulb" ; Constructor func REB_TrapShapeConvexPolygons(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; call before each iteration func Init(complex pz) TrapShape.Init(pz) twopi = 2*#pi i = 0 x=0.0 y=0.0 ; create the vertex aray repeat vx[i] = sin(i*twopi/@sides) vy[i] = cos(i*twopi/@sides) v[i] = vx[i] + flip(vy[i]) i = i + 1 until i == @sides endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) i = 0 if @flavor == "flavor 1" d = 1e10 else d = 0 endif ; calculate r[i] and t[i] for first n-1 sides repeat t[i]=(5*pz/@scale-v[i])/(v[i+1]-v[i]) x=real(t[i]) y=imag(t[i]) if @extend && @flavor == "flavor 1" r[i]=abs(y) else if(x<0.0) r[i]=cabs(t[i]) elseif(x>1.0) r[i]=cabs(t[i]-1) else r[i]=abs(y) endif endif r[i]=r[i]*cabs(v[i+1]-v[i]) i = i + 1 until i == (@sides-1) ; calculate r[i] and t[i] for the last side t[@sides-1]=(5*pz/@scale-v[@sides-1])/(v[0]-v[@sides-1]) x=real(t[@sides-1]) y=imag(t[@sides-1]) if @extend && @flavor == "flavor 1" r[@sides-1]=abs(y) else if(x<0.0) r[@sides-1]=cabs(t[@sides-1]) elseif(x>1.0) r[@sides-1]=cabs(t[@sides-1]-1) else r[@sides-1]=abs(y) endif endif r[@sides-1]=r[@sides-1]*cabs(v[0]-v[@sides-1]) i = 0 repeat if r[i] < d if @flavor == "flavor 1" d = r[i] endif endif m_LastZ = m_LastZ + t[i] if @flavor == "flavor 2" d = d + cabs(r[i]) elseif @flavor == "flavor 3" d = d + cabs(t[i]) endif i = i + 1 until i == @sides m_LastZ = m_LastZ/@sides^2 if @flavor != "flavor 1" d = d/@sides^2 else d = d/@sscale endif return d endfunc private: complex v[10] complex t[10] float r[10] float vx[10] float vy[10] float twopi int i float x float y float d default: title = "Convex Polygons" int param v_ConvexPolygons caption = "Version (ConvexPolygons)" 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_ConvexPolygons < 100 endparam int param sides caption="# of sides" default = 5 min = 3 max = 10 endparam float param scale caption = "Polygon scale" default = 1.0 endparam bool param extend caption = "Extend the sides" default = false visible = @flavor == "flavor 1" endparam param flavor caption = "Poly Shape flavor" default = 0 enum = "flavor 1" "flavor 2" "flavor 3" endparam float param sscale caption = "Poly Shape scale" default = 1.0 visible = @flavor == "flavor 1" endparam } class REB_TrapShapeStars(common.ulb:TrapShape) { ; This shape uses the Convex Polygons.
$define debug public: import "common.ulb" ; Constructor func REB_TrapShapeStars(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; call before each iteration func Init(complex pz) TrapShape.Init(pz) twopi = 2*#pi i = 0 x=0.0 y=0.0 ; create the vertex aray repeat vx[i] = sin(i*twopi/@sides) vy[i] = cos(i*twopi/@sides) v[i] = vx[i] + flip(vy[i]) i = i + 1 until i == @sides endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) i = 0 if @flavor == "flavor 1" d = 1e10 else d = 0 endif ; calculate r[i] and t[i] for first n-2 sides repeat t[i]=(5*pz/@scale-v[i])/(v[i+2]-v[i]) x=real(t[i]) y=imag(t[i]) if @extend && @flavor == "flavor 1" r[i]=abs(y) else if(x<0.0) r[i]=cabs(t[i]) elseif(x>1.0) r[i]=cabs(t[i]-1) else r[i]=abs(y) endif endif r[i]=r[i]*cabs(v[i+2]-v[i]) i = i + 1 until i == (@sides-2) ; calculate r[i] and t[i] for the last two sides t[@sides-2]=(5*pz/@scale-v[@sides-2])/(v[0]-v[@sides-2]) x=real(t[@sides-2]) y=imag(t[@sides-2]) if @extend && @flavor == "flavor 1" r[@sides-2]=abs(y) else if(x<0.0) r[@sides-2]=cabs(t[@sides-2]) elseif(x>1.0) r[@sides-2]=cabs(t[@sides-2]-1) else r[@sides-2]=abs(y) endif endif r[@sides-2]=r[@sides-2]*cabs(v[0]-v[@sides-2]) t[@sides-1]=(5*pz/@scale-v[@sides-1])/(v[1]-v[@sides-1]) x=real(t[@sides-1]) y=imag(t[@sides-1]) if @extend && @flavor == "flavor 1" r[@sides-1]=abs(y) else if(x<0.0) r[@sides-1]=cabs(t[@sides-1]) elseif(x>1.0) r[@sides-1]=cabs(t[@sides-1]-1) else r[@sides-1]=abs(y) endif endif r[@sides-1]=r[@sides-1]*cabs(v[1]-v[@sides-1]) i = 0 repeat if r[i] < d if @flavor == "flavor 1" d = r[i] endif endif m_LastZ = m_LastZ + t[i] if @flavor == "flavor 2" d = d + cabs(r[i]) elseif @flavor == "flavor 3" d = d + cabs(t[i]) endif i = i + 1 until i == @sides m_LastZ = m_LastZ/@sides^2 if @flavor != "flavor 1" d = d/@sides^2 else d = d/@sscale endif return d endfunc private: complex v[10] complex t[10] float r[10] float vx[10] float vy[10] float twopi int i float x float y float d default: title = "Stars" int param v_Stars caption = "Version (Stars)" 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_Stars < 100 endparam int param sides caption="# of sides" default = 5 min = 5 max = 10 endparam float param scale caption = "Star scale" default = 1.0 endparam bool param extend caption = "Extend the sides" default = false visible = @flavor == "flavor 1" endparam param flavor caption = "Star Shape flavor" default = 0 enum = "flavor 1" "flavor 2" "flavor 3" endparam float param sscale caption = "Star Shape scale" default = 1.0 visible = @flavor == "flavor 1" endparam } class REB_TrapShapeCircleCatacaustic(common.ulb:TrapShape) { ; This shape uses the circle catacaustic function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeCircleCatacaustic(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float theta = 0 float d = 0 float af1 = 0 float af2 = 0 complex as = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif af1 = 2*@b*(1-3*2*@b*cos(theta)+2*2*@b*cos(theta)^3)/(-(1+2*(2*@b)^2)+3*2*@b*cos(theta)) af2 = 2*(2*@b)^2*sin(theta)^3/(1+2*(2*@b)^2-3*2*@b*cos(theta)) as = @a*(af1 + sgn*flip(af2)) if @absval d = abs(cabs(pz) - cabs(as)) else d = cabs(pz - (as)) endif m_LastZ = as return d endfunc default: title = "Circle Catacaustic" int param v_trapshapecirclecatacaustic caption = "Version (Trap Shape Circle Catacaustic)" default = 102 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_trapshapecirclecatacaustic < 102 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeCruciform(common.ulb:TrapShape) { ; This shape uses the cruciform function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeCruciform(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float theta = 0 float d = 0 float af1 = 0 float af2 = 0 complex as = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif af1 = 0.1*@a/cos(theta) af2 = 0.02*@b/sin(theta) as = (af1 + sgn*flip(af2)) if @absval d = abs(cabs(pz) - cabs(as)) else d = cabs(pz - (as)) endif m_LastZ = as return d endfunc default: title = "Cruciform" int param v_trapshapecruciform caption = "Version (Trap Shape Cruciform)" default = 102 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_trapshapecruciform < 102 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeCurtateCycloid(common.ulb:TrapShape) { ; This shape uses the curtate cycloid function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeCurtateCycloid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float theta = 0 float d = 0 complex af1 = 0 complex af2 = 0 complex as = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif af1 = @a*theta - 0.1*@b*@afn2(theta) af2 = @a - 0.1*@b*@afn1(theta) as = (af1 + sgn*flip(af2)) if @absval d = abs(cabs(pz) - cabs(as)) else d = cabs(pz - (as)) endif m_LastZ = as return d endfunc default: title = "Curtate Cycloid" int param v_trapshapecurtatecycloid caption = "Version (Trap Shape Curtate Cycloid)" default = 102 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_trapshapecurtatecycloid < 102 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam func afn1 caption = "Function #1" default = cos() endfunc func afn2 caption = "Function #2" default = sin() endfunc bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeCycloid(common.ulb:TrapShape) { ; This shape uses the cycloid function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeCycloid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = cabs(pz) if @absval d = abs(cabs(pz) - cabs(rr*(theta-sin(theta) + sgn*flip(rr*(1-cos(theta)))))) else d = cabs(pz - (rr*(theta-sin(theta) + sgn*flip(rr*(1-cos(theta)))))) endif m_LastZ = (rr*(theta-sin(theta) + sgn*flip(rr*(1-cos(theta))))) return d endfunc default: title = "Cycloid" int param v_trapshapecycloid caption = "Version (Trap Shape Cycloid)" default = 102 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_trapshapecycloid < 102 endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeCycloidofSeva(common.ulb:TrapShape) { ; This shape uses the cycloid of Seva function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeCycloidofSeva(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = 0.5*@a*(1+2*cos(2*theta)) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Cycloid of Seva" int param v_trapshapecycloidofseva caption = "Version (Trap Shape Cycloid Of Seva)" default = 102 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_trapshapecycloidofseva < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeDeltoidCatacaustic(common.ulb:TrapShape) { ; This shape uses the deltoid catacaustic function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeDeltoidCatacaustic(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float theta = 0 float d = 0 complex af1 = 0 complex af2 = 0 complex as = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif af1 = 3*@afn1(theta) + @afn1(3*theta+#pi/2*@b) - @afn1(#pi/2*@b) af2 = 3*@afn2(theta) + @afn2(3*theta+#pi/2*@b) - @afn2(#pi/2*@b) as = 0.25*@a*(af1 + sgn*flip(af2)) if @absval d = abs(cabs(pz) - cabs(as)) else d = cabs(pz - (as)) endif m_LastZ = as return d endfunc default: title = "Deltoid Catacaustic" int param v_trapshapedeltoidcatacaustic caption = "Version (Trap Shape Deltoid Catacaustic)" default = 102 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_trapshapedeltoidcatacaustic < 102 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam func afn1 caption = "Function #1" default = cos() endfunc func afn2 caption = "Function #2" default = sin() endfunc bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeDevilsCurve(common.ulb:TrapShape) { ; This shape uses the devil's curve function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeDevilsCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = (((0.5*@a*sin(theta))^2-(0.2*@b*cos(theta))^2)/(sin(theta)^2-cos(theta)^2))^0.5 if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Devils Curve" int param v_trapshapedevilscurve caption = "Version (Trap Shape Devils Curve)" default = 102 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_trapshapedevilscurve < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects shape and scale of trap." endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeArachnida1(common.ulb:TrapShape) { ; This shape uses the arachnida 1 function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeArachnida1(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float x = 0 float y = 0 if @wave float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = 0.25*@a*sin(@pi*theta)/sin((@pi-1)*theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else x = real(pz) y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Arachnida 1" int param v_trapshapearachnida1 caption = "Version (Trap Shape Arachnida 1)" default = 101 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_trapshapearachnida1 < 101 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam int param pi caption = "Polar integer" default = 3 hint = "Affects shape and scale of trap." endparam bool param wave caption = "Add petal wave" default = false endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeArachnida2(common.ulb:TrapShape) { ; This shape uses the arachnida 2 function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeArachnida2(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = 0.25*@a*sin(@pi*theta)/sin((@pi+1)*theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Arachnida 2" int param v_trapshapearachnida2 caption = "Version (Trap Shape Arachnida 2)" default = 101 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_trapshapearachnida2 < 101 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam int param pi caption = "Polar integer" default = 3 hint = "Affects shape and scale of trap." endparam bool param wave caption = "Add petal wave" default = false endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeArchimedes(common.ulb:TrapShape) { ; This shape uses the Archimedes function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeArchimedes(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif float rr = @b+@a*theta if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Archimedes" int param v_trapshapearchimedes caption = "Version (Trap Shape Archimedes)" default = 102 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_trapshapearchimedes < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 0.0 hint = "Affects spiral start point" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeAtzemaSpiral(common.ulb:TrapShape) { ; This shape uses the Atzema spiral function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeAtzemaSpiral(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float theta = 0 float d = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif float af1 = 0.5*@a*(sin(theta)/theta-2*cos(theta)-theta*sin(theta)) float af2 = 0.05*@b*(cos(theta)/theta-2*sin(theta)+theta*cos(theta)) complex as = (af1 + sgn*flip(af2)) IF @absval d = abs(cabs(pz) - cabs(as)) ELSE d = cabs(pz - as) ENDIF m_LastZ = as return d endfunc default: title = "Atzema Spiral" int param v_trapshapeatzemaspiral caption = "Version (Trap Shape Atzema Spiral)" default = 102 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_trapshapeatzemaspiral < 102 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeBicorn(common.ulb:TrapShape) { ; This shape uses the bicorn function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeBicorn(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = y^2*(@aa^2-x^2)-(x^2+2*@aa*y-@aa^2)^2+cabs(pz)*@offset else d = y^2*(@aa^2-x^2)-(x^2+2*@aa*y-@aa^2)^2+@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else int sgn = 1 if @sgn sgn = -1 endif float theta = 0 float d = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif float af1 = @a*sin(theta) float af2 = @a*cos(theta)^2*(2+cos(theta))/(3+sin(theta)^2) complex as = (af1 + sgn*flip(af2)) IF @absval d = abs(cabs(pz) - cabs(as)) ELSE d = cabs(pz - as) ENDIF m_LastZ = as endif return d endfunc default: title = "Bicorn" int param v_trapshapebicorn caption = "Version (Trap Shape Bicorn)" default = 102 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_trapshapebicorn < 102 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1.25 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "Bicorn parameter" default = 1.25 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@altformula endparam bool param alttheta caption = "Alternate theta" default = false visible = !@altformula endparam } class REB_TrapShapeBicuspid(common.ulb:TrapShape) { ; This shape uses the bicuspid function.
;

; This variant of the function involves taking a square root ; so there are two solutions. A signed and absolute value version of ; the distance is also available. The transformed value is the ; complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeBicuspid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = (x^2-@aa^2)*(x-@aa)^2+(y^2-@aa^2)^2+cabs(pz)*@offset else d = (x^2-@aa^2)*(x-@aa)^2+(y^2-@aa^2)^2+@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else int sgn = 1 if @sgn sgn = -1 endif y = imag(pz) float qx = 0 float qb = -2*(0.05*@b)^2 float qc = (0.05*@b)^4 - (y^2 - (0.05*@b)^2)^2 if @negroot qx = ((-qb - (qb^2 - 4*qc)^0.5)/(2))^0.5 else qx = ((-qb + (qb^2 - 4*qc)^0.5)/(2))^0.5 endif if @absval d = abs(cabs(pz) - cabs(2.25*@a*(qx + sgn*flip(y)))) else d = cabs(pz - 2.25*@a*(qx + sgn*flip(y))) endif m_LastZ = 2.25*@a*(qx + sgn*flip(y)) endif return d endfunc default: title = "Bicuspid" int param v_trapshapebicuspid caption = "Version (Trap Shape Bicuspid)" default = 101 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_trapshapebicuspid < 101 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "parameter a" default = 1 hint = "Affects spread and scale of trap" visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@altformula endparam param negroot caption = "Quad Reg Root" default = false visible = !@altformula endparam } class REB_TrapShapeRhodonea(common.ulb:TrapShape) { ; This shape uses the rhodonea function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeRhodonea(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = @a*sin(5*@b*theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Rhodonea" int param v_Rhodonea caption = "Version (Rhodonea)" 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_Rhodonea < 100 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param @wave caption = "Add petal wave" default = false endparam float param @wamp caption = "Wave amplitude" default = 0.05 visible = @wave endparam float param @wfreq caption = "Wave frequency" default = 20 visible = @wave endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeCircleTangent(common.ulb:TrapShape) { ; This shape uses the Circle Tangent function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeCircleTangent(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = 0.5*@a*(1+@b/10*sin(theta)^(8*@c)) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Circle Tangent" int param v_CircleTangent caption = "Version (Circle Tangent)" 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_CircleTangent < 100 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param c caption = "3rd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeBifolium(common.ulb:TrapShape) { ; This shape uses the bifolium function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeBifolium(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = (x^2+y^2)^2-(x-@aa*y)*x^2-cabs(pz)*@offset else d = (x^2+y^2)^2-(x-@aa*y)*x^2-@offset endif m_lastz = x-d + flip(y-d) if abs(d) < @width d =abs(d) else d = 1e20 endif else if @wave float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float theta = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = 4*@a*sin(theta)*sin(theta)*cos(theta) if @v_trapshapebifolium >= 102 rr = 4*@a*sin(@c*theta)^@b*cos(theta) endif if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else x = real(pz) y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif endif return d endfunc default: title = "Bifolium" int param v_trapshapebifolium caption = "Version (Trap Shape Bifolium)" default = 102 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_trapshapebifolium < 102 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 0.2 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "Bifolium param" default = 5.0 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc bool param ptraps caption = "Use as Polar Traps" default = false visible = !@altformula endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." visible = !@altformula endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = @v_trapshapebifolium >= 102 && !@altformula endparam float param c caption = "Polar parameter 2" default = 1 visible = @v_trapshapebifolium >= 102 && !@altformula endparam float param b caption = "Power" default = 2 visible = @v_trapshapebifolium >= 102 && !@altformula endparam bool param @wave caption = "Add petal wave" default = false visible = @v_trapshapebifolium >= 102 && !@altformula endparam float param @wamp caption = "Wave amplitude" default = 0.05 visible = @wave && !@altformula endparam float param @wfreq caption = "Wave frequency" default = 20 visible = @wave && !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps && !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@ptraps && !@altformula endparam } class REB_TrapShapeBotanicCurve(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeBotanicCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = 0.5*@a*(1 + @b*sin(@c*theta)) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Botanic Curve" int param v_BotanicCurve caption = "Version (Botanic Curve)" 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_BotanicCurve < 100 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "Petal Sharpness" default = 1 endparam float param c caption = "Petals" default = 10 endparam bool param @wave caption = "Add petal wave" default = false endparam float param @wamp caption = "Wave amplitude" default = 0.05 visible = @wave endparam float param @wfreq caption = "Wave frequency" default = 20 visible = @wave endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeObliqueStrophoid(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeObliqueStrophoid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = @a*sin(@b-2*theta)/sin(@b-theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Oblique Strophoid" int param v_ObliqueStrophoid caption = "Version (Obliquev Strophoid)" 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_ObliqueStrophoid < 100 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "Strophoid parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeFermatsSpiral(common.ulb:TrapShape) { ; This shape uses the FermatsSpiral function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeFermatsSpiral(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = 2*@a*theta^0.5 if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Fermat's Spiral" int param v_trapshapeFermatsSpiral caption = "Version (Trap Shape Fermat's Spiral)" default = 101 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_trapshapeFermatsSpiral < 101 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeAtomSpiral(common.ulb:TrapShape) { ; This shape uses the atom spiral function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeAtomSpiral(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = 0.5*@a*theta/(theta + @b*0.25) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Atom Spiral" int param v_AtomSpiral caption = "Version (Atom Spiral)" 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_AtomSpiral < 100 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeCevasTrisectrix(common.ulb:TrapShape) { ; This shape uses the atom spiral function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeCevasTrisectrix(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = (x^2+y^2)^3-((@aa+1)*x^2-(@aa-1)*y^2)^2-cabs(pz)*@offset else d = (x^2+y^2)^3-((@aa+1)*x^2-(@aa-1)*y^2)^2-@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = 2.5*@a*(1+@b*sin(2*theta)) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else x = real(pz) y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif endif return d endfunc default: title = "Ceva's Trisectrix" int param v_CevasTrisectrix caption = "Version (Ceva's Trisectrix)" 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_CevasTrisectrix < 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "parameter a" default = 2 hint = "Affects spread and scale of trap" visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc bool param ptraps caption = "Use as Polar Traps" default = false visible = !@altformula endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps && !@altformula hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps && !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@ptraps && !@altformula endparam } class REB_TrapShapeHyperbolicSpiral(common.ulb:TrapShape) { ; This shape uses the HyperbolicSpiralfunction.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeHyperbolicSpiral(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = @a/theta if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Hyperbolic Spiral" int param v_HyperbolicSpiral caption = "Version (HyperbolicSpiral)" 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_HyperbolicSpiral < 100 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeNodalCurve(common.ulb:TrapShape) { ; This shape uses the NodalCurve function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeNodalCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = @a*tan(@b*theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Nodal Curve" int param v_NodalCurve caption = "Version (NodalCurve)" 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_NodalCurve < 100 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeGielisCurve(common.ulb:TrapShape) { ; This shape uses the Gielis curve.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeGielisCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = @a*(abs(cos(2*@b*theta))^@pa + abs(sin(2*@b*theta))^@pb)^@pc if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Gielis Curve" int param v_GielisCurve caption = "Version (GielisCurve)" 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_GielisCurve < 100 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param pa caption = "Power a" default = 10.0 hint = "Affects spread and scale of trap" endparam float param pb caption = "Power b" default = 10.0 hint = "Affects spread and scale of trap" endparam float param pc caption = "Power c" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param wave caption = "Add petal wave" default = false endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeSuperSpiral(common.ulb:TrapShape) { ; This shape uses the SuperSpiral curve.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeSuperSpiral(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = @a*exp(0.2*@c*theta)*(abs(cos(3*@b*theta))^@pa + abs(sin(3*@b*theta))^@pb)^@pc if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Super Spiral" int param v_SuperSpiral caption = "Version (Super Spiral)" 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_SuperSpiral < 100 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param c caption = "3rd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param pa caption = "Power a" default = 10.0 hint = "Affects spread and scale of trap" endparam float param pb caption = "Power b" default = 10.0 hint = "Affects spread and scale of trap" endparam float param pc caption = "Power c" default = -0.2 hint = "Affects spread and scale of trap" endparam bool param @wave caption = "Add petal wave" default = false endparam float param @wamp caption = "Wave amplitude" default = 0.05 visible = @wave endparam float param @wfreq caption = "Wave frequency" default = 20 visible = @wave endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeConchoidOfDeSluze(common.ulb:TrapShape) { ; This shape uses the ConchoidOfDeSluze function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeConchoidOfDeSluze(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale if !@cmplx x = real(@fn1(pz)) y = imag(@fn2(pz)) else x = real(@fn1(pz)) y = imag(@fn1(pz)) endif if @ref == "pz" d = x^3+x*y^2-x^2-y^2-@a1^2*x^2-cabs(pz)*@offset else d = x^3+x*y^2-x^2-y^2-@a1^2*x^2-@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = @a*(1/cos(theta) - 1.5*@b*cos(theta)) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif endif return d endfunc default: title = "Conchoid of De Sluze" int param v_ConchoidOfDeSluze caption = "Version (ConchoidOfDeSluze)" 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_ConchoidOfDeSluze < 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param a1 caption = "parameter a1" default = 2 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam bool param cmplx caption = "Apply to complex" default = false visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula && !@cmplx endfunc bool param ptraps caption = "Use as Polar Traps" default = false visible = !@altformula endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps && !@altformula hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps && !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@ptraps && !@altformula endparam } class REB_TrapShapeEpitrochoid(common.ulb:TrapShape) { ; This shape uses the Epitrochoid function.
public: import "common.ulb" ; Constructor func REB_TrapShapeEpitrochoid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = (@a*2.5+@b*0.6)*cos(t) - 1.3*@c*cos((2.5*@a/(@b*0.6)+1)*t) float y = (@a*2.5+@b*0.6)*sin(t) - 1.3*@c*sin((2.5*@a/(@b*0.6)+1)*t) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Epitrochoid" int param v_Epitrochoid caption = "Version (Epitrochoid)" default = 101 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_Epitrochoid < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param c caption = "3rd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } class REB_TrapShapeCornoid(common.ulb:TrapShape) { ; This shape uses the Cornoid function.
public: import "common.ulb" ; Constructor func REB_TrapShapeCornoid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave && @partype == "angle" float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@b*10 float x = @a*cos(t)*(1-2*sin(t)^2) float y = @a*sin(t)*(1+2*cos(t)^2) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Cornoid" int param v_Cornoid caption = "Version (Cornoid)" 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_Cornoid < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam bool param wave caption = "Add petal wave" default = false visible = @partype == "angle" endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && @partype == "angle" endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && @partype == "angle" endparam } class REB_TrapShapeResonanceCurve(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_ResonanceCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave && @partype == "angle" float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@b*10 float x = @a*tan(t) float y = @a*cos(t)^2 m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Resonance Curve" int param v_ResonanceCurve caption = "Version (Resonance Curve)" 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_ResonanceCurve < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam bool param wave caption = "Add petal wave" default = false visible = @partype == "angle" endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && @partype == "angle" endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && @partype == "angle" endparam } class REB_TrapShapeInfiniteQuadrifolium(common.ulb:TrapShape) { ; This shape uses the InfiniteQuadrifolium function.
public: import "common.ulb" ; Constructor func REB_TrapShapeInfiniteQuadrifolium(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@b*6.28 float x = 2*@a*(t^3-t)*(t-1)/(t^3+1)^2 float y = 2*@a*(t^3-t)*(t+1)/(t^3+1)^2 m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Infinite Quadrifolium" int param v_InfiniteQuadrifolium caption = "Version (Infinite Quadrifolium)" 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_InfiniteQuadrifolium < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } class REB_TrapShapeLegendre(common.ulb:TrapShape) { ; This shape uses the Legendre function.
public: import "common.ulb" ; Constructor func REB_TrapShapeLegendre(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave && @partype == "angle" float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float d = 0 float t = 0 float x = 0 float y = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@b if @n == "2" y = 5*@a*(3*sin(t)^2 - 1)/2 x = 5*@a*(3*cos(t)^2 - 1)/2 elseif @n == "3" y = 5*@a*(5*sin(t)^3 - 3*sin(t))/2 x = 5*@a*(5*cos(t)^3 - 3*cos(t))/2 elseif @n == "4" y = 5*@a*(35*sin(t)^4 - 30*sin(t)^2 + 3)/8 x = 5*@a*(35*cos(t)^4 - 30*cos(t)^2 + 3)/8 elseif @n == "5" y = 5*@a*(63*sin(t)^5 - 70*sin(t)^3 + 15*sin(t))/8 x = 5*@a*(63*cos(t)^5 - 70*cos(t)^3 + 15*cos(t))/8 elseif @n == "6" y = 5*@a*(231*sin(t)^6 - 315*sin(t)^4 + 105*sin(t)^2 -5)/16 x = 5*@a*(231*cos(t)^6 - 315*cos(t)^4 + 105*cos(t)^2 -5)/16 endif m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Legendre" int param v_Legendre caption = "Version (Legendre)" 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_Legendre < 100 endparam param n caption = "Legendre number" default = 0 enum = "2" "3" "4" "5" "6" endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam bool param wave caption = "Add petal wave" default = false visible = @partype == "angle" endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && @partype == "angle" endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && @partype == "angle" endparam } class REB_TrapShapeLaguerre(common.ulb:TrapShape) { ; This shape uses the Laguerre function.
public: import "common.ulb" ; Constructor func REB_TrapShapeLaguerre(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave && @partype == "angle" float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float d = 0 float t = 0 float x = 0 float y = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@b*5 if @n == "2" y = @a*(Sin(t)^2 - 4*sin(t) + 2)/2 x = @a*(cos(t)^2 - 4*cos(t) + 2)/2 elseif @n == "3" y = @a*(-sin(t)^3 + 9*sin(t)^2 - 18*sin(t) + 6)/6 x = @a*(-cos(t)^3 + 9*cos(t)^2 - 18*cos(t) + 6)/6 elseif @n == "4" y = @a*(sin(t)^4 - 16*sin(t)^3 + 72*sin(t)^2 - 96*sin(t) + 24)/24 x = @a*(cos(t)^4 - 16*cos(t)^3 + 72*cos(t)^2 - 96*cos(t) + 24)/24 elseif @n == "5" y = @a*(-sin(t)^5 + 25*sin(t)^4 - 200*sin(t)^3 + 600*sin(t)^2 - 600*sin(t) + 120)/120 x = @a*(-cos(t)^5 + 25*cos(t)^4 - 200*cos(t)^3 + 600*cos(t)^2 - 600*cos(t) + 120)/120 elseif @n == "6" y = @a*(sin(t)^6 - 36*sin(t)^5 + 450*sin(t)^4 - 2400*sin(t)^3 + 5400*sin(t)^2 \ -4320*sin(t) + 720)/720 x = @a*(cos(t)^6 - 36*cos(t)^5 + 450*cos(t)^4 - 2400*cos(t)^3 + 5400*cos(t)^2 \ -4320*cos(t) + 720)/720 endif m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Laguerre" int param v_Laguerre caption = "Version (Laguerre)" 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_Laguerre < 100 endparam param n caption = "Laguerre number" default = 0 enum = "2" "3" "4" "5" "6" endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam bool param wave caption = "Add petal wave" default = false visible = @partype == "angle" endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && @partype == "angle" endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && @partype == "angle" endparam } class REB_TrapShapeHermite(common.ulb:TrapShape) { ; This shape uses the Hermite function.
public: import "common.ulb" ; Constructor func REB_TrapShapeHermite(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave && @partype == "angle" float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float d = 0 float t = 0 float x = 0 float y = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@b if @htype == 0 if @n == "2" x = @a*(cos(t)^2 - 1) y = @a*(sin(t)^2 - 1) elseif @n == "3" x = @a*(cos(t)^3 - 3*cos(t))/3 y = @a*(sin(t)^3 - 3*sin(t))/3 elseif @n == "4" x = @a*(cos(t)^4 - 6*cos(t)^2 + 3)/3 y = @a*(sin(t)^4 - 6*sin(t)^2 + 3)/3 elseif @n == "5" x = @a*(cos(t)^5 - 10*cos(t)^3 + 15*cos(t))/15 y = @a*(sin(t)^5 - 10*sin(t)^3 + 15*sin(t))/15 elseif @n == "6" x = @a*(cos(t)^6 - 15*cos(t)^4 + 45*cos(t)^2 - 15)/15 y = @a*(sin(t)^6 - 15*sin(t)^4 + 45*sin(t)^2 - 15)/15 elseif @n == "7" x = @a*(cos(t)^7 - 21*cos(t)^5 + 105*cos(t)^3 - 105*cos(t))/105 y = @a*(sin(t)^7 - 21*sin(t)^5 + 105*sin(t)^3 - 105*sin(t))/105 elseif @n == "8" x = @a*(cos(t)^8 - 28*cos(t)^6 + 210*cos(t)^4 - 420*cos(t)^2 + 105)/105 y = @a*(sin(t)^8 - 28*sin(t)^6 + 210*sin(t)^4 - 420*sin(t)^2 + 105)/105 elseif @n == "9" x = @a*(cos(t)^9 - 36*cos(t)^7 + 378*cos(t)^5 - 1260*cos(t)^3 + 945*cos(t))/945 y = @a*(sin(t)^9 - 36*sin(t)^7 + 378*sin(t)^5 - 1260*sin(t)^3 + 945*sin(t))/945 elseif @n == "10" x = @a*(cos(t)^10 - 45*cos(t)^8 + 630*cos(t)^6 - 3150*cos(t)^4 + 4275*cos(t)^2 - 945)/945 y = @a*(sin(t)^10 - 45*sin(t)^8 + 630*sin(t)^6 - 3150*sin(t)^4 + 4275*sin(t)^2 - 945)/945 endif else if @n == "2" x = @a*4*(cos(t)^2 - 2)/2 y = @a*4*(sin(t)^2 - 2)/2 elseif @n == "3" x = @a*8*(cos(t)^3 - 12*cos(t))/144 y = @a*8*(sin(t)^3 - 12*sin(t))/144 elseif @n == "4" x = @a*16*(cos(t)^4 - 48*cos(t)^2 + 12)/288 y = @a*16*(sin(t)^4 - 48*sin(t)^2 + 12)/288 elseif @n == "5" x = @a*32*(cos(t)^5 - 160*cos(t)^3 + 120*cos(t))/2880 y = @a*32*(sin(t)^5 - 160*sin(t)^3 + 120*sin(t))/2880 elseif @n == "6" x = @a*64*(cos(t)^6 - 480*cos(t)^4 + 720*cos(t)^2 - 120)/14400 y = @a*64*(sin(t)^6 - 480*sin(t)^4 + 720*sin(t)^2 - 120)/14400 elseif @n == "7" x = @a*128*(cos(t)^7 - 1344*cos(t)^5 + 3360*cos(t)^3 - 1680*cos(t))/113000 y = @a*128*(sin(t)^7 - 1344*sin(t)^5 + 3360*sin(t)^3 - 1680*sin(t))/113000 elseif @n == "8" x = @a*256*(cos(t)^8 - 3584*cos(t)^6 + 13440*cos(t)^4 - 13440*cos(t)^2 + 1680)/564480 y = @a*256*(sin(t)^8 - 3584*sin(t)^6 + 13440*sin(t)^4 - 13440*sin(t)^2 + 1680)/564480 elseif @n == "9" x = @a*512*(cos(t)^9 - 9216*cos(t)^7 + 48384*cos(t)^5 - 80640*cos(t)^3 + 30240*cos(t))/1e7 y = @a*512*(sin(t)^9 - 9216*sin(t)^7 + 48384*sin(t)^5 - 80640*sin(t)^3 + 30240*sin(t))/1e7 elseif @n == "10" x = @a*1024*(cos(t)^10 - 23040*cos(t)^8 + 161280*cos(t)^6 - 403200*cos(t)^4 + 302400*cos(t)^2 - 20340)/1e8 y = @a*1024*(sin(t)^10 - 23040*sin(t)^8 + 161280*sin(t)^6 - 403200*sin(t)^4 + 302400*sin(t)^2 - 20340)/1e8 endif endif m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Hermite" int param v_Hermite caption = "Version (Hermite)" 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_Hermite < 100 endparam param n caption = "Hermite number" default = 0 enum = "2" "3" "4" "5" "6" "7" "8" "9" "10" endparam param htype caption = "Hermite type" default = 0 enum = "probabilist" "physicist" endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam bool param wave caption = "Add petal wave" default = false visible = @partype == "angle" endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && @partype == "angle" endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && @partype == "angle" endparam } class REB_TrapShapeChebychev(common.ulb:TrapShape) { ; This shape uses the Chebychev function.
public: import "common.ulb" ; Constructor func REB_TrapShapeChebychev(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 float x = 0 float y = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@b*5 y = @a*cos(@n*acos(sin(t))) x = @a*cos(@n*acos(cos(t))) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Chebychev" int param v_Chebychev caption = "Version (Chebychev)" 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_Chebychev < 100 endparam int param n caption = "Chebychev number" default = 2 min = 2 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } class REB_TrapShapeLissajous(common.ulb:TrapShape) { ; This shape uses the Lissajous function.
public: import "common.ulb" ; Constructor func REB_TrapShapeLissajous(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = @scale*t float x = 2.5*@a*sin(t) float y = 2.5*@a*sin(10*@b*t+@c) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Lissajous" int param v_Lissajous caption = "Version (Lissajous)" default = 101 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_Lissajous < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param c caption = "3rd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param scale caption = "Param scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } class REB_TrapShapeHypotrochoid(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeHypotrochoid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t *@scale float x = (@a*6-@b*0.3)*cos(t) + 1.3*@c*cos((6*@a/(@b*0.3)-1)*t) float y = (@a*6-@b*0.3)*sin(t) - 1.3*@c*sin((6*@a/(@b*0.3)-1)*t) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Hypotrochoid" int param v_Hypotrochoid caption = "Version (Hypotrochoid)" default = 101 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_Hypotrochoid < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param c caption = "3rd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } class REB_TrapShapeHypocycloid(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeHypocycloid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave && @partype == "angle" float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t *@scale float x = @a*((1-@b*3)*cos(3*@b*t)+3*@b*@c*cos((1-3*@b)*t)) float y = @a*((1-@b*3)*sin(3*@b*t)-3*@b*@c*sin((1-3*@b)*t)) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Hypocycloid" int param v_Hypocycloid caption = "Version (v)" 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_Hypocycloid < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param c caption = "3rd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam bool param wave caption = "Add petal wave" default = false visible = @partype == "angle" endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && @partype == "angle" endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && @partype == "angle" endparam } class REB_TrapShapePlateauCurve(common.ulb:TrapShape) { ; This shape uses the Plateau Curve function.
public: import "common.ulb" ; Constructor func REB_TrapShapePlateauCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = @a*sin((1+@b*1.2)*t)/sin((1-@b*1.2)*t) float y = @a*sin(t)*sin(@b*1.2*t)/sin((1-@b*1.2)*t) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Plateau Curve" int param v_PlateauCurve caption = "Version (PlateauCurve)" 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_PlateauCurve < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } class REB_TrapShapeEquiangularSpiral(common.ulb:TrapShape) { ; This shape uses the Equiangular Spiral function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeEquiangularSpiral(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = @a*exp(theta*cotan(@b/2)) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Equiangular Spiral" int param v_EquiangularSpiral caption = "Version (Equiangular Spiral)" 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_EquiangularSpiral < 100 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeFreethsNephroid(common.ulb:TrapShape) { ; This shape uses the bifolium function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeFreethsNephroid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = 0.5*@a*(1+2*sin(theta/2)) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Freeth's Nephroid" int param v_FreethsNephroid caption = "Version (FreethsNephroid)" 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_FreethsNephroid < 100 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeSinusoidalSpiral(common.ulb:TrapShape) { ; This shape uses the Sinusoidal Spiral function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeSinusoidalSpiral(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = @a*(cos(2*@b*theta))^1/(2*@b) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Sinusoidal Spiral" int param v_SinusoidalSpiral caption = "Version (SinusoidalSpiral)" 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_SinusoidalSpiral < 100 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeBow(common.ulb:TrapShape) { ; This shape uses the bow function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeBow(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = x^4-x^2*y+y^3-cabs(pz)*@offset else d = x^4-x^2*y+y^3-@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else int sgn = 1 if @sgn sgn = -1 endif float theta = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif float af1 = 0.1*@a*(1-tan(theta)^2)*cos(theta) float af2 = 0.1*@b*(1-tan(theta)^2)*sin(theta) complex as = (af1 + sgn*flip(af2)) IF @absval d = abs(cabs(pz) - cabs(as)) ELSE d = cabs(pz - as) ENDIF m_LastZ = as endif return d endfunc default: title = "Bow" int param v_trapshapebow caption = "Version (Trap Shape Bow)" default = 102 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_trapshapebow < 102 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 0.2 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@altformula endparam bool param alttheta caption = "Alternate theta" default = false visible = !@altformula endparam } class REB_TrapShapeButterfly(common.ulb:TrapShape) { ; This shape uses the butterfly function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeButterfly(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = y^6+x^6-x^2-cabs(pz)*@offset else d = y^6+x^6-x^2-@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else float theta = 0 d = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif float rr = 0.25*@a*(exp(sin(theta))-2*cos(4*theta)+sin(1/24*(2*theta-#pi))) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else x = real(pz) y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif endif return d endfunc default: title = "Butterfly" int param v_trapshapebutterfly caption = "Version (Trap Shape Butterfly)" default = 102 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_trapshapebutterfly < 102 endparam heading text = "The 'Alternate formula' is a sextic polynomial form while the regular form\ is exponential and uses trigometric functions." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc bool param ptraps caption = "Use as Polar Traps" default = false visible = !@altformula endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps && !@altformula hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps && !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@ptraps && !@altformula endparam bool param alttheta caption = "Alternate theta" default = false visible = !@altformula endparam } class REB_TrapShapeCapricornoid(common.ulb:TrapShape) { ; This shape uses the Capricornoid function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeCapricornoid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = @aa^2*(x^4+x^2*y^2)-@ab*(x^4+y^4)-@ab*(2*x^2*y^2-2*@aa*y^3+@aa^2*y^2-2*@aa*x^2*y) -cabs(pz)*@offset else d = @aa^2*(x^4+x^2*y^2)-@ab*(x^4+y^4)-@ab*(2*x^2*y^2-2*@aa*y^3+@aa^2*y^2-2*@aa*x^2*y)-@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif float rr = 0.5*@a*sin(theta)/(0.5*@b + 0.35*@c*cos(theta)) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else x = real(pz) y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif endif return d endfunc default: title = "Capricornoid" int param v_Capricornoid caption = "Version (Trap Shape Capricornoid)" 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_Capricornoid < 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "parameter a" default = 1.5 hint = "Affects spread and scale of trap" visible = @altformula endparam float param ab caption = "parameter b" default = 3 hint = "Affects spread and scale of trap" visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc bool param ptraps caption = "Use as Polar Traps" default = false visible = !@altformula endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps && !@altformula hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param c caption = "3rd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps && !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@ptraps && !@altformula endparam bool param alttheta caption = "Alternate theta" default = false visible = !@altformula endparam } class REB_TrapShapeBulletNose(common.ulb:TrapShape) { ; This shape uses the Bullet Nose function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeBulletNose(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = @aa^2*y^2-@ab^2*x^2-x^2*y^2+cabs(pz)*@offset else d = @aa^2*y^2-@ab^2*x^2-x^2*y^2+@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else if @wave float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile x = r * cos(wtheta) y = r * sin(wtheta) pz = x + flip(y) endif float theta = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif float rr = 0.25*@a*(@b^2*sin(theta)^2-(2*@c)^2*cos(theta)^2)^0.5/(sin(theta)*cos(theta)) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else x = real(pz) y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif endif return d endfunc default: title = "Bullet Nose" int param v_BulletNose caption = "Version (Trap Shape Bullet Nose)" 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_BulletNose < 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 0.7 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "parameter a" default = 1 visible = @altformula endparam float param ab caption = "parameter b" default = 1 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc bool param ptraps caption = "Use as Polar Traps" default = false visible = !@altformula endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps && !@altformula hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param c caption = "3rd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam bool param wave caption = "Add petal wave" default = false visible = !@altformula endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && !@altformula endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps && !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@ptraps && !@altformula endparam bool param alttheta caption = "Alternate theta" default = false visible = !@altformula endparam } class REB_TrapShapeTrott(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeTrott(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float x = 0 float y = 0 pz = pz/@scale x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = 144*(x^4+y^4)-225*(x^2+y^2)+350*x^2*y^2+81-cabs(pz)*@offset else d = 144*(x^4+y^4)-225*(x^2+y^2)+350*x^2*y^2+81-@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif return d endfunc default: title = "Trott" int param v_Trott caption = "Version (Trap Shape Trott)" 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_Trott < 100 endparam float param scale caption = "scale" default = 1 endparam float param width caption = "width" default = 1 endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" endparam func fn1 caption = "Function 1" default = ident() endfunc func fn2 caption = "Function 2" default = ident() endfunc } class REB_TrapShapeWattsCurve(common.ulb:TrapShape) { ; This shape uses the Watts Curve function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeWattsCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif float rr = @a*(1- @b*(sin(theta) + (@c-cos(theta)^2)^0.5)^2)^0.5 if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Watts Curve" int param v_WattsCurve caption = "Version (Watts Curve)" 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_WattsCurve < 100 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param c caption = "3rd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeCardioid(common.ulb:TrapShape) { ; This shape uses the cardiod function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeCardioid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = (x^2+y^2-2*@aa*x)^2-4*@aa^2*(x^2+y^2)-cabs(pz)*@offset else d = (x^2+y^2-2*@aa*x)^2-4*@aa^2*(x^2+y^2)-@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif float rr = @a*(1-cos(theta)) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif endif return d endfunc default: title = "Cardioid" int param v_trapshapecardioid caption = "Version (Trap Shape Cardioid)" default = 102 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_trapshapecardioid < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false visible = !@altformula endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps && !@altformula hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 0.5 visible = @altformula endparam float param width caption = "width" default = 4 visible = @altformula endparam float param aa caption = "parameter a" default = 0.75 hint = "Affects spread and scale of trap" visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps && !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@ptraps && !@altformula endparam bool param alttheta caption = "Alternate theta" default = false visible = !@altformula endparam } class REB_TrapShapeCassiniOvals(common.ulb:TrapShape) { ; This shape uses the Cassini ovals function.
;

; This variant of the function involves taking a square root ; so there are two solutions. A signed and absolute value version of ; the distance is also available. The transformed value is the ; complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeCassiniOvals(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = x^4+y^4+2*x^2*y^2-2*@aa^2*x^2+2*@aa^2*y^2+@aa^4-@ab^4-cabs(pz)*@offset else d = x^4+y^4+2*x^2*y^2-2*@aa^2*x^2+2*@aa^2*y^2+@aa^4-@ab^4-@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif if @negroot rr = 0.5*@a*(cos(2*theta)-((@b*0.1/(@a*0.5))^4-sin(2*theta)^2)^0.5)^0.5 else rr = 0.5*@a*(cos(2*theta)+((@b*0.1/(@a*0.5))^4-sin(2*theta)^2)^0.5)^0.5 endif if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) endif return d endfunc default: title = "Cassini Ovals" int param v_trapshapecassiniovals caption = "Version (Trap Shape Cassini Ovals)" default = 102 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_trapshapecassiniovals < 102 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "parameter a" default = 1 hint = "Affects spread and scale of trap" visible = @altformula endparam float param ab caption = "parameter b" default = 1.0 hint = "Affects spread and scale of trap" visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@altformula endparam param negroot caption = "Quad Neg Root" default = false visible = !@altformula endparam bool param alttheta caption = "Alternate theta" default = false visible = !@altformula endparam } class REB_TrapShapeCayleysSextic(common.ulb:TrapShape) { ; This shape uses the Cayley's sextic function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeCayleysSextic(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = -@aa^3*x^3-48*@aa*x*(x^2+y^2)^2+64*(x^2+y^2)^3-3*@aa^2*(x^2+y^2)*(5*x^2+9*y^2)-cabs(pz)*@offset else d = -@aa^3*x^3-48*@aa*x*(x^2+y^2)^2+64*(x^2+y^2)^3-3*@aa^2*(x^2+y^2)*(5*x^2+9*y^2)-@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = 1.5*@a*cos(theta)^3 if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif endif return d endfunc default: title = "Cayley's Sextic" int param v_trapshapecayleyssextic caption = "Version (Trap Shape Cayley's Sextic)" default = 101 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_trapshapecayleyssextic < 101 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "parameter a" default = 1 hint = "Affects spread and scale of trap" visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc bool param ptraps caption = "Use as Polar Traps" default = false visible = !@altformula endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps && !@altformula hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps && !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@ptraps && !@altformula endparam } class REB_TrapShapeCissoidofDiocles(common.ulb:TrapShape) { ; This shape uses the cissoid of Diocles function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeCissoidofDiocles(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = x*(x^2+y^2)-2*@aa*y^2-cabs(pz)*@offset else d = x*(x^2+y^2)-2*@aa*y^2-@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif float rr = 0.2*@a*sin(theta)*tan(theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else x = real(pz) y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif endif return d endfunc default: title = "Cissoid of Diocles" int param v_trapshapecissoidofdiocles caption = "Version (Trap Shape Cissoid Of Diocles)" default = 101 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_trapshapecissoidofdiocles < 101 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "parameter a" default = 1 hint = "Affects spread and scale of trap" visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc bool param ptraps caption = "Use as Polar Traps" default = false visible = !@altformula endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps && !@altformula hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps && !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@ptraps && !@altformula endparam } class REB_TrapShapeCochleoid(common.ulb:TrapShape) { ; This shape uses the cochleoid function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeCochleoid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif float rr = 1.25*@a*sin(theta)/theta if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Cochleoid" int param v_trapshapecochleoid caption = "Version (Trap Shape Cochleoid)" default = 102 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_trapshapecochleoid < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeHeartCurve(common.ulb:TrapShape) { ; This shape uses the Heart Curve function.
public: import "common.ulb" ; Constructor func REB_TrapShapeHeartCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = (7.5*@a*atan2(pz))%1 float x = 0.33*@b*sin(t)*cos(t)*log(abs(t)) float y = 0.33*@b*abs(t)^0.3*cos(t)^0.5 m_lastZ = x + flip(y) d = cabs(pz-m_lastZ) return d endfunc default: title = "Heart Curve" int param v_HeartCurve caption = "Version (HeartCurve)" 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_HeartCurve < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam } class REB_TrapShapeAtriphtaloid(common.ulb:TrapShape) { ; This shape uses the Atriphtaloid function.
public: import "common.ulb" ; Constructor func REB_TrapShapeAtriphtaloid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = x^4*(x^2+y^2)-(@ps*@aa*x^2-@ps*@ab)^2+cabs(pz)*@offset else d = x^4*(x^2+y^2)-(@ps*@aa*x^2-@ps*@ab)^2+@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else x = real(pz) y = (-x^2+(100*@b)^2-100*@b*@c/x^2+ (0.5*@c)^2/x^4)^0.5 m_lastZ = 0.005*@a*(x + flip(y)) d = cabs(pz-m_lastZ) endif return d endfunc default: title = "Atriphtaloid" int param v_Atriphtaloid caption = "Version (Atriphtaloid)" 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_Atriphtaloid < 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 0.2 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "parameter a" default = 5 hint = "Affects spread and scale of trap" visible = @altformula endparam float param ab caption = "parameter b" default = 1.0 hint = "Affects spread and scale of trap" visible = @altformula endparam float param ps caption = "param scaler" default = 0.4 hint = "Affects spread and scale of trap" visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param c caption = "3rd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam } class REB_TrapShapeBurnsideCurve(common.ulb:TrapShape) { ; This shape uses the Burnside Curve function.
public: import "common.ulb" ; Constructor func REB_TrapShapeBurnsideCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale ; pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" d = y^2-x*(x^4-@a1)-cabs(pz)*@offset else d = y^2-x*(x^4-@a1)-@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else x = real(pz) y = (x^5 - x)^0.5 m_lastZ = 2*@a*(x + flip(y)) d = cabs(pz-m_lastZ) endif return d endfunc default: title = "Burnside Curve" int param v_BurnsideCurve caption = "Version (BurnsideCurve)" 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_BurnsideCurve < 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 0.25 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param a1 caption = "parameter a" default = 1 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam } class REB_TrapShapeKleinQuartic(common.ulb:TrapShape) { ; This shape uses the KleinQuartic function.
public: import "common.ulb" ; Constructor func REB_TrapShapeKleinQuartic(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float x = real(pz) float y = (-x/2+(x^2/4+x^9/27)^0.5)^(1/3)+(-x/2-(x^2/4+x^9/27)^0.5)^(1/3) m_lastZ = @a*(x + flip(y)) float d = cabs(pz-m_lastZ) return d endfunc default: title = "Klein Quartic" int param v_KleinQuartic caption = "Version (Klein Quartic)" 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_KleinQuartic < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam } class REB_TrapShapeTrochoid(common.ulb:TrapShape) { ; This shape uses the Trochoid function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeTrochoid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float theta = atan2(pz) float x = @a*(@b*theta-@c*sin(theta)) float y = @a*(@b-@c*cos(theta)) m_lastZ = x + flip(y) d = cabs(pz-m_lastZ) return d endfunc default: title = "Trochoid" int param v_Trochoid caption = "Version (Trochoid)" 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_Trochoid < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param c caption = "3rd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam } class REB_TrapShapeFishCurve(common.ulb:TrapShape) { ; This shape uses the Heart Curve function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeFishCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 5*@a*atan2(pz) float x = @b*(cos(t) - sin(t)^2/sqrt(2)) float y = @b*cos(t)*sin(t) m_lastZ = x + flip(y) d = cabs(pz-m_lastZ) return d endfunc default: title = "Fish Curve" int param v_FishCurve caption = "Version (FishCurve)" 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_FishCurve < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam } class REB_TrapShapeConchoid(common.ulb:TrapShape) { ; This shape uses the conchoid function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeConchoid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif float rr = 0.1*(@a + @b*cos(theta))/cos(theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Conchoid" int param v_trapshapeconchoid caption = "Version (Trap Shape Conchoid)" default = 102 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_trapshapeconchoid < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects shape and scale of trap." endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeCotesSpiral(common.ulb:TrapShape) { ; This shape uses the Cote's spiral function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeCotesSpiral(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif float rr = @a/cosh(@b*theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Cotes' Spiral" int param v_trapshapecotesspiral caption = "Version (Trap Shape Cotes' Spiral)" default = 102 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_trapshapecotesspiral < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects shape and scale of trap." endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeDiamond(common.ulb:TrapShape) { ; This shape uses the diamond function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeDiamond(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float d = 0 if @absval d = abs(cabs(pz) - cabs(@a*@adfn(abs((real(pz)*@adj1))+sgn*abs((flip(imag(pz))^@adj2))-1))) else d = cabs(pz - @a*@adfn(abs((real(pz)*@adj1))+sgn*abs((flip(imag(pz))^@adj2))-1)) endif m_LastZ = (@a*@adfn(abs((real(pz)*@adj1))+sgn*abs((flip(imag(pz))^@adj2))-1)) return d endfunc default: title = "Diamond" int param v_trapshapediamond caption = "Version (Trap Shape Diamond)" default = 101 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_trapshapediamond < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param adj1 caption = "Adjuster 1" default = 10.0 hint = "Affects spread and scale of trap" endparam float param adj2 caption = "Adjuster 2" default = 1.0 hint = "Affects spread and scale of trap" endparam func adfn caption = "Adjuster function" default = ident() endfunc bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeDipoleCurve(common.ulb:TrapShape) { ; This shape uses the dipole function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeDipoleCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = @a*(cos(theta))^2 if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Dipole Curve" int param v_trapshapedipolecurve caption = "Version (Trap Shape Dipole Curve)" default = 102 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_trapshapedipolecurve < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeDumbellCurve(common.ulb:TrapShape) { ; This shape uses the dumbell function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeDumbellCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float cx = 0 float cy = 0 float d = 0 cx = real(pz) cy = (cx^4-cx^6)^0.5 if @absval d = abs(cabs(pz) - cabs(4*@a*(cx + sgn*flip(cy)))) else d = cabs(pz - 4*@a*(cx + sgn*flip(cy))) endif m_LastZ = 4*@a*(cx + sgn*flip(cy)) return d endfunc default: title = "Dumbell Curve" int param v_trapshapedumbellcurve caption = "Version (Trap Shape Dumbell Curve)" default = 101 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_trapshapedumbellcurve < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeEightCurve(common.ulb:TrapShape) { ; This shape uses the eight function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeEightCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = @a*cos(theta)^(-2)*cos(2*theta)^0.5 if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Eight Curve" int param v_trapshapeeightcurve caption = "Version (Trap Shape Eight Curve)" default = 102 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_trapshapeeightcurve < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeEllipseCatacaustic(common.ulb:TrapShape) { ; This shape uses the ellipse catacaustic function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeEllipseCatacaustic(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float theta = 0 float d = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif complex af1 = 4*@a*(@a-@b)*(@a*@b)*sin(theta)^3/(@a^2+@b^2+(@b^2-@a^2)*cos(2*theta)) complex af2 = 4*@b*(@b^2-@a^2)*cos(theta)^3/(@a^2+@b^2+3*(@b^2-@a^2)*cos(2*theta)) complex as = 0.1*(af1 + sgn*flip(af2)) if @absval d = abs(cabs(pz) - cabs(as)) else d = cabs(pz - as) endif m_LastZ = as return d endfunc default: title = "Ellipse Catacaustic" int param v_trapshapeellipsecatacaustic caption = "Version (Trap Shape Ellipse Catacaustic)" default = 102 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_trapshapeellipsecatacaustic < 102 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeEllipseEvolute(common.ulb:TrapShape) { ; This shape uses the ellipse evolute function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeEllipseEvolute(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float theta = 0 float d = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif complex af1 = (@a^2-(0.7*@b)^2)/@a*@afn1(theta)^(real(@pwr)) complex af2 = ((0.7*@b)^2-@a^2)/(0.7*@b)*@afn2(theta)^(imag(@pwr)) complex as = 0.1*(af1 + sgn*flip(af2)) if @absval d = abs(cabs(pz) - cabs(as)) else d = cabs(pz - as) endif m_LastZ = as return d endfunc default: title = "Ellipse Evolute" int param v_trapshapeellipseevolute caption = "Version (Trap Shape Ellipse Evolute)" default = 102 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_trapshapeellipseevolute < 102 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam complex param pwr caption = "Power" default = (3,3) hint = "Affects shape and scale of trap." endparam func afn1 caption = "Function #1" default = cos() endfunc func afn2 caption = "Function #2" default = sin() endfunc bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeEpicycloid(common.ulb:TrapShape) { ; This shape uses the epicycloid function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeEpicycloid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float theta = 0 float d = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif complex af1 = (5*@a+@b)*@afn1(theta) - @b*@afn1((5*@a+@b)*theta/@b) complex af2 = (5*@a+@b)*@afn2(theta) - @b*@afn2((5*@a+@b)*theta/@b) complex as = 0.1*(af1 + sgn*flip(af2)) if @absval d = abs(cabs(pz) - cabs(as)) else d = cabs(pz - as) endif m_LastZ = as return d endfunc default: title = "Epicycloid" int param v_trapshapeepicycloid caption = "Version (Trap Shape Epicycloid)" default = 102 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_trapshapeepicycloid < 102 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam func afn1 caption = "Function #1" default = cos() endfunc func afn2 caption = "Function #2" default = sin() endfunc bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeEpispiral(common.ulb:TrapShape) { ; This shape uses the epispiral function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeEpispiral(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif rr = 0.25*@a/cos(@pn*theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Epispiral" int param v_trapshapeepispiral caption = "Version (Trap Shape Epispiral)" default = 101 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_trapshapeepispiral < 101 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam int param pn caption = "Polar integer" default = 3 hint = "Affects shape and scale of trap." endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeFoliumOfDescartes(common.ulb:TrapShape) { ; This shape uses the folium of Descartes function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeFoliumOfDescartes(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif rr = 0.3*@a*tan(theta)/(cos(theta)*(1+tan(theta)^3)) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Folium Of Descartes" int param v_trapshapefoliumofdescartes caption = "Version (Trap Shape Folium Of Descartes)" default = 101 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_trapshapefoliumofdescartes < 101 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeGearCurve(common.ulb:TrapShape) { ; This shape uses the gear curve function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeGearCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif int sgn = 1 if @sgn sgn = -1 endif float theta = 0 float d = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif complex af1 = (0.25*@a+1/(5*@b)*tanh(5*@b*sin(@pn*theta)))*cos(theta) complex af2 = (0.25*@a+1/(5*@b)*tanh(5*@b*sin(@pn*theta)))*sin(theta) complex as = (af1 + sgn*flip(af2)) if @absval d = abs(cabs(pz) - cabs(as)) else d = cabs(pz - as) endif m_LastZ = as return d endfunc default: title = "Gear Curve" int param v_trapshapegearcurve caption = "Version (Trap Shape Gear Curve)" default = 102 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_trapshapegearcurve < 102 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam int param pn caption = "Polar integer" default = 3 hint = "Affects spread and scale of trap" endparam bool param wave caption = "Add petal wave" default = false endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeHipopede(common.ulb:TrapShape) { ; This shape uses the hipopede function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeHipopede(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = (0.5*@b*(0.5*@a-(0.5*@b)^2*cos(theta)))^0.5 if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Hipopede" int param v_trapshapehipopede caption = "Version (Trap Shape Hipopede)" default = 102 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_trapshapehipopede < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects shape and scale of trap." endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeHyperbola(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeHyperbola(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = 0.35*@a*(1/cos(2*theta))^0.5 if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Hyperbola REB" int param v_trapshapehyperbolareb caption = "Version (Trap Shape Hyperbola REB)" default = 102 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_trapshapehyperbolareb < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeKampyleofEudoxus(common.ulb:TrapShape) { ; This shape uses the kampyle of Eudoxus function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeKampyleofEudoxus(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = 0.02*@a/cos(theta)^2 if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Kampyle of Eudoxus" int param v_trapshapekampyleofeudoxus caption = "Version (Trap Shape Kampyle Of Eudoxus)" default = 102 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_trapshapekampyleofeudoxus < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeKappaCurve(common.ulb:TrapShape) { ; This shape uses the kapp a curve function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeKappaCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = 0.1*@a*tan(theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Kappa Curve" int param v_trapshapekappacurve caption = "Version (Trap Shape Kappa Curve)" default = 102 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_trapshapekappacurve < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeKeratoidCusp(common.ulb:TrapShape) { ; This shape uses the keratoid cusp function.
;

; This variant of the function involves taking a square root ; so there are two solutions. A signed and absolute value version of ; the distance is also available. The transformed value is the ; complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeKeratoidCusp(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float d = 0 complex cx = real(pz) complex qa = 1 complex qb = -cx^2 complex qc = -cx^5 if @negroot == true qy = (-qb - (qb^2 - 4*qa*qc)^0.5)/(2*qa) else qy = (-qb + (qb^2 - 4*qa*qc)^0.5)/(2*qa) endif if @absval == true d = abs(cabs(pz) - cabs(2.5*@a*(cx + sgn*flip(qy)))) else d = cabs(pz - 2.5*@a*(cx + sgn*flip(qy))) endif m_LastZ = 2.5*@a*(cx + sgn*flip(qy)) return d endfunc default: title = "Keratoid Cusp" int param v_trapshapekeratoidcusp caption = "Version (Trap Shape Keratoid Cusp)" default = 101 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_trapshapekeratoidcusp < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam param negroot caption = "Quad Neg Root" default = true endparam } class REB_TrapShapeKnotCurve(common.ulb:TrapShape) { ; This shape uses the knot curve function.
;

; This variant of the function involves taking a square root ; so there are two solutions. A signed and absolute value version of ; the distance is also available. The transformed value is the ; complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeKnotCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float x = 0 float y = 0 if @altformula x = real(@fn1(pz)) y = imag(@fn2(pz)) d = (x^2-1)^2-y^2*(2*y+3)+@offset d = abs(d) else int sgn = 1 if @sgn sgn = -1 endif complex cy = imag(pz) complex qx = 0 complex qa = 1 complex qb = -2 complex qc = 1 - 3*cy^2 - 2*cy^3 if @negroot == true qx = ((-qb - (qb^2 - 4*qa*qc)^0.5)/(2*qa))^0.5 else qx = ((-qb + (qb^2 - 4*qa*qc)^0.5)/(2*qa))^0.5 endif if @absval == true d = abs(cabs(pz) - cabs(@a*(qx + sgn*flip(cy)))) else d = cabs(pz - @a*(qx + sgn*flip(cy))) endif m_LastZ = @a*(qx + sgn*flip(cy)) endif return d endfunc default: title = "KnotCurve" int param v_trapshapeknotcurve caption = "Version (Trap Shape Knot Curve)" default = 101 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_trapshapeknotcurve < 101 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@altformula endparam param negroot caption = "Quad Neg Root" default = true visible = !@altformula endparam } class REB_TrapShapeLemniscate(common.ulb:TrapShape) { ; This shape uses the lemniscate function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeLemniscate(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = @a*(cos(2*theta))^0.5 if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Lemniscate" int param v_trapshapelemniscate caption = "Version (Trap Shape Lemniscate)" default = 102 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_trapshapelemniscate < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeArcsOfSamothrace(common.ulb:TrapShape) { ; This shape uses the lemniscate function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeArcsOfSamothrace(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float x = 0 float y = 0 if @altformula pz = pz/@scale if !@cmplx x = real(@fn1(pz)) y = imag(@fn2(pz)) else x = real(@fn1(pz)) y = imag(@fn1(pz)) endif if @ref == "pz" d = x^2*(@a1*x^2-@a2*y^2)^2-y^2*(x^2+y^2)-cabs(pz)*@offset else d = x^2*(@a1*x^2-@a2*y^2)^2-y^2*(x^2+y^2)-@offset endif if abs(d) < @width d =abs(d) else d = 1e20 endif else if @wave float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = @a*tan(theta)/(1+4*@b*cos(1.25*@c*theta)) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else x = real(pz) y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif endif return d endfunc default: title = "Arcs of Samothrace" int param v_ArcsOfSamothrace caption = "Version (ArcsOfSamothrace)" 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_ArcsOfSamothrace < 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 0.2 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam bool param adv caption = "advanced" default = false visible = @altformula endparam float param a1 caption = "parameter a1" default = 3 visible = @adv && @altformula endparam float param a2 caption = "parameter a2" default = 1 visible = @adv && @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam bool param cmplx caption = "Apply to complex" default = false visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula && !@cmplx endfunc bool param ptraps caption = "Use as Polar Traps" default = false visible = !@altformula endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps && !@altformula hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param c caption = "3rd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam bool param wave caption = "Add petal wave" default = false visible = !@altformula endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && !@altformula endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && !@altformula endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps && !@altformula endparam param absval caption = "Absolute Value" default = false visible = !@ptraps && !@altformula endparam bool param alttheta caption = "Alternate theta" default = false visible = !@altformula endparam } class REB_TrapShapeLimaconOfPascal(common.ulb:TrapShape) { ; This shape uses the limacon of Pascal function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeLimaconOfPascal(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = 0.05*@b + @a*cos(theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Limacon Of Pascal" int param v_trapshapelimaconofpascal caption = "Version (Trap Shape Limacon Of Pascal)" default = 102 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_trapshapelimaconofpascal < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects shape and scale of trap." endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeLine(common.ulb:TrapShape) { ; This shape uses the ophiuride function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeLine(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 int sgn = 1 if @sgn sgn = -1 endif float cx = real(pz) float cy = cx if @absval d = abs(cabs(pz) - cabs(3*@a*(cx + sgn*flip(cy)))) else d = cabs(pz - 3*@a*(cx + sgn*flip(cy))) endif m_LastZ = 3*@a*(cx + sgn*flip(cy)) return d endfunc default: title = "Line" int param v_trapshapeline caption = "Version (Trap Shape Line)" default = 101 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_trapshapeline < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeLinksCurve(common.ulb:TrapShape) { ; This shape uses the links curve function.
;

; This variant of the function involves taking a square root ; so there are two solutions. A signed and absolute value version of ; the distance is also available. The transformed value is the ; complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeLinksCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 int sgn = 1 if @sgn sgn = -1 endif float cx = real(pz) float qa = 1 float qb = 2*cx^2-6*cx float qc = cx^4-2*cx^3+cx^2 if @negroot qy = ((-qb - (qb^2 - 4*qa*qc)^0.5)/(2*qa))^0.5 else qy = ((-qb + (qb^2 - 4*qa*qc)^0.5)/(2*qa))^0.5 endif if @absval d = abs(cabs(pz) - cabs(@a*(cx + sgn*flip(qy)))) else d = cabs(pz - @a*(cx + sgn*flip(qy))) endif m_LastZ = @a*(cx + sgn*flip(qy)) return d endfunc default: title = "Links Curve" int param v_trapshapelinkscurve caption = "Version (Trap Shape Links Curve)" default = 101 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_trapshapelinkscurve < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam param negroot caption = "Quad Neg Root" default = true endparam } class REB_TrapShapeLituus(common.ulb:TrapShape) { ; This shape uses the lituus function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeLituus(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = 0.25*@a/theta^0.5 if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Lituus" int param v_trapshapelituus caption = "Version (Trap Shape Lituus)" default = 102 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_trapshapelituus < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeLogSpiral(common.ulb:TrapShape) { ; This shape uses the log spiral function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeLogSpiral(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = exp(@a*theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Log Spiral" int param v_trapshapelogspiral caption = "Version (Trap Shape Log Spiral)" default = 102 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_trapshapelogspiral < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeLogSpiralCatacaustic(common.ulb:TrapShape) { ; This shape uses the log spiral catacaustic function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeLogSpiralCatacaustic(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int sgn = 1 if @sgn sgn = -1 endif float theta = 0 float d = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif complex af1 = 0.2*@b*exp(0.1*@b*theta)*(0.1*@b*cos(theta)-sin(theta))/(1+(0.1*@b)^2) complex af2 = 0.2*@b*exp(0.1*@b*theta)*(0.1*@b*cos(theta)+sin(theta))/(1+(0.1*@b)^2) complex as = @a*(af1 + sgn*flip(af2)) if @absval d = abs(cabs(pz) - cabs(as)) else d = cabs(pz - as) endif m_LastZ = as return d endfunc default: title = "Log Spiral Catacaustic" int param v_trapshapelogspiralcatacaustic caption = "Version (Trap Shape Log Spiral Catacaustic)" default = 102 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_trapshapelogspiralcatacaustic < 102 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeMalteseCross(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeMalteseCross(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = 0.2*@a/(cos(theta)*sin(theta)*(cos(theta)^2-sin(theta)^2))^0.5 if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Maltese Cross" int param v_trapshapemaltesecross caption = "Version (Trap Shape Maltese Cross)" default = 102 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_trapshapemaltesecross < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeNephroid(common.ulb:TrapShape) { ; This shape uses the nephroid function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeNephroid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif complex af1 = 3*@afn1(theta) - @afn1(theta/3) complex af2 = 3*@afn2(theta) - @afn2(theta/3) complex as = 0.5*@a*(af1+sgn*flip(af2)) m_LastZ = as if @absval d = abs(cabs(pz) - cabs(as)) else d = cabs(pz - (as)) endif return d endfunc default: title = "Nephroid" int param v_trapshapenephroid caption = "Version (Trap Shape Nephroid)" default = 102 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_trapshapenephroid < 102 endparam float param a caption = "Polar Parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam func afn1 caption = "Function #1" default = cos() endfunc func afn2 caption = "Function #2" default = sin() endfunc bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeParabola(common.ulb:TrapShape) { ; This shape uses the parabola function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeParabola(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 int sgn = 1 if @sgn sgn = -1 endif float cy = imag(pz) float cx = 10*@b*cy^2 m_LastZ = 0.65*@a*(cx + sgn*flip(cy)) if @absval d = abs(cabs(pz) - cabs(0.65*@a*(cx + sgn*flip(cy)))) else d = cabs(pz - 0.65*@a*(cx + sgn*flip(cy))) endif return d endfunc default: title = "Parabola" int param v_trapshapeparabola caption = "Version (Trap Shape Parabola)" default = 101 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_trapshapeparabola < 101 endparam float param a caption = "Polar Parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar Parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeTridentOfNewton(common.ulb:TrapShape) { ; This shape uses the Trident Of Newton function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeTridentOfNewton(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 int sgn = 1 if @sgn sgn = -1 endif float cx = real(pz) float cy = cx^2 + @b*cx - @c + 0.02*@d/cx m_LastZ = @a*(cx + sgn*flip(cy)) if @absval d = abs(cabs(pz) - cabs(m_LastZ)) else d = cabs(pz - m_LastZ) endif return d endfunc default: title = "Trident Of Newton" int param v_TridentOfNewton caption = "Version (Trident Of Newton)" 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_TridentOfNewton < 100 endparam float param a caption = "Polar Parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar Parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param c caption = "3rd Polar Parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param d caption = "4th Polar Parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeWassenaarCurve(common.ulb:TrapShape) { ; This shape uses the Wassenaar Curve function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeWassenaarCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 int sgn = 1 if @sgn sgn = -1 endif complex cx = real(pz) complex cy = 0 if @negroot cy = cx^2 - (1-30*@b*cx^2)^0.5 else cy = cx^2 + (1-30*@b*cx^2)^0.5 endif m_LastZ = @a*(cx + sgn*flip(cy)) if @absval d = abs(cabs(pz) - cabs(m_LastZ)) else d = cabs(pz - m_LastZ) endif return d endfunc default: title = "Wassenaar Curve" int param v_WassenaarCurve caption = "Version (Wassenaar Curve)" 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_WassenaarCurve < 100 endparam float param a caption = "Polar Parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar Parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam param negroot caption = "Quad Neg Root" default = false endparam } class REB_TrapShapeWeibullCurve(common.ulb:TrapShape) { ; This shape uses the Weibull Curve function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeWeibullCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 int sgn = 1 if @sgn sgn = -1 endif complex cx = real(pz) complex cy = exp(-cx^(@b/10)) m_LastZ = @a*(cx + sgn*flip(cy)) if @absval d = abs(cabs(pz) - cabs(m_LastZ)) else d = cabs(pz - m_LastZ) endif return d endfunc default: title = "Weibull Curve" int param v_WeibullCurve caption = "Version (Weibull Curve)" 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_WeibullCurve < 100 endparam float param a caption = "Polar Parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar Parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapePiriform(common.ulb:TrapShape) { ; This shape uses the piriform function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapePiriform(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float theta = 0 int sgn = 1 if @sgn sgn = -1 endif if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif complex af1 = 0.1*@a*(1+sin(theta)) complex af2 = 0.1*@b*cos(theta)*(1+sin(theta)) complex as = (af1 + sgn*flip(af2)) m_LastZ = as if @absval d = abs(cabs(pz) - cabs(as)) else d = cabs(pz - as) endif return d endfunc default: title = "Piriform" int param v_trapshapepiriform caption = "Version (Trap Shape Piriform)" default = 102 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_trapshapepiriform < 102 endparam float param a caption = "Polar Parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar Parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapePoinsotSpiral1(common.ulb:TrapShape) { ; This shape uses the Poinsot spiral 1 function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapePoinsotSpiral1(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = @a/cosh(@pn*theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Poinsot Spiral 1" int param v_trapshapepoinsotspiral1 caption = "Version (Trap Shape Poinsot Spiral 1)" default = 102 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_trapshapepoinsotspiral1 < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam int param pn caption = "Polar integer" default = 3 hint = "Affects shape and scale of trap." endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapePoinsotSpiral2(common.ulb:TrapShape) { ; This shape uses the Poinsot spiral 2 function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapePoinsotSpiral2(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = @a/sinh(@pn*theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Poinsot Spiral 2" int param v_trapshapepoinsotspiral2 caption = "Version (Trap Shape Poinsot Spiral 2)" default = 102 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_trapshapepoinsotspiral2 < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam int param pn caption = "Polar integer" default = 3 hint = "Affects shape and scale of trap." endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapePolytrope(common.ulb:TrapShape) { ; This shape uses the polytrope function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapePolytrope(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 int sgn = 1 if @sgn sgn = -1 endif float cx = real(pz) float cy = 1/cx^@pn if @absval d = abs(cabs(pz) - cabs(0.00005*@a*(cx + sgn*flip(cy)))) else d = cabs(pz - 0.00005*@a*(cx + sgn*flip(cy))) endif m_LastZ = 0.00005*@a*(cx + sgn*flip(cy)) return d endfunc default: title = "Polytrope" int param v_trapshapepolytrope caption = "Version (Trap Shape Polytrope)" default = 101 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_trapshapepolytrope < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam int param pn caption = "Polar integer" default = 3 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeQuadratrixOfHippias(common.ulb:TrapShape) { ; This shape uses the quadratrix of Hippias function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeQuadratrixOfHippias(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = @a*theta/sin(theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Quadratrix of Hippias" int param v_trapshapequadratrixofhippias caption = "Version (Trap Shape Quadratrix Of Hippias)" default = 102 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_trapshapequadratrixofhippias < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeQuadrifolium(common.ulb:TrapShape) { ; This shape uses the quadrifolium function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeQuadrifolium(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = @a*sin(2*theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Quadrifolium" int param v_trapshapequadrifolium caption = "Version (Trap Shape Quadrifolium)" default = 102 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_trapshapequadrifolium < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeRose(common.ulb:TrapShape) { ; This shape uses the rose function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeRose(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif rr = @a*cos(theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Rose" int param v_trapshaperose caption = "Version (Trap Shape Rose)" default = 101 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_trapshaperose < 101 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeSuperRose(common.ulb:TrapShape) { public: import "common.ulb" ; Constructor func REB_TrapShapeSuperRose(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float theta = 0 float d = 0 float rr = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif rr = @g*sin(@f*theta*(abs(cos(@d*theta))^@a + abs(sin(@d*theta))^@b)^@c) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Super Rose" int param v_trapshapeSuperRose caption = "Version (Trap Shape Super Rose)" default = 101 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_trapshapeSuperRose < 101 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param g caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param a caption = "Shape 1" default = 2 hint = "Affects spread and scale of trap" endparam float param b caption = "Shape 2" default = 2 hint = "Affects spread and scale of trap" endparam float param c caption = "Shape 3" default =3 hint = "Affects spread and scale of trap" endparam float param d caption = "Shape 4" default = 2 hint = "Affects spread and scale of trap" endparam float param f caption = "Shape 5" default = 5 hint = "Affects spread and scale of trap" endparam bool param @wave caption = "Add petal wave" default = false endparam float param @wamp caption = "Wave amplitude" default = 0.05 visible = @wave endparam float param @wfreq caption = "Wave frequency" default = 20 visible = @wave endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeRoseOfTroy(common.ulb:TrapShape) { ; This shape uses the rose of Troy function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeRoseOfTroy(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = @c*(1+10*@a*sin(4*@b*theta)) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Rose of Troy" int param v_trapshaperoseoftroy caption = "Version (Trap Shape Rose Of Troy)" default = 102 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_trapshaperoseoftroy < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects shape and scale of trap." endparam float param c caption = "3rd Polar parameter" default = 1.0 hint = "Affects shape and scale of trap." endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeScarabaeus(common.ulb:TrapShape) { ; This shape uses the scarabaeus function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeScarabaeus(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = 0.25*@b*cos(2*theta)-0.5*@a*cos(theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Scarabaeus" int param v_trapshapescarabaeus caption = "Version (Trap Shape Scarabaeus)" default = 102 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_trapshapescarabaeus < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects shape and scale of trap." endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeSemicubicalParabola(common.ulb:TrapShape) { ; This shape uses the semicubical parabola function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeSemicubicalParabola(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = @a*(cos(2*@b*theta))^(1/(2*@b)) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Semicubical Parabola" int param v_trapshapesemicubicalparabola caption = "Version (Trap Shape Semicubical Parabola)" default = 102 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_trapshapesemicubicalparabola < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects shape and scale of trap." endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeSerpentineCurve(common.ulb:TrapShape) { ; This shape uses the serpentine curve function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeSerpentineCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif complex af1 = 0.2*@a*cotan(theta) complex af2 = 0.2*@b*sin(theta)*cos(theta) complex as = (af1 + sgn*flip(af2)) if @absval d = abs(cabs(pz) - cabs(as)) else d = cabs(pz - as) endif m_LastZ = pz - as return d endfunc default: title = "Serpentine Curve" int param v_trapshapeserpentinecurve caption = "Version (Trap Shape Serpentine Curve)" default = 101 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_trapshapeserpentinecurve < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeStirrupCurve(common.ulb:TrapShape) { ; This shape uses the stirrup curve function.
;

; This variant of the function involves taking a square root ; so there are two solutions. A signed and absolute value version of ; the distance is also available. The transformed value is the ; complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeStirrupCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 int sgn = 1 if @sgn sgn = -1 endif float cy = imag(pz) float qa = 1 float qb = -2 float qc = 1-cy^2*(cy-1)*(cy-2)*(cy+5) float qx = 0 if @negroot qx = ((-qb - (qb^2 - 4*qa*qc)^0.5)/(2*qa))^0.5 else qx = ((-qb + (qb^2 - 4*qa*qc)^0.5)/(2*qa))^0.5 endif if @absval d = abs(cabs(pz) - cabs(@a*(qx + sgn*flip(cy)))) else d = cabs(pz - @a*(qx + sgn*flip(cy))) endif m_LastZ = @a*(qx + sgn*flip(cy)) return d endfunc default: title = "Stirrup Curve" int param v_trapshapestirrupcurve caption = "Version (Trap Shape Stirrup Curve)" default = 101 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_trapshapestirrupcurve < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam param negroot caption = "Quad Neg Root" default = true endparam } class REB_TrapShapeStrophoid(common.ulb:TrapShape) { ; This shape uses the strophoid function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeStrophoid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif rr = 0.1*@b*sin(@a-2*theta)/sin(@a-theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Strophoid" int param v_trapshapestrophoid caption = "Version (Trap Shape Strophoid)" default = 101 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_trapshapestrophoid < 101 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects shape and scale of trap." endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeSwastikaCurve(common.ulb:TrapShape) { ; This shape uses the swastika curve function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeSwastikaCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = 0.25*@a*(sin(theta)*cos(theta)/(sin(theta)^4-cos(theta)^4))^0.5 if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Swastika Curve" int param v_trapshapeswastikacurve caption = "Version (Trap Shape Swastika Curve)" default = 102 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_trapshapeswastikacurve < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeTeardropCurve(common.ulb:TrapShape) { ; This shape uses the teardrop curve function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeTeardropCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif complex af1 = @a*cos(theta) complex af2 = 0.5*@b*sin(theta)*sin(theta/2)^(@pn-1) complex as = (af1 + sgn*flip(af2)) m_LastZ = as if @absval d = abs(cabs(pz) - cabs(as)) else d = cabs(pz - (as)) endif return d endfunc default: title = "Teardrop Curve" int param v_trapshapeteardropcurve caption = "Version (Trap Shape Teardrop Curve)" default = 101 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_trapshapeteardropcurve < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam int param pn caption = "Polar integer" default = 3 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam bool param absval caption = "Absolute Value" default = false endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeTractrix(common.ulb:TrapShape) { ; This shape uses the tractrix function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeTractrix(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif complex af1 = @a*(log(tan(theta/2))-@afn1(theta)) complex af2 = @a*@afn2(theta) complex as = 0.25*(af1 + sgn*flip(af2)) m_LastZ = as if @absval d = abs(cabs(pz) - cabs(as)) else d = cabs(pz - (as)) endif return d endfunc default: title = "Tractrix" int param v_trapshapetractrix caption = "Version (Trap Shape Tractrix)" default = 102 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_trapshapetractrix < 102 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam func afn1 caption = "Function #1" default = cos() endfunc func afn2 caption = "Function #2" default = sin() endfunc bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeTrefoil(common.ulb:TrapShape) { ; This shape uses the trefoil function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeTrefoil(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif rr = 0.1*@a/cos(3*theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Trefoil" int param v_trapshapetrefoil caption = "Version (Trap Shape Trefoil)" default = 101 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_trapshapetrefoil < 101 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeTrident(common.ulb:TrapShape) { ; This shape uses the trident function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeTrident(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 int sgn = 1 if @sgn sgn = -1 endif float cx = real(pz) float cy = cx^2 + 0.1*@b/cx if @absval d = abs(cabs(pz) - cabs(0.1*@a*(cx + sgn*flip(cy)))) else d = cabs(pz - 0.1*@a*(cx + sgn*flip(cy))) endif m_LastZ = 0.1*@a*(cx + sgn*flip(cy)) return d endfunc default: title = "Trident" int param v_trapshapetrident caption = "Version (Trap Shape Trident)" default = 101 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_trapshapetrident < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeTridentOfDescartes(common.ulb:TrapShape) { ; This shape uses the trident of Descartes function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeTridentOfDescartes(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 int sgn = 1 if @sgn sgn = -1 endif float cx = real(pz) float cy = (cx-0.2*@b)*(cx+0.2*@b)*(cx-0.4*@b)/cx if @absval d = abs(cabs(pz) - cabs(@a*(cx + sgn*flip(cy)))) else d = cabs(pz - @a*(cx + sgn*flip(cy))) endif m_LastZ = @a*(cx + sgn*flip(cy)) return d endfunc default: title = "Trident of Descartes" int param v_trapshapetridentofdescartes caption = "Version (Trap Shape trident Of Descartes)" default = 101 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_trapshapetridentofdescartes < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeTrifolium(common.ulb:TrapShape) { ; This shape uses the trifolium function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeTrifolium(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif rr = -@a*cos(3*theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Trifolium" int param v_trapshapetrifolium caption = "Version (Trap Shape Trifolium)" default = 101 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_trapshapetrifolium < 101 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeTrisectrixOfMclaurin(common.ulb:TrapShape) { ; This shape uses the trisectrix of McLaurin function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeTrisectrixOfMclaurin(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif rr = 0.5*@a*sin(3*theta)/sin(2*theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Trisectrix of Mclaurin" int param v_trapshapetrisectrixofmclaurin caption = "Version (Trap Shape Trisectrix Of Mclaurin)" default = 101 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_trapshapetrisectrixofmclaurin < 101 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeTrisectrixOfLongchamps(common.ulb:TrapShape) { ; This shape uses the trisectrix of Longchamps function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeTrisectrixOfLongchamps(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif rr = 0.5*@a/cos(3*theta) if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Trisectrix of Longchamps" int param v_trapshapetrisectrixofLongchamps caption = "Version (Trap Shape Trisectrix Of Longchamps)" 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_trapshapetrisectrixofLongchamps < 100 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam } class REB_TrapShapeTschirnhausenCubic(common.ulb:TrapShape) { ; This shape uses the Tschirnhausen cubic function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate and a ; polar variant. The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeTschirnhausenCubic(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 float rr = 0 if !@alttheta theta = atan2(pz) else theta = atan(imag(pz)/real(pz)) endif int sgn = 1 if @sgn sgn = -1 endif rr = @a/cos(theta/3)^3 if !@ptraps if @absval d = abs(cabs(pz) - cabs(rr*cos(theta)+ sgn*flip(rr*sin(theta)))) else d = cabs(pz - (rr*cos(theta) + sgn*flip(rr*sin(theta)))) endif m_LastZ = (rr*cos(theta) + sgn*flip(rr*sin(theta))) else float x = real(pz) float y = imag(pz) if @disttype == 0 d = abs(x-rr*cos(theta) + y-rr*sin(theta)) else d = (abs(x-rr*cos(theta)) + abs(y-rr*sin(theta))) endif m_LastZ = x-rr*cos(theta) + flip(y-rr*sin(theta)) endif return d endfunc default: title = "Tschirnhausen Cubic" int param v_trapshapetschirnhausencubic caption = "Version (Trap Shape Tschirnhausen Cubic)" default = 102 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_trapshapetschirnhausencubic < 102 endparam bool param ptraps caption = "Use as Polar Traps" default = false endparam param disttype caption = "Distance type" default = 0 enum = "Abs total" "Abs parts" visible = @ptraps hint = "The distance function must be positive. \ The absolute value can be taken of the \ whole function or of its individual parts." endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false visible = !@ptraps endparam param absval caption = "Absolute Value" default = false visible = !@ptraps endparam bool param alttheta caption = "Alternate theta" default = false endparam } class REB_TrapShapeTschirnhausenCubicCatacaustic(common.ulb:TrapShape) { ; This shape uses the Tschirnhausen cubic Catacaustic function.
public: import "common.ulb" ; Constructor func REB_TrapShapeTschirnhausenCubicCatacaustic(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = @a*6*(t^2-1) float y = @a*4*t^3 m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Tschirnhausen Cubic Catacaustic" int param v_trapshapetschirnhausencubicCatacaustic caption = "Version (Trap Shape Tschirnhausen Cubic Catacaustic)" 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_trapshapetschirnhausencubicCatacaustic < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } class REB_TrapShapeTractrixEvolute(common.ulb:TrapShape) { ; This shape uses the Tractrix Evolute function.
public: import "common.ulb" ; Constructor func REB_TrapShapeTractrixEvolute(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = 2.5*@a*t float y = 2.5*@a*cosh(t) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Tractrix Evolute" int param v_TractrixEvolute caption = "Version (Tractrix Evolute)" 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_TractrixEvolute < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } class REB_TrapShapeAstroidEvolute(common.ulb:TrapShape) { ; This shape uses the Astroid Evolute function.
public: import "common.ulb" ; Constructor func REB_TrapShapeAstroidEvolute(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave && @partype == "angle" float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = 0.78*@a*0.5*(3*cos(t)-cos(3*t)) float y = 0.78*@a*0.5*(3*sin(t)+sin(3*t)) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Astroid Evolute" int param v_AstroidEvolute caption = "Version (Astroid Evolute)" 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_AstroidEvolute < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam bool param wave caption = "Add petal wave" default = false visible = @partype == "angle" endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && @partype == "angle" endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && @partype == "angle" endparam } class REB_TrapShapeParabolaEvolute(common.ulb:TrapShape) { ; This shape uses the Parabola Evolute function.
public: import "common.ulb" ; Constructor func REB_TrapShapeParabolaEvolute(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave && @partype == "angle" float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = 0.78*@a*0.5*(1+6*t^2) float y = 0.78*@a*4*t^3 m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Parabola Evolute" int param v_ParabolaEvolute caption = "Version (Parabola Evolute)" 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_ParabolaEvolute < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam bool param wave caption = "Add petal wave" default = false visible = @partype == "angle" endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && @partype == "angle" endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && @partype == "angle" endparam } class REB_TrapShapeCardioidInvolute(common.ulb:TrapShape) { ; This shape uses the Cardiod Involute function.
public: import "common.ulb" ; Constructor func REB_TrapShapeCardioidInvolute(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = 2*@a + 3*@a*cos(t)*(1-cos(t)) float y = 3*@a*sin(t)*(1-cos(t)) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Cardioid Involute" int param v_CardioidInvolute caption = "Version (Cardioid Involute)" 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_CardioidInvolute < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } class REB_TrapShapeTalbotsCurve(common.ulb:TrapShape) { ; This shape uses the Talbot's Curve function.
public: import "common.ulb" ; Constructor func REB_TrapShapeTalbotsCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave && @partype == "angle" float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = (1+@b/10*sin(t)^2)*cos(t) float y = (1-@b/10-@b/10*cos(t)^2)*sin(t) m_LastZ = 2.5*@a*(x + flip(y)) d = cabs(pz-m_LastZ) return d endfunc default: title = "Talbot's Curve" int param v_TalbotsCurve caption = "Version (Talbot's Curve)" 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_TalbotsCurve < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam bool param wave caption = "Add petal wave" default = false visible = @partype == "angle" endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && @partype == "angle" endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && @partype == "angle" endparam } class REB_TrapShapeCircleInvolute(common.ulb:TrapShape) { ; This shape uses the Circle Involute function.
public: import "common.ulb" ; Constructor func REB_TrapShapeCircleInvolute(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = @a*(cos(t) + t*sin(t)) float y = @a*(sin(t) - t*cos(t)) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Circle Involute" int param v_CircleInvolute caption = "Version (Circle Involute)" 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_CircleInvolute < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } class REB_TrapShapeNaturalLogCatacaustic(common.ulb:TrapShape) { ; This shape uses the Natural Log Catacaustic function.
public: import "common.ulb" ; Constructor func REB_TrapShapeNaturalLogCatacaustic(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave && @partype == "angle" float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = @a*cosh(t) float y = @a*(t-1) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Natural Log Catacaustic" int param v_NaturalLogCatacaustic caption = "Version (Natural Log Catacaustic)" 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_NaturalLogCatacaustic < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam bool param wave caption = "Add petal wave" default = false visible = @partype == "angle" endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && @partype == "angle" endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && @partype == "angle" endparam } class REB_TrapShapeSuperEllipse(common.ulb:TrapShape) { ; This shape uses the Super Ellipse function.
public: import "common.ulb" ; Constructor func REB_TrapShapeSuperEllipse(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave && @partype == "angle" float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = @a*cos(t)^(2/@c) float y = @b*sin(t)^(2/@c) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Super Ellipse" int param v_SuperEllipse caption = "Version (Super Ellipse)" 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_SuperEllipse < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param c caption = "3nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam bool param wave caption = "Add petal wave" default = false visible = @partype == "angle" endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && @partype == "angle" endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && @partype == "angle" endparam } class REB_TrapShapeAstroidCatacaustic(common.ulb:TrapShape) { ; This shape uses the Astroid Catacaustic function.
public: import "common.ulb" ; Constructor func REB_TrapShapeAstroidCatacaustic(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave && @partype == "angle" float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = 5*@a*cos(t)*(8+5*cos(2*t)+3*cos(6*t))/(13+3*cos(4*t)) float y = 20*@a*sin(t)^3*(7+6*cos(2*t)+3*cos(4*t))/(13+3*cos(4*t)) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Astroid Catacaustic" int param v_AstroidCatacaustic caption = "Version (Astroid Catacaustic)" 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_AstroidCatacaustic < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam bool param wave caption = "Add petal wave" default = false visible = @partype == "angle" endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && @partype == "angle" endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && @partype == "angle" endparam } class REB_TrapShapeRanunculoid(common.ulb:TrapShape) { ; This shape uses the Ranunculoid function.
public: import "common.ulb" ; Constructor func REB_TrapShapeRanunculoid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave && @partype == "angle" float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*5*@scale float x = @n*cos(t)-cos(@n*t) float y = @n*sin(t)-sin(@n*t) m_LastZ = 0.375*@a*(x + flip(y)) d = cabs(pz-m_LastZ) return d endfunc default: title = "Ranunculoid" int param v_Ranunculoid caption = "Version (Ranunculoid)" 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_Ranunculoid < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam int param n caption = "Integer parameter" default = 6 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam bool param wave caption = "Add petal wave" default = false visible = @partype == "angle" endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && @partype == "angle" endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && @partype == "angle" endparam } class REB_TrapShapeConchoidOfACircle(common.ulb:TrapShape) { ; This shape uses the Conchoid Of A Circle function.
public: import "common.ulb" ; Constructor func REB_TrapShapeConchoidOfACircle(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float h = sqrt((sin(t)- @c)^2 + cos(t)^2) float x = 2.5*@a*(sin(t) + @b*(sin(t)-@c)/h) float y = 2.5*@a*(cos(t) + @b*cos(t)/h) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Conchoid Of A Circle" int param v_ConchoidOfACircle caption = "Version (Conchoid Of A Circle)" 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_ConchoidOfACircle < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param c caption = "3rd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } class REB_TrapShapeHandwritingCurve(common.ulb:TrapShape) { ; This shape uses the Handwriting Curve function.
public: import "common.ulb" ; Constructor func REB_TrapShapeHandwritingCurve(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = @a*(t-4*@b*sin(t)) float y = @a*(1-4*@b*sin(t)) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Handwriting Curve" int param v_HandwritingCurve caption = "Version (Handwriting Curve)" 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_HandwritingCurve < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } class REB_TrapShapeCycloidCatacaustic(common.ulb:TrapShape) { ; This shape uses the Cycloid Catacaustic function.
public: import "common.ulb" ; Constructor func REB_TrapShapeCycloidCatacaustic(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = @a*2.5*(0.5*t-sin(0.5*t)) float y = @a*2.5*(1-cos(0.5*t)) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Cycloid Catacaustic" int param v_CycloidCatacaustic caption = "Version (Cycloid Catacaustic)" 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_CycloidCatacaustic < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } class REB_TrapShapeLogSpiralEvolute(common.ulb:TrapShape) { ; This shape uses the Log Spiral Evolute function.
public: import "common.ulb" ; Constructor func REB_TrapShapeLogSpiralEvolute(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave && @partype == "angle" float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = @a*@b*exp(@b*t)*sin(t) float y = @a*@b*exp(@b*t)*cos(t) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Log Spiral Evolute" int param v_LogSpiralEvolute caption = "Version (Log Spiral Evolute)" 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_LogSpiralEvolute < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam bool param wave caption = "Add petal wave" default = false visible = @partype == "angle" endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && @partype == "angle" endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && @partype == "angle" endparam } class REB_TrapShapeDeltoid(common.ulb:TrapShape) { ; This shape uses the Deltoid function.
public: import "common.ulb" ; Constructor func REB_TrapShapeDeltoid(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave && @partype == "angle" float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = @a*(2*cos(t)+cos(2*t)) float y = @a*(2*sin(t)-sin(2*t)) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Deltoid" int param v_Deltoid caption = "Version (Deltoid)" 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_Deltoid < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam bool param wave caption = "Add petal wave" default = false visible = @partype == "angle" endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && @partype == "angle" endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && @partype == "angle" endparam } class REB_TrapShapeCatenary(common.ulb:TrapShape) { ; This shape uses the Catenary function.
public: import "common.ulb" ; Constructor func REB_TrapShapeCatenary(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float x = 5*@a*real(pz) float y = 0.25*@a*@b*cosh(x/(0.25*@a*@b)) m_LastZ = x + flip(y) if @abs d = abs(cabs(pz)-cabs(m_LastZ)) else d = cabs(pz-m_LastZ) endif return d endfunc default: title = "Catenary" int param v_Catenary caption = "Version (Catenary)" 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_Catenary < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param abs caption = "Absolute Value" default = false endparam } class REB_TrapShapeCayleysSexticEvolute(common.ulb:TrapShape) { ; This shape uses the Catenary function.
public: import "common.ulb" ; Constructor func REB_TrapShapeCayleysSexticEvolute(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) if @wave && @partype == "angle" float r = cabs(pz) float wtheta = atan2(pz) if wtheta < 0 wtheta = wtheta + 2 * #pi endif int iter = 0 while iter < 2 wtheta = wtheta + @wamp * cos(@wfreq * r) iter = iter + 1 endwhile float x = r * cos(wtheta) float y = r * sin(wtheta) pz = x + flip(y) endif float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = 0.25*@a*(2+3*cos(t)-cos(3*t)) float y = @a*sin(t)^3 m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Cayley's Sextic Evolute" int param v_CayleysSexticEvolute caption = "Version (Cayley's Sextic Evolute)" 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_CayleysSexticEvolute < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam bool param wave caption = "Add petal wave" default = false visible = @partype == "angle" endparam float param wamp caption = "Wave amplitude" default = 0.05 visible = @wave && @partype == "angle" endparam float param wfreq caption = "Wave frequency" default = 20 visible = @wave && @partype == "angle" endparam } class REB_TrapShapeCissoidofDioclesCatacaustic(common.ulb:TrapShape) { ; This shape uses the Cissoid of Diocles Catacaustic function.
public: import "common.ulb" ; Constructor func REB_TrapShapeCissoidofDioclesCatacaustic(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 if @partype == "cabs(z)" t = cabs(pz) elseif @partype == "real(z)" t = real(pz) elseif @partype == "imag(z)" t = imag(pz) elseif @partype == "real(z) + imag(z)" t = real(pz) + imag(pz) elseif @partype == "real(z) * imag(z)" t = real(pz) * imag(pz) elseif @partype == "angle" t = atan2(pz) endif t = t*@scale float x = -12*@a*t^2*(t^2-1)/(t^2+1)^2 float y = 24*@a*t^3/(t^2+1)^2 m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Cissoid of Diocles Catacaustic" int param v_CissoidofDioclesCatacaustic caption = "Version (Cissoid of Diocles Catacaustic)" 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_CissoidofDioclesCatacaustic < 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } class REB_TrapShapeCatenaryInvolute(common.ulb:TrapShape) { ; This shape uses the Catenary Involute function.
public: import "common.ulb" ; Constructor func REB_TrapShapeCatenaryInvolute(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 t = atan2(pz) t = t*@scale float x = 1.5*@a*(t-tanh(t)) float y = 1.5*@a/cosh(t) m_LastZ = x + flip(y) if @abs d = abs(cabs(pz)-cabs(m_LastZ)) else d = cabs(pz-m_LastZ) endif return d endfunc default: title = "Catenary Involute" int param v_CatenaryInvolute caption = "Version (Catenary Involute)" 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_CatenaryInvolute< 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam bool param abs caption = "Absolute Value" default = false endparam } class REB_TrapShapeSemicubicalParabolaInvolute(common.ulb:TrapShape) { ; This shape uses the Semicubical Parabola Involute function.
public: import "common.ulb" ; Constructor func REB_TrapShapeSemicubicalParabolaInvolute(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 float t = 0 t = atan2(pz) t = t*@scale float x = @a*(t^3/3-8/(27*@b^2)) float y = -4*@a*t/(9*@b) m_LastZ = x + flip(y) d = cabs(pz-m_LastZ) return d endfunc default: title = "Semicubical Parabola Involute" int param v_SemicubicalParabolaInvolute caption = "Version (Semicubical Parabola Involute)" 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_SemicubicalParabolaInvolute< 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam } class REB_TrapShapeWitchOfAgnesi(common.ulb:TrapShape) { ; This shape uses the witch of Agnesi function.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeWitchOfAgnesi(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float theta = 0 float d = 0 theta = atan2(pz) int sgn = 1 if @sgn sgn = -1 endif complex af1 = 2*cotan(theta) complex af2 = 1-cos(2*theta) complex as = 0.1*@a*(af1 + sgn*flip(af2)) m_LastZ = as if @absval d = abs(cabs(pz) - cabs(as)) else d = cabs(pz - (as)) endif return d endfunc default: title = "Witch of Agnesi" int param v_trapshapewitchofagnesi caption = "Version (Trap Shape Witch Of Agnesi)" default = 101 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_trapshapewitchofagnesi < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeSum(common.ulb:TrapShape) { ; This shape is the sum of the real and imaginary components of z.
public: import "common.ulb" ; Constructor func REB_TrapShapeSum(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) m_LastZ = flip(pz) return 5*abs(real(pz)+imag(pz)) endfunc default: title = "Sum" int param v_trapshapesum caption = "Version (Trap Shape Sum)" default = 101 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_trapshapesum < 101 endparam } class REB_TrapShapeSum2(common.ulb:TrapShape) { ; This shape is a weighted sum of the the real and imaginary components of z.
;

; This variant of the function has a signed and absolute value ; version of the distance. The function also has a complex conjugate variant. ; The transformed value is the complex return value of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeSum2(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 int sgn = 1 if @sgn sgn = -1 endif if @absval d = abs(cabs(pz) - cabs(real(@a*pz) + sgn*flip(0.2*@b*imag(pz)))) else d = cabs(real(@a*pz) + sgn*flip(0.2*@b*imag(pz))) endif m_LastZ = real(@a*pz) + sgn*flip(0.2*@b*imag(pz)) return d endfunc default: title = "Sum 2" int param v_trapshapesum2 caption = "Version (Trap Shape Sum 2)" default = 101 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_trapshapesum2 < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam bool param sgn caption = "Conjugate transform" default = false endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeProduct(common.ulb:TrapShape) { ; This shape is the product of the real and imaginary components of z.
public: import "common.ulb" ; Constructor func REB_TrapShapeProduct(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) m_LastZ = pz- real(pz)*imag(pz) return 101*abs(real(pz)*imag(pz)) endfunc default: title = "Product" int param v_trapshapeproduct caption = "Version (Trap Shape Product)" default = 101 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_trapshapeproduct < 101 endparam } class REB_TrapShapeQuotient1(common.ulb:TrapShape) { ; This shape is a quotient of the real and imaginary components of z.
; quotient = abs(real(z)/imag(z)) public: import "common.ulb" ; Constructor func REB_TrapShapeQuotient1(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) m_LastZ = pz- real(pz)/imag(pz) return 3*abs(real(pz)/imag(pz)) endfunc default: title = "Quotient 1" int param v_trapshapequotient1 caption = "Version (Trap Shape Quotient 1)" default = 101 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_trapshapequotient1 < 101 endparam } class REB_TrapShapeCeilFloor(common.ulb:TrapShape) { ; This shape uses the ceil() and floor() functions.
;

; The ceil() function is applied to the real component of z and the ; floor() function is applied to the imaginary component of z. The shape ; can also be used as a texture. public: import "common.ulb" ; Constructor func REB_TrapShapeCeilFloor(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) m_LastZ = pz - (ceil(real(pz))+ flip(floor(imag(pz)))) return abs(real(pz)-ceil(real(pz)))+abs(imag(pz)-floor(imag(pz))) endfunc default: title = "Ceil Floor" int param v_trapshapeceilfloor caption = "Version (Trap Shape Ceil Floor)" default = 101 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_trapshapeceilfloor < 101 endparam } class REB_TrapShapeTruncRound(common.ulb:TrapShape) { ; This shape uses the trunc() and round() functions.
;

; The round() function is applied to the real component of z and the ; trunc() function is applied to the imaginary component of z. The shape ; can also be used as a texture. public: import "common.ulb" ; Constructor func REB_TrapShapeTruncRound(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) m_LastZ = pz - (round(real(pz))+ flip(trunc(imag(pz)))) return 3*(abs(real(pz)-round(real(pz)))+abs(imag(pz)-trunc(imag(pz)))) endfunc default: title = "Trunc Round" int param v_trapshapetruncround caption = "Version (Trap Shape Trunc Round)" default = 101 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_trapshapetruncround < 101 endparam } class REB_TrapShapeCfPlus(common.ulb:TrapShape) { ; This shape uses the ceil() and floor() functions.
;

; The ceil() function is applied to the real component of z and the ; floor() function is applied to the imaginary component of z. The shape ; can also be used as a texture. public: import "common.ulb" ; Constructor func REB_TrapShapeCfPlus(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) m_LastZ = pz - (ceil(real(pz))+ flip(floor(imag(pz)))) return abs(real(pz)-ceil(real(pz)) + imag(pz)-floor(imag(pz))) endfunc default: title = "Cf Plus" int param v_trapshapeCFPlus caption = "Version (Trap Shape CF Plus)" default = 101 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_trapshapeCFPlus < 101 endparam } class REB_TrapShapeTrPlus(common.ulb:TrapShape) { ; This shape uses the trunc() and round() functions.
;

; The round() function is applied to the real component of z and the ; trunc() function is applied to the imaginary component of z. The shape ; can also be used as a texture. public: import "common.ulb" ; Constructor func REB_TrapShapeTrPlus(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) m_LastZ = pz - (round(real(pz))+ flip(trunc(imag(pz)))) return abs(real(pz)-round(real(pz))+imag(pz)-trunc(imag(pz))) endfunc default: title = "Tr Plus" int param v_trapshapetrplus caption = "Version (Trap Shape Tr Plus)" default = 101 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_trapshapetrplus < 101 endparam } class REB_TrapShapeFibonacci(common.ulb:TrapShape) { ; This shape based upon Fibonacci numbers
;

; The trap shape is determined by distances from Fibonacci numbers. One of the ; interesting characteristics of the shape are multiple 3D like arrows that ; follow the flow shape of the trap. public: import "common.ulb" ; Constructor func REB_TrapShapeFibonacci(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float f1 = 0 float f2 = 1 float d = 0 float d1 = 0 float d2 = 0 d1 =real(pz)-f2 while d1 > 0 float ftemp = f2 f2 = f1 + f2 f1 = ftemp d1 = real(pz)-f2 endwhile d = real(pz)-f1 ; which fibonacci number is closest if d < abs(d1) d1 = d endif f1 = 0 f2 = 1 d2 = imag(pz)-f2 while d2 > 0 ftemp = f2 f2 = f1 + f2 f1 = ftemp d2 = imag(pz)-f2 endwhile d = real(pz)-f1 ; which fibonacci number is closest if d < abs(d2) d2 = d endif d = 5*(abs(d1) + abs(d2)) m_LastZ = pz - (d1 + flip(d2)) return d endfunc default: title = "Fibonacci" int param v_trapshapefibonacci caption = "Version (Trap Shape Fibonacci)" default = 101 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_trapshapefibonacci < 101 endparam } class REB_TrapShapeQuotient2(common.ulb:TrapShape) { ; This shape is a quotient of the real and imaginary components of z.
; quotient = abs(imag(z)/real(z)) public: import "common.ulb" ; Constructor func REB_TrapShapeQuotient2(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) m_LastZ = pz- imag(pz)/real(pz) return 3*abs(imag(pz)/real(pz)) endfunc default: title = "Quotient 2" int param v_trapshapequotient2 caption = "Version (Trap Shape Quotient 2)" default = 101 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_trapshapequotient2 < 101 endparam } class REB_TrapShapeProduct2(common.ulb:TrapShape) { ; This shape is a weighted product of the the real and imaginary components of z.
;

; This variant of the function has a signed and absolute value ; version of the distance. The transformed value is the complex return value ; of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeProduct2(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 if @absval d = abs(cabs(pz) - cabs(real(@a*pz) *flip(0.2*@b*imag(pz)))) else d = cabs(real(@a*pz) * flip(0.2*@b*imag(pz))) endif m_LastZ = real(@a*pz) * flip(0.2*@b*imag(pz)) return d endfunc default: title = "Product 2" int param v_trapshapeproduct2 caption = "Version (Trap Shape Product 2)" default = 101 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_trapshapeproduct2 < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeQuotient3(common.ulb:TrapShape) { ; This shape is a weighted quotient of the the real and imaginary components of z.
;

; This variant of the function has a signed and absolute value ; version of the distance. The transformed value is the complex return value ; of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeQuotient3(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 if @absval d = abs(cabs(pz) - cabs(real(@a*pz) / (flip(0.2*@b*imag(pz))))) else d = cabs(real(@a*pz) / (flip(0.2*@b*imag(pz)))) endif m_LastZ = real(@a*pz) / (flip(0.2*@b*imag(pz))) return d endfunc default: title = "Quotient 3" int param v_trapshapequotient3 caption = "Version (Trap Shape Quotient 3)" default = 101 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_trapshapequotient3 < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeQuotient4(common.ulb:TrapShape) { ; This shape is a weighted quotient of the the real and imaginary components of z.
;

; This variant of the function has a signed and absolute value ; version of the distance. The transformed value is the complex return value ; of the function. public: import "common.ulb" ; Constructor func REB_TrapShapeQuotient4(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float d = 0 if @absval d = abs(cabs(pz) - cabs(imag(@b*pz) / (flip(0.2*@a*real(pz))))) else d = cabs(imag(@b*pz) / (flip(0.2*@a*real(pz)))) endif m_LastZ = imag(@b*pz) / (flip(0.2*@a*real(pz))) return d endfunc default: title = "Quotient 4" int param v_trapshapequotient4 caption = "Version (Trap Shape Quotient 4)" default = 101 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_trapshapequotient4 < 101 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam param absval caption = "Absolute Value" default = false endparam } class REB_TrapShapeGenTexture(common.ulb:TrapShape) { ; This texture is derived from the code of Dennis Magar.
public: import "common.ulb" ; Constructor func REB_TrapShapeGenTexture(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) complex w = fn2(fn1((pz)*10^@pwr))*@ts complex ww = fn2(fn1((w - @fn6(w)))) + @toffset float t = cabs(ww)*@tc t = (t - round(t))*0.25 m_LastZ = exp(flip(2*#pi * sqrt(2) * t)) return t endfunc default: title = "General Textures" int param v_trapshapegeneraltextures caption = "Version (Trap Shape General Textures)" default = 101 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_trapshapegeneraltextures < 101 endparam param toffset caption = "Texture offset" default = (-1,-1) hint = "Changes the texture pattern." endparam param ts caption = "Texture scale" default = 100.0 endparam param tc caption = "Texture modifier" default = 5.0 endparam param pwr caption = "Texture power" default = 0.25 endparam func fn1 caption = "Texture Function 1" default = sqr() endfunc func fn2 caption = "Texture Function 2" default = acos() endfunc func fn6 caption = "Texture Function 3" default = round() endfunc } class REB_TrapShapeGnarlTexture(common.ulb:TrapShape) { ; This texture is based upon the code of Mark Townsend
; Convolution code added 10/10/08
public: import "common.ulb" ; constructor func REB_TrapShapeGnarlTexture(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) complex z = 0 float x = 0 float y = 0 float xx = 0 int i = 0 int j = 0 int jmax = 0 float a = 0 float sum = 0 float distance = 0 if @mode == 0 jmax = 1 else jmax = 5 endif while j < jmax z = pz*@scaleg if @mode == 1 || @mode == 2 if j == 0 a = @cbl + @ctl + @cbr + @ctr + @cc elseif j == 1 z = z + @eps*(-1,-1) a = -@cbl elseif j == 2 z = z + @eps*(-1,1) a = -@ctl elseif j == 3 z = z + @eps*(1,-1) a = -@cbr elseif j == 4 z = z + @eps*(1,1) a = -@ctr endif else a = 1 endif j = j + 1 x = real(z) y = imag(z) xx = 0 while (i < @iters) xx = x if @formula == 0 ; Martin x = y - sin(x) y = @a - xx elseif @formula == 1 ; Popcorn x = x - @h * sin(y + tan(@a * y)) y = y - @h * sin(xx + tan(@a * xx)) elseif @formula == 2 ; Vine if @flavor == 0 x = x - @h * sin(y + sin(@a * y )) y = y + @h * sin(xx + sin(@a * xx)) elseif @flavor == 1 x = x - @h * sin(y^@b + sin(@a * y)) y = y + @h * sin(xx^@b + sin(@a * xx)) elseif @flavor == 2 x = x - @h * sin(y + sin(@a * (y + sin(@a * y)))) y = y + @h * sin(xx + sin(@a * (xx + sin(@a * xx)))) else float newx = y float newy = x int j = 0 while j < @flavor j = j + 1 newx = y + sin(@a * newx) newy = x + sin(@a * newy) endwhile x = x - @h * sin(newx) y = y + @h * sin(newy) endif elseif @formula == 3 ; Gnarl x = x - @h * real(@gn1(y + @gn2(@a * (y + @gn3(@b * y))))) y = y + @h * real(@gn1(xx + @gn2(@a * (xx + @gn3(@b * xx))))) endif i = i + 1 endwhile z = ((real(pz) - (@scaleg * x)) + flip((imag(pz) - (@scaleg * y))))*@strengthg distance = cabs(z) if @mode != 2 sum = sum + a*distance else sum = sum + a*abs(distance) endif distance = 0 endwhile if @mode == 2 sum = 3*abs(sum) endif if @mode == 1 distance = sum/(10*@eps*(abs(@cbl + @ctl + @cbr + @ctr)+1)) else distance = sum endif m_LastZ = z return distance endfunc default: title = "Gnarl Textures" int param v_trapshapegnarltextures caption = "Version (Trap Shape Gnarl Textures)" default = 102 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_trapshapegnarltextures < 102 endparam param formula caption = "Formula" enum = "Martin" "Popcorn" "Vine" "Gnarl" default = 1 endparam param a caption = "Alpha" default = 3.0 endparam param b caption = "Beta" default = 2.0 visible = (@formula == 2 || @formula == 3) endparam param iters caption = "Iterations" default = 20 endparam param flavor caption = "Vine flavor" default = 2 min = 0 visible = @formula == 2 endparam param h caption = "Step size" default = 0.1 visible = (@formula == 1 || @formula == 2 || @formula == 3) endparam param scaleg caption = "Scale" default = 10.0 hint = "Changes the size of the shapes." endparam param strengthg caption = "Strength" default = 0.05 endparam func gn1 caption = "Gnarl function #1" default = sin() visible = @formula == 3 endfunc func gn2 caption = "Gnarl function #2" default = tan() visible = @formula == 3 endfunc func gn3 caption = "Gnarl function #3" default = cos() visible = @formula == 3 endfunc param mode caption = "Mode" default = 0 enum = "Normal" "Convolution" "Absolute Convolution" endparam param cc caption = "Center Extra Weight" default = 0.0 visible = @mode != "Normal" endparam param cbl caption = "Bottom Left Weight" default = 1.0 visible = @mode != "Normal" endparam param ctl caption = "Top Left Weight" default = 0.0 visible = @mode != "Normal" endparam param cbr caption = "Bottom Right Weight" default = 0.0 visible = @mode != "Normal" endparam param ctr caption = "Top Right Weight" default = 0.0 visible = @mode != "Normal" endparam param eps caption = "Epsilon" default = 0.006 visible = @mode != "Normal" endparam } class REB_TrapShapeWorleyTextures(common.ulb:TrapShape) { ; Implementation of Worley cellular noise with Worley fractal modulation.
;

; The Euclidian flavor is closely equivalent to Voronoi texturing. ; Jim Blue's random number generator was essential to its development. ; Additional methods of fractal modulation have been added based upon the ; Worley model. public: import "common.ulb" import "jlb.ulb" ; Constructor func REB_TrapShapeWorleyTextures(Generic pparent) TrapShape.TrapShape(pparent) rndi = new JLB_Random(0) rndi.Init(@seed) rndi.SetNMax(5000) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) complex fz[10] complex fzc[10] complex fzz[10] float dst[10] float dst2[10] complex fzc1[10] complex fzc2[10] complex fzc3[10] complex fzc4[10] float dist = 1e20 float dist2 = 1e20 complex cells[12,10] float distance = 0 float test = 0 float sum = 0 float a = 1 complex diff = 0 int rnds[24] float fac[10] float rp[12,10] float ip[12,10] int i = 1 int j = 0 int jmax = 0 rnds[0] = rndi.RandomIntInRange(@seed) while i < 24 rnds[i] = rndi.RandomIntInRange(0) i = i + 1 endwhile i = 0 fac[0] = 1 while i < 10 dst[i] = 1e10 dst2[i] = 1e10 if i > 0 fac[i] = fac[i-1]*(i+1) endif i = i + 1 endwhile complex near = 0 complex fnear[10] if @mode == 0 jmax = 1 else jmax = 5 endif if @type == "Mosaic" jmax = 1 endif while j < jmax if @v_trapshapeworleytextures < 103 complex z = pz/@psize else complex z = (pz+(10,10))/@psize endif if @mode == 1 || @mode == 2 if j == 0 a = @cbl + @ctl + @cbr + @ctr + @cc;/20 elseif j == 1 z = z + @eps*(-1,-1) a = -@cbl elseif j == 2 z = z + @eps*(-1,1) a = -@ctl elseif j == 3 z = z + @eps*(1,-1) a = -@cbr elseif j == 4 z = z + @eps*(1,1) a = -@ctr endif else a = 1 endif j = j + 1 int f = 0 repeat if @nfrac == "2^x" fz[f] = z*2^f elseif @nfrac == "exp(x)" fz[f] = z*exp(f) elseif @nfrac == "cosh(x)" fz[f] = z*cosh(f) elseif @nfrac == "cos(x)" fz[f] = z*cos(f) elseif @nfrac == "sec(x)" fz[f] = z/cos(f) elseif @nfrac == "sech(x)" fz[f] = z/cosh(f) elseif @nfrac == "factorial(x+1)" fz[f] = z*fac[f] endif fzc[f] = round(fz[f]) fzz[f] = fz[f] - fzc[f] ; create the grid fzc1[f] = fzc[f] + (1,1)/2 fzc2[f] = fzc[f] + (1,-1)/2 fzc3[f] = fzc[f] + (-1,1)/2 fzc4[f] = fzc[f] + (-1,-1)/2 ; create the random points ; cell 1 rp[0,f] = ((real(fzc1[f])-rnds[0])^5%rnds[6] - (imag(fzc1[f])+rnds[12])^3%rnds[18])^2 %2 - 1 ip[0,f] = ((real(fzc1[f])-rnds[1])^5%rnds[7] - (imag(fzc1[f])+rnds[13])^3%rnds[19])^2 %2 - 1 rp[1,f] = ((real(fzc1[f])-rnds[2])^5%rnds[8] - (imag(fzc1[f])+rnds[14])^3%rnds[20])^2 %2 - 1 ip[1,f] = ((real(fzc1[f])-rnds[3])^5%rnds[8] - (imag(fzc1[f])+rnds[15])^3%rnds[21])^2 %2 - 1 rp[2,f] = ((real(fzc1[f])-rnds[4])^5%rnds[10] - (imag(fzc1[f])+rnds[16])^3%rnds[22])^2 %2 - 1 ip[2,f] = ((real(fzc1[f])-rnds[5])^5%rnds[11] - (imag(fzc1[f])+rnds[17])^3%rnds[23])^2 %2 - 1 ; cell 2 rp[3,f] = ((real(fzc2[f])-rnds[0])^5%rnds[6] - (imag(fzc2[f])+rnds[12])^3%rnds[18])^2 %2 - 1 ip[3,f] = ((real(fzc2[f])-rnds[1])^5%rnds[7] - (imag(fzc2[f])+rnds[13])^3%rnds[19])^2 %2 - 1 rp[4,f] = ((real(fzc2[f])-rnds[2])^5%rnds[8] - (imag(fzc2[f])+rnds[14])^3%rnds[20])^2 %2 - 1 ip[4,f] = ((real(fzc2[f])-rnds[3])^5%rnds[8] - (imag(fzc2[f])+rnds[15])^3%rnds[21])^2 %2 - 1 rp[5,f] = ((real(fzc2[f])-rnds[4])^5%rnds[10] - (imag(fzc2[f])+rnds[16])^3%rnds[22])^2 %2 - 1 ip[5,f] = ((real(fzc2[f])-rnds[5])^5%rnds[11] - (imag(fzc2[f])+rnds[17])^3%rnds[23])^2 %2 - 1 ; cell 3 rp[6,f] = ((real(fzc3[f])-rnds[0])^5%rnds[6] - (imag(fzc3[f])+rnds[12])^3%rnds[18])^2 %2 - 1 ip[6,f] = ((real(fzc3[f])-rnds[1])^5%rnds[7] - (imag(fzc3[f])+rnds[13])^3%rnds[19])^2 %2 - 1 rp[7,f] = ((real(fzc3[f])-rnds[2])^5%rnds[8] - (imag(fzc3[f])+rnds[14])^3%rnds[20])^2 %2 - 1 ip[7,f] = ((real(fzc3[f])-rnds[3])^5%rnds[8] - (imag(fzc3[f])+rnds[15])^3%rnds[21])^2 %2 - 1 rp[8,f] = ((real(fzc3[f])-rnds[4])^5%rnds[10] - (imag(fzc3[f])+rnds[16])^3%rnds[22])^2 %2 - 1 ip[8,f] = ((real(fzc3[f])-rnds[5])^5%rnds[11] - (imag(fzc3[f])+rnds[17])^3%rnds[23])^2 %2 - 1 ; cell 4 rp[9,f] = ((real(fzc4[f])-rnds[0])^5%rnds[6] - (imag(fzc4[f])+rnds[12])^3%rnds[18])^2 %2 - 1 ip[9,f] = ((real(fzc4[f])-rnds[1])^5%rnds[7] - (imag(fzc4[f])+rnds[13])^3%rnds[19])^2 %2 - 1 rp[10,f] = ((real(fzc4[f])-rnds[2])^5%rnds[8] - (imag(fzc4[f])+rnds[14])^3%rnds[20])^2 %2 - 1 ip[10,f] = ((real(fzc4[f])-rnds[3])^5%rnds[8] - (imag(fzc4[f])+rnds[15])^3%rnds[21])^2 %2 - 1 rp[11,f] = ((real(fzc4[f])-rnds[4])^5%rnds[10] - (imag(fzc4[f])+rnds[16])^3%rnds[22])^2 %2 - 1 ip[11,f] = ((real(fzc4[f])-rnds[5])^5%rnds[11] - (imag(fzc4[f])+rnds[17])^3%rnds[23])^2 %2 - 1 ; put into the grids cells[0,f] = (rp[0,f] + flip(ip[0,f]) + (1,1))/2 cells[1,f] = (rp[1,f] + flip(ip[1,f]) + (1,1))/2 cells[2,f] = (rp[2,f] + flip(ip[2,f]) + (1,1))/2 cells[3,f] = (rp[3,f] + flip(ip[3,f]) + (1,-1))/2 cells[4,f] = (rp[4,f] + flip(ip[4,f]) + (1,-1))/2 cells[5,f] = (rp[5,f] + flip(ip[5,f]) + (1,-1))/2 cells[6,f] = (rp[6,f] + flip(ip[6,f]) + (-1,1))/2 cells[7,f] = (rp[7,f] + flip(ip[7,f]) + (-1,1))/2 cells[8,f] = (rp[8,f] + flip(ip[8,f]) + (-1,1))/2 cells[9,f] = (rp[9,f] + flip(ip[9,f]) + (-1,-1))/2 cells[10,f] = (rp[10,f] + flip(ip[10,f]) + (-1,-1))/2 cells[11,f] = (rp[11,f] + flip(ip[11,f]) + (-1,-1))/2 i = 0 while i < 12 diff = fzz[f] - cells[i,f] if @flavor == "Euclidian" test = cabs(diff) elseif @flavor == "Manhattan" test = (abs(real(diff))^real(@mp) + abs(imag(diff))^imag(@mp)) elseif @flavor == "Chebychev" if abs(real(diff)) > abs(imag(diff)) test = abs(real(diff)) else test = abs(imag(diff)) endif elseif @flavor == "Minkovsky" test = (abs(real(diff))^@ex + abs(imag(diff))^@ex)^(1/@ex) elseif @flavor == "Exp/Log Manhattan" test = log(exp(abs(real(diff))) + exp(abs(imag(diff)))) endif if test < dst[f] dst2[f] = dst[f] dst[f] = test fnear[f] = fzc[f] + cells[i,f] elseif test < dst2[f] dst2[f] = test endif i = i + 1 endwhile i = 0 f = f + 1 until (f-1) == @fmax f = 0 repeat if f == 0 dist = dst[0] dist2 = dst2[0] near = fnear[0] else if @nfrac == "2^x" dist = dist + 2^(-f)*dst[f] dist2 = dist2 + 2^(-f)*dst2[f] near = near + 2^(-f)*fnear[f] elseif @nfrac == "exp(x)" dist = dist + exp(-f)*dst[f] dist2 = dist2 + exp(-f)*dst2[f] near = near + exp(-f)*fnear[f] elseif @nfrac == "cosh(x)" dist = dist + 1/cosh(f)*dst[f] dist2 = dist2 + 1/cosh(f)*dst2[f] near = near + 1/cosh(f)*fnear[f] elseif @nfrac == "cos(x)" dist = dist + 1/cos(f)*dst[f] dist2 = dist2 + 1/cos(f)*dst2[f] near = near + 1/cos(f)*fnear[f] elseif @nfrac == "sec(x)" dist = dist + cos(f)*dst[f] dist2 = dist2 + cos(f)*dst2[f] near = near + cos(f)*fnear[f] elseif @nfrac == "sech(x)" dist = dist + cosh(f)*dst[f] dist2 = dist2 + cosh(f)*dst2[f] near = near + cosh(f)*fnear[f] elseif @nfrac == "factorial(x+1)" dist = dist + 1/fac[f]*dst[f] dist2 = dist2 + 1/fac[f]*dst2[f] near = near + 1/fac[f]*fnear[f] endif endif f = f + 1 until (f-1) == @fmax if @type == "Distance" distance = dist^@thick elseif @type == "2nd Distance" distance = (@smod*dist2-dist)^@thick elseif @type == "2nd Distance variant" distance = dist2^@thick elseif @type == "Mosaic" distance = cabs(1000*near) + 1000*atan(cabs(near)+#pi)%1 endif if @mode != 2 sum = sum + a*distance else sum = sum + a*abs(distance) endif distance = 0 endwhile if @mode == 2 sum = 3*abs(sum) endif if @mode == 1 distance = sum/(10*@eps*(abs(@cbl + @ctl + @cbr + @ctr)+1)) else distance = sum endif if @dmod != 0 distance = distance*@dmod endif if @type != "Mosaic" if @invert distance = abs(1-distance) endif else distance = distance % 1 endif m_LastZ = exp(flip(2 * #pi * sqrt(2) * distance)) return distance endfunc protected: JLB_Random rndi default: title = "Worley Textures" int param v_trapshapeworleytextures caption = "Version (Trap Shape Worley Textures)" default = 103 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_trapshapeworleytextures < 103 endparam param flavor caption = "Flavor" default = 4 enum = "Chebychev" "Euclidian" "Manhattan" "Exp/Log Manhattan" "Minkovsky" endparam float param ex caption = "Minkovsky param" default = 4 visible = @flavor == "Minkovsky" endparam complex param mp caption = "Manhattan pwr" default = (1,1) visible = @flavor == "Manhattan" endparam param type caption = "Worley type" default = 2 enum = "Distance" "2nd Distance" "2nd Distance variant" "Mosaic" endparam float param smod caption = "2nd dist mod" default = 1.0 visible = @type == "2nd Distance" endparam param psize caption = "Pattern Size" default = .15 endparam float param thick caption = "Thickness" default = 0.1 endparam float param dmod caption = "Dist modulator" default = 0.0 min = 0.0 endparam int param fmax caption = "Fractal iterations" default = 4 max = 9 endparam param nfrac caption = "Fractal function" default = 0 enum = "2^x" "factorial(x+1)" "cos(x)" "cosh(x)" "exp(x)" "sec(x)" "sech(x)" endparam bool param invert caption = "Invert" default = false visible = @type != "Mosaic" endparam int param seed caption = "Worley seed" default = 123 endparam param mode caption = "Mode" default = 0 enum = "Normal" "Convolution" "Absolute Convolution" visible = @type != "Mosaic" endparam param cc caption = "Center Extra Weight" default = 0.0 visible = @mode != "Normal" && @type != "Mosaic" endparam param cbl caption = "Bottom Left Weight" default = 1.0 visible = @mode != "Normal" && @type != "Mosaic" endparam param ctl caption = "Top Left Weight" default = 0.0 visible = @mode != "Normal" && @type != "Mosaic" endparam param cbr caption = "Bottom Right Weight" default = 0.0 visible = @mode != "Normal" && @type != "Mosaic" endparam param ctr caption = "Top Right Weight" default = 0.0 visible = @mode != "Normal" && @type != "Mosaic" endparam param eps caption = "Epsilon" default = 0.006 visible = @mode != "Normal" && @type != "Mosaic" endparam } class REB_TrapShapeInversions(common.ulb:TrapShape) { ; This shape uses sphere and mobius inversions
public: import "common.ulb" ; import "reb.ulb" ; constructor func REB_TrapShapeInversions(Generic pparent) TrapShape.TrapShape(pparent) i = new @isph(this) ; z axis rotation correction zrot = (0,1)^(-#angle*2/#pi) i.recurse() cir = i.s max = i.fk endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float distance = 1e10 j = 0 idx = 0 inside = false while j < max && !inside if @shape == "functions" if cabs(@fn(pz)-(cir.sph[j].fcen+@offset)*zrot*@scale/#magn) < cir.sph[j].frad*@scale/#magn inside = true idx = j endif else if cabs(pz-(cir.sph[j].fcen+@offset)*zrot*@scale/#magn) < cir.sph[j].frad*@scale/#magn inside = true idx = j endif endif j = j + 1 endwhile if inside if @shape == "rings" distance = abs(cir.sph[idx].frad*@scale/#magn-\ cabs(pz-(cir.sph[idx].fcen+@offset)*zrot*@scale/#magn)) elseif @shape == "circles" distance = cabs(pz-(cir.sph[idx].fcen+@offset)*zrot*@scale/#magn) elseif @shape == "angle" distance = atan2(pz-(cir.sph[idx].fcen+@offset)*zrot*@scale/#magn) if distance < 0 distance = distance + 2*#pi endif distance = distance/(2*#pi) elseif @shape == "functions" distance = cabs(@fn(pz)-(cir.sph[idx].fcen+@offset)*zrot*@scale/#magn) endif endif if @ztype == "Position" m_lastz = (cir.sph[idx].fcen+@offset)*zrot*@scale/#magn elseif @ztype == "Generator" m_lastz = cir.sph[idx].fgen*@scale/#magn elseif @ztype == "Index" m_lastz = idx*@scale/#magn elseif @ztype == "Level" m_lastz = cir.sph[idx].flevel*@scale/#magn elseif @ztype == "Radius" m_LastZ = cir.sph[idx].frad*@scale/#magn endif return distance/(cir.sph[idx].frad*@scale/#magn) endfunc protected: spherearray cir int max InvertSphere i complex zrot int j int idx bool inside default: title = "Inversions" int param v_trapshapeinversions caption = "Version (Trap Shape Inversions)" default = 101 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_trapshapeinversions < 101 endparam float param scale caption = "Inversions scale" default = 1.0 endparam complex param offset caption = "Inversions offset" default = (0,0) endparam param shape caption = "Shape" default = 0 enum = "rings" "circles" "angle" "functions" endparam func fn caption = "Shape function" default = sin() visible = @shape == "functions" endfunc heading text = "To color the spheres by type, select the Trap Color Mode 'Magnitude' \ and use the value after tranformation. Select the 'Z type' desired. \ Adjust the color density and gradient to get the desired coloring." endheading param ztype caption = "Z type" default = 0 enum = "Position" "Generator" "Index" "Level" "Radius" endparam InvertSphere param isph caption = "Inversions" default = InvertCircles endparam } class REB_TrapShapeModPerlinTexture(common.ulb:TrapShape) { ; This texture is based upon the code of Damien Jones
; Convolution code added 10/10/08
public: import "common.ulb" ; Constructor func REB_TrapShapeModPerlinTexture(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) int p[514] float g3[514, 3] int i = 0 int j = 0 int k = 0 int seed = @seed float sum2 = 0 float jc = 0 float aa = 0 float jmax = 0 if @mode == 0 jmax = 1 else jmax = 5 endif while i < 256 p[i] = i j = 0 while j < 3 seed = random(seed) g3[i, j] = seed % 256 j = j + 1 endwhile float t0 = g3[i, 0] float t1 = g3[i, 1] float t2 = g3[i, 2] float s = sqrt(t0 * t0 + t1 * t1 + t2 * t2) g3[i, 0] = g3[i, 0] / s g3[i, 1] = g3[i, 1] / s g3[i, 2] = g3[i, 2] / s i = i + 1 endwhile i = 0 while i < 256 k = p[i] j = abs(seed) % 256 seed = random(seed) p[i] = p[j] p[j] = k i = i + 1 endwhile i = 0 while i < 256 p[256 + i] = p[i] j = 0 while j < 3 g3[256 + i , j] = g3[i, j]; j = j + 1 endwhile i = i + 1 endwhile while jc < jmax z = pz*@scale if @mode == 1 || @mode == 2 if jc == 0 aa = @cbl + @ctl + @cbr + @ctr + @cc;/20 elseif jc == 1 z = z + @eps*(-1,-1) aa = -@cbl elseif jc == 2 z = z + @eps*(-1,1) aa = -@ctl elseif jc == 3 z = z + @eps*(1,-1) aa = -@cbr elseif jc == 4 z = z + @eps*(1,1) aa = -@ctr endif else aa = 1 endif jc = jc + 1 int iter = 0 float sum = 0 float amplitude = 1.0, r = (0,1) ^ (1/3) while iter < @octaves float t = real(z) % 4096 + 4096 int bx0 = floor(t) % 256 int bx1 = (bx0 + 1) % 256 float rx0 = t - floor(t) float rx1 = rx0 - 1 t = imag(z) % 4096 + 4096 int by0 = floor(t) % 256 int by1 = (by0 + 1) % 256 float ry0 = t - floor(t) float ry1 = ry0 - 1 t = 4096 int bz0 = floor(t) % 256 int bz1 = (bz0 + 1) % 256 float rz0 = t - floor(t) float rz1 = rz0 - 1 int ii = p[bx0] int jj = p[bx1] int b00 = p[ii + by0] int b10 = p[jj + by0] int b01 = p[ii + by1] int b11 = p[jj + by1] float t = (rx0 * rx0 * (3.0 - 2.0 * rx0)) float sy = (ry0 * ry0 * (3.0 - 2.0 * ry0)) float sz = (rz0 * rz0 * (3.0 - 2.0 * rz0)) float u = (rx0 * g3[b00 + bz0, 0] + ry0 * g3[b00 + bz0, 1] + rz0 * g3[b00 + bz0, 2]) float v = (rx1 * g3[b10 + bz0, 0] + ry0 * g3[b10 + bz0, 1] + rz0 * g3[b10 + bz0, 2]) float a = (u + t * (v - u)) u = (rx0 * g3[b01 + bz0, 0] + ry1 * g3[b01 + bz0, 1] + rz0 * g3[b01 + bz0, 2]) v = (rx1 * g3[b11 + bz0, 0] + ry1 * g3[b11 + bz0, 1] + rz0 * g3[b11 + bz0, 2]) float b = (u + t * (v - u)) float c = (a + sy * (b - a)) u = (rx0 * g3[b00 + bz1, 0] + ry0 * g3[b00 + bz1, 1] + rz1 * g3[b00 + bz1, 2]) v = (rx1 * g3[b10 + bz1, 0] + ry0 * g3[b10 + bz1, 1] + rz1 * g3[b10 + bz1, 2]) a = (u + t * (v - u)) u = (rx0 * g3[b01 + bz1, 0] + ry1 * g3[b01 + bz1, 1] + rz1 * g3[b01 + bz1, 2]) v = (rx1 * g3[b11 + bz1, 0] + ry1 * g3[b11 + bz1, 1] + rz1 * g3[b11 + bz1, 2]) b = (u + t * (v - u)) float d = (a + sy *(b - a)) sum = sum + real(@fun(c + sz *(d - c))) * amplitude amplitude = amplitude * @persistence z = z * r / @nfactorp iter = iter + 1 endwhile if @mode != 2 sum2 = sum2 + aa*sum else sum2 = sum2 + aa*abs(sum) endif sum = 0 endwhile if @mode == 2 sum2 = 3*abs(sum2) endif if @mode == 1 sum = sum2/(10*@eps*(abs(@cbl + @ctl + @cbr + @ctr)+1)) else sum = sum2 endif z = exp(flip(2 * #pi * sqrt(2) * sum)) m_lastZ = z if @flavort == 1 m_lastZ = m_lastZ + sum + flip(sum) sum = sum + cabs(z) endif return sum endfunc default: title = "Modified Perlin Textures" int param v_trapshapemodperlintextures caption = "Version (Trap Shape Modified Perlin Textures)" default = 102 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_trapshapemodperlintextures < 102 endparam param flavort caption = "Perlin flavor" default = 0 enum = "0" "1" endparam param octaves caption = "Octaves" default = 7 min = 1 endparam param persistence caption = "Persistence" default = 0.5 endparam float param nfactorp caption = "Noise Factor" default = 0.5 endparam func fun caption = "Noise Function" default = ident() endfunc param scale caption = "Scale" default = 10.0 endparam param @seed caption = "Random Seed" default = 1234567 endparam param mode caption = "Mode" default = 0 enum = "Normal" "Convolution" "Absolute Convolution" endparam param cc caption = "Center Extra Weight" default = 0.0 visible = @mode != "Normal" endparam param cbl caption = "Bottom Left Weight" default = 1.0 visible = @mode != "Normal" endparam param ctl caption = "Top Left Weight" default = 0.0 visible = @mode != "Normal" endparam param cbr caption = "Bottom Right Weight" default = 0.0 visible = @mode != "Normal" endparam param ctr caption = "Top Right Weight" default = 0.0 visible = @mode != "Normal" endparam param eps caption = "Epsilon" default = 0.006 visible = @mode != "Normal" endparam } class REB_TrapShapeLatticeTexture(common.ulb:TrapShape) { ; This texture provides a variety of 3D lattice shapes.
public: import "common.ulb" ; Constructor func REB_TrapShapeLatticeTexture(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) ; create the texture float gridx = real(@grid) float gridy = imag(@grid) if @v_trapshapelatticetextures < 102 float x = real(#pixel)*1000 float y = imag(#pixel)*1000 else float x = real(pz)*1000 float y = imag(pz)*1000 endif float t1x = 0 float t2x = 0 float t3x = 0 float t1y = 0 float t2y = 0 float t3y = 0 complex t = 0 float e1 = 0 float e2 = 0 float e3 = 0 float tx = 0 float ty = 0 float tz = 0 float td = 0 x = x*(1+@blend*real(pz))/(1+@blend)+ real(#random)*real(@dr) y = y*(1+@blend*imag(pz))/(1+@blend)+ imag(#random)*imag(@dr) if @smooth == false if @texture == 0 ;lattice t1x = sin(x/gridx)+@toffset t1y = cos(y/gridy)+@toffset t2x = t1x+@sens t3x = t1x t2y = t1y t3y = t1y+@sens e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 1 ;quilt t1x = tan(x/gridx)+@toffset t2x = t1x + @sens t3x = t1x t1y = cotan(y/gridy)+@toffset t2y = t1y t3y = t1y + @sens e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 2 ;circles and squares t1x = sin(x/gridx)+cos(y/gridy)+@toffset t2x = t1x + @sens t3x = t1x t1y = cos(y/gridy)+sin(x/gridx)+@toffset t2y = t1y t3y = t1y + @sens e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 3 ;triangles t1x = tan(x/gridx)+cotan(y/gridy)+@toffset t2x = t1x + @sens t3x = t1x t1y = cotan(y/gridy)+tan(x/gridx)+@toffset t2y = t1y t3y = t1y + @sens e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 4 ;X's and O's t1x = 1/sin(x/gridx)+@toffset t2x = t1x + @sens t3x = t1x t1y = 1/cos(y/gridy)+@toffset t2y = t1y t3y = t1y + @sens e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 5 ;Dimples t1x = 1/tan(x/gridx)+@toffset t2x = t1x + @sens t3x = t1x t1y = 1/cotan(y/gridy)+@toffset t2y = t1y t3y = t1y + @sens e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 6 ;Arrows t1x = 1/tan(x/gridx)+@toffset t2x = t1x + @sens t3x = t1x t1y = 1/sin(y/gridy)+@toffset t2y = t1y t3y = t1y + @sens e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 7 ; basketweave t1x = 1/sin(x/gridx)+1/cos(y/gridy)+@toffset t2x = t1x + @sens t3x = t1x t1y = 1/cos(y/gridy)+1/sin(x/gridx)+@toffset t2y = t1y t3y = t1y + @sens e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 8 ; balls t1x = sin(x/gridx)^2 + cos(y/gridy)^2+@toffset t2x = t1x + @sens t3x = t1x t1y = sin(y/gridy)^2 + cos(x/gridx)^2+@toffset t2y = t1y t3y = t1y + @sens e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 9 ;Net t1x = log(abs(sin(x/gridx)))+@toffset t2x = t1x+@sens t3x = t1x t1y = log(abs(cos(y/gridy)))+@toffset t2y = t1y t3y = t1y+@sens e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) endif ELSE if @texture == 0 ;lattice t1x = sin(x/gridx)+1 t2x = sin((x+@sens)/gridx)+@toffset t3x = t1x t1y = cos(y/gridy)+1 t2y = t1y t3y = cos((y+@sens)/gridy)+@toffset e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 1 ;quilt t1x = tan(x/gridx)+1 t2x = tan((x+@sens)/gridx)+@toffset t3x = t1x t1y = cotan(y/gridy)+1 t2y = t1y t3y = cotan((y+@sens)/gridy)+@toffset e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 2 ;circles and squares t1x = sin(x/gridx)+cos(y/gridy)+@toffset t2x = sin((x+@sens)/gridx)+cos(y/gridy)+@toffset t3x = t1x t1y = cos(y/gridy)+sin(x/gridx)+@toffset t2y = t1y t3y = cos((y+@sens)/gridy)+sin(x/gridx)+@toffset e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 3 ;triangles t1x = tan(x/gridx)+cotan(y/gridy)+@toffset t2x = tan((x+@sens)/gridx)+cotan(y/gridy)+@toffset t3x = t1x t1y = cotan(y/gridy)+tan(x/gridx)+@toffset t2y = t1y t3y = cotan((y+@sens)/gridy)+tan(x/gridx)+@toffset e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 4 ;X's and O's t1x = 1/sin(x/gridx)+@toffset t2x = 1/sin((x+@sens)/gridx)+@toffset t3x = t1x t1y = 1/cos(y/gridy)+@toffset t2y = t1y t3y = 1/cos((y+@sens)/gridy)+@toffset e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 5 ;Dimples t1x = 1/tan(x/gridx)+@toffset t2x = 1/tan((x+@sens)/gridx)+@toffset t3x = t1x t1y = 1/cotan(y/gridy)+@toffset t2y = t1y t3y = 1/cotan((y+@sens)/gridy)+@toffset e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 6 ;Arrows t1x = 1/tan(x/gridx)+@toffset t2x = 1/tan((x+@sens)/gridx)+@toffset t3x = t1x t1y = 1/sin(y/gridy)+@toffset t2y = t1y t3y = 1/sin((y+@sens)/gridy)+@toffset e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 7 ; basketweave t1x = 1/sin((x+@sens)/gridx)+1/cos(y/gridy)+@toffset t2x = 1/sin(x/gridx)+1/cos(y/gridy)+@toffset t3x = t1x t1y = 1/cos(y/gridy)+1/sin(x/gridx)+@toffset t2y = t1y t3y = 1/cos((y+@sens)/gridy)+1/sin(x/gridx)+@toffset e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 8 ; balls t1x = sin((x+@sens)/gridx)^2 + cos(y/gridy)^2+@toffset t2x = sin(x/gridx)^2 + cos(y/gridy)^2+@toffset t3x = t1x t1y = sin(y/gridy)^2 + cos(x/gridx)^2+@toffset t2y = t1y t3y = sin((y+@sens)/gridy)^2 + cos(x/gridx)^2+@toffset e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) elseif @texture == 9 ;net t1x = log(abs(sin(x/gridx)))+1 t2x = log(abs(sin((x+@sens)/gridx)))+@toffset t3x = t1x t1y = log(abs(cos(y/gridy)))+1 t2y = t1y t3y = log(abs(cos((y+@sens)/gridy)))+@toffset e1 =cabs(t1x+flip(t1y)) e2 =cabs(t2x+flip(t2y)) e3 =cabs(t3x+flip(t3y)) tx = e2 - e1 ty = e3 - e1 tz = -@sens/@theight td = 1/sqrt(sqr(tx)+sqr(ty)+sqr(tz)) tx = tx*td ty = ty*td t = tx + flip(ty) endif endif m_LastZ = t return real(t) endfunc default: title = "Lattice Textures" int param v_trapshapelatticetextures caption = "Version (Trap Shape Lattice Textures)" default = 102 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_trapshapelatticetextures < 102 endparam param texture caption = "Texture" default = 0 enum = "Lattice" "Quilt" "Circles & Squares" "Triangles" \ "X's & O's" "Dimples" "Arrows" "Basketweave" "Balls" \ "Net" endparam complex param grid caption = "Texture scale" default = (1,1) endparam complex param dr caption = "Randomizer" default = (0,0) endparam float param theight caption = "Texture Height" default = 1.0 endparam float param blend caption = "Texture Blend" default = 0.05 endparam float param toffset caption = "Texturizer Offset" default = 1.0 endparam float param sens caption = "Sensitivity" default = 1e-8 endparam bool param smooth caption = "Texture Smoothing" default = true hint = "Apply 3D smoothing to the texture" endparam } class REB_TrapShapeTobyGeometrixTexture(common.ulb:TrapShape) { ; This texture is derived from the code of Toby Marshall.
public: import "common.ulb" ; Constructor func REB_TrapShapeTobyGeometrixTexture(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; Call this for each iteration being trapped. float func Iterate(complex pz) TrapShape.Iterate(pz) float zrzr = 0 float zizi = 0 float rzrz = 0 float iziz = 0 float r0r0 = 0 float i0i0 = 0 float r1r1 = 0 float i1i1 = 0 float azaz = 0 float bzbz = 0 float czcz = 0 float dzdz = 0 int iii = 0 float avav = 1 float xbxb = 1 float frfr = 0 float fifi = 0 float zaza = 0 float zzzz = 0 complex ptr = 0 complex tz = ((pz-@trxia)*@trxib)^@trxic float x = real(tz) float y = imag(tz) if @trinit == 0 ptr = (@fntx11(@fntx10(tz))^@exad10) elseif @trinit == 1 ptr = (@fntx10(real(tz))^@exad10+@fntx11(imag(tz))^@exad11) elseif @trinit == 2 ptr = (@fntx10(real(tz))^@exad10-@fntx11(imag(tz))^@exad11) elseif @trinit == 3 ptr = (@fntx10(real(tz))^@exad10*@fntx11(imag(tz))^@exad11) elseif @trinit == 4 ptr = (@fntx10(imag(tz))^@exad10-@fntx11(real(tz))^@exad11) elseif @trinit == 5 ptr = (@fntx11(@fntx10(x))^@exad10) elseif @trinit == 6 ptr = (@fntx11(@fntx10(y))^@exad10) elseif @trinit == 7 ptr = (@fntx10(x)^@exad10+@fntx11(y)^@exad11) elseif @trinit == 8 ptr = (@fntx10(x)^@exad10-@fntx11(y)^@exad11) elseif @trinit == 9 ptr = (@fntx11(y)^@exad11-@fntx10(x)^@exad10) elseif @trinit == 10 ptr = (@fntx10(x)^@exad10*@fntx11(y)^@exad11) elseif @trinit == 11 ptr = (@fntx10(x)^@exad10/@fntx11(y)^@exad11) elseif @trinit == 12 ptr = (@fntx11(y)^@exad11/@fntx10(x)^@exad10) elseif @trinit == 13 ptr = (@fntx10(x)^@exad10^@fntx11(y)^@exad11) elseif @trinit == 14 ptr = (@fntx11(y)^@exad11^@fntx10(x)^@exad10) elseif @trinit == 15 ptr = (@fntx10(x)^@exad10+@fntx11(tz)^@exad11) elseif @trinit == 16 ptr = (@fntx10(x)^@exad10-@fntx11(tz)^@exad11) elseif @trinit == 17 ptr = (@fntx11(tz)^@exad11-@fntx10(x)^@exad10) elseif @trinit == 18 ptr = (@fntx10(x)^@exad10*@fntx11(tz)^@exad11) elseif @trinit == 19 ptr = (@fntx10(x)^@exad10/@fntx11(tz)^@exad11) elseif @trinit == 20 ptr = (@fntx11(tz)^@exad11/@fntx10(x)^@exad10) elseif @trinit == 21 ptr = (@fntx10(y)^@exad10+@fntx11(tz)^@exad11) elseif @trinit == 22 ptr = (@fntx10(y)^@exad10-@fntx11(tz)^@exad11) elseif @trinit == 23 ptr = (@fntx11(tz)^@exad11-@fntx10(y)^@exad10) elseif @trinit == 24 ptr = (@fntx10(y)^@exad10*@fntx11(tz)^@exad11) elseif @trinit == 25 ptr = (@fntx10(y)^@exad10/@fntx11(tz)^@exad11) elseif @trinit == 26 ptr = (@fntx11(tz)^@exad11/@fntx10(y)^@exad10) endif zrzr = real(@fnzr(ptr))*@scc zizi = imag(@fnzi(ptr))*@scc rzrz = floor(zrzr) iziz = floor(zizi) r0r0 = rzrz - 1 i0i0 = iziz - 1 r1r1 = rzrz + 1 i1i1 = iziz + 1 azaz = cabs(@fn1tx(r0r0) + @fn2tx(i0i0)) azaz = cabs(@fn3tx(azaz)) azaz = (azaz % @shad1 * 2) bzbz = cabs(@fn1tx(r1r1) + @fn2tx(i0i0)) bzbz = cabs(@fn3tx(bzbz)) bzbz = (bzbz % @shad2 * 2) czcz = cabs(@fn1tx(r1r1) + @fn2tx(i1i1)) czcz = cabs(@fn3tx(czcz)) czcz = (czcz % @shad3 * 2) dzdz = cabs(@fn1tx(r0r0) + @fn2tx(i1i1)) dzdz = cabs(@fn3tx(dzdz)) dzdz = (dzdz % @shad4 * 2) iii = 1 repeat avav = avav / (@trp1 * 2) xbxb = xbxb / (@trp2 * 2) frfr = rzrz + avav fifi = iziz + avav zaza = (azaz + bzbz + czcz + dzdz) / (@trp3 * 4) zzzz = zzzz * xbxb + zaza if (zrzr > frfr) if (zizi > fifi) rzrz = frfr iziz = fifi azaz = zzzz else rzrz = frfr dzdz = zzzz endif else if (zizi > fifi) iziz = fifi bzbz = zzzz else czcz = zzzz endif endif iii = iii + 1 until iii >= @freq float texture_tr = (zaza-trunc(zaza*2)^@exp) if @geo_limit != 0 texture_tr = ((zaza-trunc(zaza)^@exp*2)% @geo_limit) endif if @geo_sgn == true texture_tr = abs(texture_tr) endif return texture_tr/5 endfunc default: title = "Toby's Geometrix Texture" int param v_trapshapetobysgeometrixtexture caption = "Version (Trap Shape Toby's Geometrix Texture)" default = 101 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_trapshapetobysgeometrixtexture < 101 endparam param trinit caption = "Geometrix Init" enum = "z""real+imag(z)""real-imag(z)""real*imag(z)""imag-real(z)" \ "x""y""x+y""x-y""y-x""x/y""x*y""y/x""x^y""y^x""x+z""x-z""z-x""x*z" \ "x/z""z/x""y+z""y-z""z-y""y*z""y/z""z/y" hint = "Determines which variable(s) initialize(s) the texture" default = 0 endparam func fntx10 caption = "Init Function 1" default = ident() hint = "Modifies the 1st variable defined in \ 'Geometrix Initialization'" endfunc func fntx11 caption = "Init Function 2" default = ident() hint = "Modifies the 2nd variable defined in \ 'Geometrix Initialization'" endfunc complex param trxia caption = "Pattern 1" default = (0.0,0.0) visible = (@trinit < 5 || @trinit > 14 && @trinit < 21) endparam complex param trxib caption = "Pattern 2" default = (1.0,0.0) visible = (@trinit < 5 || @trinit > 14 && @trinit < 21) endparam complex param trxic caption = "Pattern 3" default = (1.0,0.0) visible = (@trinit < 5 || @trinit > 14 && @trinit < 21) endparam complex param exad10 caption = "Frequency 1" default = (1.0,0.0) hint = "Changes the pattern frequency by acting on the 1st (or only) \ variable defined in 'Geometrix Initialization'" endparam complex param exad11 caption = "Frequency 2" default = (1.0,0.0) hint = "Changes the pattern frequency by acting on the 2nd variable \ (when present) defined in 'Geometrix Initialization'" visible = !(@trinit == 0 ||@trinit == 5 || @trinit == 6 ||\ @trinit == 21) endparam float param exp caption = "Contrast" default = 0.6 hint = "Higher values intensify the contrast between texture sections. If \ you find burned-out areas of texture try lowering this value" endparam float param scc caption = "Density" default = 1.0 hint = "Higher values create finer detail in the texture" endparam float param trp1 caption = "Scale" default = 1 hint = "Densest texture is at '1'. Try other values and increase the \ 'Density' value to achieve different texture patterns" endparam float param freq caption = "Definition 1" default = 10 hint = "Works interactively with other 'Definition' params. Higher values \ yield more texture definition and/or complexity" endparam float param trp2 caption = "Definition 2" default = .7 hint = "Works interactively with other 'Definition' params. Lower values \ yield more texture definition" endparam float param trp3 caption = "Definition 3" default = .7 hint = "Works interactively with other 'Definition' params. Higher values \ yield more texture definition" endparam float param shad1 caption = "Shading 1" default = 1 hint = "Affects the shading of certain areas of texture" endparam float param shad2 caption = "Shading 2" default = 1 hint = "Affects the shading of certain areas of texture" endparam float param shad3 caption = "Shading 3" default = 1 hint = "Affects the shading of certain areas of texture" endparam float param shad4 caption = "Shading 4" default = 1 hint = "Affects the shading of certain areas of texture" endparam func fnzr caption = "Z function 1" default = ident() endfunc func fnzi caption = "Z function 2" default = ident() endfunc func fn1tx caption = "Real function" default = sqrt() endfunc func fn2tx caption = "Imag function" default = ident() endfunc func fn3tx caption = "Overall function" default = asin() endfunc float param geo_limit caption = "Geometrix Limit" default = 0.0 hint = "Low values limit texture contrast. Zero is 'off'" endparam bool param geo_sgn caption = "Soften Texture" default = false endparam } ;---------------------------------- ; ; Image TrapMode classes ; ;------------------------------------- class ImageTrapMode(Generic) { ; This is a generic image trap mode formula. ;

; It takes a sequence of complex point pairs (untransformed and transformed), ; including image point pairs, and distances and produces a final result. It ; similar to generic trap mode in common.ulb. public: import "common.ulb" ; constructor func ImageTrapMode(Generic pparent) Generic.Generic(pparent) endfunc ; call this at the beginning of each sequence func Init(complex pz) m_Iterations = 0 m_Solid = false m_alph = 0 m_zold = 0 int j = 0 while (j < 4) m_UntransformedPoints[j] = (0,0) m_TransformedPoints[j] = (0,0) m_IterationPoints[j] = 0 m_SIterationPoints[j] = 0 m_Distances[j] = 0.0 m_ImagePoints[j] = rgba(0,0,0,0) m_Textures[j] = 0.0 j = j + 1 endwhile endfunc ; call this for each point func Iterate(complex pz, complex pzt, float pdistance, float ptexture, color pcolor) m_Iterations = m_Iterations + 1 endfunc ; call this for each point that is ignored func IterateSilent() m_Iterations = m_Iterations + 1 endfunc ; call this to compute final results func Result() endfunc ; call this to determine if the last sequence produced a solid point bool func IsSolid() return m_Solid endfunc ; get a final untransformed point complex func GetUntransformedPoint(int pindex) return m_UntransformedPoints[pindex] endfunc ; get a final transformed point complex func GetTransformedPoint(int pindex) return m_TransformedPoints[pindex] endfunc ; get a final distance float func GetDistance(int pindex) return m_Distances[pindex] endfunc ; get a final iteration float func GetIteration(int pindex) return m_IterationPoints[pindex] endfunc ; get a final smooth iteration float func GetSIteration(int pindex) return m_SIterationPoints[pindex] endfunc ; get a final color color func GetColor(int pindex) return m_ImagePoints[pindex] endfunc ; get a final texture float func GetTexture(int pindex) return m_Textures[pindex] endfunc ; get threshold value float func GetThreshold() return 1.0 endfunc func SetThreshold(float pthreshold) endfunc ; get whether threshold is even used bool func UsesThreshold() return false endfunc float func GetAThreshold() return 1.0 endfunc func SetAThreshold(float pathreshold) endfunc ; get whether alpha threshold is even used bool func UsesAThreshold() return false endfunc protected: int m_Iterations; count the number of iterations bool m_Solid; flag indicating whether sequence was solid or not complex m_UntransformedPoints[4] complex m_TransformedPoints[4] float m_IterationPoints[4] float m_SIterationPoints[4] float m_Distances[4] color m_ImagePoints[4] float m_Textures[4] float m_alph complex m_zold default: int param v_imagetrapmode caption = "Version (Image Trap Mode)" default = 101 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_imagetrapmode < 101 endparam } class ImageTrapModeWithThreshold(ImageTrapMode) { ; Variant of ImageTrapMode that is thresholdable
;

; Manages both trap thresholds and alpha image thresholds. public: import "common.ulb" ; constructor func ImageTrapModeWithThreshold(Generic pparent) ImageTrapMode.ImageTrapMode(pparent) m_Threshold = 1.0 m_aThreshold = 1.0 endfunc ; provides alpha fading at the edges of an image func EdgeFade(float pdistance) float m_alph = 0 if @edgefade if alpha(m_ImagePoints[0]) !=0 m_alph = abs(m_Threshold-pdistance)/m_Threshold else m_alph = alpha(m_ImagePoints[0]) endif m_ImagePoints[0] = rgba(red(m_ImagePoints[0]),green(m_ImagePoints[0]), \ blue(m_ImagePoints[0]),m_alph^(1/@fadepwr)) endif endfunc ; get the trap threshold float func GetThreshold() return m_Threshold endfunc ; set the trap threshold func SetThreshold(float pthreshold) m_Threshold = pthreshold endfunc ; determines whether a threshold is being used bool func UsesThreshold() return true endfunc ; get the alpha threshold float func GetAThreshold() return m_AThreshold endfunc ; set the alpha threshold func SetAThreshold(float pathreshold) m_AThreshold = pathreshold endfunc ; determines whether an alpha threshold is being used. bool func UsesAThreshold() return true endfunc protected: float m_Threshold float m_AThreshold float m_a default: int param v_imagetrapmodethreshold caption = "Version (Image Trap Mode with Threshold)" default = 101 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_imagetrapmodethreshold < 101 endparam bool param edgefade caption = "Image edge fade" default = false endparam float param fadepwr caption = "Fade power" default = 1.0 visible = @edgefade endparam } class ImageTrapModeClosest(ImageTrapModeWithThreshold) { ; Uses the closest trapped point public: import "common.ulb" ; constructor func ImageTrapModeClosest(Generic pparent) ImageTrapModeWithThreshold.IMageTrapModeWithThreshold(pparent) endfunc ; call this at the beginning of each sequence func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) m_Solid = true int j = 0 while (j < 4) m_Distances[j] = 1e20 j = j + 1 endwhile endfunc ; call this for each point func Iterate(complex pz, complex pzt, float pdistance, float ptexture,color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif m_a = alpha(pcolor) float sc = 1 if @scby == "Distance" sc = pdistance*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif if (pdistance < m_Distances[0]) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) if pdistance < m_Threshold && m_a >= m_AThreshold m_solid = false endif m_Distances[0] = pdistance m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_SIterationPoints[0] = m_SIterationPoints[0] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_Textures[0] = ptexture m_ImagePoints[0] = pcolor edgefade(pdistance) m_zold = iterp endif endfunc func Result() m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc default: title = "Closest" int param v_closest caption = "Version (Closest)" 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_closest < 100 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked \ it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "'Edge only' traps the edges of the shape." endheading bool param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapModeSmallest(ImageTrapModeWithThreshold) { ; Uses the smallest trapped point public: import "common.ulb" ; constructor func ImageTrapModeSmallest(Generic pparent) ImageTrapModeWithThreshold.IMageTrapModeWithThreshold(pparent) endfunc ; call this at the beginning of each sequence func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) m_Solid = true minval = 1e20 endfunc ; call this for each point func Iterate(complex pz, complex pzt, float pdistance, float ptexture,color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif m_a = alpha(pcolor) dist = cabs(pz-pzt) float sc = 1 if @scby == "Distance" sc = dist*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif if (dist < minval) && (!@edge || \ (@edge && (m_threshold-dist) < @width/sc)) if dist < m_Threshold && m_a >= m_AThreshold m_solid = false endif minval = dist m_Distances[0] = (abs(|pz|-|pzt|)) m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_SIterationPoints[0] = m_SIterationPoints[0] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_Textures[0] = ptexture m_ImagePoints[0] = pcolor edgefade(dist) m_zold = iterp endif endfunc func Result() m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc protected: float dist float minval default: title = "Smallest" int param v_smallest caption = "Version (Closest)" default = 101 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_smallest < 101 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "Implemented to correspond to the 'Smallest' trap mode in Simple Traps \ Enhanced, Polar Traps Enhanced and Attractor Traps." endheading heading text = "'Edge only' traps the edges of the shape." endheading param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapModeLargest(ImageTrapModeWithThreshold) { ; Uses the smallest trapped point public: import "common.ulb" ; constructor func ImageTrapModeLargest(Generic pparent) ImageTrapModeWithThreshold.IMageTrapModeWithThreshold(pparent) endfunc ; call this at the beginning of each sequence func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) m_Solid = true maxval = 0 endfunc ; call this for each point func Iterate(complex pz, complex pzt, float pdistance, float ptexture,color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif m_a = alpha(pcolor) dist = cabs(pz-pzt) float sc = 1 if @scby == "Distance" sc = dist*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif if (dist > maxval) && (!@edge || \ (@edge && (m_threshold-dist) < @width/sc)) if dist < m_Threshold && m_a >= m_AThreshold m_solid = false maxval = dist m_Distances[0] = (abs(|pz|-|pzt|)) m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_SIterationPoints[0] = m_SIterationPoints[0] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_Textures[0] = ptexture m_ImagePoints[0] = pcolor edgefade(dist) m_zold = iterp endif endif endfunc func Result() m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc protected: float dist float maxval default: title = "Largest" int param v_Largest caption = "Version (Largest)" 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_Largest < 100 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "'Edge only' traps the edges of the shape." endheading param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapModeFirst(ImageTrapModeWithThreshold) { ; This trap mode uses the first trapped point that is within the threshold. public: import "common.ulb" ; Constructor func ImageTrapModeFirst(Generic pparent) ImageTrapModeWithThreshold.IMageTrapModeWithThreshold(pparent) endfunc ; call this at the beginning of each sequence func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) m_Solid = true endfunc ; call this for each point func Iterate(complex pz, complex pzt, float pdistance, float ptexture, color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) m_a = alpha(pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif float sc = 1 if @scby == "Distance" sc = pdistance*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif if pdistance < m_Threshold && m_a >= m_AThreshold && m_Solid && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) m_points_in = m_points_in + 1 m_Distances[0] = pdistance m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_SIterationPoints[0] = m_SIterationPoints[0] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_Textures[0] = ptexture m_ImagePoints[0] = pcolor m_Solid = false edgefade(pdistance) m_zold = iterp endif endfunc func Result() m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc default: title = "First" int param v_first caption = "Version (First)" default = 101 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_first < 101 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "'Edge only' traps the edges of the shape." endheading param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapModeLast(ImageTrapModeWithThreshold) { ; This trap mode uses the last trapped point that is within the threshold. public: import "common.ulb" ; Constructor func ImageTrapModeLast(Generic pparent) ImageTrapModeWithThreshold.IMageTrapModeWithThreshold(pparent) endfunc ; call this at the beginning of each sequence func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) m_Solid = true endfunc ; call this for each point func Iterate(complex pz, complex pzt, float pdistance, float ptexture, color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif float sc = 1 if @scby == "Distance" sc = pdistance*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif m_a = alpha(pcolor) if (pdistance < m_Threshold && m_a >= m_AThreshold) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) m_Distances[0] = pdistance m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_SIterationPoints[0] = m_SIterationPoints[0] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_Textures[0] = ptexture m_ImagePoints[0] = pcolor m_Solid = false edgefade(pdistance) m_zold = iterp endif endfunc func Result() m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc default: title = "Last" int param v_last caption = "Version (Last)" default = 102 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_last < 102 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "'Edge only' traps the edges of the shape." endheading param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapModeFarthest(ImageTrapModeWithThreshold) { ; This trap mode uses the farthest trapped point that is within the threshold. public: import "common.ulb" func ImageTrapModeFarthest(Generic pparent) ImageTrapModeWithThreshold.IMageTrapModeWithThreshold(pparent) endfunc func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) m_Solid = true endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture, color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif float sc = 1 if @scby == "Distance" sc = pdistance*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif m_a = alpha(pcolor) if (pdistance < m_Threshold && pdistance >= m_Distances[0] && m_a >= m_AThreshold) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) m_Distances[0] = pdistance m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_SIterationPoints[0] = m_SIterationPoints[0] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_Textures[0] = ptexture m_ImagePoints[0] = pcolor m_Solid = false edgefade(pdistance) m_zold = iterp endif endfunc func Result() m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc default: title = "Farthest" int param v_farthest caption = "Version (Farthest)" 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_farthest < 100 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "'Edge only' traps the edges of the shape." endheading param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapModeSum(ImageTrapModeWithThreshold) { ; This trap mode sums the trapped points that are within the threshold. public: import "common.ulb" ; constructor func ImageTrapModeSum(Generic pparent) ImageTrapModeWithThreshold.IMageTrapModeWithThreshold(pparent) endfunc ; Initialize the class func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) m_Solid = true endfunc ; call for each iterated point func Iterate(complex pz, complex pzt, float pdistance, float ptexture,color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) m_a = alpha(pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif float sc = 1 if @scby == "Distance" sc = pdistance*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif if (pdistance < m_Threshold && m_a >= m_AThreshold) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) m_Distances[0] = m_Distances[0] + pdistance m_UntransformedPoints[0] = m_UntransformedPoints[0] + pz m_TransformedPoints[0] = m_TransformedPoints[0] + pzt m_IterationPoints[0] = m_IterationPoints[0] + 1 m_SIterationPoints[0] = m_SIterationPoints[0]+1 + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_Textures[0] = m_Textures[0] + ptexture m_ImagePoints[0] = pcolor m_Solid = false edgefade(pdistance) m_zold = iterp endif endfunc func Result() m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc default: title = "Sum" int param v_sum caption = "Version (Sum)" default = 101 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_sum < 101 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "'Edge only' traps the edges of the shape." endheading param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapModeHarmonicSum(ImageTrapModeWithThreshold) { ; This trap mode sums the trapped points that are within the threshold. public: import "common.ulb" ; constructor func ImageTrapModeHarmonicSum(Generic pparent) ImageTrapModeWithThreshold.IMageTrapModeWithThreshold(pparent) endfunc ; Initialize the class func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) iter = 0 m_Solid = true endfunc ; call for each iterated point func Iterate(complex pz, complex pzt, float pdistance, float ptexture,color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) m_a = alpha(pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif float sc = 1 if @scby == "Distance" sc = pdistance*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif if (pdistance < m_Threshold && m_a >= m_AThreshold) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) m_Distances[0] = m_Distances[0] + 1/pdistance m_UntransformedPoints[0] = m_UntransformedPoints[0] + 1/pz m_TransformedPoints[0] = m_TransformedPoints[0] + 1/pzt m_IterationPoints[0] = m_IterationPoints[0] + 1/m_iterations m_SIterationPoints[0] = m_SIterationPoints[0] + 1/exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_Textures[0] = m_Textures[0] + 1/ptexture m_ImagePoints[0] = pcolor m_Solid = false edgefade(pdistance) m_zold = iterp iter = iter + 1 endif endfunc func Result() m_Distances[0] = 1/m_distances[0] m_UntransformedPoints[0] = 1/m_UntransformedPoints[0] m_TransformedPoints[0] = 1/m_TransformedPoints[0] m_IterationPoints[0] = 1/m_IterationPoints[0] m_Textures[0] = 1/m_Textures[0] m_SIterationPoints[0] = 10/m_SIterationPoints[0] endfunc protected: int iter default: title = "Harmonic Sum" int param v_HarmonicSum caption = "Version (Harmonic Sum)" default = 101 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_HarmonicSum < 101 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "'Edge only' traps the edges of the shape." endheading param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapModeHarmonicMean(ImageTrapModeWithThreshold) { ; This trap mode sums the trapped points that are within the threshold. public: import "common.ulb" ; constructor func ImageTrapModeHarmonicMean(Generic pparent) ImageTrapModeWithThreshold.IMageTrapModeWithThreshold(pparent) endfunc ; Initialize the class func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) iter = 0 m_Solid = true endfunc ; call for each iterated point func Iterate(complex pz, complex pzt, float pdistance, float ptexture,color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) m_a = alpha(pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif float sc = 1 if @scby == "Distance" sc = pdistance*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif if (pdistance < m_Threshold && m_a >= m_AThreshold) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) m_Distances[0] = m_Distances[0] + 1/pdistance m_UntransformedPoints[0] = m_UntransformedPoints[0] + 1/pz m_TransformedPoints[0] = m_TransformedPoints[0] + 1/pzt m_IterationPoints[0] = m_IterationPoints[0] + 1/m_iterations m_SIterationPoints[0] = m_SIterationPoints[0] + 1/exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_Textures[0] = m_Textures[0] + 1/ptexture m_ImagePoints[0] = pcolor m_Solid = false edgefade(pdistance) m_zold = iterp iter = iter + 1 endif endfunc func Result() m_Distances[0] = iter/m_distances[0] m_UntransformedPoints[0] = iter/m_UntransformedPoints[0] m_TransformedPoints[0] = iter/m_TransformedPoints[0] m_IterationPoints[0] = iter/m_IterationPoints[0] m_Textures[0] = iter/m_Textures[0] m_SIterationPoints[0] = iter*10/m_SIterationPoints[0] endfunc protected: int iter default: title = "Harmonic Mean" int param v_HarmonicMean caption = "Version (Harmonic Mean)" default = 101 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_HarmonicMean < 101 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "'Edge only' traps the edges of the shape." endheading param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapModeAverage(ImageTrapModeSum) { ; This trap mode averages the trapped points that are within the threshold. public: import "common.ulb" ; constructor func ImageTrapModeAverage(Generic pparent) ImageTrapModeSum.ImageTrapModeSum(pparent) endfunc ; call in the final section of the coloring formula/class func Result() float ii = 1.0 / m_IterationPoints[0] m_Distances[0] = m_Distances[0] * ii m_UntransformedPoints[0] = m_UntransformedPoints[0] * ii m_SIterationPoints[0] = m_SIterationPoints[0]*ii*10 m_Textures[0] = m_Textures[0] * ii m_TransformedPoints[0] = m_TransformedPoints[0] * ii endfunc default: title = "Average" int param v_average caption = "Version (Average)" 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_average < 100 endparam } class ImageTrapModeAlternatingAverage(ImageTrapModeWithThreshold) { ; trap mode average variant based upon a class of Damien Jones public: import "common.ulb" ; constructor func ImageTrapModeAlternatingAverage(Generic pparent) ImageTrapModeWithThreshold.ImageTrapModeWithThreshold(pparent) endfunc ; initialize the object func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) m_Solid = true endfunc ; call for each iterated point func Iterate(complex pz, complex pzt, float pdistance, float ptexture, color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif float sc = 1 if @scby == "Distance" sc = pdistance*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif m_a = alpha(pcolor) if (pdistance < m_Threshold && m_a >= m_AThreshold) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) m_Distances[0] = m_Threshold - abs(m_Distances[0] - pdistance) m_UntransformedPoints[0] = pz - m_UntransformedPoints[0] m_Textures[0] = m_Threshold - abs(m_Textures[0] - ptexture) m_TransformedPoints[0] = pzt - m_TransformedPoints[0] m_IterationPoints[0] = abs(m_Iterations - m_IterationPoints[0]) m_SIterationPoints[0] = abs(m_Iterations - m_IterationPoints[0]) + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_Solid = false m_ImagePoints[0] = pcolor edgefade(pdistance) m_zold = iterp endif endfunc func Result() m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc default: title = "Alternating Average" int param v_alternatingaverage caption = "Version (Alternating Average)" default = 101 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_alternatingaverage < 101 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "'Edge only' traps the edges of the shape." endheading param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapModeSignAverage(ImageTrapMode) { ; trap mode average variant based upon a class of Damien Jones public: import "common.ulb" ; constructor func ImageTrapModeSignAverage(Generic pparent) ImageTrapMode.ImageTrapMode(pparent) endfunc ; initialize the object func Init(complex pz) ImageTrapMode.Init(pz) m_Solid = true m_PreviousDistance = 0 endfunc ; call for each iterated point func Iterate(complex pz, complex pzt, float pdistance, float ptexture, color pcolor) ImageTrapMode.Iterate(pz, pzt, pdistance, ptexture, pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif if pdistance < m_PreviousDistance m_Distances[0] = m_Distances[0] + 1 m_Textures[0] = m_Textures[0] + ptexture m_UntransformedPoints[0] = m_UntransformedPoints[0] + pz m_TransformedPoints[0] = m_TransformedPoints[0] + pzt m_IterationPoints[0] = m_IterationPoints[0] + 1 m_SIterationPoints[0] = m_SIterationPoints[0] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_Solid = false m_ImagePoints[0] = pcolor m_zold = iterp else m_IterationPoints[0] = m_IterationPoints[0] - 1 endif m_PreviousDistance = pdistance endfunc func Result() float ii = 1.0 / m_Iterations m_Distances[0] = m_Distances[0] * ii m_Textures[0] = m_Textures[0] * ii m_UntransformedPoints[0] = m_UntransformedPoints[0] * ii m_TransformedPoints[0] = m_TransformedPoints[0] * ii m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc protected: float m_PreviousDistance default: title = "Sign Average" int param v_trapmodesignaverage caption = "Version (TrapMode Sign Average)" default = 101 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_trapmodesignaverage < 101 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam } class ImageTrapModeProduct(ImageTrapModeWithThreshold) { ; trap mode variant based upon a class of Damien Jones public: import "common.ulb" ; constructor func ImageTrapModeProduct(Generic pparent) ImageTrapModeWithThreshold.ImageTrapModeWithThreshold(pparent) endfunc ; initialize the object func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) m_Solid = true int j = 0 while (j < 4) m_Distances[j] = 1.0 m_Textures[j] = 1.0 m_UntransformedPoints[j] = 1 m_TransformedPoints[j] = 1 m_IterationPoints[j] = 1 j = j + 1 endwhile iter = 0 endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture, color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance, ptexture, pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif float sc = 1 if @scby == "Distance" sc = pdistance*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif m_a = alpha(pcolor) if (pdistance < m_Threshold && m_a >= m_AThreshold) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) m_Distances[0] = m_Distances[0] * pdistance m_Textures[0] = m_Textures[0] * ptexture m_UntransformedPoints[0] = m_UntransformedPoints[0] * pz m_TransformedPoints[0] = m_TransformedPoints[0] * pzt m_IterationPoints[0] = m_IterationPoints[0] * m_Iterations m_SIterationPoints[0] = m_SIterationPoints[0]*iter + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_Solid = false m_ImagePoints[0] = pcolor edgefade(pdistance) m_zold = iterp iter = iter + 1 endif endfunc func Result() m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc protected: int iter default: title = "Product" int param v_trapmodeproduct caption = "Version (TrapMode Product)" default = 101 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_trapmodeproduct < 101 endparam heading text = "'Edge only' traps the edges of the shape." endheading heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapModeGeometricMean(ImageTrapModeProduct) { public: import "common.ulb" ; constructor func ImageTrapModeGeometricMean(Generic pparent) ImageTrapModeProduct.ImageTrapModeProduct(pparent) endfunc func Result() ImagetrapModeProduct.Result() m_Distances[0] = m_Distances[0]^(1/ iter) m_IterationPoints[0] = m_IterationPoints[0]^(1/ iter) m_SIterationPoints[0] = m_SIterationPoints[0]^(1/ iter) m_Textures[0] = m_Textures[0]^(1/ iter) m_UntransformedPoints[0] = m_UntransformedPoints[0]^(1/ iter) m_TransformedPoints[0] = m_TransformedPoints[0]^(1/ iter) endfunc default: title = "Geometric Mean" int param v_geometricmean caption = "Version (Geometric Mean)" 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_geometricmean < 100 endparam } class ImageTrapModeChangeAverage(ImageTrapMode) { ; trap mode average variant based upon a class of Damien Jones public: import "common.ulb" func DImageTrapModeChangeAverage(Generic pparent) ImageTrapMode.ImageTrapMode(pparent) endfunc func Init(complex pz) ImageTrapMode.Init(pz) m_Solid = true m_PreviousDistance = 0 m_PreviousTexture = 0 endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture, color pcolor) ImageTrapMode.Iterate(pz, pzt, pdistance, ptexture, pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif if pdistance < m_PreviousDistance m_Distances[0] = m_Distances[0] + m_PreviousDistance-pdistance m_Textures[0] = m_Textures[0] + m_PreviousTexture-ptexture m_UntransformedPoints[0] = m_UntransformedPoints[0] + pz m_TransformedPoints[0] = m_TransformedPoints[0] + pzt m_IterationPoints[0] = m_IterationPoints[0] + 1 m_SIterationPoints[0] = m_SIterationPoints[0]+1 + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_Solid = false m_ImagePoints[0] = pcolor m_zold = iterp endif m_PreviousDistance = pdistance m_previousTexture = ptexture endfunc func Result() m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc protected: float m_PreviousDistance float m_PreviousTexture default: title = "Change Average" int param v_trapmodechangeaverage caption = "Version (TrapMode Change Average)" default = 101 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_trapmodechangeaverage < 101 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam } class ImageTrapModeAlternatingAverage2(ImageTrapModeWithThreshold) { ; trap mode average variant based upon a class of Damien Jones public: import "common.ulb" ; constructor func ImageTrapModeAlternatingAverage2(Generic pparent) ImageTrapModeWithThreshold.ImageTrapModeWithThreshold(pparent) endfunc ; initialize the object func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) m_Solid = true endfunc ; call for each iterated point func Iterate(complex pz, complex pzt, float pdistance, float ptexture, color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif float sc = 1 if @scby == "Distance" sc = pdistance*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif m_a = alpha(pcolor) if (pdistance < m_Threshold && m_a >= m_AThreshold) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) m_Distances[0] = abs(pdistance - m_Threshold + m_Distances[0]) m_Textures[0] = abs(ptexture - m_Threshold + m_Textures[0]) m_UntransformedPoints[0] = pz - m_UntransformedPoints[0] m_TransformedPoints[0] = pzt - m_TransformedPoints[0] m_IterationPoints[0] = abs(m_Iterations - m_IterationPoints[0]) m_SIterationPoints[0] = abs(m_Iterations - m_IterationPoints[0]) + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_Solid = false m_ImagePoints[0] = pcolor edgefade(pdistance) m_zold = iterp endif endfunc func Result() m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc default: title = "Alternating Average 2" int param v_alternatingaverage2 caption = "Version (Alternating Average 2)" default = 101 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_alternatingaverage2 < 101 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "'Edge only' traps the edges of the shape." endheading param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapModeExponentialAverage(ImageTrapModeWithThreshold) { ; trap mode average variant based upon a class of Damien Jones public: import "common.ulb" ; constructor func ImageTrapModeExponentialAverage(Generic pparent) ImageTrapModeWithThreshold.IMageTrapModeWithThreshold(pparent) endfunc ; initialize the object func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) m_Solid = true endfunc ; call for each iterated point func Iterate(complex pz, complex pzt, float pdistance, float ptexture, color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif float sc = 1 if @scby == "Distance" sc = pdistance*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif m_a = alpha(pcolor) if (pdistance < m_Threshold && m_a >= m_AThreshold) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) float expd = exp(-pdistance) m_Distances[0] = m_Distances[0] + expd m_UntransformedPoints[0] = pz + (m_UntransformedPoints[0]-pz) * expd m_Textures[0] = m_Textures[0] + exp(abs(ptexture)) m_TransformedPoints[0] = pzt + (m_TransformedPoints[0]-pzt) * expd m_IterationPoints[0] = m_Iterations + (m_IterationPoints[0]-m_Iterations) * expd m_SIterationPoints[0] = m_SIterationPoints[0] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_Solid = false m_ImagePoints[0] = pcolor edgefade(pdistance) m_zold = iterp endif endfunc func Result() m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc default: title = "Exponential Average" int param v_exponentialaverage caption = "Version (Exponential Average)" default = 101 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_exponentialaverage < 101 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "'Edge only' traps the edges of the shape." endheading param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapModeInvertedSum(ImageTrapModeWithThreshold) { ; trap mode variant based upon a class of Damien Jones public: import "common.ulb" ; constructor func ImageTrapModeInvertedSum(Generic pparent) ImageTrapModeWithThreshold.IMageTrapModeWithThreshold(pparent) endfunc ; initialize the object func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) m_Solid = true m_TrappedIterations = 0 endfunc ; call for each iterated point func Iterate(complex pz, complex pzt, float pdistance, float ptexture, color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif float sc = 1 if @scby == "Distance" sc = pdistance*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif m_a = alpha(pcolor) if (pdistance < m_Threshold && m_a >= m_AThreshold) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) float d2 = pdistance / m_Threshold m_Distances[0] = m_Distances[0] + pdistance m_Textures[0] = ptexture + (m_Textures[0]-ptexture) * d2 m_UntransformedPoints[0] = pz + (m_UntransformedPoints[0]-pz) * d2 m_TransformedPoints[0] = pzt + (m_TransformedPoints[0]-pzt) * d2 m_IterationPoints[0] = m_Iterations + (m_IterationPoints[0]-m_Iterations) * d2 m_SIterationPoints[0] = m_SIterationPoints[0] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_TrappedIterations = m_TrappedIterations + 1 m_Solid = false m_ImagePoints[0] = pcolor edgefade(pdistance) m_zold = iterp endif endfunc func Result() m_Distances[0] = m_Threshold * m_TrappedIterations - m_Distances[0] m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc protected: int m_TrappedIterations default: title = "Inverted Sum" int param v_invertedsum caption = "Version (Inverted Sum)" 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_invertedsum < 100 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "'Edge only' traps the edges of the shape." endheading param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapModeSecondClosest(ImageTrapModeWithThreshold) { ; traps the second closest point public: import "common.ulb" ; constructor func ImageTrapModeSecondClosest(Generic pparent) ImageTrapModeWithThreshold.IMageTrapModeWithThreshold(pparent) endfunc ; initialize the object func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) m_Solid = true int j = 0 while (j < 4) m_Distances[j] = 1e20 j = j + 1 endwhile endfunc ; call for each iterated point func Iterate(complex pz, complex pzt, float pdistance, float ptexture, color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif float sc = 1 if @scby == "Distance" sc = pdistance*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif m_a = alpha(pcolor) if pdistance < m_Threshold && m_a >= m_AThreshold && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) m_solid = false endif if (pdistance < m_Distances[0]) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width)) m_Distances[1] = m_Distances[0] m_Textures[1] = m_Textures[0] m_UntransformedPoints[1] = m_UntransformedPoints[0] m_TransformedPoints[1] = m_TransformedPoints[0] m_IterationPoints[1] = m_IterationPoints[0] m_SIterationPoints[1] = m_SIterationPoints[0] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_ImagePoints[1] = m_ImagePoints[0] m_Distances[0] = pdistance m_Textures[0] = ptexture m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_SIterationPoints[0] = m_SIterationPoints[0] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_ImagePoints[0] = pcolor edgefade(pdistance) m_zold = iterp elseif (pdistance < m_Distances[1]) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) m_Distances[1] = pdistance m_UntransformedPoints[1] = pz m_Textures[1] = ptexture m_TransformedPoints[1] = pzt m_IterationPoints[1] = m_Iterations m_SIterationPoints[1] = m_SIterationPoints[1] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_ImagePoints[1] = pcolor edgefade(pdistance) m_zold = iterp endif endfunc ; call in the final section of the coloring formula/class func Result() m_Distances[0] = abs(m_Distances[0] - m_Distances[1]) m_UntransformedPoints[0] = m_UntransformedPoints[0] - m_UntransformedPoints[1] m_Textures[0] = m_Textures[0] - m_Textures[1] m_TransformedPoints[0] = m_TransformedPoints[0] - m_TransformedPoints[1] m_IterationPoints[0] = abs(m_IterationPoints[0] - m_IterationPoints[1]) m_SIterationPoints[0] = (m_SIterationPoints[0] + m_SIterationPoints[1])/2 m_SIterationPoints[0] = m_SIterationPoints[0]*10 m_ImagePoints[0] = (m_ImagePoints[1]+m_ImagePoints[0])/2 endfunc default: title = "Second Closest" int param v_secondclosest caption = "Version (Second Closest)" default = 101 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_secondclosest < 101 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "'Edge only' traps the edges of the shape." endheading param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapModeSecondFarthest(ImageTrapModeWithThreshold) { ; This trap mode uses the second farthest trapped point that is within the threshold. public: import "common.ulb" ; constructor func ImageTrapModeSecondFarthest(Generic pparent) ImageTrapModeWithThreshold.IMageTrapModeWithThreshold(pparent) endfunc ; initialize the object func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) m_Solid = true endfunc ; call for each iterated point func Iterate(complex pz, complex pzt, float pdistance, float ptexture, color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif float sc = 1 if @scby == "Distance" sc = pdistance*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif m_a = alpha(pcolor) if (pdistance >= m_Distances[0] && pdistance < m_Threshold && m_a >= m_AThreshold) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) m_Distances[1] = m_Distances[0] m_UntransformedPoints[1] = m_UntransformedPoints[0] m_Textures[1] = m_Textures[0] m_TransformedPoints[1] = m_TransformedPoints[0] m_IterationPoints[1] = m_IterationPoints[0] m_SIterationPoints[1] = m_SIterationPoints[0] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_ImagePoints[1] = m_imagePoints[0] m_Distances[0] = pdistance m_Textures[0] = ptexture m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_SIterationPoints[0] = m_SIterationPoints[0] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_ImagePoints[0] = pcolor m_Solid = false elseif (pdistance >= m_Distances[1] && pdistance < m_Threshold && m_a > m_AThreshold) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) m_Distances[1] = pdistance m_UntransformedPoints[1] = pz m_TransformedPoints[1] = pzt m_IterationPoints[1] = m_Iterations m_SIterationPoints[1] = m_SIterationPoints[1] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_ImagePoints[1] = pcolor m_Solid = false endif edgefade(pdistance) m_zold = iterp endfunc func Result() m_Distances[0] = abs(m_Distances[0] - m_Distances[1]) m_UntransformedPoints[0] = m_UntransformedPoints[0] - m_UntransformedPoints[1] m_Textures[0] = m_Textures[0] - m_Textures[1] m_TransformedPoints[0] = m_TransformedPoints[0] - m_TransformedPoints[1] m_IterationPoints[0] = abs(m_IterationPoints[0] - m_IterationPoints[1]) m_ImagePoints[0] = (m_imagePoints[0]+ m_ImagePoints[1])/2 m_SIterationPoints[0] = (m_SIterationPoints[0] + m_SIterationPoints[1])/2 m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc default: title = "Second Farthest" int param v_secondfarthest caption = "Version (Second Farthest)" 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_secondfarthest < 100 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "'Edge only' traps the edges of the shape." endheading param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapModeStacked(ImageTrapModeWithThreshold) { ; trap mode variant based upon a class of Damien Jones public: import "common.ulb" ; constructor func ImageTrapModeStacked(Generic pparent) ImageTrapModeWithThreshold.IMageTrapModeWithThreshold(pparent) endfunc ; initialize the object func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) m_Solid = true int j = 0 while (j < 4) m_Distances[j] = 1e20 j = j + 1 endwhile endfunc ; call for each iterated point func Iterate(complex pz, complex pzt, float pdistance, float ptexture, color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif float sc = 1 if @scby == "Distance" sc = pdistance*10 elseif @scby == "Z" sc = cabs(pz)*10 elseif @scby == "Transformed Z" sc = cabs(pzt)*10 endif m_a = alpha(pcolor) float d2 = 0 if (@p_trapstackorder == 0) d2 = m_Distances[0] - (m_Iterations-m_IterationPoints[0]) * @p_trapstackdistance * m_Threshold else d2 = m_Distances[0] + (m_Iterations-m_IterationPoints[0]) * @p_trapstackdistance * m_Threshold endif if (pdistance < d2 && pdistance < m_Threshold && m_a >= m_AThreshold) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width/sc)) m_Distances[0] = pdistance m_UntransformedPoints[0] = pz m_Textures[0] = ptexture m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_SIterationPoints[0] = m_SIterationPoints[0] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) m_Solid = false m_ImagePoints[0] = pcolor edgefade(pdistance) m_zold = iterp endif endfunc func Result() m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc default: title = "Stacked" int param v_stacked caption = "Version (Stacked)" 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_stacked < 100 endparam int param p_trapstackorder caption = "Stack Order" default = 0 enum = "top-down" "bottom-up" hint = "Sets the order in which traps are stacked. Top-down places earlier iterations above later iterations; bottom-up places later iterations above earlier iterations." endparam float param p_trapstackdistance caption = "Stack Distance" default = 0.25 min = 0.0 hint = "Amount trap distance varies with each iteration. Use this to adjust how close together traps appear and intertwine with each other." endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "'Edge only' traps the edges of the shape." endheading param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam param scby caption = "Scale by" default = 0 enum = "None" "Distance" "Z" "Transformed Z" visible = @edge endparam } class ImageTrapTrapOnly(ImageTrapModeWithThreshold) { ; trap mode variant based upon a class of Damien Jones public: import "common.ulb" ; constructor func ImageTrapModeTrapOnly(Generic pparent) ImageTrapModeWithThreshold.IMageTrapModeWithThreshold(pparent) endfunc ; initialize the object func Init(complex pz) ImageTrapModeWithThreshold.Init(pz) m_Solid = true endfunc ; call for each iterated point func Iterate(complex pz, complex pzt, float pdistance, float ptexture, color pcolor) ImageTrapModeWithThreshold.Iterate(pz, pzt, pdistance,ptexture,pcolor) complex iterp = 0 if @usetx iterp = pzt else iterp = pz endif m_a = alpha(pcolor) if m_Iterations == 1 m_Distances[0] = pdistance/m_Threshold m_UntransformedPoints[0] = pz m_Textures[0] = ptexture m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_SIterationPoints[0] = m_SIterationPoints[0] + exp(-cabs(iterp)-0.5/(cabs(iterp-m_zold))) if (pdistance < m_Threshold) && (!@edge || \ (@edge && (m_threshold-pdistance) < @width)) m_Solid = false endif m_ImagePoints[0] = pcolor edgefade(pdistance) m_zold = iterp endif endfunc func Result() m_SIterationPoints[0] = m_SIterationPoints[0]*10 endfunc default: title = "Trap Only" int param v_traponly caption = "Version (Trap Only)" 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_traponly < 100 endparam heading text = "This parameter is for use with the Trap Color Mode 'Iteration'. When checked it uses the value of z tranformed by the trap." endheading bool param usetx caption = "Transform smooth iterations" default = false endparam heading text = "'Edge only' traps the edges of the shape." endheading param edge caption = "Edge only" default = false endparam float param width caption = "Edge width" default = 0.05 visible = @edge endparam } class ImageTrapModeTwoClosest(ImageTrapModeSecondClosest) { ; trap mode variant based upon a class of Damien Jones public: import "common.ulb" ; constructor func ImageTrapModeTwoClosest(Generic pparent) ImageTrapModeSecondClosest.ImageTrapModeSecondClosest(pparent) endfunc ; call in the final section of a coloring formula/class func Result() m_Distances[0] = (m_Distances[0] + m_Distances[1]) / 2 m_Textures[0] = (m_Textures[0] + m_Textures[1]) / 2 m_UntransformedPoints[0] = (m_UntransformedPoints[0] + m_UntransformedPoints[1]) / 2 m_TransformedPoints[0] = (m_TransformedPoints[0] + m_TransformedPoints[1]) / 2 m_IterationPoints[0] = ((m_IterationPoints[0] + m_IterationPoints[1]) / 2) m_SIterationPoints[0] = ((m_SIterationPoints[0] + m_SIterationPoints[1]) / 2) m_SIterationPoints[0] = m_SIterationPoints[0]*10 m_ImagePoints[0] = (m_ImagePoints[1]+m_ImagePoints[0])/2 endfunc default: title = "Two Closest" int param v_twoclosest caption = "Version (Two Closest)" 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_twoclosest < 100 endparam } class IMageTrapModeTwoFarthest(ImageTrapModeSecondFarthest) { ; trap mode variant based upon a class of Damien Jones public: import "common.ulb" ; constructor func ImageTrapModeTwoFarthest(Generic pparent) ImageTrapModeSecondFarthest.ImageTrapModeSecondFarthest(pparent) endfunc ; call in the final section of a coloring formula/class func Result() m_Distances[0] = (m_Distances[0] + m_Distances[1]) / 2 m_Textures[0] = (m_Textures[0] + m_Textures[1]) / 2 m_UntransformedPoints[0] = (m_UntransformedPoints[0] + m_UntransformedPoints[1]) / 2 m_TransformedPoints[0] = (m_TransformedPoints[0] + m_TransformedPoints[1]) / 2 m_IterationPoints[0] = ((m_IterationPoints[0] + m_IterationPoints[1]) / 2) m_SIterationPoints[0] = ((m_SIterationPoints[0] + m_SIterationPoints[1]) / 2) m_SIterationPoints[0] = m_SIterationPoints[0]*10 m_ImagePoints[0] = (m_ImagePoints[1]+m_ImagePoints[0])/2 endfunc default: title = "Two Farthest" int param v_twofarthest caption = "Version (Two Farthest)" default = 101 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_twofarthest < 101 endparam } ;-------------------------- ; ; Image Trap ColorMode classes ; ;----------------------------- class ImageTrapColoring(Generic) { ; This is a generic image trap coloring mode formula.
;

; It take the results of a imag trap mode and returns both a value to use as ; a color index and a color public: import "common.ulb" ; constructor func ImageTrapColoring(Generic pparent) Generic.Generic(pparent) endfunc ; get a final index result float func Result(ImageTrapMode ptrapmode) return ptrapmode.GetDistance(0) endfunc ; get a final color result color func CResult(ImageTrapMode ptrapmode) return ptrapmode.GetColor(0) endfunc default: int param v_imagetrapcoloring caption = "Version (Image Trap Coloring)" 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_imagetrapcoloring < 100 endparam } class ImageTrapColoringDistance(ImageTrapColoring) { ; Returns a trap distance which has been weighted by a texture
;

; The inherited function CResult() returns a color from a ColorTrap class ; if one is being used. public: import "common.ulb" ; constructor func ImageTrapColoringDistance(Generic pparent) ImageTrapColoring.ImageTrapColoring(pparent) endfunc ; use in the Result section of a direct coloring formula. float func Result(ImageTrapMode ptrapmode) ImageTrapColoring.Result(ptrapmode) float scalef = 1 if @d_iter if @stype == "multiply" if @smooth scalef = @sfact*ptrapmode.GetSIteration(0) else scalef = @sfact*ptrapmode.GetIteration(0) endif elseif @stype == "divide" if @smooth scalef = @sfact/ptrapmode.GetSIteration(0) else scalef = @sfact/ptrapmode.GetIteration(0) endif else if @smooth scalef = @sfact^(1/ptrapmode.GetSIteration(0)) else scalef = @sfact^(1/ptrapmode.GetIteration(0)) endif endif endif if (@p_autoscale) return (ptrapmode.GetDistance(0)*scalef + ptrapmode.GetTexture(0)) / ptrapmode.GetThreshold() else return ptrapmode.GetDistance(0)*scalef + ptrapmode.GetTexture(0) endif endfunc default: title = "Distance" int param v_distance caption = "Version (Distance)" 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_distance < 100 endparam bool param p_autoscale caption = "Auto-scale Coloring" default = true hint = "If checked, coloring will be automatically scaled to match the trap threshold." endparam bool param d_iter caption = "Scale by iteration" default = false endparam bool param smooth caption = "Use smooth iter" default = false visible = @d_iter == true endparam float param sfact caption = "Scale factor" default = 1.0 visible = @d_iter == true endparam param stype caption = "Scale type" default = 0 enum = "divide" "reciprocal power" "multiply" visible = @d_iter == true endparam } class ImageTrapColoringIteration(ImageTrapColoring) { ; Returns a value based upon the iteration # which has been weighted by a texture
;

; An option for returning a modulus of the interation # is also available. ; The inherited function CResult() returns a color from a ColorTrap class ; if one is being used. public: import "common.ulb" ; constructor func ImageTrapColoringIteration(Generic pparent) ImageTrapColoring.ImageTrapColoring(pparent) endfunc ; use in the Result section of a direct coloring formula. float func Result(ImageTrapMode ptrapmode) ImageTrapColoring.Result(ptrapmode) float iters if @smooth iters = ptrapmode.GetSIteration(0) else iters = ptrapmode.GetIteration(0) endif if @discrete == "discrete colors" return (ptrapmode.GetIteration(0) % @modcolor)/@modcolor + ptrapmode.GetTexture(0) else return iters*0.01 + ptrapmode.GetTexture(0) endif endfunc default: title = "Iteration" int param v_imagetrapiteration caption = "Version (image Trap Iteration)" 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_imagetrapiteration < 100 endparam param discrete caption = "Iteration options" default = 0 enum = "normal" "discrete colors" hint = "'discrete colors' allows the user to set the total number of colors \ to use with mod iter." endparam int param modcolor caption = "# of iteration colors" default = 8 visible = @discrete == "discrete colors" hint = "Number of iteration colors to use with mod iter. This is useful \ for gradient masks where the mask allows a specific mod iter to \ be opaque or transparent." endparam bool param smooth caption = "Smooth iteration" default = false visible = @discrete != "discrete colors" endparam } class REB_TrapColoringIteration(common.ulb:TrapColoring) { ; Returns a value based upon the iteration # which has been weighted by a texture
;

; An option for returning a modulus of the interation # is also available. public: import "common.ulb" ; Constructor func REB_TrapColoringIteration(Generic pparent) TrapColoring.TrapColoring(pparent) endfunc ; use in the Result section of a gradient coloring formula. float func Result(TrapMode ptrapmode) TrapColoring.Result(ptrapmode) if @discrete == "discrete colors" return (ptrapmode.GetIteration(0) % @modcolor)/@modcolor + ptrapmode.GetTexture(0) else return ptrapmode.GetIteration(0)*0.01 + ptrapmode.GetTexture(0) endif endfunc default: title = "REB Iteration" int param v_rebiteration caption = "Version (REB Iteration)" 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_rebiteration < 100 endparam param discrete caption = "Iteration options" default = 0 enum = "normal" "discrete colors" hint = "'discrete colors' allows the user to set the total number of colors \ to use with mod iter." endparam int param modcolor caption = "# of iteration colors" default = 8 visible = @discrete == "discrete colors" hint = "Number of iteration colors to use with mod iter. This is useful \ for gradient masks where the mask allows a specific mod iter to \ be opaque or transparent." endparam } class ImageTrapColoringMagnitude(ImageTrapColoring) { ; Returns the magnitude of the trapped point which has been weighted by a texture
;

; Returns either the transformed or the untransformed point.The inherited ; function CResult() returns a color from a ColorTrap class if one is being used. public: import "common.ulb" ; constructor func ImageTrapColoringMagnitude(Generic pparent) ImageTrapColoring.ImageTrapColoring(pparent) endfunc ; use in the Result section of a direct coloring formula. float func Result(ImageTrapMode ptrapmode) ImageTrapColoring.Result(ptrapmode) if (@p_untransformed) return cabs(ptrapmode.GetUntransformedPoint(0)) + ptrapmode.GetTexture(0) else return cabs(ptrapmode.GetTransformedPoint(0)) + ptrapmode.GetTexture(0) endif endfunc default: title = "Magnitude" int param v_magnitude caption = "Version (Magnitude)" 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_magnitude < 100 endparam bool param p_untransformed caption = "Use value before transformation" default = true hint = "If checked, coloring will be based on the value prior to any trap position transformations." endparam } class ImageTrapColoringReal(ImageTrapColoring) { ; Returns the real value of the trapped point which has been weighted by a texture
;

; Returns either the transformed or the untransformed point.The inherited ; function CResult() returns a color from a ColorTrap class if one is being used. public: import "common.ulb" ; constructor func ImageTrapColoringReal(Generic pparent) ImageTrapColoring.ImageTrapColoring(pparent) endfunc ; use in the Result section of a direct coloring formula. float func Result(ImageTrapMode ptrapmode) ImageTrapColoring.Result(ptrapmode) if (@p_untransformed) return abs(real(ptrapmode.GetUntransformedPoint(0))) + ptrapmode.GetTexture(0) else return abs(real(ptrapmode.GetTransformedPoint(0))) + ptrapmode.GetTexture(0) endif endfunc default: title = "Real" int param v_real caption = "Version (Real)" 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_real < 100 endparam bool param p_untransformed caption = "Use value before transformation" default = true hint = "If checked, coloring will be based on the value prior to any trap position transformations." endparam } class ImageTrapColoringImag(ImageTrapColoring) { ; Returns the imaginary value of the trapped point which has been weighted by a texture
;

; Returns either the transformed or the untransformed point.The inherited ; function CResult() returns a color from a ColorTrap class if one is being used. public: import "common.ulb" ; constructor func ImageTrapColoringImag(Generic pparent) ImageTrapColoring.ImageTrapColoring(pparent) endfunc ; use in the Result section of a direct coloring formula. float func Result(ImageTrapMode ptrapmode) ImageTrapColoring.Result(ptrapmode) if (@p_untransformed) return abs(imag(ptrapmode.GetUntransformedPoint(0))) + ptrapmode.GetTexture(0) else return abs(imag(ptrapmode.GetTransformedPoint(0))) + ptrapmode.GetTexture(0) endif endfunc default: title = "Imaginary" int param v_imag caption = "Version (Imaginary)" 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_imag < 100 endparam bool param p_untransformed caption = "Use value before transformation" default = true hint = "If checked, coloring will be based on the value prior to any trap position transformations." endparam } class ImageTrapColoringAngleToOrigin(ImageTrapColoring) { ; Returns the angle to origin of the trapped point which has been weighted by a texture
;

; Returns either the transformed or the untransformed point.The inherited ; function CResult() returns a color from a ColorTrap class if one is being used. public: import "common.ulb" ; constructor func ImageTrapColoringAngleToOrgin(Generic pparent) ImageTrapColoring.ImageTrapColoring(pparent) endfunc ; use in the Result section of a direct coloring formula. float func Result(ImageTrapMode ptrapmode) ImageTrapColoring.Result(ptrapmode) float d = atan2(ptrapmode.GetUntransformedPoint(0)) if (d < 0) d = d + #pi*2 float rvalue = d / (#pi * 2) + ptrapmode.GetTexture(0) endif return d / (#pi * 2) + ptrapmode.GetTexture(0) endfunc default: title = "Angle to Origin" int param v_angletoorigin caption = "Version (Angle To Origin)" 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_angletoorigin < 100 endparam } class ImageTrapColoringAngleToOrigin2(ImageTrapColoring) { ; Returns the angle to origin of the trapped point which has been weighted by a texture
;

; Returns either the transformed or the untransformed point.The inherited ; function CResult() returns a color from a ColorTrap class if one is being used. public: import "common.ulb" ; constructor func ImageTrapColoringAngleToOrgin2(Generic pparent) ImageTrapColoring.ImageTrapColoring(pparent) endfunc ; use in the Result section of a direct coloring formula. float func Result(ImageTrapMode ptrapmode) ImageTrapColoring.Result(ptrapmode) complex z = pTrapMode.getUntransformedPoint(0) return 0.02 * abs(atan(imag(z) / real(z)) * 180/#pi) endfunc default: title = "Angle to Origin 2" int param v_angletoorigin caption = "Version (Angle To Origin 2)" 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_angletoorigin < 100 endparam } class ImageTrapColoringAngleToTrap(ImageTrapColoring) { ; Returns the angle to the trapped point which has been weighted by a texture
;

; Returns either the transformed or the untransformed point.The inherited ; function CResult() returns a color from a ColorTrap class if one is being used. public: import "common.ulb" ; constructor func ImageTrapColoringAngleToTrap(Generic pparent) ImageTrapColoring.ImageTrapColoring(pparent) endfunc ; use in the Result section of a direct coloring formula. float func Result(ImageTrapMode ptrapmode) ImageTrapColoring.Result(ptrapmode) float d = atan2(ptrapmode.GetTransformedPoint(0)) if (d < 0) d = d + #pi*2 endif return d / (#pi * 2) + ptrapmode.GetTexture(0) endfunc default: title = "Angle to Trap" int param v_angletotrap caption = "Version (Angle To Trap)" 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_angletotrap < 100 endparam } ;------------------------ ; ; Trap Transfer classes ; ------------------------- class TransferDistanceVariants(common.ulb:Transfer) { ; This is a basic transfer function useful for trap distances.
;

; The distance variants reproduce distance options available in my old UF4 formulas. public: import "common.ulb" ; constructor func TransferDistanceVariants(Generic pparent) Transfer.Transfer(pparent) endfunc ; call for each iterated point float func Iterate(float pr) Transfer.Iterate(pr) float rt = pr*@dmod if @trapvar == 1 rt = abs(rt*rt - rt) elseif @trapvar == 2 rt = abs(rt*rt*rt - rt) elseif @trapvar == 3 rt = abs(rt*rt*rt -rt*rt +rt) elseif @trapvar == 4 rt = abs(rt - |f_p|) elseif @trapvar == 5 rt = abs(rt - cabs(fn3(f_p))) elseif @trapvar == 6 rt = cabs((z1-f_p)*(rt/10-f_p)) elseif @trapvar == 7 rt = cabs(fn3(f_p)*(rt/10-z1+f_p)) elseif @trapvar == 8 rt = cabs(fn3(f_p)*(rt/10-(x+y))) elseif @trapvar == 9 rt = cabs(fn3(f_p)*(rt/10-(x*y))) endif return rt endfunc ; set the transformed point value func SetTransformed(complex tx) f_p = tx endfunc ; set the untransformed point value func SetUnTransformed(complex utx) z1 = utx x = real(z1) y = imag(z1) endfunc protected: complex f_p complex z1 float x float y default: title = "Distance Variants" int param v_distancevariants caption = "Version (Distance Variants)" default = 101 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_distancevariants < 101 endparam float param dmod caption = "Distance modifier" default = 1.0 endparam param trapvar caption = "Variants" default = 0 enum = "default" "1" "2" "3" "4" "5" "6" "7" "8" "9" endparam func fn3 caption = "Trap var function" default = acos() visible=@trapvar == 5||@trapvar == 7||@trapvar == 8||@trapvar == 9 endfunc } class TrapTransferBias(common.ulb:Transfer) { ; This is a basic transfer function useful for trap distances. ; This line is an attempt to change TTB so that it will be added to the database public: import "common.ulb" func TrapTransferBias(Generic pparent) Transfer.Transfer(pparent) endfunc float func Iterate(float pr) float rt = (pr + @p_preadd1) * @p_prescale + @p_preadd2 if @p_cut rt = rt - @bias endif if (@p_function == "sqr") rt = sqr(rt) elseif (@p_function == "sqrt") rt = sqrt(rt) elseif (@p_function == "cube") rt = (rt)^3 elseif (@p_function == "cuberoot") rt = rt^(1/3) elseif (@p_function == "log") rt = log(rt) elseif (@p_function == "exp") rt = exp(rt) elseif (@p_function == "sin") rt = sin(rt) elseif (@p_function == "atan") rt = atan(rt) elseif (@p_function == "cos") rt = cos(rt) elseif (@p_function == "tan") rt = tan(rt) elseif (@p_function == "sinc") if (rt == 0) rt = 1 else rt = sin(#pi*rt)/rt endif elseif (@p_function == "round") rt = round(rt) endif rt = (rt + @p_postadd1) * @p_postscale + @p_postadd2 if (@p_abs) rt = abs(rt) endif if @p_cut if rt < 0 rt = 0 endif endif return rt endfunc default: title = "Trap Transfer Bias" int param v_traptransferbias caption = "Version (TrapTransferBias)" 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_traptransferbias < 100 endparam float param bias caption = "Distance bias" default = 0.5 visible = @p_cut endparam float param p_preadd1 caption = "Pre-offset" default = 0.0 hint = "This value is added to the trap distance before the multiplier is used." endparam float param p_prescale caption = "Pre-scale" default = 1.0 hint = "This value is multiplied with the trap distance before the function is applied to it." endparam float param p_preadd2 caption = "Offset" default = 0.0 hint = "This value is added to the trap distance after the multiplier is used but before the function is applied." endparam int param p_function caption = "Function" default = 0 enum = "linear" "sqr" "sqrt" "cube" "cuberoot" "log" "exp" "sin" "atan" \ "cos" "tan" "sinc" "round" hint = "This function modifies the trap distance." endparam float param p_postadd1 caption = "Post-offset" default = 0.0 hint = "This value is added to the trap distance after the function is applied." endparam float param p_postscale caption = "Post-scale" default = 1.0 hint = "This value is multiplied with the function and offset result." endparam float param p_postadd2 caption = "Final offset" default = 0.0 hint = "This value is added to the trap distance after the post-scale multiplier is used." endparam bool param p_abs caption = "No Negative Values" default = false hint = "If enabled, eliminates 'negative' distances by taking the absolute value." visible = !@p_cut endparam bool param p_cut caption = "Cut at zero" default = false visible = !@p_abs endparam } ;-------------------------- ; ; Image Traps class ; ;-------------------------- class REB_ImageTrapsColoring(common.ulb:DirectColoring) { ; An Orbit Traps variant with the addition of trapped image import. ;

; The formula provides for the import of images which are trapped according to ; the trap shape, trap mode and trap coloring used. Internally the the regular ; trap coloring and the image trap coloring are treated as separate layers which ; can be merged by the usual merge options. The image import plugin is a ColorTrap ; type, and any other ColorTrap type can be used in its slot. $define debug public: import "common.ulb" import "dmj5.ulb" ; constructor func REB_ImageTrapsColoring(Generic pparent) DirectColoring.DirectColoring(pparent) m_TrapSelect = new @f_trapselect(this) fTransform = new @transform(this) m_TrapShape = new @f_trapshape(this) m_ImageTrapMode = new @f_trapmode(this) fTransfer = new @transfer(this) fDTransfer = new @dtransfer(this) m_ImageTrapColoring = new @f_trapcoloring(this) m_TrapShape.SetThreshold(@p_threshold) m_ImageTrapMode.SetThreshold(@p_threshold) if @f_trapcolor != ColorTrapNoColor float athresh = @p_athreshold+0.001 m_ImageTrapMode.SetAThreshold(athresh) else m_ImageTrapMode.SetAThreshold(@p_athreshold) endif m_TrapTexture = new @f_traptexture(this) m_MergeColor = new @f_colormerge(this) m_TrapColor = new @f_trapcolor(this) m_img = new @f_image(0) m_empty = m_img.GetEmpty() endfunc ; Initialize the coloring formula func Init(complex pz, complex ppixel) DirectColoring.Init(pz,ppixel) m_TrapSelectSequence = m_TrapSelect.InitDefault() fTransform.init(pz) fTransfer.init(pz) m_ImageTrapMode.Init(pz) m_TrapShape.Init(pz) m_TrapTexture.Init(pz) m_TrapColor.Init(pz) endfunc ; call for each iterated point func Iterate(complex pz) DirectColoring.Iterate(pz) m_TrapSelectSequence = m_TrapSelect.Iterate(m_TrapSelectSequence) if ((@f_trapselect == DMJ_TrapSelect && m_TrapSelectSequence > 0.5) \ || m_TrapSelectSequence > @p_trapselectthreshold) complex m_zr = fTransform.Iterate(pz) float pdistance = m_TrapShape.iterate(m_zr) complex pdcomplex = 0 if @v_imagetraps >= 103 pdcomplex = m_TrapShape.GetTransformedPoint() if @dtype == "Manhattan" pdistance = abs(real(m_zr-pdcomplex))^real(@mp) + \ abs(imag(m_zr-pdcomplex))^imag(@mp) elseif @dtype == "Bray Curtis" pdistance = pdistance*(abs(real(m_zr-pdcomplex)) + abs(imag(m_zr-pdcomplex)))/ \ ((abs(real(m_zr+pdcomplex)) + abs(imag(m_zr+pdcomplex)))) elseif @dtype == "Canberra" pdistance = pdistance*abs(real(m_zr-pdcomplex))/(abs(real(m_zr)) + abs(real(pdcomplex))) + \ abs(imag(m_zr-pdcomplex))/(abs(imag(m_zr)) + abs(imag(pdcomplex))) elseif @dtype == "Minkovsky" pdistance = (abs(real(m_zr-pdcomplex))^@ex + \ abs(imag(m_zr-pdcomplex))^@ex)^(1/@ex) elseif @dtype == "Chebychev" pdistance = abs(real(m_zr-pdcomplex)) if pdistance < abs(imag(m_zr-pdcomplex)) pdistance = abs(imag(m_zr-pdcomplex)) endif endif endif complex tx = m_TrapShape.GetTransformedPoint() if @shapeflavor == 1 if @v_imagetraps < 106 pdistance = pdistance + cabs(tx) else pdistance = (pdistance + @flvweight*cabs(tx))/(1+@flvweight) endif endif fdTransfer.SetTransformed(tx) fdTransfer.SetUnTransformed(m_zr) pdistance = fTransfer.Iterate(pdistance) pdistance = fdTransfer.Iterate(pdistance) if @v_imagetraps < 101 m_img = new @f_image(0) m_empty = m_img.GetEmpty() endif color pcolor = @colorempty if @v_imagetraps >= 101 if @f_trapcolor == ColorTrapNoColor m_empty = true else pcolor = m_TrapColor.Iterate(m_zr) m_empty = false endif else if !m_empty complex m_zi = (0,1)^(@iangle/90.0) complex m_zs = (0,1)^(@sangle/90.0) complex pzrs = pz ; offset if !@itile pzrs = pzrs+@ioffset endif ; aspect ratio pzrs = real(pzrs) + flip(imag(pzrs)*@iaspect) ; rotation pzrs = pzrs*m_zi ; skew pzrs = real(pzrs)*m_zs + flip(imag(pzrs)) float width = m_img.getWidth() float height = m_img.getHeight() if @itile pzrs = (pzrs+#width/2+flip(#height/2))*@scale*#width complex c = @adjx-2*((real(pzrs) % (width-1))/width) + \ flip(@adjy-2*((imag(pzrs) % (height-1))/height)) pcolor = m_img.getColor(c) else pcolor = m_img.getColor(pzrs*@scale) endif else pcolor = @colorempty endif endif float ptexture = 0 if !@p_textureposttransform ptexture = m_TrapTexture.Iterate(pz) if @texflavor == 1 ptexture = cabs(m_trapTexture.GetTransformedPoint()) elseif @texflavor == 2 if @v_imagetraps < 106 ptexture = ptexture + cabs(m_trapTexture.GetTransformedPoint()) else ptexture = (ptexture + @tflrvwt*cabs(m_trapTexture.GetTransformedPoint()))/ \ (1 + @tflrvwt) endif endif ptexture = ptexture*@p_texturestrength else ptexture = m_TrapShape.GetTextureValue() ptexture = ptexture + m_TrapTexture.Iterate(tx) ptexture = (ptexture + m_TrapTexture.GetTextureValue()) * @p_texturestrength endif if @weighttodist && (@f_traptexture != DMJ_TrapShapeFlat) ptexture = ptexture/(@dweight + 1/(1e-10+pdistance^@dpower)) endif if @weighttothresh && (@f_traptexture != DMJ_TrapShapeFlat) ptexture = ptexture*((@p_Threshold-pdistance)/@p_Threshold)^@tpower if ptexture < 0 ptexture = 0 endif endif if !fTransform.IsSolid() m_ImageTrapMode.Iterate(m_zr, tx, pdistance,ptexture,pcolor) else m_ImageTrapMode.IterateSilent() endif else fTransform.IterateSilent() m_TrapShape.IterateSilent() fTransfer.IterateSilent() fdTransfer.IterateSilent() m_ImageTrapMode.IterateSilent() m_TrapTexture.IterateSilent() endif endfunc ; call in the final section of the ucl to get final coloring results. color func Result(complex pz) m_ImageTrapMode.Result() color final_color = m_ImageTrapColoring.CResult(m_ImageTrapMode) if @v_imagetraps >= 102 && @v_imageTraps < 105 if @ahue final_color = hsla(hue(final_color), sat(final_color), lum(final_color), \ hue(final_color)) elseif @alum final_color = hsla(hue(final_color), sat(final_color), lum(final_color), \ lum(final_color)) elseif @asat final_color = hsla(hue(final_color), sat(final_color), lum(final_color), \ sat(final_color)) endif endif if @v_imageTraps >= 105 if @ahue final_color = hsla(hue(final_color), sat(final_color), lum(final_color), \ hue(final_color)*alpha(final_color/6)) endif if @alum final_color = hsla(hue(final_color), sat(final_color), lum(final_color), \ lum(final_color)*alpha(final_color)) endif if @asat final_color = hsla(hue(final_color), sat(final_color), lum(final_color), \ sat(final_color)*alpha(final_color)) endif endif color merge_color = gradient(m_ImageTrapColoring.Result(m_ImageTrapMode)) m_Solid = @usesolid && m_ImageTrapMode.IsSolid() float opacity = 0 color temp = rgba(0,0,0,0) if @nmerge == 1 || m_empty temp = merge_color merge_color = final_color final_color = temp endif if !m_empty opacity = @opacity else opacity = 1 endif color rcolor = m_MergeColor.FullMerge(merge_color, final_color, opacity) if @v_imageTraps >= 105 float br = (0.5-@p_bright)*2 int sign = 0 if br < 0 sign = -1 else sign = 1 endif br = br^2*sign float cr = (@p_contrast-0.5)*2 if cr < 0 sign = -1 else sign = 1 endif cr = cr^2*sign+1 float st = (0.5-@p_sat)*2 if st < 0 sign = -1 else sign = 1 endif st = st^2*sign*2 float hu = @p_hue*6 float rd = red(rcolor)-br float gr = green(rcolor)-br float bl = blue(rcolor)-br if rd > 1 rd = 1 endif if gr > 1 gr = 1 endif if bl > 1 bl = 1 endif if rd < 0 rd = 0 endif if gr < 0 gr = 0 endif if bl < 0 bl = 0 endif rcolor = rgba(rd,gr,bl,alpha(rcolor)) rd = red(rcolor)^cr gr = green(rcolor)^cr bl = blue(rcolor)^cr rcolor = rgba(rd,gr,bl,alpha(rcolor)) float satval = sat(rcolor)-st if satval > 1 satval = 1 endif if satval < 0 satval = 0 endif rcolor = hsla(hue(rcolor), satval, lum(rcolor), alpha(rcolor)) float hueval = (hue(rcolor)+hu) % 6 rcolor = hsla(hueval, sat(rcolor), lum(rcolor), alpha(rcolor)) endif if @p_poster float rd = floor(red(rcolor)*@p_chan)/@p_chan + 0.5/@p_chan float gr = floor(green(rcolor)*@p_chan)/@p_chan + 0.5/@p_chan float bl = floor(blue(rcolor)*@p_chan)/@p_chan + 0.5/@p_chan rcolor = rgba(rd,gr,bl,alpha(rcolor)) endif if @p_gray float gry = 0.3 * red(rcolor)+ 0.59 * green(rcolor) + 0.11 * blue(rcolor) rcolor = rgba(gry,gry,gry,alpha(rcolor)) endif if @p_solar float rd = red(rcolor) float gr = green(rcolor) float bl = blue(rcolor) if rd > @p_thresh rd = 1-rd endif if gr > @p_thresh gr = 1-gr endif if bl > @p_thresh bl = 1-bl endif rcolor = rgba(rd,gr,bl,alpha(rcolor)) endif if @p_bw float gry = 0.3 * red(rcolor)+ 0.59 * green(rcolor) + 0.11 * blue(rcolor) if gry < @p_bwt rcolor = rgba(0,0,0,alpha(rcolor)) else rcolor = rgba(1,1,1,alpha(rcolor)) endif endif return rcolor endfunc ; Is the coloring solid? - used by the coloring ucl. bool func IsSolid() return m_Solid endfunc protected: Generator m_TrapSelect TrapShape m_TrapShape UserTransform fTransform Transfer fTransfer TransferDistanceVariants fDTransfer ImageTrapMode m_ImageTrapMode ImageTrapColoring m_ImageTrapColoring TrapShape m_TrapTexture ImageImport m_img ColorTrap m_TrapColor DefaultColorMerge m_MergeColor int m_image_width int m_image_height float m_ratio bool m_empty float m_TrapSelectSequence complex iters default: title = "Image Traps" int param v_imagetraps caption = "Version (Image Traps)" default = 106 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_imagetraps < 106 endparam heading text = "This coloring formula combines classical orbit traps with color \ objects, including images." endheading float param version caption = "version parameter" default = 1.0 visible = false endparam heading caption = "Trap Parameters" endheading Generator param f_trapselect caption = "Trap Iteration" default = DMJ_TrapSelect expanded = false endparam float param p_trapselectthreshold caption = "Threshold" default = 0.5 hint = "When using a Generator other than a TrapSelect type, values could range anywhere from 0 to 1. This threshold sets which values will be interpreted as 'do not trap' and which will be interpreted as 'trap'." visible = (@f_trapselect != DMJ_TrapSelect) && (@f_trapselect != REB_KerrysSelect) endparam UserTransform param transform caption = "Trap Position" default = TrapTransformMod expanded = false hint = "Transforms the orbit values from the fractal formula before they \ are passed to the trap shape." endparam TrapShape param f_trapshape caption = "Trap Shape" default = REB_TrapShapeBifolium endparam heading text = "Flavor 1 uses the trap distance. Flavor 2 uses a combination of the \ trap distance and the transformed point. For some Trap Shapes \ there is no difference, as the author used the transformed point for \ the distance calculation." endheading param shapeflavor caption = "Shape flavor" default = 0 enum = "flavor 1" "flavor 2" endparam float param flvweight caption = "Flavor weight" default = 1 visible = @v_imagetraps >= 106 && @shapeflavor == "flavor 2" endparam param dtype caption = "Distance metric" default = 3 enum = "Bray Curtis" "Canberra" "Chebychev" "Euclidian" \ "Manhattan" "Minkovsky" visible = @v_imagetraps >= 103 endparam complex param mp caption = "Manhattan power" default = (1,1) visible = @v_imagetraps >= 103 && @dtype == "Manhattan" endparam float param ex caption = "Minkovsky param" default = 0.5 visible = @v_imagetraps >= 103 && @dtype == "Minkovsky" endparam Transfer param transfer caption = "Trap Transfer" expanded = false default = TrapTransfer hint = "Provides additional options to scale and transform the distance \ that the trap shape returns." endparam TransferDistanceVariants param dtransfer caption = "Custom Transfer" expanded = false default = TransferDistanceVariants hint = "Provides additional options to scale and transform the distance \ that the trap shape returns." endparam ImageTrapMode param f_trapmode caption = "Trap Mode" default = ImageTrapModeClosest endparam float param p_threshold caption = "Trap Threshold" default = 0.25 hint = "This is the overall size or thickness of the trap area. (Some trap modes may not use the threshold value.)" visible = (@f_trapmode == ImageTrapModeWithThreshold) endparam float param p_athreshold caption = "Alpha Threshold" default = 0.0 hint = "This is the overall size or thickness of the trap area. (Some trap modes may not use the threshold value.)" visible = (@f_trapmode == ImageTrapModeWithThreshold) endparam bool param usesolid caption = "Use Solid Color" default = false endparam TrapShape param f_traptexture caption = "Trap Texture" default = DMJ_TrapShapeFlat expanded = false hint = "A trap shape that is used as a texture. Textures do not change the shape of the trap but may change its coloring." endparam bool param p_textureposttransform caption = "Use Transformed Coordinate" default = false hint = "If checked, texturing will be based on the final transformed coordinate used in the trap shape (i.e. it will follow the trap shape, rather than being separate from it)." visible = (@f_traptexture != DMJ_TrapShapeFlat) endparam bool param weighttodist caption = "Weight by Distance" default = false visible = !@weighttothresh && (@f_traptexture != DMJ_TrapShapeFlat) endparam bool param weighttothresh caption = "Weight by Threshold" default = false visible = !@weighttodist && (@f_traptexture != DMJ_TrapShapeFlat) endparam float param p_texturestrength caption = "Texture Amount" default = 0.0 hint = "Sets the overall amount of texture to be used. Larger numbers will increase the effect of the texture. A value of 0 will remove the effects of the texture." visible = (@f_traptexture != DMJ_TrapShapeFlat) endparam float param dweight caption = "Distance weight" default = 1.0 visible = @weighttodist && (@f_traptexture != DMJ_TrapShapeFlat) endparam float param dpower caption = "Distance power" default = 1.0 visible = @weighttodist && (@f_traptexture != DMJ_TrapShapeFlat) endparam float param tpower caption = "Threshold power" default = 1.0 visible = @weighttothresh && (@f_traptexture != DMJ_TrapShapeFlat) endparam heading text = "Flavor 1 uses the distance calculation for texture. Flavor 2 uses \ the transformed point. Flavor 3 uses a combination of the distance \ calculation and the transformed point. For some Trap Shape textures \ there is no difference, as the author used the transformed point for \ the distance calculation." visible = (@f_traptexture != DMJ_TrapShapeFlat)&& !@p_textureposttransform endheading param texflavor caption = "Texture flavor" default = 0 enum = "flavor 1" "flavor 2" "flavor 3" visible = (@f_traptexture != DMJ_TrapShapeFlat)&& !@p_textureposttransform endparam float param tflrvwt caption = "Texture flavor weight" default = 1 visible = @v_imagetraps >= 106 && @texflavor == "flavor 3" endparam ImageTrapColoring param f_trapcoloring caption = "Trap Color Mode" default = ImageTrapColoringDistance endparam heading caption = "Images and Colorings" endheading ColorTrap param f_trapcolor caption = "Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." visible = @v_imagetraps >= 101 endparam ImageImport param f_image caption = "Image" default = ImageImport visible = @v_imagetraps < 101 endparam float param scale caption = "Image scale" default = 1 min = 0 hint = "Changes the scale of the image." visible = @v_imagetraps < 101 endparam float param adjx caption = "Tile adj x" default = 0.99 min = 0.9 max = 1.1 visible = @v_imagetraps < 101 endparam float param adjy caption = "Tile adj y" default = 0.999 min = 0.9 max = 1.1 visible = @v_imagetraps < 101 endparam complex param ioffset caption = "Image offset" default = (0,0) visible = !@itile && @v_imagetraps < 101 endparam float param iaspect caption = "Image aspect" default = 1.0 visible = @v_imagetraps < 101 endparam float param iangle caption = "Image rotation" default = 0 hint = "Rotates the image" visible = @v_imagetraps < 101 endparam float param sangle caption = "Image skew" default = 0 hint = "Skews the image" visible = @v_imagetraps < 101 endparam bool param itile caption = "Tile the image" default = false visible = @v_imagetraps < 101 endparam color param colorempty caption = "No Image Color" default = rgba(1,1,1,0) visible = @f_trapcolor == ColorTrapNoColor endparam heading caption = "Color Merging" endheading DefaultColorMerge param f_colormerge caption = "Color Merge" default = DefaultColorMerge endparam param nmerge caption = "Merge order" default = 0 enum = "Image on Top" "Image on Bottom" endparam float param opacity caption = "Merge Opacity" default = 1.0 endparam heading text = "Make image transparent by: " visible = @v_imagetraps >= 102 && @f_trapcolor != ColorTrapNoColor endheading bool param ahue caption = "Hue value" default = false visible = ((@v_imagetraps >= 102 && @v_imagetraps < 105 && !@alum && !@asat) || \ @v_imagetraps >= 105) && @f_trapcolor != ColorTrapNoColor endparam bool param alum caption = "Luminance value" default = false visible = ((@v_imagetraps >= 102 && @v_imagetraps < 105 && !@ahue && !@asat) || \ @v_imagetraps >= 105) && @f_trapcolor != ColorTrapNoColor endparam bool param asat caption = "Saturation value" default = false visible = ((@v_imagetraps >= 102 && @v_imagetraps < 105 && !@alum && !@ahue) || \ @v_imagetraps >= 105) && @f_trapcolor != ColorTrapNoColor endparam heading caption = "Special Effects" endheading float param p_bright caption = "Brightness" default = 0.5 min = 0 max = 1 visible = @v_imagetraps >= 105 endparam float param p_contrast caption = "Contrast" default = 0.5 min = 0 max = 1 visible = @v_imagetraps >= 105 endparam float param p_sat caption = "Saturation" default = 0.5 min = 0 max = 1 visible = @v_imagetraps >= 105 endparam float param p_hue caption = "Hue" default = 0.0 min = 0 max = 1 visible = @v_imagetraps >= 105 endparam bool param p_gray caption = "Grayscale" default = false endparam bool param p_solar caption = "Solarize" default = false endparam float param p_thresh caption = "Threshold" default = 0.5 visible = @p_solar endparam bool param p_poster caption = "Posterize" default = false endparam int param p_chan caption = "Colors per channel" default = 4 min = 2 visible = @p_poster endparam bool param p_bw caption = "Black and White" default = false endparam float param p_bwt caption = "Threshold" default = 0.5 min = 0 max = 1 visible = @p_bw endparam } ;----------------------------- ; ; Color Trap classes ; ;------------------------------ class REB_ConvolutionWrapper(common.ulb:ColorTrap) { ; This wrapper allows you to use any color trap and any convolution ; filter to produce blurred or sharpened (or other) trap effects. ; This is largely based upon BlurTrapWrapper of Damien Jones and modified ; to work with Image Traps, Exponential Smoothing (REB version), Fiber and ; Things, and Lighting with Textures Direct. $define debug public: import "common.ulb" import "dmj5.ulb" func REB_ConvolutionWrapper(Generic pparent) ColorTrap.ColorTrap(pparent) m_Filter = new @f_filter(this) m_Samples = length(m_Filter.m_Offsets) if @f_filter != REB_MedianFilter && @f_filter != REB_ColorPencilFilter && \ @f_filter != REB_OilPaintFilter && @f_filter != REB_ConservativeSmoothingFilter && \ @f_filter != REB_CrimminsDespeckleFilter setLength(m_TrapShapes, m_Samples) int j = 0 while (j < m_Samples) m_TrapShapes[j] = new @f_trapshape(this) j = j + 1 endwhile else setLength(m_TrapShapes, 1) setlength(med,m_samples) setlength(mc,m_samples) setlength(mr,m_samples) setlength(mg,m_samples) setlength(mb,m_samples) m_TrapShapes[0] = new @f_trapshape(this) endif endfunc func Init(complex pz) ColorTrap.Init(pz) if @f_filter != REB_MedianFilter && @f_filter != REB_ColorPencilFilter && \ @f_filter != REB_OilPaintFilter && @f_filter != REB_ConservativeSmoothingFilter && \ @f_filter != REB_CrimminsDespeckleFilter int j = 0 while (j < m_Samples) m_TrapShapes[j].Init(pz) j = j + 1 endwhile else m_TrapShapes[0].Init(pz) endif if (@p_filterreset == 0 && DMJ_VariableConvolutionFilter(m_Filter) != 0) m_Filter.Init(pz) endif endfunc color func Iterate(complex pz) ColorTrap.Iterate(pz) if @f_filter == REB_AverageBlurFilter m_filter.Init(pz) depth = m_filter.m_bias m_filter.m_bias = 0 endif color return_color = rgba(0,0,0,0) if (@p_filterreset == 1 && DMJ_VariableConvolutionFilter(m_Filter) != 0) m_Filter.Init(pz) endif float r = 0.0 float g = 0.0 float b = 0.0 float a = 0.0 float w = 0 float o = 0 float g = 0 color c = rgba(0,0,0,0) int k = 0 int l = 0 float tmp = 0 color tmp2 = rgba(0,0,0,0) int si = 0 int sj = 0 bool continue = true float rmin = 1e10 float gmin = 1e10 float bmin = 1e10 float rmax = 0 float gmax = 0 float bmax = 0 int bin[100] while k < 100 bin[k] = 0 k = k + 1 endwhile int val = 0 float maxval = 0 ; int binnum = 0 int maxvalidx = 0 k = 0 int j = 0 if @f_filter == REB_MedianFilter || @f_filter == REB_ColorPencilFilter || \ @f_filter == REB_OilPaintFilter || @f_filter == REB_ConservativeSmoothingFilter ||\ @f_filter == REB_CrimminsDespeckleFilter while j < m_samples mc[j] = m_TrapShapes[0].Iterate(pz+m_Filter.m_Offsets[j]) med[j] = 0.3 * red(mc[j])+ 0.59 * green(mc[j]) + 0.11 * blue(mc[j]) if @f_filter == REB_ColorPencilFilter ; determine min and max values in the neighborhood mr[j] = red(mc[j])*255 if mr[j] < rmin rmin = mr[j] endif if mr[j] > rmax rmax = mr[j] endif mg[j] = green(mc[j])*255 if mg[j] < gmin gmin = mg[j] endif if mg[j] > gmax gmax = mg[j] endif mb[j] = blue(mc[j])*255 if mb[j] < bmin bmin = mb[j] endif if mb[j] > bmax bmax = mb[j] endif endif if @f_filter == REB_OilPaintFilter ; create a 100 bin histogram to determine the most common value val = round(med[j]*100) % 100 bin[val] = bin[val] + 1 if maxval < bin[val] maxval = bin[val] maxvalidx = j ; binnum = val endif endif j = j + 1 endwhile if @f_filter == REB_CrimminsDespeckleFilter ; 3 4 5 ; 1 4 7 ; 0 4 8 ; 2 4 6 int idx = 4 if med[3] >= med[4] + .2 med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 3 endif if med[1] >= med[4] + .2 med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 1 endif if med[0] >= med[4] + .2 med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 0 endif if med[2] >= med[4] + .2 med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 2 endif if med[3] > med[4] && med[4] <= med[5] med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 3 endif if med[1] > med[4] && med[4] <= med[7] med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 1 endif if med[0] > med[4] && med[4] <= med[8] med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 0 endif if med[2] > med[4] && med[4] <= med[6] med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 2 endif if med[5] > med[4] && med[4] <= med[3] med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 5 endif if med[7] > med[4] && med[4] <= med[1] med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 7 endif if med[8] > med[4] && med[4] <= med[0] med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 8 endif if med[6] > med[4] && med[4] <= med[2] med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 6 endif if med[5] >= med[4] + .2 med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 5 endif if med[7] >= med[4] + .2 med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 7 endif if med[8] >= med[4] + .2 med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 8 endif if med[6] >= med[4] + .2 med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 6 endif if med[3] <= med[4] - .2 med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 3 endif if med[1] <= med[4] - .2 med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 1 endif if med[0] <= med[4] - .2 med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 0 endif if med[2] >= med[4] - .2 med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 2 endif if med[3] < med[4] && med[4] >= med[5] med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 3 endif if med[1] < med[4] && med[4] >= med[7] med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 1 endif if med[0] < med[4] && med[4] >= med[8] med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 0 endif if med[2] < med[4] && med[4] >= med[6] med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 2 endif if med[5] < med[4] && med[4] >= med[3] med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 5 endif if med[7] < med[4] && med[4] >= med[1] med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 7 endif if med[8] < med[4] && med[4] >= med[0] med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 8 endif if med[6] < med[4] && med[4] >= med[2] med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 6 endif if med[5] <= med[4] - .2 med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 5 endif if med[7] <= med[4] - .2 med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 7 endif if med[8] <= med[4] - .2 med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 8 endif if med[6] <= med[4] - .2 med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 6 endif c = mc[idx] endif if @f_filter == REB_MedianFilter ;find the median value ;heapsort without recursion, sorted on med[] l = round(m_samples/2)+1 k = m_samples tmp = 0 tmp2 = rgba(0,0,0,0) repeat if l > 1 l = l-1 tmp = med[l-1] tmp2 = mc[l-1] else tmp = med[k-1] tmp2 = mc[k-1] med[k-1] = med[0] mc[k-1] = mc[0] k = k-1 if k == 0 med[0] = tmp mc[0] = tmp2 continue = false endif endif if continue == true si = l sj = 2*l endif while (sj <= k) && (continue == true) if sj < k if med[sj-1] < med[sj] sj = sj + 1 endif endif if tmp < med[sj-1] med[si-1] = med[sj-1] mc[si-1] = mc[sj-1] si = sj sj = sj + sj else sj = k + 1 endif endwhile if (continue == true) med[si-1] = tmp mc[si-1] = tmp2 endif until continue == false ; end heapsort c = mc[round(m_samples/2)] endif if @f_filter == REB_ConservativesmoothingFilter ;find the min and max values ;heapsort without recursion, sorted on med[] l = round(m_samples/2)+1 k = m_samples c = mc[l] float intense = med[l] tmp = 0 tmp2 = rgba(0,0,0,0) repeat if l > 1 l = l-1 tmp = med[l-1] tmp2 = mc[l-1] else tmp = med[k-1] tmp2 = mc[k-1] med[k-1] = med[0] mc[k-1] = mc[0] k = k-1 if k == 0 med[0] = tmp mc[0] = tmp2 continue = false endif endif if continue == true si = l sj = 2*l endif while (sj <= k) && (continue == true) if sj < k if med[sj-1] < med[sj] sj = sj + 1 endif endif if tmp < med[sj-1] med[si-1] = med[sj-1] mc[si-1] = mc[sj-1] si = sj sj = sj + sj else sj = k + 1 endif endwhile if (continue == true) med[si-1] = tmp mc[si-1] = tmp2 endif until continue == false ; end heapsort if intense >= med[m_samples-1] ; largest value c = mc[m_samples-2] elseif intense <= med[0] ; smallest value c = mc[1] endif endif if @f_filter == REB_ColorPencilFilter float mdr = 0 float mdg = 0 float mdb = 0 float maskr = 0 float maskg = 0 float maskb = 0 r = mr[round(m_samples/2)] g = mg[round(m_samples/2)] b = mb[round(m_samples/2)] if r == rmax mdr = 0 else mdr = abs(r-rmin) if mdr < abs(r-rmax) mdr = abs(r-rmax) endif endif if g == gmax mdg = 0 else mdg = abs(g-gmin) if mdg < abs(g-gmax) mdg = abs(g-gmax) endif endif if b == bmax mdb = 0 else mdb = abs(b-bmin) if mdb < abs(b-bmax) mdb = abs(b-bmax) endif endif maskr = 1/(mdr/(sqrt(r+1)/3)+1) maskg = 1/(mdg/(sqrt(g+1)/3)+1) maskb = 1/(mdb/(sqrt(b+1)/3)+1) r = (r + @cpr*((255-r)*maskr-mdr*r/@atten))/255 g = (g + @cpr*((255-g)*maskg-mdg*g/@atten))/255 b = (b + @cpr*((255-b)*maskb-mdb*b/@atten))/255 c = rgba(r,g,b,alpha(mc[round(m_samples/2)])) endif if @f_filter == REB_OilPaintFilter c = mc[maxvalidx] endif endif j = 0 while (j < m_Samples) if @f_filter != REB_MedianFilter && @f_filter != REB_ColorPencilFilter && \ @f_filter != REB_OilPaintFilter && @f_filter != REB_ConservativeSmoothingFilter &&\ @f_filter != REB_CrimminsDespeckleFilter c = m_TrapShapes[j].Iterate(pz+m_Filter.m_Offsets[j]) endif if (@f_filter != REB_MedianFilter && @f_filter != REB_ColorPencilFilter && \ @f_filter != REB_OilPaintFilter && @f_filter != REB_ConservativeSmoothingFilter &&\ @f_filter != REB_CrimminsDespeckleFilter) || j == 0 if @v_REB_ConvolutionWrapper >= 101 if @f_filter == REB_AverageBlurFilter && depth > 1 && @usedist float p_bright = @p_bright/depth else p_bright = @p_bright endif float br = (0.5-p_bright)*2 int sign = 0 if br < 0 sign = -1 else sign = 1 endif br = br^2*sign if @f_filter == REB_AverageBlurFilter && depth > 1 && @usedist float p_contrast = @p_contrast/depth else p_contrast = @p_contrast endif float cr = (p_contrast-0.5)*2 if cr < 0 sign = -1 else sign = 1 endif cr = cr^2*sign+1 if @f_filter == REB_AverageBlurFilter && depth > 1 && @usedist float p_sat = @p_sat/depth else p_sat = @p_sat endif float st = (0.5-p_sat)*2 if st < 0 sign = -1 else sign = 1 endif st = st^2*sign*2 float hu = @p_hue*6 float rd = red(c)-br float gr = green(c)-br float bl = blue(c)-br if rd > 1 rd = 1 endif if gr > 1 gr = 1 endif if bl > 1 bl = 1 endif if rd < 0 rd = 0 endif if gr < 0 gr = 0 endif if bl < 0 bl = 0 endif c = rgba(rd,gr,bl,alpha(c)) rd = red(c)^cr gr = green(c)^cr bl = blue(c)^cr c = rgba(rd,gr,bl,alpha(c)) float satval = sat(c)-st if satval > 1 satval = 1 endif if satval < 0 satval = 0 endif c = hsla(hue(c), satval, lum(c), alpha(c)) float hueval = (hue(c)+hu) % 6 c = hsla(hueval, sat(c), lum(c), alpha(c)) endif if @p_poster float rd = floor(red(c)*@p_chan)/@p_chan + 0.5/@p_chan float gr = floor(green(c)*@p_chan)/@p_chan + 0.5/@p_chan float bl = floor(blue(c)*@p_chan)/@p_chan + 0.5/@p_chan c = rgba(rd,gr,bl,alpha(c)) endif if @p_gscale float gry = 0.3 * red(c)+ 0.59 * green(c) + 0.11 * blue(c) c = rgba(gry,gry,gry,alpha(c)) endif if @p_solar float rd = red(c) float gr = green(c) float bl = blue(c) if rd > @p_thresh rd = 1-rd endif if gr > @p_thresh gr = 1-gr endif if bl > @p_thresh bl = 1-bl endif c = rgba(rd,gr,bl,alpha(c)) endif if @p_bw float gry = 0.3 * red(c)+ 0.59 * green(c) + 0.11 * blue(c) if gry < @p_bwt c = rgba(0,0,0,alpha(c)) else c = rgba(1,1,1,alpha(c)) endif endif if @f_filter != REB_MedianFilter && @f_filter != REB_ColorPencilFilter && \ @f_filter != REB_OilPaintFilter && @f_filter != REB_ConservativeSmoothingFilter && \ @f_filter != REB_CrimminsDespeckleFilter w = m_Filter.m_Weights[j] r = r + red(c) * w g = g + green(c) * w b = b + blue(c) * w if @p_alpha a = a + alpha(c) * w endif endif endif j = j + 1 endwhile if @f_filter != REB_MedianFilter && @f_filter != REB_ColorPencilFilter && \ @f_filter != REB_OilPaintFilter && @f_filter != REB_ConservativeSmoothingFilter && \ @f_filter != REB_CrimminsDespeckleFilter w = m_Filter.m_Multiplier o = m_Filter.m_Bias r = r * w + o g = g * w + o b = b * w + o if @p_alpha a = a * w + o return_color = rgba(r,g,b,a) else return_color = rgb(r,g,b) endif else if @p_alpha return_color = c else return_color = rgb(red(c),green(c),blue(c)) endif endif return return_color endfunc protected: DMJ_ConvolutionFilter m_Filter int m_Samples ColorTrap m_TrapShapes[] float med[] color mc[] float mr[] float mg[] float mb[] float depth default: title = "Convolution Color Wrapper" int param v_REB_ConvolutionWrapper caption = "Version (REB_ConvolutionWrapper)" default = 101 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_REB_ConvolutionWrapper < 101 endparam heading text = "To apply convolution filters in imported images, replace the ColorTrapShapeBlock \ plugin with the Color Trap Image Tiles plugin." endheading ColorTrap param f_trapshape caption = "Trap Shape" default = ColorTrapShapeBlock hint = "Sets the trap shape that the convolution filter will be applied to." endparam DMJ_ConvolutionFilter param f_filter caption = "Convolution Filter" default = REB_NullFilter hint = "Sets the filter that will be applied." endparam float param cpr caption = "Color Pencil Intensity" default = 0.5 visible = @f_filter == REB_ColorPencilFilter endparam float param atten caption = "Color Pencil Contrast" default = 100 min = 1 max = 255 visible = @f_filter == REB_ColorPencilFilter endparam int param p_filterreset caption = "Reset Filter" default = 0 min = 0 max = 1 enum = "first iteration" "every iteration" hint = "Some convolution filters are position-dependent: the filter's effect varies from one part of the complex plane to another. For this kind of filter, you may choose whether to recompute the filter's effect only at the first iteration or on every iteration." visible = (@f_filter == DMJ_VariableConvolutionFilter) endparam bool param p_alpha caption = "Use alpha values" default = false visible = @f_filter != REB_NullFilter endparam heading caption = "Special Effects for Convolution Wrapper" endheading bool param usedist caption = "Color by distance" default = false visible = @f_filter == REB_AverageBlurFilter endparam float param p_bright caption = "Brightness" default = 0.5 min = 0 max = 1 visible = @v_REB_ConvolutionWrapper >= 101 endparam float param p_contrast caption = "Contrast" default = 0.5 min = 0 max = 1 visible = @v_REB_ConvolutionWrapper >= 101 endparam float param p_sat caption = "Saturation" default = 0.5 min = 0 max = 1 visible = @v_REB_ConvolutionWrapper >= 101 endparam float param p_hue caption = "Hue" default = 0.0 min = 0 max = 1 visible = @v_REB_ConvolutionWrapper >= 101 endparam bool param p_gscale caption = "Grayscale" default = false endparam bool param p_solar caption = "Solarize" default = false endparam float param p_thresh caption = "Threshold" default = 0.5 visible = @p_solar endparam bool param p_poster caption = "Posterize" default = false endparam int param p_chan caption = "Colors per channel" default = 4 min = 2 visible = @p_poster endparam bool param p_bw caption = "Black and White" default = false endparam float param p_bwt caption = "Threshold" default = 0.5 min = 0 max = 1 visible = @p_bw endparam } class REB_ImageFilter(common.ulb:ColorTrap) { ; This wrapper allows you to use any color trap and any convolution ; filter to produce blurred or sharpened (or other) trap effects. ; This is largely based upon BlurTrapWrapper of Damien Jones and modified ; to work with Image Traps, Exponential Smoothing (REB version), Fiber and ; Things, and Lighting with Textures Direct. $define debug public: import "common.ulb" import "dmj5.ulb" func REB_ImageFilter(Generic pparent) ColorTrap.ColorTrap(pparent) m_Filter = new @f_filter(this) m_Samples = length(m_Filter.m_Offsets) if @f_filter != REB_MedianFilter && @f_filter != REB_ColorPencilFilter && \ @f_filter != REB_OilPaintFilter && @f_filter != REB_ConservativeSmoothingFilter && \ @f_filter != REB_CrimminsDespeckleFilter setLength(m_TrapShapes, m_Samples) int j = 0 while (j < m_Samples) m_TrapShapes[j] = new @f_trapshape(this) j = j + 1 endwhile else setLength(m_TrapShapes, 1) setlength(med,m_samples) setlength(mc,m_samples) setlength(mr,m_samples) setlength(mg,m_samples) setlength(mb,m_samples) m_TrapShapes[0] = new @f_trapshape(this) endif endfunc func Init(complex pz) ColorTrap.Init(pz) if @f_filter != REB_MedianFilter && @f_filter != REB_ColorPencilFilter && \ @f_filter != REB_OilPaintFilter && @f_filter != REB_ConservativeSmoothingFilter && \ @f_filter != REB_CrimminsDespeckleFilter int j = 0 while (j < m_Samples) m_TrapShapes[j].Init(pz) j = j + 1 endwhile else m_TrapShapes[0].Init(pz) endif if (@p_filterreset == 0 && DMJ_VariableConvolutionFilter(m_Filter) != 0) m_Filter.Init(pz) endif endfunc color func Iterate(complex pz) ColorTrap.Iterate(pz) if @f_filter == REB_AverageBlurFilter m_filter.Init(pz) depth = m_filter.m_bias m_filter.m_bias = 0 endif color return_color = rgba(0,0,0,0) if (@p_filterreset == 1 && DMJ_VariableConvolutionFilter(m_Filter) != 0) m_Filter.Init(pz) endif float r = 0.0 float g = 0.0 float b = 0.0 float a = 0.0 float w = 0 float o = 0 float g = 0 color c = rgba(0,0,0,0) int k = 0 int l = 0 float tmp = 0 color tmp2 = rgba(0,0,0,0) int si = 0 int sj = 0 bool continue = true float rmin = 1e10 float gmin = 1e10 float bmin = 1e10 float rmax = 0 float gmax = 0 float bmax = 0 int bin[100] while k < 100 bin[k] = 0 k = k + 1 endwhile int val = 0 float maxval = 0 ; int binnum = 0 int maxvalidx = 0 k = 0 int j = 0 if @f_filter == REB_MedianFilter || @f_filter == REB_ColorPencilFilter || \ @f_filter == REB_OilPaintFilter || @f_filter == REB_ConservativeSmoothingFilter ||\ @f_filter == REB_CrimminsDespeckleFilter while j < m_samples mc[j] = m_TrapShapes[0].Iterate(pz+m_Filter.m_Offsets[j]) med[j] = 0.3 * red(mc[j])+ 0.59 * green(mc[j]) + 0.11 * blue(mc[j]) if @f_filter == REB_ColorPencilFilter ; determine min and max values in the neighborhood mr[j] = red(mc[j])*255 if mr[j] < rmin rmin = mr[j] endif if mr[j] > rmax rmax = mr[j] endif mg[j] = green(mc[j])*255 if mg[j] < gmin gmin = mg[j] endif if mg[j] > gmax gmax = mg[j] endif mb[j] = blue(mc[j])*255 if mb[j] < bmin bmin = mb[j] endif if mb[j] > bmax bmax = mb[j] endif endif if @f_filter == REB_OilPaintFilter ; create a 100 bin histogram to determine the most common value val = round(med[j]*100) % 100 bin[val] = bin[val] + 1 if maxval < bin[val] maxval = bin[val] maxvalidx = j ; binnum = val endif endif j = j + 1 endwhile if @f_filter == REB_CrimminsDespeckleFilter ; 3 4 5 ; 1 4 7 ; 0 4 8 ; 2 4 6 int idx = 4 if med[3] >= med[4] + .2 med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 3 endif if med[1] >= med[4] + .2 med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 1 endif if med[0] >= med[4] + .2 med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 0 endif if med[2] >= med[4] + .2 med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 2 endif if med[3] > med[4] && med[4] <= med[5] med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 3 endif if med[1] > med[4] && med[4] <= med[7] med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 1 endif if med[0] > med[4] && med[4] <= med[8] med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 0 endif if med[2] > med[4] && med[4] <= med[6] med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 2 endif if med[5] > med[4] && med[4] <= med[3] med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 5 endif if med[7] > med[4] && med[4] <= med[1] med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 7 endif if med[8] > med[4] && med[4] <= med[0] med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 8 endif if med[6] > med[4] && med[4] <= med[2] med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 6 endif if med[5] >= med[4] + .2 med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 5 endif if med[7] >= med[4] + .2 med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 7 endif if med[8] >= med[4] + .2 med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 8 endif if med[6] >= med[4] + .2 med[4] = med[4] + 0.1 if med[4] > 1 med[4] = 1 endif idx = 6 endif if med[3] <= med[4] - .2 med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 3 endif if med[1] <= med[4] - .2 med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 1 endif if med[0] <= med[4] - .2 med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 0 endif if med[2] >= med[4] - .2 med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 2 endif if med[3] < med[4] && med[4] >= med[5] med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 3 endif if med[1] < med[4] && med[4] >= med[7] med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 1 endif if med[0] < med[4] && med[4] >= med[8] med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 0 endif if med[2] < med[4] && med[4] >= med[6] med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 2 endif if med[5] < med[4] && med[4] >= med[3] med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 5 endif if med[7] < med[4] && med[4] >= med[1] med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 7 endif if med[8] < med[4] && med[4] >= med[0] med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 8 endif if med[6] < med[4] && med[4] >= med[2] med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 6 endif if med[5] <= med[4] - .2 med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 5 endif if med[7] <= med[4] - .2 med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 7 endif if med[8] <= med[4] - .2 med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 8 endif if med[6] <= med[4] - .2 med[4] = med[4] - 0.1 if med[4] < 0 med[4] = 0 endif idx = 6 endif c = mc[idx] endif if @f_filter == REB_MedianFilter ;find the median value ;heapsort without recursion, sorted on med[] l = round(m_samples/2)+1 k = m_samples tmp = 0 tmp2 = rgba(0,0,0,0) repeat if l > 1 l = l-1 tmp = med[l-1] tmp2 = mc[l-1] else tmp = med[k-1] tmp2 = mc[k-1] med[k-1] = med[0] mc[k-1] = mc[0] k = k-1 if k == 0 med[0] = tmp mc[0] = tmp2 continue = false endif endif if continue == true si = l sj = 2*l endif while (sj <= k) && (continue == true) if sj < k if med[sj-1] < med[sj] sj = sj + 1 endif endif if tmp < med[sj-1] med[si-1] = med[sj-1] mc[si-1] = mc[sj-1] si = sj sj = sj + sj else sj = k + 1 endif endwhile if (continue == true) med[si-1] = tmp mc[si-1] = tmp2 endif until continue == false ; end heapsort c = mc[round(m_samples/2)] endif if @f_filter == REB_ConservativesmoothingFilter ;find the min and max values ;heapsort without recursion, sorted on med[] l = round(m_samples/2)+1 k = m_samples c = mc[l] float intense = med[l] tmp = 0 tmp2 = rgba(0,0,0,0) repeat if l > 1 l = l-1 tmp = med[l-1] tmp2 = mc[l-1] else tmp = med[k-1] tmp2 = mc[k-1] med[k-1] = med[0] mc[k-1] = mc[0] k = k-1 if k == 0 med[0] = tmp mc[0] = tmp2 continue = false endif endif if continue == true si = l sj = 2*l endif while (sj <= k) && (continue == true) if sj < k if med[sj-1] < med[sj] sj = sj + 1 endif endif if tmp < med[sj-1] med[si-1] = med[sj-1] mc[si-1] = mc[sj-1] si = sj sj = sj + sj else sj = k + 1 endif endwhile if (continue == true) med[si-1] = tmp mc[si-1] = tmp2 endif until continue == false ; end heapsort if intense >= med[m_samples-1] ; largest value c = mc[m_samples-2] elseif intense <= med[0] ; smallest value c = mc[1] endif endif if @f_filter == REB_ColorPencilFilter float mdr = 0 float mdg = 0 float mdb = 0 float maskr = 0 float maskg = 0 float maskb = 0 r = mr[round(m_samples/2)] g = mg[round(m_samples/2)] b = mb[round(m_samples/2)] if r == rmax mdr = 0 else mdr = abs(r-rmin) if mdr < abs(r-rmax) mdr = abs(r-rmax) endif endif if g == gmax mdg = 0 else mdg = abs(g-gmin) if mdg < abs(g-gmax) mdg = abs(g-gmax) endif endif if b == bmax mdb = 0 else mdb = abs(b-bmin) if mdb < abs(b-bmax) mdb = abs(b-bmax) endif endif maskr = 1/(mdr/(sqrt(r+1)/3)+1) maskg = 1/(mdg/(sqrt(g+1)/3)+1) maskb = 1/(mdb/(sqrt(b+1)/3)+1) r = (r + @cpr*((255-r)*maskr-mdr*r/@atten))/255 g = (g + @cpr*((255-g)*maskg-mdg*g/@atten))/255 b = (b + @cpr*((255-b)*maskb-mdb*b/@atten))/255 c = rgba(r,g,b,alpha(mc[round(m_samples/2)])) endif if @f_filter == REB_OilPaintFilter c = mc[maxvalidx] endif endif j = 0 while (j < m_Samples) if @f_filter != REB_MedianFilter && @f_filter != REB_ColorPencilFilter && \ @f_filter != REB_OilPaintFilter && @f_filter != REB_ConservativeSmoothingFilter &&\ @f_filter != REB_CrimminsDespeckleFilter c = m_TrapShapes[j].Iterate(pz+m_Filter.m_Offsets[j]) endif if (@f_filter != REB_MedianFilter && @f_filter != REB_ColorPencilFilter && \ @f_filter != REB_OilPaintFilter && @f_filter != REB_ConservativeSmoothingFilter &&\ @f_filter != REB_CrimminsDespeckleFilter) || j == 0 if @f_filter == REB_AverageBlurFilter && depth > 1 && @usedist float p_bright = @p_bright/depth else p_bright = @p_bright endif float br = (0.5-p_bright)*2 int sign = 0 if br < 0 sign = -1 else sign = 1 endif br = br^2*sign if @f_filter == REB_AverageBlurFilter && depth > 1 && @usedist float p_contrast = @p_contrast/depth else p_contrast = @p_contrast endif float cr = (p_contrast-0.5)*2 if cr < 0 sign = -1 else sign = 1 endif cr = cr^2*sign+1 if @f_filter == REB_AverageBlurFilter && depth > 1 && @usedist float p_sat = @p_sat/depth else p_sat = @p_sat endif float st = (0.5-p_sat)*2 if st < 0 sign = -1 else sign = 1 endif st = st^2*sign*2 float hu = @p_hue*6 if @f_filter == REB_AverageBlurFilter && depth < 1 && @usedist && @basehue hu = @p_hue*6*depth endif float rd = red(c)-br float gr = green(c)-br float bl = blue(c)-br if rd > 1 rd = 1 endif if gr > 1 gr = 1 endif if bl > 1 bl = 1 endif if rd < 0 rd = 0 endif if gr < 0 gr = 0 endif if bl < 0 bl = 0 endif c = rgba(rd,gr,bl,alpha(c)) rd = red(c)^cr gr = green(c)^cr bl = blue(c)^cr c = rgba(rd,gr,bl,alpha(c)) float satval = sat(c)-st if satval > 1 satval = 1 endif if satval < 0 satval = 0 endif c = hsla(hue(c), satval, lum(c), alpha(c)) float hueval = (hue(c)+hu) % 6 c = hsla(hueval, sat(c), lum(c), alpha(c)) if @p_poster float rd = floor(red(c)*@p_chan)/@p_chan + 0.5/@p_chan float gr = floor(green(c)*@p_chan)/@p_chan + 0.5/@p_chan float bl = floor(blue(c)*@p_chan)/@p_chan + 0.5/@p_chan c = rgba(rd,gr,bl,alpha(c)) endif if @p_gscale float gry = 0.3 * red(c)+ 0.59 * green(c) + 0.11 * blue(c) c = rgba(gry,gry,gry,alpha(c)) endif if @p_solar float rd = red(c) float gr = green(c) float bl = blue(c) if rd > @p_thresh rd = 1-rd endif if gr > @p_thresh gr = 1-gr endif if bl > @p_thresh bl = 1-bl endif c = rgba(rd,gr,bl,alpha(c)) endif if @p_bw float gry = 0.3 * red(c)+ 0.59 * green(c) + 0.11 * blue(c) if gry < @p_bwt c = rgba(0,0,0,alpha(c)) else c = rgba(1,1,1,alpha(c)) endif endif if @f_filter != REB_MedianFilter && @f_filter != REB_ColorPencilFilter && \ @f_filter != REB_OilPaintFilter && @f_filter != REB_ConservativeSmoothingFilter && \ @f_filter != REB_CrimminsDespeckleFilter w = m_Filter.m_Weights[j] r = r + red(c) * w g = g + green(c) * w b = b + blue(c) * w if @p_alpha a = a + alpha(c) * w endif endif endif j = j + 1 endwhile if @f_filter != REB_MedianFilter && @f_filter != REB_ColorPencilFilter && \ @f_filter != REB_OilPaintFilter && @f_filter != REB_ConservativeSmoothingFilter && \ @f_filter != REB_CrimminsDespeckleFilter w = m_Filter.m_Multiplier o = m_Filter.m_Bias r = r * w + o g = g * w + o b = b * w + o if @p_alpha a = a * w + o return_color = rgba(r,g,b,a) else return_color = rgb(r,g,b) endif else if @p_alpha return_color = c else return_color = rgb(red(c),green(c),blue(c)) endif endif return return_color endfunc protected: DMJ_ConvolutionFilter m_Filter int m_Samples ColorTrap m_TrapShapes[] float med[] color mc[] float mr[] float mg[] float mb[] float depth default: title = "Image Filter" int param v_REB_ImageFilter caption = "Version (Image Filter)" 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_REB_ImageFilter < 100 endparam ColorTrap param f_trapshape caption = "Trap Shape" default = ColorTrapImageTiles selectable = false endparam DMJ_ConvolutionFilter param f_filter caption = "Image Filter" default = REB_AverageBlurFilter hint = "Sets the filter that will be applied." endparam float param cpr caption = "Color Pencil Intensity" default = 0.5 visible = @f_filter == REB_ColorPencilFilter endparam float param atten caption = "Color Pencil Contrast" default = 100 min = 1 max = 255 visible = @f_filter == REB_ColorPencilFilter endparam int param p_filterreset caption = "Reset Filter" default = 0 min = 0 max = 1 enum = "first iteration" "every iteration" hint = "Some convolution filters are position-dependent: the filter's effect varies from one part of the complex plane to another. For this kind of filter, you may choose whether to recompute the filter's effect only at the first iteration or on every iteration." visible = (@f_filter == DMJ_VariableConvolutionFilter) endparam bool param p_alpha caption = "Use alpha values" default = false visible = @f_filter != REB_NullFilter endparam heading caption = "Image Filter Effects" endheading bool param usedist caption = "Color by distance" default = false visible = @f_filter == REB_AverageBlurFilter endparam float param p_bright caption = "Brightness" default = 0.5 min = 0 max = 1 endparam float param p_contrast caption = "Contrast" default = 0.5 min = 0 max = 1 endparam float param p_sat caption = "Saturation" default = 0.5 min = 0 max = 1 endparam bool param basehue caption = "Use base hue at focus" default = false visible = @usedist endparam float param p_hue caption = "Hue" default = 0.0 min = 0 max = 1 endparam bool param p_gscale caption = "Grayscale" default = false endparam bool param p_solar caption = "Solarize" default = false endparam float param p_thresh caption = "Threshold" default = 0.5 visible = @p_solar endparam bool param p_poster caption = "Posterize" default = false endparam int param p_chan caption = "Colors per channel" default = 4 min = 2 visible = @p_poster endparam bool param p_bw caption = "Black and White" default = false endparam float param p_bwt caption = "Threshold" default = 0.5 min = 0 max = 1 visible = @p_bw endparam } class ColorTrapShapeBlock(common.ulb:ColorTrap) { ; This is essentially a wrapper around a transformation, a trap shape, ; and a transfer function. It returns a color, either from the gradient, ; or from an internal color array. public: func ColorTrapShapeBlock(Generic pparent) ColorTrap.ColorTrap(pparent) m_TrapTransform = new @f_traptransform(this) m_TrapShape = new @f_trapshape(this) m_TrapTransfer = new @f_traptransfer(this) m_DirColor = new @f_dircolor(this) endfunc func Init(complex pz) ColorTrap.Init(pz) m_TrapTransform.Init(pz) m_TrapShape.Init(pz) m_TrapTransfer.Init(pz) m_dircolor.Init() endfunc color func Iterate(complex pz) complex zt = m_TrapTransform.Iterate(pz) float distance = m_TrapShape.Iterate(zt) distance = m_TrapTransfer.Iterate(distance) color pat = rgba(0,0,0,0) pz = exp(flip(2 * #pi * sqrt(2) * distance)) float cindex = 0 if @flavorp == 0 if @cfun == "Linear" cindex = (@cscale*(cabs((real(pz)/cabs(pz))))+ @rot) % 1 elseif @cfun == "Sqr" cindex = (@cscale*(cabs(sqr(real(pz)/cabs(pz))))+ @rot) % 1 elseif @cfun == "Sqrt" cindex = (@cscale*(cabs(sqrt(real(pz)/cabs(pz))))+ @rot) % 1 elseif @cfun == "Cube" cindex = (@cscale*(cabs((real(pz)/cabs(pz))^3))+ @rot) % 1 elseif @cfun == "Cuberoot" cindex = (@cscale*(cabs((real(pz)/cabs(pz))^(1/3)))+ @rot) % 1 elseif @cfun == "Log" cindex = (@cscale*(cabs(log(real(pz)/cabs(pz))))+ @rot) % 1 elseif @cfun == "Exp" cindex = (@cscale*(cabs(exp(real(pz)/cabs(pz))))+ @rot) % 1 elseif @cfun == "Sin" cindex = (@cscale*(cabs(sin(real(pz)/cabs(pz))))+ @rot) % 1 elseif @cfun == "ArcTan" cindex = (@cscale*(cabs(atan(real(pz)/cabs(pz))))+ @rot) % 1 endif if cindex >= 0 && cindex < 0.125 pat = blend(m_dircolor.direct[0],m_dircolor.direct[1],cindex/0.125) elseif cindex >= 0.125 && cindex < 0.25 pat = blend(m_dircolor.direct[1],m_dircolor.direct[2],(cindex-0.125)/0.125) elseif cindex >= 0.25 && cindex < 0.375 pat = blend(m_dircolor.direct[2],m_dircolor.direct[3],(cindex-0.25)/0.125) elseif cindex >= 0.375 && cindex < 0.5 pat = blend(m_dircolor.direct[3],m_dircolor.direct[4],(cindex-0.375)/0.125) elseif cindex >= 0.5 && cindex < 0.625 pat = blend(m_dircolor.direct[4],m_dircolor.direct[5],(cindex-0.5)/0.125) elseif cindex >= 0.625 && cindex < 0.75 pat = blend(m_dircolor.direct[5],m_dircolor.direct[6],(cindex-0.625)/0.125) elseif cindex >= 0.75 && cindex < 0.875 pat = blend(m_dircolor.direct[6],m_dircolor.direct[7],(cindex-0.75)/0.125) elseif cindex >= 0.875 && cindex < 1.0 pat = blend(m_dircolor.direct[7],m_dircolor.direct[0],(cindex-0.875)/0.125) endif elseif @flavorp == 1 if @cfun == "Linear" cindex = (@cscale*(cabs((distance))) + @rot)%1 elseif @cfun == "Sqr" cindex = (@cscale*(cabs(sqr(distance))) + @rot)%1 elseif @cfun == "Sqrt" cindex = (@cscale*(cabs(sqrt(distance))) + @rot)%1 elseif @cfun == "Cube" cindex = (@cscale*(cabs((distance)^3)) + @rot)%1 elseif @cfun == "Cuberoot" cindex = (@cscale*(cabs((distance)^(1/3))) + @rot)%1 elseif @cfun == "Log" cindex = (@cscale*(cabs(log(distance))) + @rot)%1 elseif @cfun == "Exp" cindex = (@cscale*(cabs(exp(distance))) + @rot)%1 elseif @cfun == "Sin" cindex = (@cscale*(cabs(sin(distance))) + @rot)%1 elseif @cfun == "ArcTan" cindex = (@cscale*(cabs(atan(distance))) + @rot)%1 endif if cindex >= 0 && cindex < 0.125 pat = blend(m_dircolor.direct[0],m_dircolor.direct[1],cindex/0.125) elseif cindex >= 0.125 && cindex < 0.25 pat = blend(m_dircolor.direct[1],m_dircolor.direct[2],(cindex-0.125)/0.125) elseif cindex >= 0.25 && cindex < 0.375 pat = blend(m_dircolor.direct[2],m_dircolor.direct[3],(cindex-0.25)/0.125) elseif cindex >= 0.375 && cindex < 0.5 pat = blend(m_dircolor.direct[3],m_dircolor.direct[4],(cindex-0.375)/0.125) elseif cindex >= 0.5 && cindex < 0.625 pat = blend(m_dircolor.direct[4],m_dircolor.direct[5],(cindex-0.5)/0.125) elseif cindex >= 0.625 && cindex < 0.75 pat = blend(m_dircolor.direct[5],m_dircolor.direct[6],(cindex-0.625)/0.125) elseif cindex >= 0.75 && cindex < 0.875 pat = blend(m_dircolor.direct[6],m_dircolor.direct[7],(cindex-0.75)/0.125) elseif cindex >= 0.875 && cindex < 1.0 pat = blend(m_dircolor.direct[7],m_dircolor.direct[0],(cindex-0.875)/0.125) endif elseif @flavorp == 2 if @cfun == "Linear" cindex = (@cscale*(cabs((distance))) + @rot)%1 elseif @cfun == "Sqr" cindex = (@cscale*(cabs(sqr(distance))) + @rot)%1 elseif @cfun == "Sqrt" cindex = (@cscale*(cabs(sqrt(distance))) + @rot)%1 elseif @cfun == "Cube" cindex = (@cscale*(cabs((distance)^3)) + @rot)%1 elseif @cfun == "Cuberoot" cindex = (@cscale*(cabs((distance)^(1/3))) + @rot)%1 elseif @cfun == "Log" cindex = (@cscale*(cabs(log(distance))) + @rot)%1 elseif @cfun == "Exp" cindex = (@cscale*(cabs(exp(distance))) + @rot)%1 elseif @cfun == "Sin" cindex = (@cscale*(cabs(sin(distance))) + @rot)%1 elseif @cfun == "ArcTan" cindex = (@cscale*(cabs(atan(distance))) + @rot)%1 endif pat = gradient(cindex) endif if @v_colortrapshapeblock < 102 return pat else if red(pat) != 0 && green(pat) != 0 && blue(pat) != 0 return pat else return @bcolor endif endif endfunc protected: UserTransform m_TrapTransform TrapShape m_TrapShape Transfer m_TrapTransfer REB_DirectColorHelper m_dircolor default: title = "ColorTrapShape Block" int param v_colortrapshapeblock caption = "Version (ColorTrapShapeBlock)" default = 102 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_colortrapshapeblock < 102 endparam color param bcolor caption = "Background" default = rgba(0,0,0,1) visible = @v_colortrapshapeblock >= 102 endparam UserTransform param f_traptransform caption = "Trap Position" default = TrapTransform expanded = false endparam TrapShape param f_trapshape caption = "Trap Shape" default = TrapShapePoint endparam Transfer param f_traptransfer caption = "Trap Transfer" default = NullTransfer endparam heading caption = "Coloring parameters and Flavors" endheading REB_DirectColorHelper param f_dircolor caption = "Direct color array" default = REB_Default visible = @flavorp != "gradient" endparam param flavorp caption = "Coloring flavor" default = 0 enum = "direct color1" "direct color2" "gradient" endparam float param cscale caption = "Color scale" default = 1.0 endparam float param rot caption = "Color rotation" default = 0 min = 0 max = 1 endparam param cfun caption = "Color Function" default = 0 enum = "Linear" "Sqr" "Sqrt" "Cube" "Cuberoot" "Log" "Exp" "Sin" "ArcTan" endparam } class Monnier_SFBM_II_TextureC(common.ulb:ColorTrap) { ; This is an fBm color texture upon Sam Monnier's S.F.B.M. II ucl
; Used with his permission.
public: import "common.ulb" ; constructor func Monnier_SFBM_II_TextureC(Generic pparent) ColorTrap.ColorTrap(pparent) endfunc ; call this before each sequence of values to be trapped func Init(complex pz) ColorTrap.Init(pz) if !@init z = 0 zc1 = 0 zc2 = 0 zc3 = 0 zc4 = 0 i = 0 j = 0 jmax = 0 niter = 0 a = 0 sum = 0 x = 0 y = 0 d1 = 0 d2 = 0 d3 = 0 d4 = 0 nindex = 0 sindex = 0 scale = 1 cr1r = 0 cr1i = 0 cr2r = 0 cr2i = 0 cr3r = 0 cr3i = 0 cr4r = 0 cr4i = 0 crp1 = 0 crp2 = 0 crp3 = 0 crp4 = 0 norm = 1 if @interp == 0 niter = ceil(real(log(real(@fmm)-imag(@fmm))/log(1+@mstep))) else niter = ceil((real(@fmm)-imag(@fmm))/@mstep) endif if @mode == 0 jmax = 1 else jmax = 5 endif endif endfunc ; call for each iterated point color func Iterate(complex pz) ColorTrap.Iterate(pz) if @init z = 0 zc1 = 0 zc2 = 0 zc3 = 0 zc4 = 0 i = 0 j = 0 jmax = 0 niter = 0 a = 0 sum = 0 x = 0 y = 0 d1 = 0 d2 = 0 d3 = 0 d4 = 0 nindex = 0 sindex = 0 scale = 1 cr1r = 0 cr1i = 0 cr2r = 0 cr2i = 0 cr3r = 0 cr3i = 0 cr4r = 0 cr4i = 0 crp1 = 0 crp2 = 0 crp3 = 0 crp4 = 0 norm = 1 if @interp == 0 niter = ceil(real(log(real(@fmm)-imag(@fmm))/log(1+@mstep))) else niter = ceil((real(@fmm)-imag(@fmm))/@mstep) endif if @mode == 0 jmax = 1 else jmax = 5 endif endif while j < jmax z = pz/@size if @mode == 1 || @mode == 2 if j == 0 a = @cbl + @ctl + @cbr + @ctr + @cc;/20 elseif j == 1 z = z + @eps*(-1,-1) a = -@cbl elseif j == 2 z = z + @eps*(-1,1) a = -@ctl elseif j == 3 z = z + @eps*(1,-1) a = -@cbr elseif j == 4 z = z + @eps*(1,1) a = -@ctr endif else a = 1 endif j = j + 1 i = 0 while i < niter + 2 if i == 2 if @pptype == 0 z = (real(@pp)*(1/sqrt(imag(@ppp))*x + 1i*sqrt(imag(@ppp))*y)^real(@ppp)+(1-real(@pp))*z)*imag(@pp) else z = (real(@pp)*x^real(@ppp)*exp(imag(@ppp)*1i*y)+(1-real(@pp))*z)*imag(@pp) endif elseif i == 0 z = z/imag(@pp) endif z = z*exp(1i*pi/180*@rot) + 1 - 2i if i > 1 if @interp == 0 scale = (1+@mstep)^(i-2)*imag(@fmm) else scale = real(@fmm)-(i-1)*(@mstep+.001) endif endif i = i + 1 zc = round(scale*z)/scale zc1 = zc + (.5,.5)/scale zc2 = zc + (-.5,.5)/scale zc3 = zc + (.5,-.5)/scale zc4 = zc + (-.5,-.5)/scale cr1r = ((real(zc1)-859-i)^5 % (132+i) - (imag(zc1)+328+i)^3 % (113+i))^2 %2 - 1 if @noise != 6 && @noise != 8 && @noise != 10 && @noise != 12 && @noise != 14 cr2r = ((real(zc2)-859-i)^5 % (132+i) - (imag(zc2)+328+i)^3 % (113+i))^2 %2 - 1 cr3r = ((real(zc3)-859-i)^5 % (132+i) - (imag(zc3)+328+i)^3 % (113+i))^2 %2 - 1 cr4r = ((real(zc4)-859-i)^5 % (132+i) - (imag(zc4)+328+i)^3 % (113+i))^2 %2 - 1 endif if @noise == 0 || @noise == 5 cr1i = ((real(zc1)-465+i)^3 % (120+i) - (imag(zc1)-756+i)^2 % (107+i))^2 %2 - 1 cr2i = ((real(zc2)-465+i)^3 % (120+i) - (imag(zc2)-756+i)^2 % (107+i))^2 %2 - 1 cr3i = ((real(zc3)-465+i)^3 % (120+i) - (imag(zc3)-756+i)^2 % (107+i))^2 %2 - 1 cr4i = ((real(zc4)-465+i)^3 % (120+i) - (imag(zc4)-756+i)^2 % (107+i))^2 %2 - 1 endif if @noise == 0 v1 = (z - zc1)*scale v2 = (z - zc2)*scale v3 = (z - zc3)*scale v4 = (z - zc4)*scale crp1 = cr1r*real(v1) + cr1i*imag(v1) crp2 = cr2r*real(v2) + cr2i*imag(v2) crp3 = cr3r*real(v3) + cr3i*imag(v3) crp4 = cr4r*real(v4) + cr4i*imag(v4) elseif @noise == 1 crp1 = cr1r crp2 = cr1r crp3 = cr1r crp4 = cr1r norm = .5 elseif @noise == 2 crp1 = cr1r crp2 = cr2r crp3 = cr1r crp4 = cr2r norm = .5 elseif @noise == 3 crp1 = cr1r crp2 = cr2r crp3 = cr3r crp4 = cr2r norm = .5 elseif @noise == 4 crp1 = -cr1r crp2 = cr2r crp3 = cr3r crp4 = -cr4r norm = .5 elseif @noise == 5 crp1 = cr1r*abs(real(z-zc)*scale)^real(@noisep) + cr1i*abs(imag(z-zc)*scale)^imag(@noisep) crp2 = cr2r*abs(real(z-zc)*scale)^real(@noisep) + cr2i*abs(imag(z-zc)*scale)^imag(@noisep) crp3 = cr3r*abs(real(z-zc)*scale)^real(@noisep) + cr3i*abs(imag(z-zc)*scale)^imag(@noisep) crp4 = cr4r*abs(real(z-zc)*scale)^real(@noisep) + cr4i*abs(imag(z-zc)*scale)^imag(@noisep) norm = .2 elseif @noise == 6 crp1 = (cabs(z-zc)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 7 crp1 = cr1r*(cabs(z-zc)*scale-imag(@noisep))^real(@noisep) crp2 = cr2r*(cabs(z-zc)*scale-imag(@noisep))^real(@noisep) crp3 = cr3r*(cabs(z-zc)*scale-imag(@noisep))^real(@noisep) crp4 = cr4r*(cabs(z-zc)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 8 arg = atan2(z-zc) arg = -round(arg/(2*pi)*4)/4*(2*pi) ztest = (z-zc)*exp(1i*arg) crp1 = (real(ztest)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 9 arg = atan2(z-zc) arg = -round(arg/(2*pi)*4)/4*(2*pi) ztest = (z-zc)*exp(1i*arg) crp1 = cr1r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp2 = cr2r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp3 = cr3r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp4 = cr4r*(real(ztest)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 10 arg = atan2(z-zc) arg = -round(arg/(2*pi)*8)/8*(2*pi) ztest = (z-zc)*exp(1i*arg) crp1 = (real(ztest)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 11 arg = atan2(z-zc) arg = -round(arg/(2*pi)*8)/8*(2*pi) ztest = (z-zc)*exp(1i*arg) crp1 = cr1r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp2 = cr2r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp3 = cr3r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp4 = cr4r*(real(ztest)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 12 ztest = z - zc if real(cr1r) > 0 d1 = abs(cabs(ztest*scale+(.5,.5))-.5) d2 = abs(cabs(ztest*scale-(.5,.5))-.5) if d2 < d1 d1 = d2 endif else d1 = abs(cabs(ztest*scale+(.5,-.5))-.5) d2 = abs(cabs(ztest*scale-(.5,-.5))-.5) if d2 < d1 d1 = d2 endif endif crp1 = d1^real(@noisep) norm = .4 elseif @noise == 13 ztest = z - zc if real(cr1r) > 0 d1 = abs(cabs(ztest*scale+(.5,.5))-.5) d2 = abs(cabs(ztest*scale-(.5,.5))-.5) if d2 < d1 d1 = d2 endif else d1 = abs(cabs(ztest*scale+(.5,-.5))-.5) d2 = abs(cabs(ztest*scale-(.5,-.5))-.5) if d2 < d1 d1 = d2 endif endif crp1 = cr1r*(d1^real(@noisep)-imag(@noisep)) crp2 = cr2r*(d1^real(@noisep)-imag(@noisep)) crp3 = cr3r*(d1^real(@noisep)-imag(@noisep)) crp4 = cr4r*(d1^real(@noisep)-imag(@noisep)) norm = .4 elseif @noise == 14 ztest = (z - zc)*scale if real(cr1r) > 0 d1 = abs(real(ztest) - imag(ztest) -.5) d2 = abs(real(ztest) - imag(ztest) +.5) if d2 < d1 d1 = d2 endif else d1 = abs(real(ztest) + imag(ztest) -.5) d2 = abs(real(ztest) + imag(ztest) +.5) if d2 < d1 d1 = d2 endif endif crp1 = d1^real(@noisep) norm = .4 elseif @noise == 15 ztest = (z - zc)*scale if real(cr1r) > 0 d1 = abs(real(ztest) - imag(ztest) -.5) d2 = abs(real(ztest) - imag(ztest) +.5) if d2 < d1 d1 = d2 endif else d1 = abs(real(ztest) + imag(ztest) -.5) d2 = abs(real(ztest) + imag(ztest) +.5) if d2 < d1 d1 = d2 endif endif crp1 = cr1r*(d1^real(@noisep)-imag(@noisep)) crp2 = cr2r*(d1^real(@noisep)-imag(@noisep)) crp3 = cr3r*(d1^real(@noisep)-imag(@noisep)) crp4 = cr4r*(d1^real(@noisep)-imag(@noisep)) norm = .4 elseif @noise == 16 endif if @noise == 6 || @noise == 8 || @noise == 10 || @noise == 12 || @noise == 14 nindex = crp1 else d1 = real(z - zc)*scale + 0.5 d2 = (1 - d1) d3 = imag(z - zc)*scale + 0.5 d4 = (1 - d3) d1 = (.5 + .5*sin(pi*d1-pi/2))^@power d2 = (.5 + .5*sin(pi*d2-pi/2))^@power d3 = (.5 + .5*sin(pi*d3-pi/2))^@power d4 = (.5 + .5*sin(pi*d4-pi/2))^@power nindex = crp1*d1*d3 + crp3*d1*d4 + crp2*d2*d3 + crp4*d2*d4 endif if @f1 == 1 nindex = real(sin(100*real(@fp1)*nindex+imag(@fp1)))/10 elseif @f1 == 2 nindex = real(@fp1)*10*nindex+2+imag(@fp1) if abs(nindex) > 1 nindex = 1 endif nindex = real(asin(nindex))/4 elseif @f1 == 3 nindex = 20*real(@fp1)*nindex+1+imag(@fp1) if abs(nindex) > 1 nindex = 1 endif nindex = real(acos(nindex))/4 elseif @f1 == 4 nindex = real(atanh(20*real(@fp1)*nindex+imag(@fp1)))/8 elseif @f1 == 5 nindex = (20*nindex+imag(@fp1))^(2+real(@fp1))/160 elseif @f1 == 6 nindex = real((15*nindex+imag(@fp1))^(.1*real(@fp1))) elseif @f1 == 7 nindex = real(exp(10*real(@fp1)*nindex+imag(@fp1)-.5))/8 elseif @f1 == 8 nindex = real(round(5*real(@fp1)*nindex+imag(@fp1)/5))/4 elseif @f1 == 9 nindex = real(round(15*real(@fp1)*nindex+imag(@fp1)/5)^.1)/3 elseif @f1 == 10 nindex = (sin(5*sqrt(real(@fp1))*(real(z)+(4+imag(@fp1))*nindex))+cos(5*1/sqrt(real(@fp1))*(imag(z)+(4+imag(@fp1))*nindex)))/15 endif if @f2 == 1 nindex = real(sin(100*real(@fp2)*nindex+imag(@fp2)))/10 elseif @f2 == 2 nindex = real(@fp2)*10*nindex+2+imag(@fp2) if abs(nindex) > 1 nindex = 1 endif nindex = real(asin(nindex))/4 elseif @f2 == 3 nindex = 20*real(@fp2)*nindex+1+imag(@fp2) if abs(nindex) > 1 nindex = 1 endif nindex = real(acos(nindex))/4 elseif @f2 == 4 nindex = real(atanh(20*real(@fp2)*nindex+imag(@fp2)))/8 elseif @f2 == 5 nindex = (20*nindex+imag(@fp2))^(2+real(@fp2))/160 elseif @f2 == 6 nindex = real((15*nindex+imag(@fp2))^(.1*real(@fp2))) elseif @f2 == 7 nindex = real(exp(10*real(@fp2)*nindex+imag(@fp2)-.5))/8 elseif @f2 == 8 nindex = real(round(5*real(@fp2)*nindex+imag(@fp2)/5))/4 elseif @f2 == 9 nindex = real(round(15*real(@fp2)*nindex+imag(@fp2)/5)^.1)/3 elseif @f2 == 10 nindex = (sin(5*sqrt(real(@fp2))*(real(z)+(4+imag(@fp2))*nindex))+cos(5*1/sqrt(real(@fp2))*(imag(z)+(4+imag(@fp2))*nindex)))/15 endif nindex = real(nindex^@power2) if i == 1 x = nindex elseif i == 2 y = nindex else sindex = sindex + nindex/scale^@beta endif endwhile if @mode != 2 sum = sum + a*sindex else sum = sum + a*abs(sindex) endif sindex = 0 scale = 1 endwhile if @mode == 2 sum = 3*abs(sum) endif if @mode == 1 sindex = sum/(10*@eps*(abs(@cbl + @ctl + @cbr + @ctr)+1)) else sindex = sum endif if @interp == 0 d = 2*norm*sindex/(niter)^.5 else d = .4*norm*sindex endif color pat = rgba(0,0,0,0) if @flavorp == 0 pz = exp(flip(2 * #pi * sqrt(2) * d)) pat = compose(@pattern1,@pattern2,real(pz)/cabs(pz) * @strength) elseif @flavorp == 1 pat = compose(@pattern1,@pattern2,abs(d)*@strength) elseif @flavorp == 2 pz = exp(flip(2 * #pi * sqrt(2) * d)) * @strength pat = compose(gradient((cabs(pz)% @pmod)/@pmod),gradient((2*abs(sum)%@pmod)/@pmod),real(pz)/cabs(pz)) endif return pat endfunc protected: complex z complex zc1 complex zc2 complex zc3 complex zc4 int i int j int jmax int niter float a float sum float x float y float d1 float d2 float d3 float d4 float nindex float sindex float scale float cr1r float cr1i float cr2r float cr2i float cr3r float cr3i float cr4r float cr4i float crp1 float crp2 float crp3 float crp4 float norm float d default: title = "Monnier's SFBM II Coloring Texture" int param v_monniersfbmc caption = "Version (Monnier's S.F.B.M. II Coloring Texture)" 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_monniersfbmc < 100 endparam param init caption = "Init with each iter" default = true endparam param noise caption = "Noise Function" default = 0 enum = "Perlin" "Raw Gird" "Strips" "Corners" "Checkerboard" \ "Soft Gird" "Circles" "Soft Circles" "Squares" "Soft Squares" \ "Octogons" "Soft Octogons" "Roundy Truchet" "Soft Roundy Truchet" \ "Squarry Truchet" "Soft Squarry Truchet" endparam heading caption = "Coloring parameters and Flavors" endheading color param pattern1 caption = "Color 1" default = rgb(0.66,0.29,0.1) visible = @flavorp != "gradient" endparam color param pattern2 caption = "Color 2" default = rgb(0.89,0.84,0.30) visible = @flavorp != "gradient" endparam param flavorp caption = "Coloring flavor" default = 0 enum = "0" "1" "gradient" endparam float param strength caption = "Color strength" default = 1.0 endparam int param pmod caption = "Color modulus" default = 2 visible = @flavorp == "gradient" endparam heading caption = "SFBM parameters" endheading param noisep caption = "Noise F. Parameters" default = (.2,.5) hint = "Noise Function Parameters" endparam param f1 caption = "flavor 1" default = 0 enum = "Original" "Wavy" "Blobs" "Cut" "Messy" "Soft I" "Strings" "Soft II" "Sharp" "String-Sharp" "Random Phase" endparam param fp1 caption = "flavor 1 Parameters" default = (1,0) hint = "flavor 1 Parameters" endparam param f2 caption = "flavor 2" default = 0 enum = "Original" "Wavy" "Blobs" "Cut" "Messy" "Soft I" "Strings" "Soft II" "Sharp" "String-Sharp" "Random Phase" endparam param fp2 caption = "flavor 2 Parameters" default = (1,0) hint = "flavor 2 Parameters" endparam param mode caption = "Mode" default = 0 enum = "Normal" "Convolution" "Absolute Convolution" endparam param beta caption = "Beta (Spectral Density Parameter)" default = 1.0 hint = "Spectral Density Exponent" endparam param power caption = "Power" default = 2.0 endparam param power2 caption = "Post-Power" default = 1.0 endparam param pp caption = "Pre-Processing" default = (0,1) endparam param pptype caption = "Pre-Processing Type" default = 0 enum = "Cartesian" "Polar" hint = "Pre-Processing Type" endparam param ppp caption = "Pre-P. Power and Aspect" default = (1,1) hint = "Pre-Processing Power and Aspect" endparam param size caption = "Pattern Size" default = 0.1 endparam param rot caption = "Rotation Step" default = 28.0 endparam param mstep caption = "Frequency Separation" default = 1.0 hint = "Frequency Separation" endparam param fmm caption = "Inv. of max/min Frequency" default = (40,1) hint = "Inverse of max/min Frequency" endparam param interp caption = "Frequency Interpolation" default = 0 enum = "Logarithmic" "Linear" hint = "Frequency Interpolation" endparam param cc caption = "Center Extra Weight" default = 0.0 endparam param cbl caption = "Bottom Left Weight" default = 1.0 endparam param ctl caption = "Top Left Weight" default = 0.0 endparam param cbr caption = "Bottom Right Weight" default = 0.0 endparam param ctr caption = "Top Right Weight" default = 0.0 endparam param eps caption = "Epsilon" default = 0.006 endparam } class REB_ColorTrapModPerlin(common.ulb:ColorTrap) { ; This is a Perlin coloring texture based upon the code of Damien Jones.
;

; Provides Perlin coloring using either a binary coloring mix or a gradient. public: import "common.ulb" ; constructor func REB_ColorTrapModPerlin(Generic pparent) ColorTrap.ColorTrap(pparent) endfunc ; call for each iterated point color func Iterate(complex pz) ColorTrap.Iterate(pz) int p[514] float g3[514, 3] int i = 0 int j = 0 int k = 0 int seed = @seed pz = pz*@scale while i < 256 p[i] = i j = 0 while j < 3 seed = random(seed) g3[i, j] = seed % 256 j = j + 1 endwhile float t0 = g3[i, 0] float t1 = g3[i, 1] float t2 = g3[i, 2] float s = sqrt(t0 * t0 + t1 * t1 + t2 * t2) g3[i, 0] = g3[i, 0] / s g3[i, 1] = g3[i, 1] / s g3[i, 2] = g3[i, 2] / s i = i + 1 endwhile i = 0 while i < 256 k = p[i] j = abs(seed) % 256 seed = random(seed) p[i] = p[j] p[j] = k i = i + 1 endwhile i = 0 while i < 256 p[256 + i] = p[i] j = 0 while j < 3 g3[256 + i , j] = g3[i, j]; j = j + 1 endwhile i = i + 1 endwhile int iter = 0 float sum = 0 float amplitude = 1.0, r = (0,1) ^ (1/3) while iter < @octaves float t = real(pz) % 4096 + 4096 int bx0 = floor(t) % 256 int bx1 = (bx0 + 1) % 256 float rx0 = t - floor(t) float rx1 = rx0 - 1 t = imag(pz) % 4096 + 4096 int by0 = floor(t) % 256 int by1 = (by0 + 1) % 256 float ry0 = t - floor(t) float ry1 = ry0 - 1 t = 4096 int bz0 = floor(t) % 256 int bz1 = (bz0 + 1) % 256 float rz0 = t - floor(t) float rz1 = rz0 - 1 int ii = p[bx0] int jj = p[bx1] int b00 = p[ii + by0] int b10 = p[jj + by0] int b01 = p[ii + by1] int b11 = p[jj + by1] float t = (rx0 * rx0 * (3.0 - 2.0 * rx0)) float sy = (ry0 * ry0 * (3.0 - 2.0 * ry0)) float sz = (rz0 * rz0 * (3.0 - 2.0 * rz0)) float u = (rx0 * g3[b00 + bz0, 0] + ry0 * g3[b00 + bz0, 1] + rz0 * g3[b00 + bz0, 2]) float v = (rx1 * g3[b10 + bz0, 0] + ry0 * g3[b10 + bz0, 1] + rz0 * g3[b10 + bz0, 2]) float a = (u + t * (v - u)) u = (rx0 * g3[b01 + bz0, 0] + ry1 * g3[b01 + bz0, 1] + rz0 * g3[b01 + bz0, 2]) v = (rx1 * g3[b11 + bz0, 0] + ry1 * g3[b11 + bz0, 1] + rz0 * g3[b11 + bz0, 2]) float b = (u + t * (v - u)) float c = (a + sy * (b - a)) u = (rx0 * g3[b00 + bz1, 0] + ry0 * g3[b00 + bz1, 1] + rz1 * g3[b00 + bz1, 2]) v = (rx1 * g3[b10 + bz1, 0] + ry0 * g3[b10 + bz1, 1] + rz1 * g3[b10 + bz1, 2]) a = (u + t * (v - u)) u = (rx0 * g3[b01 + bz1, 0] + ry1 * g3[b01 + bz1, 1] + rz1 * g3[b01 + bz1, 2]) v = (rx1 * g3[b11 + bz1, 0] + ry1 * g3[b11 + bz1, 1] + rz1 * g3[b11 + bz1, 2]) b = (u + t * (v - u)) float d = (a + sy *(b - a)) sum = sum + real(@fun(c + sz *(d - c))) * amplitude amplitude = amplitude * @persistence pz = pz * r / @nfactorp iter = iter + 1 endwhile color pat = rgba(0,0,0,0) if @flavorp == 0 pz = exp(flip(2 * #pi * sqrt(2) * sum)) pat = compose(@pattern1,@pattern2,real(pz)/cabs(pz) * @strength) elseif @flavorp == 1 pat = compose(@pattern1,@pattern2,abs(sum)*@strength) elseif @flavorp == 2 pz = exp(flip(2 * #pi * sqrt(2) * sum)) * @strength pat = compose(gradient((cabs(pz)% @pmod)/@pmod),gradient((2*abs(sum)%@pmod)/@pmod),real(pz)/cabs(pz)) endif return pat endfunc default: title = "Modified Perlin Colors" int param v_colortrapmodperlin caption = "Version (Color Trap Modified Perlin Colors)" default = 101 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_colortrapmodperlin < 101 endparam color param pattern1 caption = "Color 1" default = rgb(0.66,0.29,0.1) visible = @flavorp != "gradient" endparam color param pattern2 caption = "Color 2" default = rgb(0.89,0.84,0.30) visible = @flavorp != "gradient" endparam param flavorp caption = "Perlin flavor" default = 0 enum = "0" "1" "gradient" endparam int param pmod caption = "Color modulus" default = 8 visible = @flavorp == "gradient" endparam param octaves caption = "Octaves" default = 7 min = 1 endparam param persistence caption = "Persistence" default = 0.5 endparam float param nfactorp caption = "Noise Factor" default = 0.5 endparam func fun caption = "Noise Function" default = ident() endfunc param scale caption = "Scale" default = 10.0 endparam float param strength caption = "Strength" default = 1.0 endparam param @seed caption = "Random Seed" default = 1234567 endparam } class REB_ColorTrapWorley(common.ulb:ColorTrap) { ; This is a coloring texture based upon the code of Stephen Worley.
;

; Provides Worley coloring using either a binary coloring mix or a gradient. Additional ; distance and fractal modes have been added. public: import "common.ulb" import "jlb.ulb" ; constructor func REB_ColorTrapWorley(Generic pparent) ColorTrap.ColorTrap(pparent) rndi = new JLB_Random(0) rndi.init(@seed) rndi.setnmax(5000) endfunc ; call for each iterated point color func Iterate(complex pz) ColorTrap.Iterate(pz) complex fz[10] complex fzc[10] complex fzz[10] float dst[10] float dst2[10] complex fzc1[10] complex fzc2[10] complex fzc3[10] complex fzc4[10] float dist = 1e20 float dist2 = 1e20 complex cells[12,10] float distance = 0 float test = 0 float sum = 0 float a = 1 complex diff = 0 int rnds[24] float fac[10] float rp[12,10] float ip[12,10] int i = 1 int j = 0 int jmax = 0 rnds[0] = rndi.RandomIntInRange(@seed) while i < 24 rnds[i] = rndi.RandomIntInRange(0) i = i + 1 endwhile i = 0 fac[0] = 1 while i < 10 dst[i] = 1e10 dst2[i] = 1e10 if i > 0 fac[i] = fac[i-1]*(i+1) endif i = i + 1 endwhile complex near = 0 complex fnear[10] if @mode == 0 jmax = 1 else jmax = 5 endif if @type == "Mosaic" jmax = 1 endif while j < jmax if @v_colortrapworley < 102 complex z = pz/@psize else complex z = (pz+(10,10))/@psize endif if @mode == 1 || @mode == 2 if j == 0 a = @cbl + @ctl + @cbr + @ctr + @cc;/20 elseif j == 1 z = z + @eps*(-1,-1) a = -@cbl elseif j == 2 z = z + @eps*(-1,1) a = -@ctl elseif j == 3 z = z + @eps*(1,-1) a = -@cbr elseif j == 4 z = z + @eps*(1,1) a = -@ctr endif else a = 1 endif j = j + 1 int f = 0 repeat if @nfrac == "2^x" fz[f] = z*2^f elseif @nfrac == "exp(x)" fz[f] = z*exp(f) elseif @nfrac == "cosh(x)" fz[f] = z*cosh(f) elseif @nfrac == "cos(x)" fz[f] = z*cos(f) elseif @nfrac == "sec(x)" fz[f] = z/cos(f) elseif @nfrac == "sech(x)" fz[f] = z/cosh(f) elseif @nfrac == "factorial(x+1)" fz[f] = z*fac[f] endif fzc[f] = round(fz[f]) fzz[f] = fz[f] - fzc[f] ; create the grid fzc1[f] = fzc[f] + (1,1)/2 fzc2[f] = fzc[f] + (1,-1)/2 fzc3[f] = fzc[f] + (-1,1)/2 fzc4[f] = fzc[f] + (-1,-1)/2 ; create the random points ; cell 1 rp[0,f] = ((real(fzc1[f])-rnds[0])^5%rnds[6] - (imag(fzc1[f])+rnds[12])^3%rnds[18])^2 %2 - 1 ip[0,f] = ((real(fzc1[f])-rnds[1])^5%rnds[7] - (imag(fzc1[f])+rnds[13])^3%rnds[19])^2 %2 - 1 rp[1,f] = ((real(fzc1[f])-rnds[2])^5%rnds[8] - (imag(fzc1[f])+rnds[14])^3%rnds[20])^2 %2 - 1 ip[1,f] = ((real(fzc1[f])-rnds[3])^5%rnds[8] - (imag(fzc1[f])+rnds[15])^3%rnds[21])^2 %2 - 1 rp[2,f] = ((real(fzc1[f])-rnds[4])^5%rnds[10] - (imag(fzc1[f])+rnds[16])^3%rnds[22])^2 %2 - 1 ip[2,f] = ((real(fzc1[f])-rnds[5])^5%rnds[11] - (imag(fzc1[f])+rnds[17])^3%rnds[23])^2 %2 - 1 ; cell 2 rp[3,f] = ((real(fzc2[f])-rnds[0])^5%rnds[6] - (imag(fzc2[f])+rnds[12])^3%rnds[18])^2 %2 - 1 ip[3,f] = ((real(fzc2[f])-rnds[1])^5%rnds[7] - (imag(fzc2[f])+rnds[13])^3%rnds[19])^2 %2 - 1 rp[4,f] = ((real(fzc2[f])-rnds[2])^5%rnds[8] - (imag(fzc2[f])+rnds[14])^3%rnds[20])^2 %2 - 1 ip[4,f] = ((real(fzc2[f])-rnds[3])^5%rnds[8] - (imag(fzc2[f])+rnds[15])^3%rnds[21])^2 %2 - 1 rp[5,f] = ((real(fzc2[f])-rnds[4])^5%rnds[10] - (imag(fzc2[f])+rnds[16])^3%rnds[22])^2 %2 - 1 ip[5,f] = ((real(fzc2[f])-rnds[5])^5%rnds[11] - (imag(fzc2[f])+rnds[17])^3%rnds[23])^2 %2 - 1 ; cell 3 rp[6,f] = ((real(fzc3[f])-rnds[0])^5%rnds[6] - (imag(fzc3[f])+rnds[12])^3%rnds[18])^2 %2 - 1 ip[6,f] = ((real(fzc3[f])-rnds[1])^5%rnds[7] - (imag(fzc3[f])+rnds[13])^3%rnds[19])^2 %2 - 1 rp[7,f] = ((real(fzc3[f])-rnds[2])^5%rnds[8] - (imag(fzc3[f])+rnds[14])^3%rnds[20])^2 %2 - 1 ip[7,f] = ((real(fzc3[f])-rnds[3])^5%rnds[8] - (imag(fzc3[f])+rnds[15])^3%rnds[21])^2 %2 - 1 rp[8,f] = ((real(fzc3[f])-rnds[4])^5%rnds[10] - (imag(fzc3[f])+rnds[16])^3%rnds[22])^2 %2 - 1 ip[8,f] = ((real(fzc3[f])-rnds[5])^5%rnds[11] - (imag(fzc3[f])+rnds[17])^3%rnds[23])^2 %2 - 1 ; cell 4 rp[9,f] = ((real(fzc4[f])-rnds[0])^5%rnds[6] - (imag(fzc4[f])+rnds[12])^3%rnds[18])^2 %2 - 1 ip[9,f] = ((real(fzc4[f])-rnds[1])^5%rnds[7] - (imag(fzc4[f])+rnds[13])^3%rnds[19])^2 %2 - 1 rp[10,f] = ((real(fzc4[f])-rnds[2])^5%rnds[8] - (imag(fzc4[f])+rnds[14])^3%rnds[20])^2 %2 - 1 ip[10,f] = ((real(fzc4[f])-rnds[3])^5%rnds[8] - (imag(fzc4[f])+rnds[15])^3%rnds[21])^2 %2 - 1 rp[11,f] = ((real(fzc4[f])-rnds[4])^5%rnds[10] - (imag(fzc4[f])+rnds[16])^3%rnds[22])^2 %2 - 1 ip[11,f] = ((real(fzc4[f])-rnds[5])^5%rnds[11] - (imag(fzc4[f])+rnds[17])^3%rnds[23])^2 %2 - 1 ; put into the grids cells[0,f] = (rp[0,f] + flip(ip[0,f]) + (1,1))/2 cells[1,f] = (rp[1,f] + flip(ip[1,f]) + (1,1))/2 cells[2,f] = (rp[2,f] + flip(ip[2,f]) + (1,1))/2 cells[3,f] = (rp[3,f] + flip(ip[3,f]) + (1,-1))/2 cells[4,f] = (rp[4,f] + flip(ip[4,f]) + (1,-1))/2 cells[5,f] = (rp[5,f] + flip(ip[5,f]) + (1,-1))/2 cells[6,f] = (rp[6,f] + flip(ip[6,f]) + (-1,1))/2 cells[7,f] = (rp[7,f] + flip(ip[7,f]) + (-1,1))/2 cells[8,f] = (rp[8,f] + flip(ip[8,f]) + (-1,1))/2 cells[9,f] = (rp[9,f] + flip(ip[9,f]) + (-1,-1))/2 cells[10,f] = (rp[10,f] + flip(ip[10,f]) + (-1,-1))/2 cells[11,f] = (rp[11,f] + flip(ip[11,f]) + (-1,-1))/2 i = 0 while i < 12 diff = fzz[f] - cells[i,f] if @flavor == "Euclidian" test = cabs(diff) elseif @flavor == "Manhattan" test = (abs(real(diff))^real(@mp) + abs(imag(diff))^imag(@mp)) elseif @flavor == "Chebychev" if abs(real(diff)) > abs(imag(diff)) test = abs(real(diff)) else test = abs(imag(diff)) endif elseif @flavor == "Minkovsky" test = (abs(real(diff))^@ex + abs(imag(diff))^@ex)^(1/@ex) elseif @flavor == "Exp/Log Manhattan" test = log(exp(abs(real(diff))) + exp(abs(imag(diff)))) endif if test < dst[f] dst2[f] = dst[f] dst[f] = test fnear[f] = fzc[f] + cells[i,f] elseif test < dst2[f] dst2[f] = test endif i = i + 1 endwhile i = 0 f = f + 1 until (f-1) == @fmax f = 0 repeat if f == 0 dist = dst[0] dist2 = dst2[0] near = fnear[0] else if @nfrac == "2^x" dist = dist + 2^(-f)*dst[f] dist2 = dist2 + 2^(-f)*dst2[f] near = near + 2^(-f)*fnear[f] elseif @nfrac == "exp(x)" dist = dist + exp(-f)*dst[f] dist2 = dist2 + exp(-f)*dst2[f] near = near + exp(-f)*fnear[f] elseif @nfrac == "cosh(x)" dist = dist + 1/cosh(f)*dst[f] dist2 = dist2 + 1/cosh(f)*dst2[f] near = near + 1/cosh(f)*fnear[f] elseif @nfrac == "cos(x)" dist = dist + 1/cos(f)*dst[f] dist2 = dist2 + 1/cos(f)*dst2[f] near = near + 1/cos(f)*fnear[f] elseif @nfrac == "sec(x)" dist = dist + cos(f)*dst[f] dist2 = dist2 + cos(f)*dst2[f] near = near + cos(f)*fnear[f] elseif @nfrac == "sech(x)" dist = dist + cosh(f)*dst[f] dist2 = dist2 + cosh(f)*dst2[f] near = near + cosh(f)*fnear[f] elseif @nfrac == "factorial(x+1)" dist = dist + 1/fac[f]*dst[f] dist2 = dist2 + 1/fac[f]*dst2[f] near = near + 1/fac[f]*fnear[f] endif endif f = f + 1 until (f-1) == @fmax if @type == "Distance" distance = dist^@thick elseif @type == "2nd Distance" distance = (@smod*dist2-dist)^@thick elseif @type == "2nd Distance variant" distance = dist2^@thick elseif @type == "Mosaic" distance = cabs(1000*near) + 1000*atan(cabs(near)+#pi)%1 endif if @mode != 2 sum = sum + a*distance else sum = sum + a*abs(distance) endif distance = 0 endwhile if @mode == 2 sum = 3*abs(sum) endif if @mode == 1 distance = sum/(10*@eps*(abs(@cbl + @ctl + @cbr + @ctr)+1)) else distance = sum endif if @dmod != 0 distance = distance*@dmod endif if @type != "Mosaic" if @invert distance = abs(1-distance) endif else distance = distance % 1 endif color pat = rgba(0,0,0,0) pz = exp(flip(2 * #pi * sqrt(2) * distance)) float cindex = (@cscale*(cabs(@cfn(real(pz)/cabs(pz))))+ @rot) % 1 if @v_colortrapworley >= 103 if @flavorpn == 0 if @intype == "Bicolor" pat = compose(@pattern1,@pattern2,abs(real(pz))/cabs(pz) * @strength) else if cindex >= 0 && cindex < 0.25 pat = blend(@pattern1,@pattern2,cindex/0.25) elseif cindex >= 0.25 && cindex < 0.5 pat = blend(@pattern2,@pattern3,(cindex-0.25)/0.25) elseif cindex >= 0.5 && cindex < 0.75 pat = blend(@pattern3,@pattern4,(cindex-0.5)/0.25) elseif cindex >= 0.75 && cindex < 1.0 pat = blend(@pattern4,@pattern1,(cindex-0.75)/0.25) endif endif elseif @flavorpn == 1 pat = compose(gradient((cabs(pz)% @pmod)/@pmod),\ gradient((2*abs(distance)%@pmod)/@pmod),real(pz)/cabs(pz)) * @strength endif else if @flavorp == 0 pat = compose(@pattern1,@pattern2,abs(real(pz))/cabs(pz) * @strength) elseif @flavorp == 1 pat = compose(gradient((cabs(pz)% @pmod)/@pmod),\ gradient((2*abs(distance)%@pmod)/@pmod),real(pz)/cabs(pz)) * @strength endif endif return pat endfunc protected: JLB_Random rndi default: title = "Worley Colors" int param v_colortrapworley caption = "Version (Color Trap Worley Colors)" default = 103 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_colortrapworley < 103 endparam color param pattern1 caption = "Color 1" default = rgb(0.66,0.29,0.1) visible = @flavorp != "gradient" endparam color param pattern2 caption = "Color 2" default = rgb(0.89,0.84,0.30) visible = @flavorp != "gradient" endparam color param pattern3 caption = "Color 3" default = rgb(0.53,0.63,0.12) visible = @flavorpn != "gradient" && @intype == "Multicolor" && \ @v_colortrapworley >= 103 endparam color param pattern4 caption = "Color 4" default = rgb(0.89,0.45,0.30) visible = @flavorpn != "gradient" && @intype == "Multicolor" && \ @v_colortrapworley >= 103 endparam param intype caption = "Coloring type" default = 0 enum = "Bicolor" "Multicolor" visible = @flavorpn != "gradient" && \ @v_colortrapworley >= 103 endparam float param cscale caption = "Color scale" default = 1.0 visible = @flavorpn != "gradient" && @intype == "Multicolor" && \ @v_colortrapworley >= 103 endparam float param rot caption = "Color rotation" default = 0 min = 0 max = 1 visible = @flavorpn != "gradient" && @intype == "Multicolor" && \ @v_colortrapworley >= 103 endparam func cfn caption = "Color Function" default = ident() visible = @flavorpn != "gradient" && @intype == "Multicolor" && \ @v_colortrapworley >= 103 endfunc param flavorp caption = "Color method" default = 0 enum = "bicolor" "gradient" visible = @v_colortrapworley < 103 endparam param flavorpn caption = "Color method" default = 0 enum = "internal" "gradient" visible = @v_colortrapworley >= 103 endparam int param pmod caption = "Color modulus" default = 8 visible = @flavorp == "gradient" endparam param flavor caption = "Flavor" default = 4 enum = "Chebychev" "Euclidian" "Manhattan" "Exp/Log Manhattan" "Minkovsky" endparam float param ex caption = "Minkovsky param" default = 4 visible = @flavor == "Minkovsky" endparam complex param mp caption = "Manhattan pwr" default = (1,1) visible = @flavor == "Manhattan" endparam param type caption = "Worley type" default = 2 enum = "Distance" "2nd Distance" "2nd Distance variant" "Mosaic" endparam float param smod caption = "2nd dist mod" default = 1.0 visible = @type == "2nd Distance" endparam param psize caption = "Pattern Size" default = .15 endparam float param thick caption = "Thickness" default = 1.0 endparam float param dmod caption = "Dist modulator" default = 0.0 min = 0.0 endparam int param fmax caption = "Fractal iterations" default = 4 max = 9 endparam param nfrac caption = "Fractal function" default = 0 enum = "2^x" "factorial(x+1)" "cos(x)" "cosh(x)" "exp(x)" "sec(x)" "sech(x)" endparam bool param invert caption = "Invert" default = false visible = @type != "Mosaic" endparam int param seed caption = "Worley seed" default = 123 endparam float param strength caption = "Strength" default = 1.0 endparam param mode caption = "Mode" default = 0 enum = "Normal" "Convolution" "Absolute Convolution" visible = @type != "Mosaic" endparam param cc caption = "Center Extra Weight" default = 0.0 visible = @mode != "Normal" && @type != "Mosaic" endparam param cbl caption = "Bottom Left Weight" default = 1.0 visible = @mode != "Normal" && @type != "Mosaic" endparam param ctl caption = "Top Left Weight" default = 0.0 visible = @mode != "Normal" && @type != "Mosaic" endparam param cbr caption = "Bottom Right Weight" default = 0.0 visible = @mode != "Normal" && @type != "Mosaic" endparam param ctr caption = "Top Right Weight" default = 0.0 visible = @mode != "Normal" && @type != "Mosaic" endparam param eps caption = "Epsilon" default = 0.006 visible = @mode != "Normal" && @type != "Mosaic" endparam } class ColorTrapImageTiles(common.ulb:ColorTrap) { ; ColorTrap Wrapper for Image Import
;

; Image Import has a major defect in that many images are imported upside down. ; This ColorTrap provides the capability to rotate the image so that the original ; doesn't need to altered to be imported correctly. The image can also be scaled, ; offset and tiled. Image Import leaves a row of outside pixels without color, and ; so there is also a built-in capability to adjust the tiling. ; public: import "common.ulb" ; constructor func ColorTrapImageTiles(Generic pparent) ColorTrap.ColorTrap(pparent) m_img = new @f_image(this) m_empty = m_img.GetEmpty() endfunc ; call for each iterated point color func Iterate(complex pz) ColorTrap.Iterate(pz) color pcolor = rgba(0,0,0,0) if !m_empty complex m_zi = (0,1)^(@iangle/90.0) complex m_zs = (0,1)^(@sangle/90.0) complex pzrs = pz ; offset if !@itile pzrs = pzrs+@ioffset endif ; aspect ratio pzrs = real(pzrs) + flip(imag(pzrs)*@iaspect) ; rotation pzrs = pzrs*m_zi ; skew pzrs = real(pzrs)*m_zs + flip(imag(pzrs)) if @flipi == "horizontal" pzrs = -conj(pzrs) elseif @flipi == "vertical" pzrs = conj(pzrs) endif float width = m_img.getWidth() float height = m_img.getHeight() if @itile if @v_colortrapimagetiles >= 103 pzrs = (pzrs+500+flip(500))*@scale*500 else pzrs = (pzrs+#width/2+flip(#height/2))*@scale*#width endif complex c = @adjx-2*((real(pzrs) % (width-1))/width) + \ flip(@adjy-2*((imag(pzrs) % (height-1))/height)) pcolor = m_img.getColor(c) else pcolor = m_img.getColor(pzrs*@scale) endif endif return pcolor endfunc bool m_empty protected: ImageImport m_img int m_image_width int m_image_height float m_ratio default: title = "Color Trap Image Tiles" int param v_colortrapimagetiles caption = "Version (Color Trap Image Tiles)" default = 103 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_colortrapimagetiles < 103 endparam heading caption = "Image Parameters" endheading ImageImport param f_image caption = "Image" default = ImageImport selectable = false endparam float param scale caption = "Image scale" default = 1 min = 0 hint = "Changes the scale of the image." endparam float param adjx caption = "Tile adj x" default = 0.99 min = 0.9 max = 1.1 endparam float param adjy caption = "Tile adj y" default = 0.999 min = 0.9 max = 1.1 endparam complex param ioffset caption = "Image offset" default = (0,0) visible = !@itile endparam float param iaspect caption = "Image aspect" default = 1.0 endparam float param iangle caption = "Image rotation" default = 0 hint = "Rotates the image" endparam param flipi caption = "Flip the image" enum = "none" "horizontal" "vertical" default = 0 endparam float param sangle caption = "Image skew" default = 0 hint = "Skews the image" endparam bool param itile caption = "Tile the image" default = false endparam } class ColorTrapChecker(common.ulb:ColorTrap) { ; ColorTrap that provides checker coloring.
;

; The coloring can be bicolor or use a gradient. There are mulitiple options ; the checker patterns. public: import "common.ulb" ; constructor func ColorTrapChecker(Generic pparent) ColorTrap.ColorTrap(pparent) endfunc ; Initializes the coloring func Init(complex pz) ColorTrap.Init(pz) endfunc ; call for each iterated point color func Iterate(complex pz) ColorTrap.Iterate(pz) color pat = rgba(0,0,0,0) float x = 0 float y = 0 if @pattern == 0 float scale = @scalec/20 if @v_ColorTrapChecker < 102 pz = floor(@patfun(pz*#width*scale)) else pz = floor(@patfun(pz*640*scale)) endif int patmod = 2 if @flavorc == 0 patmod = 2 elseif @flavorc == 1 patmod = 3 elseif @flavorc == 2 patmod = 4 elseif @flavorc == 3 patmod = 5 elseif @flavorc == 4 patmod = 6 elseif @flavorc == 5 patmod = 7 elseif @flavorc == 6 patmod = 8 endif float patval = 0 x = trunc(real(@testfun(real(pz)))*@scalex) y = trunc(real(@testfun(imag(pz)))*@scaley) if @patop == "+" patval = (x + y) % patmod elseif @patop == "*" patval = (x * y) % patmod elseif @patop == "/" patval = (x / y) % patmod elseif @patop == "^" patval = (x ^ y) % patmod endif if !@cgrad if patval == 0 pat = @pattern1 else pat = @pattern2 endif else pat = gradient((patmod -1-patval)/patmod) endif elseif @pattern == 1 complex w = fn2(fn1((pz)*10^@pwr))*@ts complex ww = fn2(fn1((w - @fn6(w)))) + @toffset float t = cabs(ww)*@tc t = (t - round(t)) if !@cgrad if ceil(t) < 1 pat = @pattern1 else pat = @pattern2 endif else pat = gradient(t) endif else float zrzr = 0 float zizi = 0 float rzrz = 0 float iziz = 0 float r0r0 = 0 float i0i0 = 0 float r1r1 = 0 float i1i1 = 0 float azaz = 0 float bzbz = 0 float czcz = 0 float dzdz = 0 int iii = 0 float avav = 1 float xbxb = 1 float frfr = 0 float fifi = 0 float zaza = 0 float zzzz = 0 complex ptr = 0 complex tz = ((pz-@trxia)*@trxib)^@trxic float x = real(tz) float y = imag(tz) if @trinit == 0 ptr = (@fntx11(@fntx10(tz))^@exad10) elseif @trinit == 1 ptr = (@fntx10(real(tz))^@exad10+@fntx11(imag(tz))^@exad11) elseif @trinit == 2 ptr = (@fntx10(real(tz))^@exad10-@fntx11(imag(tz))^@exad11) elseif @trinit == 3 ptr = (@fntx10(real(tz))^@exad10*@fntx11(imag(tz))^@exad11) elseif @trinit == 4 ptr = (@fntx10(imag(tz))^@exad10-@fntx11(real(tz))^@exad11) elseif @trinit == 5 ptr = (@fntx11(@fntx10(x))^@exad10) elseif @trinit == 6 ptr = (@fntx11(@fntx10(y))^@exad10) elseif @trinit == 7 ptr = (@fntx10(x)^@exad10+@fntx11(y)^@exad11) elseif @trinit == 8 ptr = (@fntx10(x)^@exad10-@fntx11(y)^@exad11) elseif @trinit == 9 ptr = (@fntx11(y)^@exad11-@fntx10(x)^@exad10) elseif @trinit == 10 ptr = (@fntx10(x)^@exad10*@fntx11(y)^@exad11) elseif @trinit == 11 ptr = (@fntx10(x)^@exad10/@fntx11(y)^@exad11) elseif @trinit == 12 ptr = (@fntx11(y)^@exad11/@fntx10(x)^@exad10) elseif @trinit == 13 ptr = (@fntx10(x)^@exad10^@fntx11(y)^@exad11) elseif @trinit == 14 ptr = (@fntx11(y)^@exad11^@fntx10(x)^@exad10) elseif @trinit == 15 ptr = (@fntx10(x)^@exad10+@fntx11(tz)^@exad11) elseif @trinit == 16 ptr = (@fntx10(x)^@exad10-@fntx11(tz)^@exad11) elseif @trinit == 17 ptr = (@fntx11(tz)^@exad11-@fntx10(x)^@exad10) elseif @trinit == 18 ptr = (@fntx10(x)^@exad10*@fntx11(tz)^@exad11) elseif @trinit == 19 ptr = (@fntx10(x)^@exad10/@fntx11(tz)^@exad11) elseif @trinit == 20 ptr = (@fntx11(tz)^@exad11/@fntx10(x)^@exad10) elseif @trinit == 21 ptr = (@fntx10(y)^@exad10+@fntx11(tz)^@exad11) elseif @trinit == 22 ptr = (@fntx10(y)^@exad10-@fntx11(tz)^@exad11) elseif @trinit == 23 ptr = (@fntx11(tz)^@exad11-@fntx10(y)^@exad10) elseif @trinit == 24 ptr = (@fntx10(y)^@exad10*@fntx11(tz)^@exad11) elseif @trinit == 25 ptr = (@fntx10(y)^@exad10/@fntx11(tz)^@exad11) elseif @trinit == 26 ptr = (@fntx11(tz)^@exad11/@fntx10(y)^@exad10) endif zrzr = real(@fnzr(ptr))*@scc zizi = imag(@fnzi(ptr))*@scc rzrz = floor(zrzr) iziz = floor(zizi) r0r0 = rzrz - 1 i0i0 = iziz - 1 r1r1 = rzrz + 1 i1i1 = iziz + 1 azaz = cabs(@fn1tx(r0r0) + @fn2tx(i0i0)) azaz = cabs(@fn3tx(azaz)) azaz = (azaz % @shad1 * 2) bzbz = cabs(@fn1tx(r1r1) + @fn2tx(i0i0)) bzbz = cabs(@fn3tx(bzbz)) bzbz = (bzbz % @shad2 * 2) czcz = cabs(@fn1tx(r1r1) + @fn2tx(i1i1)) czcz = cabs(@fn3tx(czcz)) czcz = (czcz % @shad3 * 2) dzdz = cabs(@fn1tx(r0r0) + @fn2tx(i1i1)) dzdz = cabs(@fn3tx(dzdz)) dzdz = (dzdz % @shad4 * 2) iii = 1 repeat avav = avav / (@trp1 * 2) xbxb = xbxb / (@trp2 * 2) frfr = rzrz + avav fifi = iziz + avav zaza = (azaz + bzbz + czcz + dzdz) / (@trp3 * 4) zzzz = zzzz * xbxb + zaza if (zrzr > frfr) if (zizi > fifi) rzrz = frfr iziz = fifi azaz = zzzz else rzrz = frfr dzdz = zzzz endif else if (zizi > fifi) iziz = fifi bzbz = zzzz else czcz = zzzz endif endif iii = iii + 1 until iii >= @freq float texture_tr = (zaza-trunc(zaza*2)^@exp) if @geo_limit != 0 texture_tr = ((zaza-trunc(zaza)^@exp*2)% @geo_limit) endif if @geo_sgn == true texture_tr = abs(texture_tr) endif if !@cgrad if texture_tr*@thresh < 1 pat = @pattern2 else pat = @pattern1 endif else pat = gradient(texture_tr*@thresh) endif endif return pat endfunc default: title = "Checker Coloring" int param v_ColorTrapChecker caption = "Version (Checker Coloring)" default = 102 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_ColorTrapChecker < 102 endparam heading text = "Pattern generator which applies either generalized checker patterns, \ general textures based upon the pattern generator of Dennis Magar or \ Toby Marshall's geometrix texture." endheading param pattern caption = "Pattern type" default = 0 enum = "checker" "general" "geometrix" endparam color param pattern1 caption = "Color 1" default = rgb(0.66,0.29,0.1) visible = !@cgrad endparam color param pattern2 caption = "Color 2" default = rgb(0.89,0.84,0.30) visible = !@cgrad endparam float param scalec caption = "Scale" default = 1.0 visible = @pattern == 0 endparam float param scalex caption = "Scale X" default = 1.0 visible = @pattern == 0 endparam float param scaley caption = "Scale Y" default = 1.0 visible = @pattern == 0 endparam param flavorc caption = "Flavor" default = 0 enum = "0" "1" "2" "3" "4" "5" "6" visible = @pattern == 0 endparam param patop caption = "Pattern Operator" default = 0 enum = "+" "*" "/" "^" visible = @pattern == 0 endparam func patfun caption = "Pattern function" default = ident() visible = @pattern == 0 endfunc func testfun caption = "Scale function" default = ident() visible = @pattern == 0 endfunc bool param cgrad caption = "Use Gradient" default = false endparam param toffset caption = "Texture offset" default = (-1,-1) hint = "Changes the texture pattern." visible = @pattern == 1 endparam param ts caption = "Texture scale" default = 10.0 visible = @pattern == 1 endparam param tc caption = "Texture modifier" default = 5.0 visible = @pattern == 1 endparam param pwr caption = "Texture power" default = 0.25 visible = @pattern == 1 endparam func fn1 caption = "Texture Function 1" default = sqr() visible = @pattern == 1 endfunc func fn2 caption = "Texture Function 2" default = acos() visible = @pattern == 1 endfunc func fn6 caption = "Texture Function 3" default = round() visible = @pattern == 1 endfunc float param thresh caption = "Color threshold" default = 1 visible = @pattern == 2 endparam param trinit caption = "Geometrix Init" enum = "z""real+imag(z)""real-imag(z)""real*imag(z)""imag-real(z)" \ "x""y""x+y""x-y""y-x""x/y""x*y""y/x""x^y""y^x""x+z""x-z""z-x""x*z" \ "x/z""z/x""y+z""y-z""z-y""y*z""y/z""z/y" hint = "Determines which variable(s) initialize(s) the texture" default = 0 visible = @pattern == 2 endparam func fntx10 caption = "Init Function 1" default = ident() hint = "Modifies the 1st variable defined in \ 'Geometrix Initialization'" visible = @pattern == 2 endfunc func fntx11 caption = "Init Function 2" default = ident() hint = "Modifies the 2nd variable defined in \ 'Geometrix Initialization'" visible = @pattern == 2 endfunc complex param trxia caption = "Pattern 1" default = (0.0,0.0) visible = (@trinit < 5 || @trinit > 14 && @trinit < 21)&&@pattern == 2 endparam complex param trxib caption = "Pattern 2" default = (1.0,0.0) visible = (@trinit < 5 || @trinit > 14 && @trinit < 21)&&@pattern == 2 endparam complex param trxic caption = "Pattern 3" default = (1.0,0.0) visible = (@trinit < 5 || @trinit > 14 && @trinit < 21)&&@pattern == 2 endparam complex param exad10 caption = "Frequency 1" default = (1.0,0.0) hint = "Changes the pattern frequency by acting on the 1st (or only) \ variable defined in 'Geometrix Initialization'" visible = @pattern == 2 endparam complex param exad11 caption = "Frequency 2" default = (1.0,0.0) hint = "Changes the pattern frequency by acting on the 2nd variable \ (when present) defined in 'Geometrix Initialization'" visible = !(@trinit == 0 ||@trinit == 5 || @trinit == 6 ||\ @trinit == 21)&&@pattern == 2 endparam float param exp caption = "Contrast" default = 0.6 hint = "Higher values intensify the contrast between texture sections. If \ you find burned-out areas of texture try lowering this value" visible = @pattern == 2 endparam float param scc caption = "Density" default = 1.0 hint = "Higher values create finer detail in the texture" visible = @pattern == 2 endparam float param trp1 caption = "Scale" default = 1 hint = "Densest texture is at '1'. Try other values and increase the \ 'Density' value to achieve different texture patterns" visible = @pattern == 2 endparam float param freq caption = "Definition 1" default = 10 hint = "Works interactively with other 'Definition' params. Higher values \ yield more texture definition and/or complexity" visible = @pattern == 2 endparam float param trp2 caption = "Definition 2" default = .7 hint = "Works interactively with other 'Definition' params. Lower values \ yield more texture definition" visible = @pattern == 2 endparam float param trp3 caption = "Definition 3" default = .7 hint = "Works interactively with other 'Definition' params. Higher values \ yield more texture definition" visible = @pattern == 2 endparam float param shad1 caption = "Shading 1" default = 1 hint = "Affects the shading of certain areas of texture" visible = @pattern == 2 endparam float param shad2 caption = "Shading 2" default = 1 hint = "Affects the shading of certain areas of texture" visible = @pattern == 2 endparam float param shad3 caption = "Shading 3" default = 1 hint = "Affects the shading of certain areas of texture" visible = @pattern == 2 endparam float param shad4 caption = "Shading 4" default = 1 hint = "Affects the shading of certain areas of texture" visible = @pattern == 2 endparam func fnzr caption = "Z function 1" default = ident() visible = @pattern == 2 endfunc func fnzi caption = "Z function 2" default = ident() visible = @pattern == 2 endfunc func fn1tx caption = "Real function" default = sqrt() visible = @pattern == 2 endfunc func fn2tx caption = "Imag function" default = ident() visible = @pattern == 2 endfunc func fn3tx caption = "Overall function" default = asin() visible = @pattern == 2 endfunc float param geo_limit caption = "Geometrix Limit" default = 0.0 hint = "Low values limit texture contrast. Zero is 'off'" visible = @pattern == 2 endparam bool param geo_sgn caption = "Soften Texture" default = false visible = @pattern == 2 endparam } class ColorTrapNoColor(common.ulb:ColorTrap) { ; Placeholder for Colors public: import "common.ulb" func ColorTrapNoColor(Generic pparent) ColorTrap.ColorTrap(pparent) endfunc color func Iterate(complex pz) ColorTrap.Iterate(pz) return rgba(0,0,0,0) endfunc default: title = "No Color" int param v_colornocolor caption = "Version (No Color)" 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_colornocolor < 100 endparam } class ColorTrapGnarl(common.ulb:ColorTrap) { ; This is a Perlin coloring texture based upon the code of Mark Townsend.
;

; Provides Martin, Popcorn, Vine and Gnarl coloring using either a binary ; coloring mix or a gradient. public: import "common.ulb" ; constructor func ColorTrapGnarl(Generic pparent) ColorTrap.ColorTrap(pparent) endfunc ; call for each iterated point color func Iterate(complex pz) ColorTrap.Iterate(pz) float x = real(pz) * @scaleg float y = imag(pz) * @scaleg float xx = 0 int i = 0 while (i < @iters) xx = x if @formula == 0 ; Martin x = y - sin(x) y = @a - xx elseif @formula == 1 ; Popcorn x = x - @h * sin(y + tan(@a * y)) y = y - @h * sin(xx + tan(@a * xx)) elseif @formula == 2 ; Vine if @flavor == 0 x = x - @h * sin(y + sin(@a * y )) y = y + @h * sin(xx + sin(@a * xx)) elseif @flavor == 1 x = x - @h * sin(y^@b + sin(@a * y)) y = y + @h * sin(xx^@b + sin(@a * xx)) elseif @flavor == 2 x = x - @h * sin(y + sin(@a * (y + sin(@a * y)))) y = y + @h * sin(xx + sin(@a * (xx + sin(@a * xx)))) else float newx = y float newy = x int j = 0 while j < @flavor j = j + 1 newx = y + sin(@a * newx) newy = x + sin(@a * newy) endwhile x = x - @h * sin(newx) y = y + @h * sin(newy) endif elseif @formula == 3 ; Gnarl x = x - @h * real(@gn1(y + @gn2(@a * (y + @gn3(@b * y))))) y = y + @h * real(@gn1(xx + @gn2(@a * (xx + @gn3(@b * xx))))) endif i = i + 1 endwhile x = (real(pz) - (@scaleg * x)) y = (imag(pz) - (@scaleg * y)) pz = x + flip(y) if @flavorg == 2 pz = pz*@strengthg endif color pat = rgba(0,0,0,0) float cindex = (@cscale*(cabs(@cfn(real(pz)/cabs(pz))))+ @rot) % 1 if @flavorg == 0 if @intype == "Bicolor" pat = compose(@pattern1,@pattern2,abs(real(pz))/cabs(pz) * @strengthg*25) else if cindex < 0.25 pat = compose(@pattern4,@pattern1,cindex) elseif cindex >= 0.25 && cindex > 0.5 pat = compose(@pattern1,@pattern2,cindex) elseif cindex >= 0.5 && cindex > 0.75 pat = compose(@pattern2,@pattern3,cindex) else pat = compose(@pattern3,@pattern4,cindex) endif endif elseif @flavorg == 1 if @intype == "Bicolor" pat = compose(@pattern1,@pattern2,cabs(pz)*@strengthg) else if cindex < 0.25 pat = compose(@pattern4,@pattern1,cindex) elseif cindex >= 0.25 && cindex > 0.5 pat = compose(@pattern1,@pattern2,cindex) elseif cindex >= 0.5 && cindex > 0.75 pat = compose(@pattern2,@pattern3,cindex) else pat = compose(@pattern3,@pattern4,cindex) endif endif elseif @flavorg == 2 pat = compose(gradient((cabs(pz)% @pmod)/@pmod),gradient((2*cabs(pz)%@pmod)/@pmod),abs(real(pz))/cabs(pz)) endif return pat endfunc default: title = "Gnarl Coloring" int param v_colortrapgnarl caption = "Version (Color Trap Gnarl Coloring)" default = 102 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_colortrapgnarl < 102 endparam color param pattern1 caption = "Color 1" default = rgb(0.66,0.29,0.1) visible = @flavorg != "gradient" endparam color param pattern2 caption = "Color 2" default = rgb(0.89,0.84,0.30) visible = @flavorg != "gradient" endparam color param pattern3 caption = "Color 3" default = rgb(0.53,0.63,0.12) visible = @flavorg != "gradient" && @intype == "Multicolor" endparam color param pattern4 caption = "Color 4" default = rgb(0.89,0.45,0.30) visible = @flavorg != "gradient" && @intype == "Multicolor" endparam param intype caption = "Coloring type" default = 0 enum = "Bicolor" "Multicolor" visible = @flavorg != "gradient" endparam float param cscale caption = "Color scale" default = 1.0 visible = @flavorg != "gradient" && @intype == "Multicolor" endparam float param rot caption = "Color rotation" default = 0 min = 0 max = 1 visible = @flavorg != "gradient" && @intype == "Multicolor" endparam func cfn caption = "Color Function" default = ident() visible = @flavorg != "gradient" && @intype == "Multicolor" endfunc param flavorg caption = "Gnarl flavor" default = 0 enum = "0" "1" "gradient" endparam int param pmod caption = "Color modulus" default = 1 visible = @flavorg == "gradient" endparam param formula caption = "Formula" enum = "Martin" "Popcorn" "Vine" "Gnarl" default = 1 endparam param a caption = "Alpha" default = 3.0 endparam param b caption = "Beta" default = 2.0 visible = (@formula == 2 || @formula == 3) endparam param iters caption = "Iterations" default = 20 endparam param flavor caption = "Vine flavor" default = 2 min = 0 visible = @formula == 2 endparam param h caption = "Step size" default = 0.1 visible = (@formula == 1 || @formula == 2 || @formula == 3) endparam param scaleg caption = "Scale" default = 10.0 hint = "Changes the size of the shapes." endparam param strengthg caption = "Strength" default = 0.05 endparam func gn1 caption = "Gnarl function #1" default = sin() visible = @formula == 3 endfunc func gn2 caption = "Gnarl function #2" default = tan() visible = @formula == 3 endfunc func gn3 caption = "Gnarl function #3" default = cos() visible = @formula == 3 endfunc } ;-------------------------------------------------------- ; Formula object classes ;-------------------------------------------------------- class REB_IFSEscape1(common.ulb:DivergentFormula) { ; IFS Escape time July 19, 2013 ; adapted from Fractint code of Ramiro Perez ; two transforms to gice a tree ; Fractint style bailout options.
;

; The default drawing method is multi-pass linear and periodicity checking ; is off. public: import "common.ulb" ; constructor func REB_IFSEscape1(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) divergentFormula.Init(pz) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) k = real(pz) ; transform 1 if k < @t1 pz=pz*@p1+@p2 endif ; transform 2 if @t2 <= k pz=pz*conj(@p1)+@p3 endif return pz endfunc ; This overrides the divergent formula bailout. bool func IsBailedOut(complex pz) bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: float k bool bail default: title = "IFS Escape 2 Transform Tree" int param v_IFSEsc2TxTree caption = "Version (IFS Escape 2 Transform Tree)" 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_IFSEsc2TxTree < 100 endparam heading text = "This is a two transform IFS formula that uses an escape time algorithm as first \ presented by Ramiro Perez for Fractint. The default settings produce a tree." endheading param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 1e10 min = 1.0 endparam complex param p1 caption = "IFS parameter 1" default = (0.9,-0.87) endparam complex param p2 caption = "IFS parameter 2" default = (-1,0) endparam complex param p3 caption = "IFS parameter 3" default = (1,0) endparam float param t1 caption = "Threshold 1" default = 0 endparam float param t2 caption = "Threshold 2" default = 0 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_FunBarnsleyJulia1(common.ulb:DivergentFormula) { ; Barnsley Julia with Fractint style bailout options.
;

; The default drawing method is multi-pass linear and periodicity checking ; is off. public: import "common.ulb" ; constructor func REB_FunBarnsleyJulia1(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) divergentFormula.Init(pz) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) IF real(pz) >= 0 pz = @fn1(pz) pz = (pz - 1) * @seed ELSE pz = @fn1(pz) pz = (pz + 1) * @seed ENDIF return pz endfunc ; This overrides the divergent formula bailout. bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc default: title = "Function Barnsley 1 Julia" int param v_funbarnsleyjulia1 caption = "Version (FunBarnsleyJulia1)" 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_funbarnsleyjulia1 < 100 endparam heading text = "This a Barnsley Julia that includes the Fractint bailout options." endheading param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 endparam complex param seed caption = "Julia seed" default = (0.9, 1.0) hint = "Use this parameter to create many different Julia sets. A good \ way to set this parameter is with the Eyedropper or Explore features." endparam func fn1 caption = "Function" default = ident() endfunc complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_Julia(common.ulb:DivergentFormula) { ; Mandelbrot Julia with Fractint style bailout options.
;

; The default drawing method is multi-pass linear and periodicity checking ; is off. public: import "common.ulb" ; constructor func REB_Julia(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) divergentFormula.Init(pz) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) return pz^@p_power + @seed endfunc ; This overrides the divergent formula bailout. bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc default: title = "Julia" int param v_julia caption = "Version (Julia)" default = 101 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_julia < 101 endparam heading text = "This a Julia that includes the Fractint bailout options." endheading param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param seed caption = "Julia seed" default = (-0.75, 0.25) hint = "Use this parameter to create many different Julia sets. A good \ way to set this parameter is with the Eyedropper or Explore features." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) endparam } class REB_Sierpinski(common.ulb:DivergentFormula) { public: import "common.ulb" ; constructor func REB_Sierpinski(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) divergentFormula.Init(pz) complex rot = (0,1)^((135)/(2*#pi)) pz = pz*rot + (0.2,0.2) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) if (imag(pz)>0.5) pz = @f1(2*real(pz) + flip(2*imag(pz)-1)) elseif (real(pz)>0.5) pz = @f2(2*real(pz)-1 + flip(2*imag(pz))) else pz = @f3(2*real(pz) + flip(2*imag(pz))) endif return pz endfunc ; This overrides the divergent formula bailout. bool func IsBailedOut(complex pz) bool bail = false bail = (|pz| > @p_bailout) return bail endfunc default: title = "Sierpinski" int param v_Sierpinski caption = "Version (Sierpinski)" default = 101 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_Sierpinski < 101 endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param seed caption = "Julia seed" default = (-0.75, 0.25) hint = "Use this parameter to create many different Julia sets. A good \ way to set this parameter is with the Eyedropper or Explore features." visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam func f1 caption = "Function 1" default = ident() endfunc func f2 caption = "Function 2" default = ident() endfunc func f3 caption = "Function 3" default = ident() endfunc } class REB_KochSnowflake(common.ulb:DivergentFormula) { public: import "common.ulb" ; constructor func REB_KochSnowflake(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) divergentFormula.Init(pz) zz = 0 ; Twist pz = 1/sqrt(@r)*real(pz) + 1i*sqrt(@r)*imag(pz) x = real(pz) y = imag(pz) sq3 = sqrt(3) bail2 = false bail = false i = 0 im = (0,1) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) i = i + 1 ;---------------- ; First Iteration ;---------------- if i == 2 ; Calculate the argument of pz arg = atan2(pz) ; Inside approximation if @region == 0 || @region == 2 ; Draw the Star of David if (y + 1/sq3 > 0) && (sq3*x - y + 2/sq3 > 0) \ && (sq3*x + y - 2/sq3 < 0) bail = true endif if (-y + 1/sq3 > 0) && (sq3*x + y + 2/sq3 > 0) \ && (sq3*x - y - 2/sq3 < 0) bail = true endif ; Deal the case where pz needs a rotation if (arg > 5/6*#pi) || (arg < -#pi/2) pz = pz*exp(im*4/3*#pi) endif if (arg < #pi/6) && (arg > -#pi/2) pz = pz*exp(im*2/3*#pi) endif pz = pz - im*1/sq3 if @region == 2 zz = pz pz = #pixel endif endif ; Outside approximation if @region == 1 || @region == 2 ; Draw the hexagon if |x| > 1 || x/sq3 + y - 2*sq3/3 > 0 \ || x/sq3 + y + 2*sq3/3 < 0 || x/sq3 \ - y + 2*sq3/3 < 0 || x/sq3 - y - \ 2*sq3/3 > 0 bail = true endif ; Deal the case where pz needs a rotation if (abs(arg) < #pi/6) pz = pz*exp(-im*#pi/2) elseif (arg > #pi/6) && (arg < #pi/2) pz = pz*exp(-im*5*#pi/6) elseif (arg > #pi/2) && (arg < 5*#pi/6) pz = pz*exp(im*5*#pi/6) elseif (abs(arg) > 5*#pi/6) pz = pz*exp(im*#pi/2) elseif (arg < -#pi/6) && (arg > -#pi/2) pz = pz*exp(-im*#pi/6) elseif (arg < -#pi/2) && (arg > -5*#pi/6) pz = pz*exp(im*#pi/6) endif pz = pz + im pz = sq3*pz endif ;---------------- ;Other Iterations ;---------------- elseif i > 2 ; "Undo" the offset parameter's ; action pz = pz + @offset pz = 1/sqrt(@r)*real(pz) + im*sqrt(@r)*imag(pz) if @region == 2 oldz = pz pz = zz zz = oldz endif ; Magnify pz so that a simple formula ; allows to compute... pz = 3*pz x = real(pz) y = imag(pz) ; ...the new triangle on the segment if (y > 0) && (sq3*x - y + sq3 > 0) \ && (sq3*x + y - sq3 < 0) bail2 = true endif ; Restore the original value of pz pz = pz/3 x = real(pz) y = imag(pz) ; Transforms the left segment if x < -1/3 pz = 3*pz + 2 ; Transforms the right segment elseif x > 1/3 pz = 3*pz - 2 else ; Transforms the middle-left segment if x < 0 pz = pz + 1/3 pz = pz*exp(-im*#pi/3) pz = 3*pz - 1 ; Transforms the middle-right segment else pz = pz - 1/3 pz = pz*exp(im*#pi/3) pz = 3*pz + 1 endif endif endif ; A parameter to fool some coloring ; algorythms like final decomposition... if i >= 2 pz = pz - @offset endif return pz endfunc ; This overrides the divergent formula bailout. bool func IsBailedOut(complex pz) return (bail2 || bail) endfunc protected: bool bail bool bail2 complex zz float x float y float sq3 complex oldz int i float arg complex im default: title = "Koch Snowflake" int param v_KochSnowflake caption = "Version (Koch Snowflake)" default = 101 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_KochSnowflake < 101 endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." visible = false endparam complex param seed caption = "Julia seed" default = (-0.75, 0.25) hint = "Use this parameter to create many different Julia sets. A good \ way to set this parameter is with the Eyedropper or Explore features." visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam param region caption = "Trapped Region" default = 0 enum = "Inside" "Outside" "Both" endparam param offset caption = "Offset" default = (0,0) endparam param r caption = "Twist Parameter" default = (1,0) endparam } class REB_Gopalsamy(common.ulb:DivergentFormula) { ; Gopalsamy with Fractint style bailout options.
;

; The default drawing method is multi-pass linear and periodicity checking ; is off. The formula comes from the Fractint formulas of Ron Barnett public: import "common.ulb" ; constructor func REB_Gopalsamy(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) return pz endfunc ; call for each iteration of the point. complex func Iterate(complex pz) DivergentFormula.Iterate(pz) return -(0,1)*conj(pz)^@p_power + @seed endfunc ; overrides the DivergentFormula function bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc default: title = "Gopalsamy" int param v_gopalsamy caption = "Version (Gopalsamy)" default = 101 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_gopalsamy < 101 endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param seed caption = "Julia seed" default = (0.49375,0.20625) hint = "Use this parameter to create many different Julia sets. A good \ way to set this parameter is with the Eyedropper or Explore features." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) endparam } class REB_Gopalsamy3(common.ulb:DivergentFormula) { ; Gopalsamy3 with Fractint style bailout options.
;

; The default drawing method is multi-pass linear and periodicity checking ; is off. The formula comes from the Fractint formulas of Ron Barnett public: import "common.ulb" complex func Init(complex pz) DivergentFormula.Init(pz) return pz endfunc ; call for every iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) float x = real(pz) float y = imag(pz) complex x1 = 3*x*y*y - x*x*x + @seed y = y*y*y - 3*x*x*y return x1 + flip(y) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc default: title = "Gopalsamy 3" int param v_gopalsamy3 caption = "Version (gopalsamy 3)" default = 101 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_gopalsamy3 < 101 endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param seed caption = "Julia seed" default = (0.7875,-0.09375) hint = "Use this parameter to create many different Julia sets. A good \ way to set this parameter is with the Eyedropper or Explore features." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_Gopalsamy5(common.ulb:DivergentFormula) { ; Gopalsamy5 with Fractint style bailout options.
;

; The default drawing method is multi-pass linear and periodicity checking ; is off. The formula comes from the Fractint formulas of Ron Barnett public: import "common.ulb" ; constructor func REB_Gopalsamy5(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) return pz endfunc ; call for every iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) float x = real(pz) float y = imag(pz) float x1 = 2*x*y float y1 = x*x - y*y complex x2 = -2*x1*y1 + @seed y = y1*y1 - x1*x1 return x2 + flip(y) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc default: title = "Gopalsamy 5" int param v_gopalsamy5 caption = "Version (Gopalsamy 5)" default = 101 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_gopalsamy5 < 101 endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param seed caption = "Julia seed" default = (0.74467773438,0.32087402344) hint = "Use this parameter to create many different Julia sets. A good \ way to set this parameter is with the Eyedropper or Explore features." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_FrameRobertJulia(common.ulb:DivergentFormula) { ; Based upon the Frame-Robertson fractal.
;

; The Frame-Robertson fractal is described in Mazes for the Mind by Pickover. ; Fractint-style bailout options are available. public: import "common.ulb" ; constructor func REB_FrameRobertJulia(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) return pz endfunc ; call for every iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) return pz^3/5 + pz^2 + @seed endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc default: title = "Frame Robert Julia" int param v_framerobertjulia caption = "Version (Frame Robert Julia)" default = 101 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_framerobertjulia < 101 endparam heading text = "This a Julia that includes the Fractint bailout options." endheading param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param seed caption = "Julia seed" default = (-0.964,-0.178) hint = "Use this parameter to create many different Julia sets. A good \ way to set this parameter is with the Eyedropper or Explore features." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_IkenagaJulia(common.ulb:DivergentFormula) { ; Based upon the Ikenaga fractal
;

; The function was discovered by Bruce Ikenaga who passed it on to A.K. Dewdney ; which appeared in his book "The Armchair Universe". I first used this formula ; in Fractint, about 1993 - Ron Barnett. The formula uses Fractint style bailouts. public: import "common.ulb" ; constructor func REB_IkenagaJulia(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) return pz endfunc ; call for every iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) return pz^3 + (@seed-1)*pz - @seed endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc default: title = "Ikenaga Julia" int param v_ikenagajulia caption = "Version (Ikenaga Julia)" default = 101 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_ikenagajulia < 101 endparam heading text = "This an Ikenaga Julia that includes the Fractint bailout options." endheading param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param seed caption = "Julia seed" default = (0.0,-0.1625) hint = "Use this parameter to create many different Julia sets. A good \ way to set this parameter is with the Eyedropper or Explore features." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_3RDIMFrame_Robert(common.ulb:DivergentFormula) { public: import "common.ulb" ; constructor func REB_3RDIMFrame_Robert(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) complex z2 = pz pz=@p1*real(z2)+flip(imag(z2)) m_c=@p2+real(z2)+flip(imag(z2)*@p1) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) return pz^3/5 + pz^2 + m_c endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c default: title = "3RDIM Frame-Robert" int param v_3RDIMFrame_Robert caption = "Version (3RDIM Frame-Robert)" 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_3RDIMFrame_Robert < 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_3RDIMIkenaga(common.ulb:DivergentFormula) { public: import "common.ulb" ; constructor func REB_3RDIMIkenaga(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) complex z2 = pz complex z3 = ((1-pz)/3)^0.5 pz=@p1*real(z3)+flip(imag(z3)) m_c=@p2+real(z2)+flip(imag(z2)*@p1) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) return pz^3 + (m_c-1)*pz - m_c endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c default: title = "3RDIM Ikenaga" int param v_3RDIMIkenaga caption = "Version (3RDIM Ikenaga)" 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_3RDIMIkenaga < 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_3RDIMManowar(common.ulb:DivergentFormula) { public: import "common.ulb" ; constructor func REB_3RDIMManowar(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) complex z2 = pz pz=@p1*real(z2)+flip(imag(z2)) z1 = pz m_c=@p2+real(z2)+flip(imag(z2)*@p1) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) oldz = pz pz = oldz*oldz + z1 + m_c z1 = oldz return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c complex z1 complex oldz default: title = "3RDIM Manowar" int param v_3RDIMManowar caption = "Version (3RDIM Manowar)" 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_3RDIMManowar < 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_3RDIMSpider(common.ulb:DivergentFormula) { public: import "common.ulb" ; constructor func REB_3RDIMSpider(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) complex z2 = pz pz=@p1*real(z2)+flip(imag(z2)) m_c=@p2+real(z2)+flip(imag(z2)*@p1) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) pz=pz^2+m_c m_c=m_c/2+pz return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c default: title = "3RDIM Spider" int param v_3RDIMSpider caption = "Version (3RDIM Spider)" 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_3RDIMSpider< 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_3RDIMMagnet1(common.ulb:ConvergentDivergentFormula) { ; public: ; constructor func REB_3RDIMMagnet1(Generic pparent) ConvergentDivergentFormula.ConvergentDivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) ConvergentDivergentFormula.Init(pz) complex z2 = pz pz = 0 m_c = @p2+real(z2)+flip(imag(z2)*@p1) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) ConvergentDivergentFormula.Iterate(pz) return sqr( (pz^2 + m_c - 1) / (2*pz + m_c - 2) ) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz| >= @p_upperbailout || |pz - 1| <= @p_lowerbailout endfunc private: complex m_c default: title = "3RDIM Magnet 1" int param v_3RDIMMagnet1 caption = "Version (3RDIM Magnet 1)" 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_3RDIMMagnet1< 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading param start caption = "Perturbation" default = (0, 0) hint = "Starting value for each point. You can use this to \ 'perturb' the fractal. Use (0, 0) for the classic set." endparam float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam param p_upperbailout ; Overrides p_upperbailout from ConvergentDivergentFormula caption = "Bailout value" default = 100.0 min = 1 ; exponential = true hint = "This parameter defines how soon an orbit bails out while \ iterating. Larger values give smoother outlines; smaller values \ generally produce more interesting shapes around the set." endparam param p_lowerbailout ; Overrides p_lowerbailout from ConvergentDivergentFormula caption = "Convergent bailout value" default = 0.00001 min = 0 ; exponential = true hint = "This parameter defines how soon a convergent orbit bails out while \ iterating. Smaller values give more precise results but usually \ require more iterations." endparam complex param p_power ; Hide p_power from Formula visible = false endparam } class REB_3RDIMMagnet2(common.ulb:ConvergentDivergentFormula) { ; public: ; constructor func REB_3RDIMMagnet2(Generic pparent) ConvergentDivergentFormula.ConvergentDivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) ConvergentDivergentFormula.Init(pz) complex z2 = pz pz = @p1*real(@start)+flip(imag(@start)) m_c = @p2+real(z2)+flip(imag(z2)*@p1) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) ConvergentDivergentFormula.Iterate(pz) return sqr( (pz^3 + 3*(m_c-1)*pz + (m_c-1)*(m_c-2)) / \ (3*pz^2 + 3*(m_c-2)*pz + (m_c-1)*(m_c-2) + 1) ) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz| >= @p_upperbailout || |pz - 1| <= @p_lowerbailout endfunc private: complex m_c default: title = "3RDIM Magnet 2" int param v_3RDIMMagnet2 caption = "Version (3RDIM Magnet 2)" 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_3RDIMMagnet2< 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading param start caption = "Perturbation" default = (0, 0) hint = "Starting value for each point. You can use this to \ 'perturb' the fractal. Use (0, 0) for the classic set." endparam float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam param p_upperbailout ; Overrides p_upperbailout from ConvergentDivergentFormula caption = "Bailout value" default = 100.0 min = 1 ; exponential = true hint = "This parameter defines how soon an orbit bails out while \ iterating. Larger values give smoother outlines; smaller values \ generally produce more interesting shapes around the set." endparam param p_lowerbailout ; Overrides p_lowerbailout from ConvergentDivergentFormula caption = "Convergent bailout value" default = 0.00001 min = 0 ; exponential = true hint = "This parameter defines how soon a convergent orbit bails out while \ iterating. Smaller values give more precise results but usually \ require more iterations." endparam complex param p_power ; Hide p_power from Formula visible = false endparam } class REB_3RDIMMagnet1Julia(common.ulb:ConvergentDivergentFormula) { public: ; constructor func REB_3RDIMMagnet1Julia(Generic pparent) ConvergentDivergentFormula.ConvergentDivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) ConvergentDivergentFormula.Init(pz) complex z2 = pz pz = @p1*real(z2)+flip(imag(z2)) m_c = @p2+real(@seed)+flip(imag(@seed)*@p1) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) ConvergentDivergentFormula.Iterate(pz) return sqr( (pz^2 + m_c - 1) / (2*pz + m_c - 2) ) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz| >= @p_upperbailout || |pz - 1| <= @p_lowerbailout endfunc private: complex m_c default: title = "3RDIM Magnet 1 Julia" int param v_3RDIMMagnet1Julia caption = "Version (3RDIM Magnet 1 Julia)" 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_3RDIMMagnet1Julia< 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam param p_upperbailout ; Overrides p_upperbailout from ConvergentDivergentFormula caption = "Bailout value" default = 100.0 min = 1 endparam param p_lowerbailout ; Overrides p_lowerbailout from ConvergentDivergentFormula caption = "Convergent bailout value" default = 0.00001 min = 0 endparam param @seed caption = "Seed" default = (-0.1375, 0.1625) endparam complex param p_power ; Hide p_power from Formula visible = false endparam } class REB_3RDIMMagnet2Julia(common.ulb:ConvergentDivergentFormula) { public: ; constructor func REB_3RDIMMagnet2Julia(Generic pparent) ConvergentDivergentFormula.ConvergentDivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) ConvergentDivergentFormula.Init(pz) complex z2 = pz pz = @p1*real(z2)+flip(imag(z2)) m_c = @p2+real(@seed)+flip(imag(@seed)*@p1) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) ConvergentDivergentFormula.Iterate(pz) zold = pz return sqr( (pz^3 + 3*(m_c-1)*pz + (m_c-1)*(m_c-2)) / \ (3*pz^2 + 3*(m_c-2)*pz + (m_c-1)*(m_c-2) + 1) ) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz| >= @p_upperbailout || |pz - zold| <= @p_lowerbailout endfunc private: complex m_c complex zold default: title = "3RDIM Magnet 2 Julia" int param v_3RDIMMagnet2Julia caption = "Version (3RDIM Magnet 2 Julia)" 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_3RDIMMagnet2Julia< 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam param p_upperbailout ; Overrides p_upperbailout from ConvergentDivergentFormula caption = "Bailout value" default = 100.0 min = 1 endparam param p_lowerbailout ; Overrides p_lowerbailout from ConvergentDivergentFormula caption = "Convergent bailout value" default = 0.00001 min = 0 endparam param @seed caption = "Seed" default = (1.34,-1.34) endparam complex param p_power ; Hide p_power from Formula visible = false endparam } class REB_3RDIMIkenagaJulia(common.ulb:DivergentFormula) { public: import "common.ulb" ; constructor func REB_3RDIMIkenagaJulia(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) complex z2 = pz pz=@p1*real(z2)+flip(imag(z2)) m_c=@p2+real(@p3)+flip(imag(@p3)*@p1) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) return pz^3 + (m_c-1)*pz - m_c endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c default: title = "3RDIM Ikenaga Julia" int param v_3RDIMIkenagaJulia caption = "Version (3RDIM Ikenaga Julia)" 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_3RDIMIkenagaJulia < 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam param p3 caption = "Julia seed" default = (0.05,0.45) endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_3RDIMManowarJulia(common.ulb:DivergentFormula) { public: import "common.ulb" ; constructor func REB_3RDIMManowarJulia(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) complex z2 = pz pz=@p1*real(z2)+flip(imag(z2)) z1 = pz m_c=@p2+real(@p3)+flip(imag(@p3)*@p1) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) oldz = pz pz = oldz*oldz + z1 + m_c z1 = oldz return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c complex z1 complex oldz default: title = "3RDIM Manowar Julia" int param v_3RDIMManowarJulia caption = "Version (3RDIM Manowar Julia)" 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_3RDIMManowarJulia < 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam param p3 caption = "Julia seed" default = (0.06,-0.1) endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_3RDIMSpiderJulia(common.ulb:DivergentFormula) { public: import "common.ulb" ; constructor func REB_3RDIMSpiderJulia(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) complex z2 = pz pz=@p1*real(z2)+flip(imag(z2)) m_c=@p2+real(@p3)+flip(imag(@p3)*@p1) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) pz=pz^2+m_c m_c=m_c/2+pz return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c default: title = "3RDIM Spider Julia" int param v_3RDIMSpiderJulia caption = "Version (3RDIM Spider Julia)" 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_3RDIMSpiderJulia < 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam param p3 caption = "Julia seed" default = (0.1,-0.625) endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_3RDIMFrame_RobertJulia(common.ulb:DivergentFormula) { public: import "common.ulb" ; constructor func REB_3RDIMFrame_RobertJulia(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) complex z2 = pz pz=@p1*real(z2)+flip(imag(z2)) m_c=@p2+real(@p3)+flip(imag(@p3)*@p1) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) return pz^3/5 + pz^2 + m_c endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c default: title = "3RDIM Frame-Robert Julia" int param v_3RDIMFrame_RobertJulia caption = "Version (3RDIM Frame-Robert Julia)" 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_3RDIMFrame_RobertJulia < 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam param p3 caption = "Julia seed" default = (-0.97,-0.55) endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_OldPhoenix(common.ulb:DivergentFormula) { public: import "common.ulb" ; constructor func REB_OldPhoenix(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) pz = flip(pz) x1 = 0 y = 0 return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) x1 = pz*pz + real(@seed) + imag(@seed)*y y = pz pz = x1 return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c complex x1 complex y default: title = "Old Phoenix" int param v_REB_OldPhoenix caption = "Version (Old Phoenix)" 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_REB_OldPhoenix < 100 endparam heading text = "This a Mandelbrot that includes the Fractint bailout options." endheading param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param seed caption = "Julia seed" default = (0.56667, -0.5) hint = "Use this parameter to create many different Julia sets. A good \ way to set this parameter is with the Eyedropper or Explore features." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_FunBarnsley1(common.ulb:DivergentFormula) { ; Barnsley formula that uses Fractint style bailouts.
public: import "common.ulb" ; constructor func REB_FunBarnsley1(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) m_c = pz return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) if real(pz) >= 0 pz = @fn1(pz) pz = (pz - 1) * m_c else pz = @fn1(pz) pz = (pz + 1) * m_c endif return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c default: title = "Function Barnsley 1" int param v_funbarnsley1 caption = "Version (Function Barnsley 1)" 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_funbarnsley1 < 100 endparam heading text = "This a Barnsley formula that includes the Fractint bailout options." endheading param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 endparam func fn1 caption = "Function" default = ident() endfunc complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_Mandelbrot(common.ulb:DivergentFormula) { ; Mandelbrot formula that uses Fractint style bailouts.
public: import "common.ulb" ; constructor func REB_Mandelbrot(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) m_c = pz return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) return pz^@p_power + m_c endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c default: title = "Mandelbrot" int param v_mandelbrot caption = "Version (Mandelbrot)" default = 101 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_mandelbrot < 101 endparam heading text = "This a Mandelbrot that includes the Fractint bailout options." endheading param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout caption = "Bailout" default = 1e10 min = 1.0 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam } class REB_OldPhoenixMandelbrot(common.ulb:DivergentFormula) { public: import "common.ulb" ; constructor func REB_OldPhoenixMandelbrot(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) m_c = pz pz = 0 x1 = 0 y = 0 return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) x1 = pz*pz + real(m_c) + imag(m_c)*y y = pz pz = x1 return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c complex x1 complex y default: title = "Old Phoenix Mandelbrot" int param v_REB_OldPhoenixMandelbrot caption = "Version (Old Phoenix Mandelbrot)" 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_REB_OldPhoenixMandelbrot < 100 endparam heading text = "This a Mandelbrot that includes the Fractint bailout options." endheading param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." visible = false endparam } class REB_MandelGopalsamy(common.ulb:DivergentFormula) { ; Gopalsamy with Fractint style bailout options.
;

; The default drawing method is multi-pass linear and periodicity checking ; is off. The formula comes from the Fractint formulas of Ron Barnett public: import "common.ulb" ; constructor func REB_MandelGopalsamy(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) m_c = pz return pz endfunc ; call for each iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) return -(0,1)*conj(pz)^@p_power + m_c endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c default: title = "Mandel Gopalsamy" int param v_mandelgopalsamy caption = "Version (Mandel Gopalsamy)" default = 101 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_mandelgopalsamy < 101 endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) endparam } class REB_MandelGopalsamy3(common.ulb:DivergentFormula) { ; Mandel Gopalsamy3 with Fractint style bailout options.
;

; The default drawing method is multi-pass linear and periodicity checking ; is off. The formula comes from the Fractint formulas of Ron Barnett public: import "common.ulb" ; constructor func REB_MandelGopalsamy3(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) m_c = pz return pz endfunc ; call for every iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) float x = real(pz) float y = imag(pz) complex x1 = 3*x*y*y - x*x*x + m_c y = y*y*y - 3*x*x*y return x1 + flip(y) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c default: title = "Mandel Gopalsamy3" int param v_mandelgopalsamy3 caption = "Version (Mandel Gopalsamy 3)" default = 101 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_mandelgopalsamy3 < 101 endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_MandelGopalsamy5(common.ulb:DivergentFormula) { ; Mandel Gopalsamy5 with Fractint style bailout options.
;

; The default drawing method is multi-pass linear and periodicity checking ; is off. The formula comes from the Fractint formulas of Ron Barnett public: import "common.ulb" ; constructor func REB_MandelGopalsamy5(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) m_c = pz return pz endfunc ; call for every iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) float x = real(pz) float y = imag(pz) float x1 = 2*x*y float y1 = x*x - y*y complex x2 = -2*x1*y1 + m_c y = y1*y1 - x1*x1 return x2 + flip(y) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c default: title = "Mandel Gopalsamy5" int param v_mandelgopalsamy5 caption = "Version (Mandel Gopalsamy 5)" default = 101 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_mandelgopalsamy5 < 101 endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_TentMap(common.ulb:DivergentFormula) { ; The Tent Map as described in Wikipedia and Mathworld.
;

; This version of the tent map has somewhat different initializing conditions ; from those used by Kerry Mitchell. For this version: ; T(x) = s*x for x <= 0.5
; T(x) = s*(1-x) for x > 0.5
;

An inverted form is available, along with several tent types and two ; flavors. public: import "common.ulb" ; constructor func REB_TentMap(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) m_c = pz if @invert pz = 1/(m_c+(0.000001,0.000001)) else pz = m_c endif if @flavor == "Flavor 1" pz = @tentfn(pz) endif return pz endfunc ; call for every iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) if @flavor == "Flavor 2" pz = @tentfn(pz) endif if @invert if @type == "cabs" if cabs(@tentfn2(pz)) <= @tent3 pz = @tent1*pz/(m_c+(0.000001,0.000001)) else pz = @tent1*(@tent2-pz)/(m_c+(0.000001,0.000001)) endif elseif @type == "real" if real(@tentfn2(pz)) <= @tent3 pz = @tent1*pz/(m_c+(0.000001,0.000001)) else pz = @tent1*(@tent2-pz)/(m_c+(0.000001,0.000001)) endif elseif @type == "imag" if imag(@tentfn2(pz)) <= @tent3 pz = @tent1*pz/(m_c+(0.000001,0.000001)) else pz = @tent1*(@tent2-pz)/(m_c+(0.000001,0.000001)) endif else if imag(@tentfn2(pz)) > @tent3 pz = @tent1*(@tent2-pz)/(m_c+(0.000001,0.000001)) elseif real(@tentfn2(pz)) > @tent3 pz = @tent1*(@tent2-pz)/(m_c+(0.000001,0.000001)) else pz = @tent1*pz/(m_c+(0.000001,0.000001)) endif endif else if @type == "cabs" if cabs(@tentfn2(pz)) <= @tent3 pz = @tent1*pz*m_c else pz = @tent1*(@tent2-pz)*m_c endif elseif @type == "real" if real(@tentfn2(pz)) <= @tent3 pz = @tent1*pz*m_c else pz = @tent1*(@tent2-pz)*m_c endif elseif @type == "imag" if imag(@tentfn2(pz)) <= @tent3 pz = @tent1*pz*m_c else pz = @tent1*(@tent2-pz)*m_c endif else if imag(@tentfn2(pz)) > @tent3 pz = @tent1*(@tent2-pz)*m_c elseif real(@tentfn2(pz)) > @tent3 pz = @tent1*(@tent2-pz)*m_c else pz = @tent1*pz*m_c endif endif endif return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c default: title = "Tent Map" int param v_tentmap caption = "Version (Tent Map)" default = 101 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_tentmap < 101 endparam heading text = "Based upon the Tent Map function:" endheading heading text = " T(x) = s*x for x <= 0.5" endheading heading text = " T(x) = s*(1-x) for x > 0.5" endheading heading text = "and the code for the Barnsley type fractals." endheading param type caption = "Tent type" default = 3 enum = "cabs" "real" "imag" "Pinsky" endparam param flavor caption = "Flavor" default = 0 enum = "Flavor 1" "Flavor 2" endparam bool param invert caption = "Inversion" default = false endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" endparam float param p_bailout caption = "Bailout value" default = 10000 min = 1 endparam float param tent1 caption ="Tent param #1" default = 1 endparam float param tent2 caption ="Tent param #2" default = 1 endparam float param tent3 caption ="Tent param #3" default = 0.5 endparam func tentfn caption = "Tent function" default = ident() endfunc func tentfn2 caption = "Tent function #2" default = ident() endfunc complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_TentMapJulia(common.ulb:DivergentFormula) { ; Julia version of the Tent Map as described in Wikipedia and Mathworld.
;

; This version of the tent map has somewhat different initializing conditions ; from those used by Kerry Mitchell. For this version: ; T(x) = s*x for x <= 0.5
; T(x) = s*(1-x) for x > 0.5
;

An inverted form is available, along with several tent types and two ; flavors. public: import "common.ulb" ; constructor func REB_TentMapJulia(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) m_c = pz if @invert pz = 1/(m_c+(0.000001,0.000001)) endif if @flavor == "Flavor 1" pz = @tentfn(pz) endif return pz endfunc ; call for every iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) if @flavor == "Flavor 2" pz = @tentfn(pz) endif if @invert if @type == "cabs" if cabs(@tentfn2(pz)) <= @tent3 pz = @tent1*pz/(@seed+(0.000001,0.000001)) else pz = @tent1*(@tent2-pz)/(@seed+(0.000001,0.000001)) endif elseif @type == "real" if real(@tentfn2(pz)) <= @tent3 pz = @tent1*pz/(@seed+(0.000001,0.000001)) else pz = @tent1*(@tent2-pz)/(@seed+(0.000001,0.000001)) endif elseif @type == "imag" if imag(@tentfn2(pz)) <= @tent3 pz = @tent1*pz/(@seed+(0.000001,0.000001)) else pz = @tent1*(@tent2-pz)/(@seed+(0.000001,0.000001)) endif else if imag(@tentfn2(pz)) > @tent3 pz = @tent1*(@tent2-pz)/(@seed+(0.000001,0.000001)) elseif real(@tentfn2(pz)) > @tent3 pz = @tent1*(@tent2-pz)/(@seed+(0.000001,0.000001)) else pz = @tent1*pz/(@seed+(0.000001,0.000001)) endif endif else if @type == "cabs" if cabs(@tentfn2(pz)) <= @tent3 pz = @tent1*pz*@seed else pz = @tent1*(@tent2-pz)*@seed endif elseif @type == "real" if real(@tentfn2(pz)) <= @tent3 pz = @tent1*pz*@seed else pz = @tent1*(@tent2-pz)*@seed endif elseif @type == "imag" if imag(@tentfn2(pz)) <= @tent3 pz = @tent1*pz*@seed else pz = @tent1*(@tent2-pz)*@seed endif else if imag(@tentfn2(pz)) > @tent3 pz = @tent1*(@tent2-pz)*@seed elseif real(@tentfn2(pz)) > @tent3 pz = @tent1*(@tent2-pz)*@seed else pz = @tent1*pz*@seed endif endif endif return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c default: title = "Tent Map Julia" int param v_tentmapjulia caption = "Version (Tent Map Julia)" default = 101 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_tentmapjulia < 101 endparam heading text = "Based upon the Tent Map function:" endheading heading text = " T(x) = s*x for x <= 0.5" endheading heading text = " T(x) = s*(1-x) for x > 0.5" endheading heading text = "and the code for the Barnsley type fractals." endheading param type caption = "Tent type" default = 3 enum = "cabs" "real" "imag" "Pinsky" endparam param flavor caption = "Flavor" default = 0 enum = "Flavor 1" "Flavor 2" endparam bool param invert caption = "Inversion" default = false endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" endparam float param p_bailout caption = "Bailout value" default = 10000 min = 1 endparam float param tent1 caption ="Tent param #1" default = 1 endparam float param tent2 caption ="Tent param #2" default = 1 endparam float param tent3 caption ="Tent param #3" default = 0.5 endparam func tentfn caption = "Tent function" default = ident() endfunc func tentfn2 caption = "Tent function #2" default = ident() endfunc complex param seed caption = "Julia seed" default = (1.04375,0.35625) hint = "Use this parameter to create many different Julia sets. A good \ way to set this parameter is with the Eyedropper or Explore features." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_FrameRobert(common.ulb:DivergentFormula) { ; Based upon the Frame-Robertson fractal.
;

; The Frame-Robertson fractal is described in Mazes for the Mind by Pickover. ; Fractint-style bailout options are available. public: ; constructor func REB_FrameRobert(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) m_c = pz return pz endfunc ; call for every iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) return pz^3/5 + pz^2 + m_c endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c default: title = "Frame Robert" int param v_framerobert caption = "Version (Frame Robert)" default = 101 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_framerobert < 101 endparam heading text = "This a Frame Robert that includes the Fractint bailout options." endheading param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_IkenagaMap(common.ulb:DivergentFormula) { ; based upon the Ikenaga function described in Dewdneys's The Armchair Universe.
;

; The initial starting point allows the function to provide a "map" for the ; corresponding Julia function. modified from the original Fractint frm; of ; Ron Barnett public: import "common.ulb" ; constructor func REB_IkenagaMap(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) DivergentFormula.Init(pz) m_c = pz pz = ((1-m_c)/3)^0.5 return pz endfunc ; call for every iterated point complex func Iterate(complex pz) DivergentFormula.Iterate(pz) return pz^3 + (m_c-1)*pz - m_c endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @test == 0 bail = (|pz| > @p_bailout) elseif @test == 1 bail = (sqr(real(pz)) > @p_bailout) elseif @test == 2 bail = (sqr(imag(pz)) > @p_bailout) elseif @test == 3 bail = (sqr(real(pz)) > @p_bailout || sqr(imag(pz)) > @p_bailout) elseif @test == 4 bail = (sqr(real(pz)) > @p_bailout && sqr(imag(pz)) > @p_bailout) elseif @test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > @p_bailout) elseif @test == 6 bail = (sqr(real(pz) + imag(pz)) > @p_bailout) endif return bail endfunc protected: complex m_c default: title = "Ikenaga Map" int param v_ikenagamap caption = "Version (Ikenaga Map)" default = 101 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_ikenagamap < 101 endparam heading text = "This an Ikenaga that includes the Fractint bailout options." endheading param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout value" default = 10000.0 min = 1.0 hint = "Use a value of 4 if the bailout test is other than mod." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_Newton(common.ulb:ConvergentFormula) { ; Newton with multiple convergence methods.
;

; In addition to the the well-known Newton's method for determining roots of ; polynomials, three additional methods can be used: Householder's method, ; Halley's method and Schroder's Method. All three are described in Mathworld. ; This formula has three additional methods which are hybrid methods. ;

; A modified bailout procedure is used which provide better behavior with complex ; powers with respect to coloring formulas. public: import "common.ulb" ; constructor func REB_Newton(Generic pparent) ConvergentFormula.ConvergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) ConvergentFormula.Init(pz) fz = 0 fzp = 0 fzp2 = 0 pwrtest = 10^(100/cabs(@p_power)) bTest = false isnear = @p_bailout*cabs(@p2)^cabs(@p_power) oldz = 0 cz = 0 return pz endfunc ; call for each iterated point complex func Iterate(complex pz) ConvergentFormula.Iterate(pz) oldz = pz fz = pz^@p_power - @p2 fzp = @p_power*pz^(@p_power-1) fzp2 = @p_power*(@p_power-1)*pz^(@p_power-2) if @converge == 0 ; Newton pz = pz - fz/fzp elseif @converge == 1 ; Householder pz = pz - fz/fzp*(1 + fz*fzp2/(2*fzp^2)) elseif @converge == 2 ; Halley pz = pz - 2*fz*fzp/(2*fzp^2 - fz*fzp2) elseif @converge == 3 ; Schroder pz = pz - fz*fzp/(fzp^2 - fz*fzp2) elseif @converge == 4 ; Ho custom pz = pz - fz/fzp*(1 + fz*fzp2/(@custom*fzp^2)) elseif @converge == 5 ; Ha custom pz = pz - 2*fz*fzp/(@custom*fzp^2 - fz*fzp2) elseif @converge == 6 ; H_S custom pz = pz - @custom*fz*fzp/(@custom*fzp^2 - fz*fzp2) endif btest = (|oldz-pz| < isnear) cz = |pz| return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return !(!btest && (cz < pwrtest)) endfunc protected: complex fz complex fzp complex fzp2 float pwrtest bool bTest float isnear complex oldz float cz default: title = "Newton" int param v_newton caption = "Version (Newton)" 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_newton < 100 endparam heading text = "This a Newton with multiple convergence options." endheading param p_power caption = "Power" default = (3,0) endparam param p2 caption = "Root" default = (1,0) endparam param p_bailout caption = "Bailout value" default = 1e-12 max = 0.1 endparam heading caption = "Convergence Methods" endheading param converge caption = "Convergence Method" default = 0 enum = "Newton" "Householder" "Halley" "Schroder" "Ho Custom" \ "Ha Custom" "H_S Custom" endparam float param custom caption = "H_S Constant" default = 1.5 visible = @converge==4 || @converge==5 || @converge==6 endparam } class REB_CayleyJulia(common.ulb:ConvergentFormula) { ; Based upon a formula of Mark Townsend.
;

; In addition to the the well-known Newton's method for determining roots of ; polynomials, three additional methods can be used: Householder's method, ; Halley's method and Schroder's Method. All three are described in Mathworld. ; This formula has seven additional methods which are hybrid methods. ;

; One of the unique characteristics of this convergent formula is the presence ; of multiple julia sets similar to the classical julia sets. For this formula ; they are much smaller and hard to find. The julia sets can be found with the ; Newton, Mixed 1, Mixed 2, Mixed 3 and Mixed 4 convergence methods. public: import "common.ulb" ; constructor func REB_CayleyJulia(Generic pparent) ConvergentFormula.ConvergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) ConvergentFormula.Init(pz) fz = 0 fzp = 0 fzp2 = 0 oldz = 0 m_iterations = 0 return pz endfunc ; call for each iterated point complex func Iterate(complex pz) ConvergentFormula.Iterate(pz) complex seed = 0 if @converge == 0 || @converge == 1 || @converge == 2 || @converge == 3 || \ @converge == 4 || @converge == 5 || @converge == 6 seed = @p10 elseif @converge == 7 seed = @p17 elseif @converge == 8 seed = @p18 elseif @converge == 9 seed = @p19 elseif @converge == 10 seed = @p110 endif oldz = pz fz = pz^3 - seed*pz - seed + 1 fzp = 3*pz^2 - seed fzp2 = 6*pz if @converge == 0 ; Newton pz = pz - fz/fzp elseif @converge == 1 ; Householder pz = pz - fz/fzp*(1 + fz*fzp2/(2*fzp^2)) elseif @converge == 2 ; Halley pz = pz - 2*fz*fzp/(2*fzp^2 - fz*fzp2) elseif @converge == 3 ; Schroder pz = pz - fz*fzp/(fzp^2 - fz*fzp2) elseif @converge == 4 ; Ho custom pz = pz - fz/fzp*(1 + fz*fzp2/(@custom*fzp^2)) elseif @converge == 5 ; Ha custom pz = pz - 2*fz*fzp/(@custom*fzp^2 - fz*fzp2) elseif @converge == 6 ; H_S custom pz = pz - @custom*fz*fzp/(@custom*fzp^2 - fz*fzp2) elseif @converge == 7 ; Mixed 1 if m_iterations % 2 == 0 pz = pz - fz/fzp*(1 + fz*fzp2/(2*fzp^2)) else pz = pz - fz/fzp endif elseif @converge == 8 ; Mixed 2 if m_iterations % 2 == 0 pz = pz - 2*fz*fzp/(2*fzp^2 - fz*fzp2) else pz = pz - fz/fzp endif elseif @converge == 9 ; Mixed 3 if m_iterations % 2 == 0 pz = pz - fz*fzp/(fzp^2 - fz*fzp2) else pz = pz - fz/fzp endif elseif @converge == 10 ; Mixed 4 if m_iterations % 2 == 0 pz = pz - @custom*fz*fzp/(@custom*fzp^2 - fz*fzp2) else pz = pz - fz/fzp endif endif return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-oldz| < @p_bailout endfunc protected: complex fz complex fzp complex fzp2 complex oldz default: title = "Cayley Julia" int param v_cayleyjulia caption = "Version (Cayley Julia)" default = 101 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_cayleyjulia < 101 endparam float param p_bailout caption = "Bailout value" default = 1e-12 endparam param p10 caption = "Julia seed" default = (0.360968017578125,0.00074462890625) visible = (@converge == 0 || @converge == 1 || @converge == 2 || @converge == 3 || \ @converge == 4 || @converge == 5 || @converge == 6) endparam param p17 caption = "Julia seed" default = (0.31216913789,1.38719537118) visible = @converge==7 endparam param p18 caption = "Julia seed" default = (0.0973120321799,1.15430065766) visible = @converge==8 endparam param p19 caption = "Julia seed" default = (0.127944,0.186804) visible = @converge==9 endparam param p110 caption = "Julia seed" default = (-0.009955549007286, 0.9678595903229) visible = @converge==10 endparam heading caption = "Convergence Methods" endheading param converge caption = "Convergence Method" default = 0 enum = "Newton" "Householder" "Halley" "Schroder" "Ho Custom" \ "Ha Custom" "H_S Custom" "Mixed1" "Mixed2" "Mixed3" "Mixed4" endparam float param custom caption = "H_S Constant" default = 1.5 visible = @converge==4 || @converge==5 || @converge==6 || @converge==10 endparam param p_power caption = "Power" default = (3,0) visible = false endparam } class REB_CayleyMandel(common.ulb:ConvergentFormula) { ; Based upon a formula of Mark Townsend.
;

; In addition to the the well-known Newton's method for determining roots of ; polynomials, three additional methods can be used: Householder's method, ; Halley's method and Schroder's Method. All three are described in Mathworld. ; This formula has seven additional methods which are hybrid methods. ;

; One of the unique characteristics of this convergent formula is the presence ; of multiple julia sets similar to the classical julia sets. For this formula ; they are much smaller and hard to find. The julia sets can be found with the ; Newton, Mixed 1, Mixed 2, Mixed 3 and Mixed 4 convergence methods. public: import "common.ulb" ; constructor func REB_CayleyMandel(Generic pparent) ConvergentFormula.ConvergentFormula(pparent) endfunc ; initialize the formula complex func Init(complex pz) ConvergentFormula.Init(pz) m_c = pz fz = 0 fzp = 0 fzp2 = 0 oldz = 0 m_iterations = 0 pz = 0 return pz endfunc complex func Iterate(complex pz) ConvergentFormula.Iterate(pz) oldz = pz fz = pz^3 - m_c*pz - m_c + 1 fzp = 3*pz^2 - m_c fzp2 = 6*pz if @converge == 0 ; Newton pz = pz - fz/fzp elseif @converge == 1 ; Householder pz = pz - fz/fzp*(1 + fz*fzp2/(2*fzp^2)) elseif @converge == 2 ; Halley pz = pz - 2*fz*fzp/(2*fzp^2 - fz*fzp2) elseif @converge == 3 ; Schroder pz = pz - fz*fzp/(fzp^2 - fz*fzp2) elseif @converge == 4 ; Ho custom pz = pz - fz/fzp*(1 + fz*fzp2/(@custom*fzp^2)) elseif @converge == 5 ; Ha custom pz = pz - 2*fz*fzp/(@custom*fzp^2 - fz*fzp2) elseif @converge == 6 ; H_S custom pz = pz - @custom*fz*fzp/(@custom*fzp^2 - fz*fzp2) elseif @converge == 7 ; Mixed 1 if m_iterations % 2 == 0 pz = pz - fz/fzp*(1 + fz*fzp2/(2*fzp^2)) else pz = pz - fz/fzp endif elseif @converge == 8 ; Mixed 2 if m_iterations % 2 == 0 pz = pz - 2*fz*fzp/(2*fzp^2 - fz*fzp2) else pz = pz - fz/fzp endif elseif @converge == 9 ; Mixed 3 if m_iterations % 2 == 0 pz = pz - fz*fzp/(fzp^2 - fz*fzp2) else pz = pz - fz/fzp endif elseif @converge == 10 ; Mixed 4 if m_iterations % 2 == 0 pz = pz - @custom*fz*fzp/(@custom*fzp^2 - fz*fzp2) else pz = pz - fz/fzp endif endif return pz endfunc protected: complex fz complex fzp complex fzp2 complex oldz complex m_c default: title = "Cayley Mandel" int param v_cayleymandel caption = "Version (Cayley Mandel)" default = 101 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_cayleymandel < 101 endparam float param p_bailout caption = "Bailout value" default = 1e-12 endparam heading caption = "Convergence Methods" endheading param converge caption = "Convergence Method" default = 0 enum = "Newton" "Householder" "Halley" "Schroder" "Ho Custom" \ "Ha Custom" "H_S Custom" "Mixed1" "Mixed2" "Mixed3" "Mixed4" endparam float param custom caption = "H_S Constant" default = 1.5 visible = @converge==4 || @converge==5 || @converge==6 || @converge==10 endparam param p_power caption = "Power" default = (3,0) visible = false endparam } class REB_SlopeHelper { ; Helper class for REB_Slope.
;

; Makes possible the use of any object formula with REB_Slope. Works for both ; convergent and divergent formulas. Manages height values as trap shapes. public: import "common.ulb" import "Standard.ulb" ; constructor func REB_SlopeHelper(REB_Slope owner) fFormula = new @formulaclass(owner) fFormula2 = new @formulaclass2(owner) fTransfer = new @transferclass(owner) fheight = new @heightvalue(owner) fTransform = new @transform(owner) fTransform2 = new @transform2(owner) endfunc ; initialize the object complex func Init(const complex pz) fZ = fFormula.Init(pz) if @dual fZ2 = fFormula2.Init(pz) endif fTransform.init(fZ) fTransform2.init(fZ) fTransfer.Init(pz) fheight.Init(pz) fMinDist = 1e20 m_sflag = false fIterz = 0 fOldz = 0 iter = 0 return fZ endfunc ; call for each iterated point complex func Iterate() iter1 = false iter2 = false switch1 = false switch2 = false foldz = fZ if @dual if iter % (@seqgap1) >= 0 && @seqgap2 != 0 switch1 = true switch2 = false endif if (iter % (@seqgap1) >= (iter % @seqgap2)+1) || @seqgap2 == 0 switch1 = false switch2 = true endif if @seqgap2 > @seqgap1 switch1 = true switch2 = false endif endif if !@dual || @flavor == "Merge" || (@flavor == "Sequence" && @seqmethod == \ "Default") iter1 = true iter2 = true elseif @dual && @flavor == "Sequence" && @seqmethod == "By Iter Value" && \ switch1 iter1 = true elseif @dual && @flavor == "Sequence" && @seqmethod == "By Iter Value" && \ switch2 iter2 = true endif if @v_slopehelper >= 101 notx = true if @combine == "Tx1 Fr1 Fr2 Tx2" if (iter >= @prestart && iter < (@prestart+@preend))&& @transform != NullTransform fZ = (fZ + fTransform.Iterate(fZ)*@strength)/(1+@strength) if iter1 fZ = fFormula.iterate(fZ) endif if @dual if @flavor == "Sequence" fZ = (fZ + fTransform.Iterate(fZ)*@strength)/(1+@strength) if iter2 fZ = fFormula2.iterate(fZ) endif elseif @flavor == "Merge" fZ2 = (fZ2 + fTransform.Iterate(fZ2)*@strength)/(1+@strength) fZ2 = fFormula2.iterate(fZ2) endif endif notx = false endif if (iter >= @poststart && iter < (@poststart+@postend))&& @transform2 != NullTransform if iter1 fZ = fFormula.iterate(fZ) endif fZ = (fZ + fTransform2.Iterate(fZ)*@strength2)/(1+@strength2) if @dual if @flavor == "Sequence" if iter2 fZ = fFormula2.iterate(fZ) endif fZ = (fZ + fTransform2.Iterate(fZ)*@strength2)/(1+@strength2) elseif @flavor == "Merge" fZ2 = fFormula2.Iterate(fZ2) fZ2 = (fZ2 + fTransform2.Iterate(fZ2)*@strength2)/(1+@strength2) endif endif notx = false endif elseif @combine == "Tx1 Fr1 Tx2 Fr2" if (iter >= @prestart && iter < (@prestart+@postend))&& @transform != NullTransform fZ = (fZ + fTransform.Iterate(fZ)*@strength)/(1+@strength) if iter1 fZ = fFormula.iterate(fZ) endif if @dual if @flavor == "Sequence" fZ = (fZ + fTransform.Iterate(fZ)*@strength)/(1+@strength) if iter2 fZ = fFormula2.iterate(fZ) endif elseif @flavor == "Merge" fZ2 = (fZ2 + fTransform.Iterate(fZ2)*@strength)/(1+@strength) fZ2 = fFormula2.iterate(fZ2) endif endif notx = false endif if (iter >= @poststart && iter < (@poststart+@postend))&& @transform2 != NullTransform fZ = (fZ + fTransform2.Iterate(fZ)*@strength2)/(1+@strength2) if iter1 fZ = fFormula.iterate(fZ) endif if @dual if @flavor == "Sequence" fZ = (fZ + fTransform2.Iterate(fZ)*@strength2)/(1+@strength2) if iter2 fZ = fFormula2.iterate(fZ) endif elseif @flavor == "Merge" fZ2 = (fZ2 + fTransform2.Iterate(fZ2)*@strength2)/(1+@strength2) fZ2 = fFormula2.Iterate(fZ2) endif endif notx = false endif elseif @combine == "Fr1 Tx1 Tx2 Fr2" if (iter >= @prestart && iter < (@prestart+@postend))&& @transform != NullTransform if iter1 fZ = fFormula.iterate(fZ) endif fZ = (fZ + fTransform.Iterate(fZ)*@strength)/(1+@strength) if @dual if @flavor == "Sequence" if iter2 fZ = fFormula2.iterate(fZ) endif fZ = (fZ + fTransform.Iterate(fZ)*@strength)/(1+@strength) elseif @flavor == "Merge" fZ2 = fFormula2.iterate(fZ2) fZ2 = (fZ2 + fTransform.Iterate(fZ2)*@strength)/(1+@strength) endif endif notx = false endif if (iter >= @poststart && iter < (@poststart+@postend))&& @transform2 != NullTransform fZ = (fZ + fTransform2.Iterate(fZ)*@strength2)/(1+@strength2) if iter1 fZ = fFormula.iterate(fZ) endif if @dual if @flavor == "Sequence" fZ = (fZ + fTransform2.Iterate(fZ)*@strength2)/(1+@strength2) if iter2 fZ = fFormula2.iterate(fZ) endif elseif @flavor == "Merge" fZ2 = (fZ2 + fTransform2.Iterate(fZ2)*@strength2)/(1+@strength2) fZ2 = fFormula2.Iterate(fZ2) endif endif notx = false endif elseif @combine == "Fr1 Tx1 Fr2 Tx2" if (iter >= @prestart && iter < (@prestart+@postend))&& @transform != NullTransform if iter1 fZ = fFormula.iterate(fZ) endif fZ = (fZ + fTransform.Iterate(fZ)*@strength)/(1+@strength) if @dual if @flavor == "Sequence" if iter2 fZ = fFormula2.iterate(fZ) endif fZ = (fZ + fTransform.Iterate(fZ)*@strength)/(1+@strength) elseif @flavor == "Merge" fZ2 = fFormula2.iterate(fZ2) fZ2 = (fZ2 + fTransform.Iterate(fZ2)*@strength)/(1+@strength) endif endif notx = false endif if (iter >= @poststart && iter < (@poststart+@postend))&& @transform2 != NullTransform if iter1 fZ = fFormula.iterate(fZ) endif fZ = (fZ + fTransform2.Iterate(fZ)*@strength2)/(1+@strength2) if @dual if @flavor == "Sequence" if iter2 fZ = fFormula2.iterate(fZ) endif fZ = (fZ + fTransform2.Iterate(fZ)*@strength2)/(1+@strength2) elseif @flavor == "Merge" fZ2 = fFormula2.Iterate(fZ2) fZ2 = (fZ2 + fTransform2.Iterate(fZ2)*@strength2)/(1+@strength2) endif endif notx = false endif endif if notx if iter1 fZ = fFormula.iterate(fZ) endif if @dual if @flavor == "Sequence" if iter2 fZ = fFormula2.iterate(fZ) endif elseif @flavor == "Merge" fZ2 = fFormula2.iterate(fZ2) endif endif endif iter = iter + 1 if @dual && @flavor == "Merge" if @merget == "A+B" fZ = (fZ + fZ2)*@scale elseif @merget == "A+1/B" fZ = (fZ + 1/fZ2)*@scale elseif @merget == "1/A+B" fZ = (1/fZ + fZ2)*@scale elseif @merget == "A*B" fZ = (fZ*fZ2)*@scale elseif @merget == "A/B" fZ = (fZ/fZ2)*@scale elseif @merget == "B/A" fZ = (fZ2/fZ)*@scale elseif @merget == "Largest(A,B)" if cabs(fZ) < cabs(fZ2) fZ = fZ2 endif elseif @merget == "Largest(A,1/B)" if cabs(fZ) < cabs(1/fZ2) fZ = fZ2 endif elseif @merget == "Largest(1/A,B)" if cabs(1/fZ) < cabs(fZ2) fZ = fZ2 endif elseif @merget == "Smallest(A,B)" if cabs(fZ) > cabs(fZ2) fZ = fZ2 endif elseif @merget == "Smallest(A,1/B)" if cabs(fZ) > cabs(1/fZ2) fZ = fZ2 endif elseif @merget == "Smallest(1/A,B)" if cabs(1/fZ) > cabs(fZ2) fZ = fZ2 endif endif endif else fZ = fFormula.iterate(fZ) endif float d = fheight.Iterate(fZ) if d == -10000 m_sflag = true endif if @tx d = cabs(fheight.GetTransformedPoint()) endif if d < fMinDist && !m_sflag fMinDist = d endif if m_sflag if @formulaclass == DivergentFormula fIterz = fIterz + exp(-cabs(fZ)) else fIterz = fIterz + exp(-1/(cabs(fOldz - fZ))) endif endif return fZ endfunc bool func IsBailedOut() return fFormula.IsBailedOut(fZ) endfunc ; determine continuous iteration (height) float func CalcHeight(int iter) float height = fMinDist if m_sflag height = fIterz endif return fTransfer.Iterate(height) endfunc private: Formula fFormula Formula fFormula2 UserTransform fTransform UserTransform fTransform2 float fMinDist Transfer fTransfer complex fZ complex fZ2 TrapShape fheight bool m_sflag complex fOldz float fIterz int iter bool notx bool iter1 bool iter2 bool switch1 bool switch2 default: int param v_slopehelper caption = "Version (REB Slope Helper)" default = 101 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_slopehelper < 101 endparam UserTransform param transform caption = "Pre transform" default = NullTransform expanded = false visible = @v_slopehelper >= 101 endparam int param prestart caption = "Start Iter (Pre)" default = 0 visible = @transform != NullTransform && @v_slopehelper >= 101 endparam int param preend caption = "Iterations (Pre)" default = 1 visible = @transform != NullTransform && @v_slopehelper >= 101 endparam float param strength caption = "Strength (Pre)" default = 1 visible = @transform != NullTransform && @v_slopehelper >= 101 endparam bool param dual caption = "Use dual formulas" default = false visible = @v_slopehelper >= 101 endparam param combine caption = "Combine Order" default = 0 enum ="Tx1 Fr1 Fr2 Tx2" "Tx1 Fr1 Tx2 Fr2" "Fr1 Tx1 Tx2 Fr2" "Fr1 Tx1 Fr2 Tx2" visible = @dual && @v_slopehelper >= 101 endparam param flavor caption = "Combine Type" default = 0 enum = "Sequence" "Merge" visible = @dual && @v_slopehelper >= 101 endparam param seqmethod caption = "Sequence method" default = 0 enum = "Default" "By Iter Value" visible = @dual && @flavor == "Sequence" && @v_slopehelper >= 101 \ && @formulaclass != REB_Slope endparam int param seqgap1 caption = "Iteration cycle" default = 4 visible = @dual && @flavor == "Sequence" && @formulaclass != REB_Slope &&\ @seqmethod == "By Iter Value" && @v_slopehelper >= 101 endparam heading text = "'Formula 1 iters' must be less than or equal to the 'Iteration cycle' \ Out of range values will be truncated to the size of the 'Iteration \ cycle'." visible = @dual && @formulaclass != REB_Slope && @flavor == "Sequence" \ && @seqmethod == "By Iter Value" endheading int param seqgap2 caption = "Formula 1 Iters" default = 2 visible = @dual && @formulaclass != REB_Slope && @flavor == "Sequence" \ && @seqmethod == "By Iter Value" endparam param merget caption = "Merge Type" default = 0 enum = "A+B" "A+1/B" "1/A+B" "A*B" "A/B" "B/A" "Largest(A,B)" "Largest(A,1/B)"\ "Largest(1/A,B)" "Smallest(A,B)" "Smallest(A,1/B)" "Smallest(1/A,B)" visible = @dual && @flavor == "Merge" && @v_slopehelper >= 101 endparam float param scale caption = "Merge Scale" default = 1.0 visible = @dual && @flavor == "Merge" && (@merget == "A+B" || @merget == "A+1/B" \ || @merget == "1/A+B" || @merget == "A*B" || @merget == "A/B" || \ @merget == "B/A" ) && @v_slopehelper >= 101 endparam Formula param formulaClass caption = "Fractal Formula" default = REB_Julia endparam Formula param formulaClass2 caption = "Fractal Formula" default = REB_IkenagaJulia visible = @dual && @v_slopehelper >= 101 endparam UserTransform param transform2 caption = "Post transform" default = NullTransform expanded = false visible = @v_slopehelper >= 101 endparam int param poststart caption = "Start Iter (Post)" default = 0 visible = @transform2 != NullTransform && @v_slopehelper >= 101 endparam int param postend caption = "Iterations (Post)" default = 1 visible = @transform2 != NullTransform && @v_slopehelper >= 101 endparam float param strength2 caption = "Strength (Post)" default = 1 visible = @transform2 != NullTransform && @v_slopehelper >= 101 endparam TrapShape param heightvalue caption = "Height value" default = REB_TrapShapeSlopeBasic endparam Transfer param transferclass caption = "Height Transfer" default = Standard_HeightTransfer hint = "Selects a class that can transform the calculated height value." expanded = false endparam bool param tx caption = "Use transformed value" default = false visible = @heightvalue != REB_TrapShapeSlopeBasic endparam } class REB_Slope(common.ulb:Formula) { ; A slope formula that can be used with any object formualas.
;

; Original code modified from Damien M. Jones. ; Uses a special helper class that allows TrapShape plugins for height values public: import "common.ulb" ; constructor func REB_Slope(Generic pparent) Formula.Formula(pparent) fHelper[0] = new @helperclass(this) fHelper[1] = new @helperclass(this) fHelper[2] = new @helperclass(this) endfunc ; initialize the object complex func Init(complex pz) Formula.Init(pz) complex z1 = fHelper[0].Init(pz) ; primary iterated point fHelper[1].Init(pz + @offset) ; horizontally offset point fHelper[2].Init(pz + flip(@offset)) ; vertically offset point fIteration = 0 return z1 endfunc ; call for each iterated point. Overrides the parent Iterate function.
;

; We can't use the pz value because we need to keep track of three z values. ; The helper function manages the pz values and bailout. complex func Iterate(complex pz) fIteration = fIteration + 1 complex z1 = fHelper[0].Iterate() fHelper[1].Iterate() fHelper[2].Iterate() m_BailedOut = fHelper[0].IsBailedOut() if @everyiter || m_BailedOut || fIteration == #maxiter ; done, or every iteration, or last float e1 = fHelper[0].CalcHeight(fIteration) float e2 = fHelper[1].CalcHeight(fIteration) float e3 = fHelper[2].CalcHeight(fIteration) ; determine surface normal ; that is, the normal to the surface defined by: ; (real(c1), imag(c1), e1) ; (real(c2), imag(c2), e2) ; (real(c3), imag(c3), e3) float vx = e2-e1 float vy = e3-e1 float vz = -@offset ; normalize vector float vd = 1/sqrt(sqr(vx)+sqr(vy)+sqr(vz)) vx = vx*vd vy = vy*vd vz = vz*vd return vx + flip(vy); fudge z from vector else ; didn't compute z this time ; use primary iteration value to keep periodicity working return z1 endif endfunc private: REB_SlopeHelper fHelper[3] int fIteration default: title = "Slope with Shapes" int param v_slopewithshapes caption = "Version (Slope With Shapes)" default = 101 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_slopewithshapes < 101 endparam heading text = "Formulas that contain \ the word 'Switch' should not be used here. For those formulas use the 'Switch \ Slope' plugin together with 'Object Formula Switch Lite'." endheading REB_SlopeHelper param helperclass selectable = false endparam float param offset caption = "Orbit Separation" default = 0.00000001 exponential = true hint = "Defines how far apart the simultaneous orbits are. Smaller \ distances will produce more accurate results." endparam bool param everyiter caption = "Every Iteration" default = false hint = "If set, the surface normal will be computed at every \ iteration. If you are using a coloring algorithm which \ processes every iteration, you will need this." endparam complex param p_power ; Hide p_power from Formula visible = false endparam } class REB_FractalTiles(common.ulb:Formula) { ; A tiling formula that can be used with any object formualas.
;

public: import "common.ulb" ; constructor func REB_FractalTiles(Generic pparent) Formula.Formula(pparent) fFormula = new @formulaclass(this) endfunc ; initialize the object complex func Init(complex pz) Formula.Init(pz) pz=(@fn1(@fn2(real(pz)))+flip(@fn1(@fn2(imag(pz)))))/@p2 pz = fFormula.Init(pz) return pz endfunc ; call for each iterated point. Overrides the parent Iterate function.
;

complex func Iterate(complex pz) pz = fFormula.Iterate(pz) return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return fFormula.IsBailedOut(pz) endfunc private: Formula fFormula default: title = "Fractal Tiler" heading text = "This a formula that can create seamless tiles with any fractal \ object. For the best results, set the magnification on the location \ tab to 0.6366 and do not change the other location tab settings \ other than position. Set the Image width equal to the image height. \ There are other combinations that will give seamless tiles." endheading int param v_fractaltiler caption = "Version (Fractal Tiler)" 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_fractaltiler < 100 endparam Formula param formulaclass caption = "Fractal Formula" default = REB_Julia hint = "Sets the actual fractal formula to use for tiing." endparam param p2 caption = "Zoom" default = 2.0 endparam func fn1 caption = "First Function" default = tan() endfunc func fn2 caption = "Second Function" default = sin() endfunc complex param p_power ; Hide p_power from Formula visible = false endparam } ;------------------- ; ; Formula Switch Classes ; ;-------------------------- class Switch(common.ulb:ConvergentDivergentFormula) { public: import "common.ulb" ; Constructor ; func Switch(Generic pparent) ConvergentDivergentFormula.ConvergentDivergentFormula(pparent) endfunc complex func Init(complex pz) ConvergentDivergentFormula.Init(pz) m_BailedOut = false m_zold = pz return pz endfunc complex func Iterate(complex pz) ConvergentDivergentFormula.Iterate(pz) m_zold = pz return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc bool func IsBailedOut(complex pz) return |pz| > @p_upperbailout || |pz-m_zold| < @p_lowerbailout endfunc func SetParams(bool mand, bool jul, complex c) m_mand = mand m_jul = jul m_c = c endfunc func GetParams(bool &mand, bool &jul, complex &c) mand = m_mand jul = m_jul c = m_c endfunc protected: ; complex m_zold float m_bailout float m_bailout2 complex m_power int m_test complex m_c bool m_mand bool m_jul default: int param v_switchformula caption = "Version (Switch Formula)" 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_switchformula < 100 endparam float param p_upperbailout caption = "Bailout (Divergent)" default = 1.0e10 endparam float param p_lowerbailout caption = "Bailout (Convergent)" default = 1e-10 endparam } class REB_SAM_Ducks_Switch(Switch) { ; Converted from the sam.ufm wirh several additions and changes
public: import "common.ulb" ; constructor func REB_SAM_Ducks_Switch(Generic pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c ci = (0,1) endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if @v_ducksswitch <= 101 pz = exp(flip(@p2*#pi/180))*@fn1(pz) * @p3 else if @fna1 == "sin" pz = sin(pz) elseif @fna1 == "cosec" pz = 1/sin(pz) elseif @fna1 == "sinc" if cabs(pz) != 0 pz = sin(pz)/pz else pz = 1 endif elseif @fna1 == "haversin" ; pz = (1-cos(pz))/2 elseif @fna1 == "versin" pz = 1-cos(pz) elseif @fna1 == "sinh" pz = sinh(pz) elseif @fna1 == "sinhc" if cabs(pz) != 0 pz = sinh(pz)/pz else pz = 1 endif elseif @fna1 == "asin" pz = asin(pz) elseif @fna1 == "ahaversin" pz = 2*asin(sqrt(pz)) elseif @fna1 == "aversin" pz = acos(1-pz) elseif @fna1 == "asinh" pz = asinh(pz) elseif @fna1 == "cos" pz = cos(pz) elseif @fna1 == "havercos" pz = (1+cos(pz))/2 elseif @fna1 == "exsec" pz = 1/cos(pz) -1 elseif @fna1 == "excsc" pz = 1/sin(pz) -1 elseif @fna1 == "aexsec" pz = acos(1/(pz+1)) elseif @fna1 == "aexcsc" pz = asin(1/(pz+1)) elseif @fna1 == "vercos" pz = 1+cos(pz) elseif @fna1 == "sec" pz = 1/cos(pz) elseif @fna1 == "asec" pz = acos(1/pz) elseif @fna1 == "acsc" pz = -ci*log(sqrt(1 - 1/sqr(pz)) + ci/pz) elseif @fna1 == "cosh" pz = cosh(pz) elseif @fna1 == "acos" pz = acos(pz) elseif @fna1 == "ahavercos" ; pz = 2*acos(sqrt(pz)) elseif @fna1 == "avercos" ; pz = acos(1+pz) elseif @fna1 == "acosh" pz = acosh(pz) elseif @fna1 == "tan" pz = tan(pz) elseif @fna1 == "tanc" if cabs(pz) != 0 pz = tan(pz)/pz else pz = 1 endif elseif @fna1 == "tanh" pz = tanh(pz) elseif @fna1 == "tanhc" if cabs(pz) != 0 pz = tanh(pz)/pz else pz = 1 endif elseif @fna1 == "atan" pz = atan(pz) elseif @fna1 == "atan2" pz = atan2(pz) elseif @fna1 == "atanh" pz = atanh(pz) elseif @fna1 == "cotan" pz = cotan(pz) elseif @fna1 == "cotanh" pz = cotanh(pz) elseif @fna1 == "sqr" pz = sqr(pz) elseif @fna1 == "sqrt" pz = sqrt(pz) elseif @fna1 == "cube" pz = pz^3 elseif @fna1 == "cuberoot" pz = pz^(1/3) elseif @fna1 == "log" pz = log(pz) elseif @fna1 == "logit" pz = log(pz/(1-pz)) elseif @fna1 == "colog" pz = -log(pz) elseif @fna1 == "exp" pz = exp(pz) elseif @fna1 == "gauss" pz = exp(-sqr(pz)) elseif @fna1 == "gd" pz = 2*atan(tanh(0.5*pz)) elseif @fna1 == "agd" pz = 2*atanh(tan(0.5*pz)) elseif @fna1 == "sigmoid" pz = 1/(1+exp(-pz)) elseif @fna1 == "abs" pz = abs(pz) elseif @fna1 == "cabs" pz = cabs(pz) elseif @fna1 == "conj" pz = conj(pz) elseif @fna1 == "flip" pz = flip(pz) elseif @fna1 == "ident" pz = ident(pz) elseif @fna1 == "recip" pz = recip(pz) elseif @fna1 == "ceil" pz = ceil(pz) elseif @fna1 == "floor" pz = floor(pz) elseif @fna1 == "trunc" pz = trunc(pz) elseif @fna1 == "round" pz = round(pz) endif if @useold && @v_ducksswitch > 102 pz = exp(flip(@p2*#pi/180))*pz + @p3 if @addpix pz = exp(flip(@p2*#pi/180))*pz + @p3 + m_c endif else pz = exp(flip(@p2*#pi/180))*pz * @p3 endif endif arg = real(round(atan2(pz)/(2*#pi)*@order)/@order)*2*#pi pz = pz*exp(-flip(arg)) if @v_ducksswitch < 101 pz = real(pz) + flip(abs(imag(pz))) endif if @v_ducksswitch == 101 if @flavor == 0 pz = real(pz) + flip(abs(imag(pz))) endif if @flavor == 1 pz = @fn3(pz) pz = real(pz) + flip(abs(imag(pz))) endif if @flavor == 2 pz = @fn3(abs(pz)) endif endif if @v_ducksswitch > 101 if @flavor == 0 pz = real(pz) + flip(abs(imag(pz))) elseif @flavor == 3 pz = pz - real(pz) + abs(real(pz)) endif if @flavor == 2 if @fna3 == "sin" pz = sin(abs(pz)) elseif @fna3 == "cosec" pz = 1/sin(abs(pz)) elseif @fna3 == "sinc" if cabs(pz) != 0 pz = sin(abs(pz))/abs(pz) else pz = 1 endif elseif @fna3 == "haversin" pz = (1-cos(abs(pz)))/2 elseif @fna3 == "versin" pz = 1-cos(abs(pz)) elseif @fna3 == "sinh" pz = sinh(abs(pz)) elseif @fna3 == "sinhc" if cabs(pz) != 0 pz = sinh(abs(pz))/abs(pz) else pz = 1 endif elseif @fna3 == "asin" pz = asin(abs(pz)) elseif @fna3 == "ahaversin" pz = 2*asin(sqrt(abs(pz))) elseif @fna3 == "aversin" pz = acos(1-abs(pz)) elseif @fna3 == "asinh" pz = asinh(abs(pz)) elseif @fna3 == "cos" pz = cos(abs(pz)) elseif @fna3 == "havercos" pz = (1+cos(abs(pz)))/2 elseif @fna3 == "exsec" pz = 1/cos(abs(pz)) -1 elseif @fna3 == "excsc" pz = 1/sin(abs(pz)) -1 elseif @fna3 == "aexsec" pz = acos(1/(abs(pz)+1)) elseif @fna3 == "aexcsc" pz = asin(1/(abs(pz)+1)) elseif @fna3 == "vercos" pz = 1+cos(abs(pz)) elseif @fna3 == "sec" pz = 1/cos(abs(pz)) elseif @fna3 == "asec" pz = acos(1/abs(pz)) elseif @fna3 == "acsc" pz = -ci*log(sqrt(1 - 1/sqr(abs(pz))) + ci/abs(pz)) elseif @fna3 == "cosh" pz = cosh(abs(pz)) elseif @fna3 == "acos" pz = acos(abs(pz)) elseif @fna3 == "ahavercos" pz = 2*acos(sqrt(abs(pz))) elseif @fna3 == "avercos" pz = acos(1+abs(pz)) elseif @fna3 == "acosh" pz = acosh(abs(pz)) elseif @fna3 == "tan" pz = tan(abs(pz)) elseif @fna3 == "tanc" if cabs(pz) != 0 pz = tan(abs(pz))/abs(pz) else pz = 1 endif elseif @fna3 == "tanh" pz = tanh(abs(pz)) elseif @fna3 == "tanhc" if cabs(pz) != 0 pz = tanh(abs(pz))/abs(pz) else pz = 1 endif elseif @fna3 == "atan" pz = atan(abs(pz)) elseif @fna3 == "atan2" pz = atan2(abs(pz)) elseif @fna3 == "atanh" pz = atanh(abs(pz)) elseif @fna3 == "cotan" pz = cotan(abs(pz)) elseif @fna3 == "cotanh" pz = cotanh(abs(pz)) elseif @fna3 == "sqr" pz = sqr(abs(pz)) elseif @fna3 == "sqrt" pz = sqrt(abs(pz)) elseif @fna3 == "cube" pz = abs(pz)^3 elseif @fna3 == "cuberoot" pz = abs(pz)^(1/3) elseif @fna3 == "log" pz = log(abs(pz)) elseif @fna3 == "logit" pz = log(abs(pz)/(1-abs(pz))) elseif @fna3 == "colog" pz = -log(abs(pz)) elseif @fna3 == "exp" pz = exp(abs(pz)) elseif @fna3 == "gauss" pz = exp(-sqr(abs(pz))) elseif @fna3 == "gd" pz = 2*atan(tanh(0.5*abs(pz))) elseif @fna3 == "agd" pz = 2*atanh(tan(0.5*abs(pz))) elseif @fna3 == "sigmoid" pz = 1/(1+exp(-abs(pz))) elseif @fna3 == "abs" pz = abs(abs(pz)) elseif @fna3 == "cabs" pz = cabs(abs(pz)) elseif @fna3 == "conj" pz = conj(abs(pz)) elseif @fna3 == "flip" pz = flip(abs(pz)) elseif @fna3 == "ident" pz = ident(abs(pz)) elseif @fna3 == "recip" pz = recip(abs(pz)) elseif @fna3 == "ceil" pz = ceil(abs(pz)) elseif @fna3 == "floor" pz = floor(abs(pz)) elseif @fna3 == "trunc" pz = trunc(abs(pz)) elseif @fna3 == "round" pz = round(abs(pz)) endif endif if @flavor == 1 if @fna3 == "sin" pz = sin(pz) elseif @fna3 == "cosec" pz = 1/sin(pz) elseif @fna3 == "sinc" if cabs(pz) != 0 pz = sin(pz)/pz else pz = 1 endif elseif @fna3 == "haversin" pz = (1-cos(pz))/2 elseif @fna3 == "versin" pz = 1-cos(pz) elseif @fna3 == "sinh" pz = sinh(pz) elseif @fna3 == "sinhc" if cabs(pz) != 0 pz = sinh(pz)/pz else pz = 1 endif elseif @fna3 == "asin" pz = asin(pz) elseif @fna3 == "ahaversin" pz = 2*asin(sqrt(pz)) elseif @fna3 == "aversin" pz = acos(1-pz) elseif @fna3 == "asinh" pz = asinh(pz) elseif @fna3 == "cos" pz = cos(pz) elseif @fna3 == "havercos" pz = (1+cos(pz))/2 elseif @fna3 == "exsec" pz = 1/cos(pz) -1 elseif @fna3 == "excsc" pz = 1/sin(pz) -1 elseif @fna3 == "aexsec" pz = acos(1/(pz+1)) elseif @fna3 == "aexcsc" pz = asin(1/(pz+1)) elseif @fna3 == "vercos" pz = 1+cos(pz) elseif @fna3 == "sec" pz = 1/cos(pz) elseif @fna3 == "asec" pz = acos(1/pz) elseif @fna3 == "acsc" pz = -ci*log(sqrt(1 - 1/sqr(pz)) + ci/pz) elseif @fna3 == "cosh" pz = cosh(pz) elseif @fna3 == "acos" pz = acos(pz) elseif @fna3 == "ahavercos" pz = 2*acos(sqrt(pz)) elseif @fna3 == "avercos" pz = acos(1+pz) elseif @fna3 == "acosh" pz = acosh(pz) elseif @fna3 == "tan" pz = tan(pz) elseif @fna3 == "tanc" if cabs(pz) != 0 pz = tan(pz)/pz else pz = 1 endif elseif @fna3 == "tanh" pz = tanh(pz) elseif @fna3 == "tanhc" if cabs(pz) != 0 pz = tanh(pz)/pz else pz = 1 endif elseif @fna3 == "atan" pz = atan(pz) elseif @fna3 == "atan2" pz = atan2(pz) elseif @fna3 == "atanh" pz = atanh(pz) elseif @fna3 == "cotan" pz = cotan(pz) elseif @fna3 == "cotanh" pz = cotanh(pz) elseif @fna3 == "sqr" pz = sqr(pz) elseif @fna3 == "sqrt" pz = sqrt(pz) elseif @fna3 == "cube" pz = pz^3 elseif @fna3 == "cuberoot" pz = pz^(1/3) elseif @fna3 == "log" pz = log(pz) elseif @fna3 == "logit" pz = log(pz/(1-pz)) elseif @fna3 == "colog" pz = -log(pz) elseif @fna3 == "exp" pz = exp(pz) elseif @fna3 == "gauss" pz = exp(-sqr(pz)) elseif @fna3 == "gd" pz = 2*atan(tanh(0.5*pz)) elseif @fna3 == "agd" pz = 2*atanh(tan(0.5*pz)) elseif @fna3 == "sigmoid" pz = 1/(1+exp(-pz)) elseif @fna3 == "abs" pz = abs(pz) elseif @fna3 == "cabs" pz = cabs(pz) elseif @fna3 == "conj" pz = conj(pz) elseif @fna3 == "flip" pz = flip(pz) elseif @fna3 == "ident" pz = ident(pz) elseif @fna3 == "recip" pz = recip(pz) elseif @fna3 == "ceil" pz = ceil(pz) elseif @fna3 == "floor" pz = floor(pz) elseif @fna3 == "trunc" pz = trunc(pz) elseif @fna3 == "round" pz = round(pz) endif pz = real(pz) + flip(abs(imag(pz))) endif endif if @v_ducksswitch <= 101 pz = @fn2((log(pz^m_power)+m_c)^@pow) else if @fna2 == "sin" pz = sin((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "cosec" pz = 1/sin((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "sinc" if cabs((log(pz^m_power)+m_c)^@pow) != 0 pz = sin((log(pz^m_power)+m_c)^@pow)/(log(pz^m_power)+m_c)^@pow else pz = (log(1)+m_c)^@pow endif elseif @fna2 == "haversin" pz = (1-cos((log(pz^m_power)+m_c)^@pow))/2 elseif @fna2 == "versin" pz = 1-cos((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "sinh" pz = sinh((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "sinhc" if cabs((log(pz^m_power)+m_c)^@pow) != 0 pz = sinh((log(pz^m_power)+m_c)^@pow)/(log(pz^m_power)+m_c)^@pow else pz = (log(1)+m_c)^@pow endif elseif @fna2 == "asin" pz = asin((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "ahaversin" ; pz = 2*asin(sqrt((log(pz^m_power)+m_c)^@pow)) elseif @fna2 == "aversin" ; pz = acos(1-(log(pz^m_power)+m_c)^@pow) elseif @fna2 == "asinh" pz = asinh((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "cos" pz = cos((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "havercos" ; pz = (1+cos((log(pz^m_power)+m_c)^@pow))/2 elseif @fna2 == "exsec" pz = 1/cos((log(pz^m_power)+m_c)^@pow) -1 elseif @fna2 == "excsc" pz = 1/sin((log(pz^m_power)+m_c)^@pow) -1 elseif @fna2 == "aexsec" pz = acos(1/((log(pz^m_power)+m_c)^@pow+1)) elseif @fna2 == "aexcsc" pz = asin(1/((log(pz^m_power)+m_c)^@pow+1)) elseif @fna2 == "vercos" pz = 1+cos((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "sec" pz = 1/cos((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "asec" pz = acos(1/(log(pz^m_power)+m_c)^@pow) elseif @fna2 == "acsc" pz = -ci*log(sqrt(1 - 1/sqr((log(pz^m_power)+m_c)^@pow)) + \ ci/(log(pz^m_power)+m_c)^@pow) elseif @fna2 == "cosh" pz = cosh((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "acos" pz = acos((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "ahavercos" ; pz = 2*acos(sqrt(log(pz^m_power)+m_c)^@pow) elseif @fna2 == "avercos" ; pz = acos(1+(log(pz^m_power)+m_c)^@pow) elseif @fna2 == "acosh" pz = acosh((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "tan" pz = tan((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "tanc" if cabs((log(pz^m_power)+m_c)^@pow) != 0 pz = tan((log(pz^m_power)+m_c)^@pow)/(log(pz^m_power)+m_c)^@pow else pz = (log(1)+m_c)^@pow endif elseif @fna2 == "tanh" pz = tanh((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "tanhc" if cabs((log(pz^m_power)+m_c)^@pow) != 0 pz = tanh((log(pz^m_power)+m_c)^@pow)/(log(pz^m_power)+m_c)^@pow else pz = (log(1)+m_c)^@pow endif elseif @fna2 == "atan" pz = atan((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "atan2" pz = atan2((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "atanh" pz = atanh((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "cotan" pz = cotan((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "cotanh" pz = cotanh((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "sqr" pz = sqr((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "sqrt" pz = sqrt((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "cube" pz = (log(pz^m_power)+m_c)^@pow^3 elseif @fna2 == "cuberoot" pz = (log(pz^m_power)+m_c)^@pow^(1/3) elseif @fna2 == "log" pz = log((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "logit" pz = log((log(pz^m_power)+m_c)^@pow/(1-(log(pz^m_power)+m_c)^@pow)) elseif @fna2 == "colog" pz = -log((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "exp" pz = exp((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "gauss" pz = exp(-sqr((log(pz^m_power)+m_c)^@pow)) elseif @fna2 == "gd" pz = 2*atan(tanh(0.5*(log(pz^m_power)+m_c)^@pow)) elseif @fna2 == "agd" pz = 2*atanh(tan(0.5*(log(pz^m_power)+m_c)^@pow)) elseif @fna2 == "sigmoid" pz = 1/(1+exp(-(log(pz^m_power)+m_c)^@pow)) elseif @fna2 == "abs" pz = abs((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "cabs" pz = cabs((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "conj" pz = conj((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "flip" pz = flip((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "ident" pz = ident((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "recip" pz = recip((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "ceil" pz = ceil((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "floor" pz = floor((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "trunc" pz = trunc((log(pz^m_power)+m_c)^@pow) elseif @fna2 == "round" pz = round((log(pz^m_power)+m_c)^@pow) endif endif return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return (m_iterations > @maxiter) endfunc private: float arg complex ci default: title = "Ducks Switch" int param v_ducksswitch caption = "Version (Ducks Switch)" default = 103 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_ducksswitch < 103 endparam heading text = "This formula derived from the Ducks formula sam.ufm with multiple modifications. \ Bailout is determined by the number of iterations rather than a \ convergence or divergence criteria, so an iterations parameter which \ is independent of the value on the Maximum Iterations vslue on \ the Formula Tab has been included. The value for 'Iterations for Bailout' \ must always be less than the Maximum Iterations setting. Unlike other \ Duck formulas the Outside Coloring tab should be used. If the coloring \ method has options of convergent or divergent coloring, convergent \ coloring will usually be the best choice." endheading heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.433443,-1.571891) visible = @mans && @stype == "Julia" endparam int param maxiter caption = "Iterations for Bailout" default = 100 endparam float param p2 caption = "Angle (deg)" default = 0.0 endparam bool param useold caption = "Use Sam's version of 'Twist'" default = false visible = @v_ducksswitch > 102 endparam bool param addpix caption = "Add pixel value" default = false visible = @v_ducksswitch > 102 && @useold endparam complex param p3 caption = "Twist" default = (1,0) endparam complex param order caption = "Order" default = (1,0) endparam complex param p_power ; Overrides p_power from Formula caption = "First Power" default = (1,0) endparam complex param pow caption = "Second power" default = (1,0) endparam param flavor caption = "Pattern Flavor" default = 0 enum = "flavor 1" "flavor 2" "flavor 3" "flavor 4" visible = @v_ducksswitch > 100 endparam heading text = "'Ducks Switch' has an extended set of single arguemt functions, \ mostly taken from from the special functions section of Wolfram Mathworld." visible = @v_ducksswitch >= 102 endheading heading text = "'Flavor 4' has elements from the Celtic and Druid Mandelbrot formulas. To use \ either set 'Pattern Modifier 1' or 'Pattern Modifier 2' to something other than \ ident()." visible = @v_ducksswitch >= 103 && @flavor == 3 endheading func fn1 caption = "Pattern Modifier 1" default = ident() visible = @v_ducksswitch <= 101 endfunc param fna1 caption = "Pattern Modifier 1" default = 51 enum = "sin" "cosec" "sinc" "haversin" "versin" "sinh" "sinhc" "asin" "ahaversin" "aversin" "asinh" \ "cos" "havercos" "exsec" "excsc" "aexsec" "aexcsc" "vercos" "sec" "asec" \ "acsc" "cosh" "acos" "ahavercos" "avercos" "acosh" "tan" "tanc" "tanh" "tanhc" \ "atan" "atan2" "atanh" "cotan" "cotanh" "sqr" "sqrt" "cube" "cuberoot" \ "log" "logit" "colog" "exp" "gauss" "gd" "agd" "sigmoid" "abs" "cabs" "conj" "flip" \ "ident" "recip" "ceil" "floor" "trunc" "round" visible = @v_ducksswitch >= 102 endparam func fn2 caption = "Pattern Modifier 2" default = ident() visible = @v_ducksswitch <= 101 endfunc param fna2 caption = "Pattern Modifier 2" default = 51 enum = "sin" "cosec" "sinc" "haversin" "versin" "sinh" "sinhc" "asin" "ahaversin" "aversin" "asinh" \ "cos" "havercos" "exsec" "excsc" "aexsec" "aexcsc" "vercos" "sec" "asec" \ "acsc" "cosh" "acos" "ahavercos" "avercos" "acosh" "tan" "tanc" "tanh" "tanhc" \ "atan" "atan2" "atanh" "cotan" "cotanh" "sqr" "sqrt" "cube" "cuberoot" \ "log" "logit" "colog" "exp" "gauss" "gd" "agd" "sigmoid" "abs" "cabs" "conj" "flip" \ "ident" "recip" "ceil" "floor" "trunc" "round" visible = @v_ducksswitch >= 102 endparam func fn3 caption = "Pattern Modifier 3" default = log() visible = @v_ducksswitch > 100 && @v_ducksswitch <= 101 && @flavor != 0 endfunc param fna3 caption = "Pattern Modifier 3" default = 39 enum = "sin" "cosec" "sinc" "haversin" "versin" "sinh" "sinhc" "asin" "ahaversin" "aversin" "asinh" \ "cos" "havercos" "exsec" "excsc" "aexsec" "aexcsc" "vercos" "sec" "asec" \ "acsc" "cosh" "acos" "ahavercos" "avercos" "acosh" "tan" "tanc" "tanh" "tanhc" \ "atan" "atan2" "atanh" "cotan" "cotanh" "sqr" "sqrt" "cube" "cuberoot" \ "log" "logit" "colog" "exp" "gauss" "gd" "agd" "sigmoid" "abs" "cabs" "conj" "flip" \ "ident" "recip" "ceil" "floor" "trunc" "round" visible = @v_ducksswitch >= 102 && @flavor != 0 && @flavor != 3 endparam float param p_upperbailout caption = "Bailout value" default = 10000 min = 1.0 visible = false endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam } class REB_OldPhoenix_Switch(Switch) { public: import "common.ulb" ; constructor func REB_OldPhoenix_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif complex z2 = pz pz = flip(pz) x1 = 0 y = 0 if m_mand m_c = z2 pz = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) x1 = pz*pz + real(m_c) + imag(m_c)*y y = pz pz = x1 return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc protected: complex x1 complex y default: title = "Old Phoenix Switch" int param v_OldPhoenixswitch caption = "Version (Old Phoenix Switch)" 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_OldPhoenixswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.56667,-0.5) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_Phoenix_Switch(Switch) { public: import "common.ulb" ; constructor func REB_Phoenix_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif newz= 0 y = 0 if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) newz = pz^m_power + pz^@power2*m_c + @induct*y y = pz pz = newz return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc protected: complex newz complex y default: title = "Phoenix Switch" int param v_Phoenixswitch caption = "Version (Phoenix Switch)" 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_Phoenixswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.566667,0) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) endparam param power2 caption = "Exponent 2" default = (0,0) hint = "Defines the secondary exponent for the fractal. The classic \ Phoenix curve uses exponent (0, 0)." endparam heading text = "The standard value for 'Distortion' is (0.5,0). The given value is \ the one which produces the classical Phoenix Julia." endheading param induct caption = "Distortion" default = (-0.5,0) hint = "Sets how 'strong' the previous iteration's effect should be \ on the fractal." endparam } class REB_Chebyshev_Switch(Switch) { public: import "common.ulb" ; constructor func REB_Chebyshev_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return m_c*cos(@n*acos(pz)) endfunc complex func Drcalc(complex pz, complex zd) zd = @n*m_c*sin(@n*acos(pz))/sqrt(1-pz^2)*zd return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Chebyshev Switch" int param v_ChebyshevSwitch caption = "Version (Chebyshev Switch)" 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_ChebyshevSwitch < 100 endparam heading text = "The Chebyshev polynomials of the first kind are a set of orthogonal \ polynomials defined as the solutions to the Chebyshev differential \ equation. They are used as an approximation to a least squares fit \ to a set of points. These polynomials can also be used to define an \ interesting set of fractals." endheading heading text = "The non-polynomial algorithm is from Wikipedia, and has been generalized \ to use complex values and a seed value added to create fractals. \ The 'n' value is the number of the Chebyshev Polynomial." endheading heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (1,0) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam int param n caption = "Chebyshev number" default = 2 min = 2 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_Legendre_Switch(Switch) { public: import "common.ulb" ; constructor func REB_Legendre_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if @n == 2 pz = m_c*(3*pz^2 - 1)/2 elseif @n == 3 pz = m_c*(5*pz^3 - 3*pz)/2 elseif @n == 4 pz = m_c*(35*pz^4 - 30*pz^2 + 3)/8 elseif @n == 5 pz = m_c*(63*pz^5 - 70*pz^3 + 15*pz)/8 elseif @n == 6 pz = m_c*(231*pz^6 - 315*pz^4 + 105*pz^2 -5)/16 endif return pz endfunc complex func Drcalc(complex pz, complex zd) if @n == 2 zd = m_c*3*pz*zd + (3*pz^2 - 1)/2 elseif @n == 3 zd = m_c*(15*pz^2 - 3)/2*zd + (5*pz^3 - 3*pz)/2 elseif @n == 4 zd = m_c*(35*pz^3 - 15*pz)/2*zd + (35*pz^4 - 30*pz^2 + 3)/8 elseif @n == 5 zd = m_c*(315*pz^4 - 210*pz^2 + 15)/8*zd + (63*pz^5 - 70*pz^3 + 15*pz)/8 elseif @n == 6 zd = m_c*(1386*pz^5 - 1260*pz^3 + 210*pz)/16*zd + (231*pz^6 - 315*pz^4 + 105*pz^2 -5)/16 endif return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Legendre Switch" int param v_LegendreSwitch caption = "Version (Legendre Switch)" 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_LegendreSwitch < 100 endparam heading text = "Legendre polynomials are solutions to the Legendre differential equation \ which is frequently encountered in physics and other technical fields. \ These polynomials can also be used to define an \ interesting set of fractals." endheading heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (1,0) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam int param n caption = "Legendre number" default = 2 min = 2 max = 6 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_Laguerre_Switch(Switch) { public: import "common.ulb" ; constructor func REB_Laguerre_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if @n == 2 pz = m_c*(pz^2 - 4*pz + 2)/2 elseif @n == 3 pz = m_c*(-pz^3 + 9*pz^2 - 18*pz + 6)/6 elseif @n == 4 pz = m_c*(pz^4 - 16*pz^3 + 72*pz^2 - 96*pz + 24)/24 elseif @n == 5 pz = m_c*(-pz^5 + 25*pz^4 - 200*pz^3 + 600*pz^2 - 600*pz + 120)/120 elseif @n == 6 pz = m_c*(pz^6 - 36*pz^5 + 450*pz^4 - 2400*pz^3 + 5400*pz^2 \ -4320*pz + 720)/720 endif return pz endfunc complex func Drcalc(complex pz, complex zd) if @n == 2 zd = (pz^2 - 4*pz + 2)/2 + m_c*zd*(2*pz - 4)/2 elseif @n == 3 zd = (-pz^3 + 9*pz^2 - 18*pz + 6)/6 + m_c*zd*(-3*pz^2 + 18*pz - 18)/6 elseif @n == 4 zd = (pz^4 - 16*pz^3 + 72*pz^2 - 96*pz + 24)/24 + m_c*zd*(4*pz^3 - 48*pz^2 + \ 144*pz - 96)/24 elseif @n == 5 zd = (-pz^5 + 25*pz^4 - 200*pz^3 + 600*pz^2 - 600*pz + 120)/120 + \ m_c*zd*(-5*pz^4 + 100*pz^3 - 600*pz^2 + 1200*pz -600 )/120 elseif @n == 6 zd = (pz^6 - 36*pz^5 + 450*pz^4 - 2400*pz^3 + 5400*pz^2 - 4320*pz + 720)/720 + \ m_c*zd*(6*pz^5 - 180*pz^4 + 1800*pz^3 - 7200*pz^2 + 10800*pz - 4320 )/720 endif return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Laguerre Switch" int param v_LaguerreSwitch caption = "Version (Laguerre Switch)" 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_LaguerreSwitch < 100 endparam heading text = "The Laguerre polynomials are solutions to Laguerre's differential equation. \ The Laguerre polynomials arise in quantum mechanics, in the radial part \ of the solution of the Schrödinger equation for a one-electron atom. \ These polynomials can also be used to define an \ interesting set of fractals." endheading heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (1,0) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam int param n caption = "Laguerre number" default = 2 min = 2 max = 6 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_MandelbrotJulia_Switch(Switch) { public: import "common.ulb" ; constructor func REB_MandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return pz^m_power + m_c endfunc complex func Drcalc(complex pz, complex zd) zd = m_power*pz^(m_power-1)*zd + 1 return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Mandelbrot Julia Switch" int param v_mandelbrotjuliaswitch caption = "Version (Mandelbrot Julia Switch)" default = 101 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_mandelbrotjuliaswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam } class REB_LucyGoosey_Switch(Switch) { import "common.ulb" ; constructor func REB_LucyGoosey_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c ci = (0,1) endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) iter1 = false iter2 = false switch1 = false switch2 = false if @smethod == 1 && @v_lucygooseyswitch >= 103 if m_iterations % (@seqgap1) >= 0 && @seqgap2 != 0 switch1 = true switch2 = false endif if (m_iterations % (@seqgap1) >= (m_iterations % @seqgap2)+1) || @seqgap2 == 0 switch1 = false switch2 = true endif if @seqgap2 > @seqgap1 switch1 = true switch2 = false endif endif if @v_lucygooseyswitch < 103 || @smethod == 0 switch1 = (m_iterations % @modulus == 1) if switch1 == true switch2 = false else switch2 = true endif endif if @v_lucygooseyswitch > 100 if @v_lucygooseyswitch < 104 pz = @fn5(pz) endif if @v_lucygooseyswitch >= 104 if @fn7 == "sin" pz = sin(pz) elseif @fn7 == "sinxx" pz = conj(sin(pz)) elseif @fn7 == "cosec" pz = 1/sin(pz) elseif @fn7 == "sinc" if cabs(pz) != 0 pz = sin(pz)/pz else pz = 1 endif elseif @fn7 == "haversin" pz = (1-cos(pz))/2 elseif @fn7 == "versin" pz = 1-cos(pz) elseif @fn7 == "sinh" pz = sinh(pz) elseif @fn7 == "sinhc" if cabs(pz) != 0 pz = sinh(pz)/pz else pz = 1 endif elseif @fn7 == "asin" pz = asin(pz) elseif @fn7 == "ahaversin" pz = 2*asin(sqrt(pz)) elseif @fn7 == "aversin" pz = acos(1-pz) elseif @fn7 == "asinh" pz = asinh(pz) elseif @fn7 == "cos" pz = cos(pz) elseif @fn7 == "cosxx" pz = conj(cos(pz)) elseif @fn7 == "havercos" pz = (1+cos(pz))/2 elseif @fn7 == "exsec" pz = 1/cos(pz) -1 elseif @fn7 == "excsc" pz = 1/sin(pz) -1 elseif @fn7 == "aexsec" pz = acos(1/(pz+1)) elseif @fn7 == "aexcsc" pz = asin(1/(pz+1)) elseif @fn7 == "vercos" pz = 1+cos(pz) elseif @fn7 == "sec" pz = 1/cos(pz) elseif @fn7 == "asec" pz = acos(1/pz) elseif @fn7 == "acsc" pz = -ci*log(sqrt(1-1/sqr(pz)) + ci/pz) elseif @fn7 == "cosh" pz = cosh(pz) elseif @fn7 == "acos" pz = acos(pz) elseif @fn7 == "ahavercos" pz = 2*acos(sqrt(pz)) elseif @fn7 == "avercos" pz = acos(1+pz) elseif @fn7 == "acosh" pz = acosh(pz) elseif @fn7 == "tan" pz = tan(pz) elseif @fn7 == "tanc" if cabs(pz) != 0 pz = tan(pz)/pz else pz = 1 endif elseif @fn7 == "tanh" pz = tanh(pz) elseif @fn7 == "tanhc" if cabs(pz) != 0 pz = tanh(pz)/pz else pz = 1 endif elseif @fn7 == "atan" pz = atan(pz) elseif @fn7 == "atan2" pz = atan2(pz) elseif @fn7 == "atanh" pz = atanh(pz) elseif @fn7 == "cotan" pz = cotan(pz) elseif @fn7 == "cotanh" pz = cotanh(pz) elseif @fn7 == "sqr" pz = sqr(pz) elseif @fn7 == "sqrt" pz = sqrt(pz) elseif @fn7 == "cube" pz = pz^3 elseif @fn7 == "cuberoot" pz = pz^(1/3) elseif @fn7 == "log" pz = log(pz) elseif @fn7 == "logit" pz = log(pz/(1-pz)) elseif @fn7 == "colog" pz = -log(pz) elseif @fn7 == "exp" pz = exp(pz) elseif @fn7 == "gauss" pz = exp(-sqr(pz)) elseif @fn7 == "gd" pz = 2*atan(tanh(0.5*pz)) elseif @fn7 == "agd" pz = 2*atanh(tan(0.5*pz)) elseif @fn7 == "sigmoid" pz = 1/(1+exp(-pz)) elseif @fn7 == "abs" pz = abs(pz) elseif @fn7 == "cabs" pz = cabs(pz) elseif @fn7 == "conj" pz = conj(pz) elseif @fn7 == "flip" pz = flip(pz) elseif @fn7 == "recip" pz = recip(pz) elseif @fn7 == "ceil" pz = ceil(pz) elseif @fn7 == "floor" pz = floor(pz) elseif @fn7 == "trunc" pz = trunc(pz) elseif @fn7 == "round" pz = round(pz) ; endif elseif @fn7 == "coversin" pz = 1-sin(pz) elseif @fn7 == "acoversin" pz = asin(1-pz) elseif @fn7 == "hacoversin" pz = (1-sin(pz))/2 elseif @fn7 == "covercos" pz = 1 + sin(pz) elseif @fn7 == "acovercos" pz = asin(1+pz) elseif @fn7 == "hacovercos" pz = (1+sin(pz))/2 elseif @fn7 == "acotan" pz = atan(1/pz) elseif @fn7 == "acotanh" pz = atanh(1/pz) elseif @fn7 == "sech" pz = 1/(cosh(pz)) elseif @fn7 == "crd" pz = 2*sin(pz/2) elseif @fn7 == "acrd" pz = 2*asin(pz/2) elseif @fn7 == "asech" pz = acosh(1/pz) elseif @fn7 == "cosech" pz = 1/sinh(pz) elseif @fn7 == "acosech" pz = asinh(1/pz) elseif @fn7 == "coshc" if cabs(pz) != 0 pz = cosh(pz)/pz else pz = 1 endif elseif @fn7 == "cosc" if cabs(pz) != 0 pz = cos(pz)/pz else pz = 1 endif elseif @fn7 == "cotanc" if cabs(pz) != 0 pz = cotan(pz)/pz else pz = 1 endif elseif @fn7 == "cotanhc" if cabs(pz) != 0 pz = cotanh(pz)/pz else pz = 1 endif elseif @fn7 == "secc" if cabs(pz) != 0 pz = 1/(pz*cos(pz)) else pz = 1 endif elseif @fn7 == "sechc" if cabs(pz) != 0 pz = 1/(pz*cosh(pz)) else pz = 1 endif elseif @fn7 == "cosecc" if cabs(pz) != 0 pz = 1/(pz*sin(pz)) else pz = 1 endif elseif @fn7 == "cosechc" if cabs(pz) != 0 pz = 1/(pz*sinh(pz)) else pz = 1 endif elseif @fn7 == "logistic" pz = 1/(1+exp(-pz)) elseif @fn7 == "softplus" pz = log(1+exp(pz)) elseif @fn7 == "primecount" pz = pz/log(pz) endif endif if @v_lucygooseyswitch > 101 arg = real(round(atan2(pz)/(2*#pi)*@order)/@order)*2*#pi pz = pz*exp(-flip(arg)) endif endif if switch1 ; Mod formula if @vm11 == 0 pz = real(pz) + flip(abs(imag(pz))) elseif @vm11 == 1 pz = abs(pz) elseif @vm11 == 2 pz = pz - real(pz) + abs(real(pz)) endif pz = @p2*(@fn3(pz^m_power)+m_c) + @fn4(m_c) endif if switch2 ; Main formula if @v_lucygooseyswitch <= 101 arg = real(round(atan2(pz)/(2*#pi)*@order)/@order)*2*#pi pz = pz*exp(-flip(arg)) endif if @vm21 == 0 pz = real(pz) + flip(abs(imag(pz))) elseif @vm21 == 1 pz = abs(pz) elseif @vm21 == 2 pz = pz - real(pz) + abs(real(pz)) endif pz = @fn1((@p1*pz^@power2) + @fn2(m_c)) + @p1*pz endif if @v_lucygooseyswitch > 100 if @v_lucygooseyswitch < 104 pz = @fn6(pz) endif if @v_lucygooseyswitch >= 104 if @fn8 == "sin" pz = sin(pz) elseif @fn8 == "sinxx" pz = conj(sin(pz)) elseif @fn8 == "cosec" pz = 1/sin(pz) elseif @fn8 == "sinc" if cabs(pz) != 0 pz = sin(pz)/pz else pz = 1 endif elseif @fn8 == "haversin" pz = (1-cos(pz))/2 elseif @fn8 == "versin" pz = 1-cos(pz) elseif @fn8 == "sinh" pz = sinh(pz) elseif @fn8 == "sinhc" if cabs(pz) != 0 pz = sinh(pz)/pz else pz = 1 endif elseif @fn8 == "asin" pz = asin(pz) elseif @fn8 == "ahaversin" pz = 2*asin(sqrt(pz)) elseif @fn8 == "aversin" pz = acos(1-pz) elseif @fn8 == "asinh" pz = asinh(pz) elseif @fn8 == "cos" pz = cos(pz) elseif @fn8 == "cosxx" pz = conj(cos(pz)) elseif @fn8 == "havercos" pz = (1+cos(pz))/2 elseif @fn8 == "exsec" pz = 1/cos(pz) -1 elseif @fn8 == "excsc" pz = 1/sin(pz) -1 elseif @fn8 == "aexsec" pz = acos(1/(pz+1)) elseif @fn8 == "aexcsc" pz = asin(1/(pz+1)) elseif @fn8 == "vercos" pz = 1+cos(pz) elseif @fn8 == "sec" pz = 1/cos(pz) elseif @fn8 == "asec" pz = acos(1/pz) elseif @fn8 == "acsc" pz = -ci*log(sqrt(1-1/sqr(pz)) + ci/pz) elseif @fn8 == "cosh" pz = cosh(pz) elseif @fn8 == "acos" pz = acos(pz) elseif @fn8 == "ahavercos" pz = 2*acos(sqrt(pz)) elseif @fn8 == "avercos" pz = acos(1+pz) elseif @fn8 == "acosh" pz = acosh(pz) elseif @fn8 == "tan" pz = tan(pz) elseif @fn8 == "tanc" if cabs(pz) != 0 pz = tan(pz)/pz else pz = 1 endif elseif @fn8 == "tanh" pz = tanh(pz) elseif @fn8 == "tanhc" if cabs(pz) != 0 pz = tanh(pz)/pz else pz = 1 endif elseif @fn8 == "atan" pz = atan(pz) elseif @fn8 == "atan2" pz = atan2(pz) elseif @fn8 == "atanh" pz = atanh(pz) elseif @fn8 == "cotan" pz = cotan(pz) elseif @fn8 == "cotanh" pz = cotanh(pz) elseif @fn8 == "sqr" pz = sqr(pz) elseif @fn8 == "sqrt" pz = sqrt(pz) elseif @fn8 == "cube" pz = pz^3 elseif @fn8 == "cuberoot" pz = pz^(1/3) elseif @fn8 == "log" pz = log(pz) elseif @fn8 == "logit" pz = log(pz/(1-pz)) elseif @fn8 == "colog" pz = -log(pz) elseif @fn8 == "exp" pz = exp(pz) elseif @fn8 == "gauss" pz = exp(-sqr(pz)) elseif @fn8 == "gd" pz = 2*atan(tanh(0.5*pz)) elseif @fn8 == "agd" pz = 2*atanh(tan(0.5*pz)) elseif @fn8 == "sigmoid" pz = 1/(1+exp(-pz)) elseif @fn8 == "abs" pz = abs(pz) elseif @fn8 == "cabs" pz = cabs(pz) elseif @fn8 == "conj" pz = conj(pz) elseif @fn8 == "flip" pz = flip(pz) elseif @fn8 == "recip" pz = recip(pz) elseif @fn8 == "ceil" pz = ceil(pz) elseif @fn8 == "floor" pz = floor(pz) elseif @fn8 == "trunc" pz = trunc(pz) elseif @fn8 == "round" pz = round(pz) ; endif ; endif elseif @fn8 == "coversin" pz = 1-sin(pz) elseif @fn8 == "acoversin" pz = asin(1-pz) elseif @fn8 == "hacoversin" pz = (1-sin(pz))/2 elseif @fn8 == "covercos" pz = 1 + sin(pz) elseif @fn8 == "acovercos" pz = asin(1+pz) elseif @fn8 == "hacovercos" pz = (1+sin(pz))/2 elseif @fn8 == "acotan" pz = atan(1/pz) elseif @fn8 == "acotanh" pz = atanh(1/pz) elseif @fn8 == "sech" pz = 1/(cosh(pz)) elseif @fn8 == "crd" pz = 2*sin(pz/2) elseif @fn8 == "acrd" pz = 2*asin(pz/2) elseif @fn8 == "asech" pz = acosh(1/pz) elseif @fn8 == "cosech" pz = 1/sinh(pz) elseif @fn8 == "acosech" pz = asinh(1/pz) elseif @fn8 == "coshc" if cabs(pz) != 0 pz = cosh(pz)/pz else pz = 1 endif elseif @fn8 == "cosc" if cabs(pz) != 0 pz = cos(pz)/pz else pz = 1 endif elseif @fn8 == "cotanc" if cabs(pz) != 0 pz = cotan(pz)/pz else pz = 1 endif elseif @fn8 == "cotanhc" if cabs(pz) != 0 pz = cotanh(pz)/pz else pz = 1 endif elseif @fn8 == "secc" if cabs(pz) != 0 pz = 1/(pz*cos(pz)) else pz = 1 endif elseif @fn8 == "sechc" if cabs(pz) != 0 pz = 1/(pz*cosh(pz)) else pz = 1 endif elseif @fn8 == "cosecc" if cabs(pz) != 0 pz = 1/(pz*sin(pz)) else pz = 1 endif elseif @fn8 == "cosechc" if cabs(pz) != 0 pz = 1/(pz*sinh(pz)) else pz = 1 endif elseif @fn8 == "logistic" pz = 1/(1+exp(-pz)) elseif @fn8 == "softplus" pz = log(1+exp(pz)) elseif @fn8 == "primecount" pz = pz/log(pz) endif endif endif iter = iter + 1 return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if @bmethod == 0 bail = m_iterations > @maxiter elseif @bmethod == 1 bail = (|pz| > @p_upperbailout) else bail = (m_iterations > @maxiter) || (|pz| > @p_upperbailout) endif return bail endfunc protected: bool iter1 bool iter2 bool switch1 bool switch2 complex ci default: title = "Lucy Goosey Switch" int param v_lucygooseyswitch caption = "Version (Lucy Goosey Switch)" default = 104 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_lucygooseyswitch < 104 endparam heading text = "This formula derived from the Ducks Switch formula with multiple modifications. \ Bailout is determined by the number of iterations or classical bailout. \ An iterations parameter which is independent of the value on the Maximum \ Iterations value on the Formula Tab has been included. The value for \ 'Iterations for Bailout' must always be less than the Maximum Iterations \ setting. Unlike other Duck formulas the Outside Coloring tab should \ be used. If the coloring method has options of convergent or divergent \ coloring, convergent coloring will usually be the best choice." endheading heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam int param bmethod caption = "Bailout method" default = 0 enum = "Iteration" "Value" "Both" endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 visible = @bmethod != 0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam int param maxiter caption = "Iterations for bailout" default = 100 visible = @bmethod != 1 endparam complex param power2 caption = "Main Power" default = (1,0) endparam complex param p_power ; Overrides p_power from Formula caption = "Mod Power" default = (1,0) endparam heading text = "Lucy Goosey uses two formulas internally. Iteration based switching is \ provided by the 'Modulus' parameter (old method) or by the sequence \ parameters." visible = @v_lucygooseyswitch >= 103 endheading int param smethod enum = "Modulus" "Sequence" default = 0 visible = @v_lucygooseyswitch >= 103 endparam int param modulus caption = "Modulus" default = 2 min = 2 visible = (@smethod == 0) || @v_lucygooseyswitch < 103 endparam int param seqgap1 caption = "Iteration cycle" default = 4 visible = @v_lucygooseyswitch >= 103 && @smethod == 1 endparam heading text = "'Main formula iters' must be less than or equal to the 'Iteration cycle'. \ Out of range values will be truncated to the size of the 'Iteration \ cycle'." visible = @v_lucygooseyswitch >= 103 && @smethod == 1 endheading int param seqgap2 caption = "Main formula iters" default = 2 visible = @v_lucygooseyswitch >= 103 && @smethod == 1 endparam float param order caption = "Order" default = 1 endparam int param vm21 caption = "Modulator 1 (Main) variants" default = 0 enum = "variant 1" "variant 2" "variant 3" "none" endparam int param vm11 caption = "Modulator 2 (Mod) variants" default = 0 enum = "variant 1" "variant 2" "variant 3" "none" endparam complex param p1 caption = "Parameter 1" default = (1,0) endparam complex param p2 caption = "Mod Parameter" default = (1,0) endparam func fn5 caption = "First function" default = log() visible = @v_lucygooseyswitch > 100 && @v_lucygooseyswitch < 104 endfunc heading text = "'First function' and 'Last function' use an extended function set." visible = @v_lucygooseyswitch >= 104 endheading param fn7 caption = "First function" default = 41 enum = "sin" "sinxx" "cosec" "sinc" "haversin" "versin" "sinh" "sinhc" "asin" "ahaversin" \ "aversin" "asinh" "cos" "cosxx" "havercos" "exsec" "excsc" "aexsec" "aexcsc" \ "vercos" "sec" "asec" "acsc" "cosh" "acos" "ahavercos" "avercos" "acosh" "tan" "tanc" "tanh" "tanhc" \ "atan" "atan2" "atanh" "cotan" "cotanh" "sqr" "sqrt" "cube" "cuberoot" \ "log" "logit" "colog" "exp" "gauss" "gd" "agd" "sigmoid" "abs" "cabs" "conj" "flip" \ "ident" "recip" "ceil" "floor" "trunc" "round" \ "coversin" "acoversin" "hacoversin" "covercos" "acovercos" "hacovercos" \ "acotan" "acotanh" "sech" "crd" "acrd" "asech" "cosech" "acosech" "coshc" "cosc" "cotanc" \ "cotanhc" "secc" "sechc" "cosecc" "cosechc" "softplus" "primecount" "logistic" visible = @v_lucygooseyswitch >= 104 endparam func fn6 caption = "Last function" default = ident() visible = @v_lucygooseyswitch > 100 && @v_lucygooseyswitch < 104 endfunc param fn8 caption = "Last function" default = 53 enum = "sin" "sinxx" "cosec" "sinc" "haversin" "versin" "sinh" "sinhc" "asin" "ahaversin" \ "aversin" "asinh" "cos" "cosxx" "havercos" "exsec" "excsc" "aexsec" "aexcsc" \ "vercos" "sec" "asec" "acsc" "cosh" "acos" "ahavercos" "avercos" "acosh" "tan" "tanc" "tanh" "tanhc" \ "atan" "atan2" "atanh" "cotan" "cotanh" "sqr" "sqrt" "cube" "cuberoot" \ "log" "logit" "colog" "exp" "gauss" "gd" "agd" "sigmoid" "abs" "cabs" "conj" "flip" \ "ident" "recip" "ceil" "floor" "trunc" "round" \ "coversin" "acoversin" "hacoversin" "covercos" "acovercos" "hacovercos" \ "acotan" "acotanh" "sech" "crd" "acrd" "asech" "cosech" "acosech" "coshc" "cosc" "cotanc" \ "cotanhc" "secc" "sechc" "cosecc" "cosechc" "softplus" "primecount" "logistic" visible = @v_lucygooseyswitch >= 104 endparam func fn1 caption = "Main function" default = ident() endfunc func fn2 caption = "Const function" default = ident() endfunc func fn3 caption = "Mod function" default = ident() endfunc func fn4 caption = "Mod const function" default = ident() endfunc } class REB_BirdofPrey_Switch(Switch) { ; Based upon an optimized Fractint formula of Sylvia Gallet. The Fractint ; cosxx() function was replaced with conj(cos)). public: import "common.ulb" ; constructor func REB_BirdofPrey_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @start endif m_c = @fn3(m_c) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz = @fn1(@fn2(pz^m_power + m_c)) + m_c return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Bird of Prey Switch" int param v_birdofpreyswitch caption = "Version (Bird of Prey Switch)" 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_birdofpreyswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1000 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param start caption = "Z initialization" default = (0,0) endparam func fn1 caption = "Function 1" default = conj() endfunc func fn2 caption = "Function 2" default = cos() endfunc func fn3 caption = "Function 3" default = ident() endfunc complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam } class REB_BesselFunctions_Switch(Switch) { ; Modified from the Fractint code of Michael G. Wareman ; The code is based upon are based on formulas taken from ; the article on bessels from the Encyclopedia of Science. public: import "common.ulb" ; constructor func REB_BesselFunctions_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if @function == 0 pz = sin(pz) / pz * m_c elseif @function == 1 pz = cos(pz) / pz + m_c elseif @function == 2 pz = -cos(pz) / pz + sin(pz) / pz^2 + m_c else pz = -sin(pz) / pz - cos(pz) / pz^2 + m_c endif return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Bessel Functions Switch" int param v_besselfunctionsswitch caption = "Version (Bessel Functions Switch)" 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_besselfunctionsswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 10000 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam int param function caption = "Function" enum = "Bessel 1" "Bessel 2" "Bessel 3" "Bessel 4" endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class MT_REB_RingMandelbrotJulia_Switch(Switch) { ; modified from the code of Mark Townsend public: import "common.ulb" ; constructor func MT_REB_RingMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) s = 0 if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz = pz^m_power + m_c + s s = @ringfuno(|@ringfuni(pz)-@rad|) return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc protected: complex s default: title = "Ring Mandelbrot Julia Switch" int param v_ringmandelbrotjuliaswitch caption = "Version (Ring Mandelbrot Julia Switch)" 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_ringmandelbrotjuliaswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1000 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam param rad caption = "Radius" default = 0.5 endparam func ringfuno caption = "Outside ring function" default = ident() endfunc func ringfuni caption = "Inside ring function" default = cabs() endfunc complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam } class REB_AverageMandelbrotJulia_Switch(Switch) { public: import "common.ulb" ; constructor func REB_AverageMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) x = 0 y = 0 if @flavor == 0 || @flavor == 3 oldx = 0 oldy = 0 else oldx = real(pz) oldy = imag(pz) endif if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz = pz^m_power + m_c x = real(pz) y = imag(pz) if @flavor == 2 x = (@wt*x - oldx)/(1+@wt) y = (@wt*y - oldy)/(1+@wt) elseif @flavor == 3 x = (@wt*x - oldx)/(1+@wt) y = (@wt*y - oldy)/(1+@wt) else x = (@wt*x + oldx)/(1+@wt) y = (@wt*y + oldy)/(1+@wt) endif oldx = x oldy = y pz = (x + flip(y)) return pz^m_power + m_c endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc protected: float x float y float oldx float oldy default: title = "Average Mandelbrot Julia Switch" int param v_averagemandelbrotjuliaswitch caption = "Version (Average Mandelbrot Julia Switch)" 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_averagemandelbrotjuliaswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1000 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam float param wt caption = "Weight factor" default = 1 min = 0.5 endparam int param flavor caption = "Average flavor" enum = "Flavor 1" "Flavor 2" "Flavor 3" "Flavor 4" default = 0 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam } class REB_BackwardMandelbrotJulia_Switch(Switch) { ; major modification to a Fractint foemula of Jim Muth public: import "common.ulb" ; constructor func REB_BackwardMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @start endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz=log(@p1^(pz^m_power)) + @p2*m_c return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Backward Mandelbrot Julia Switch" int param v_backwardmandelbrotjuliaswitch caption = "Version (Backward Mandelbrot Julia Switch)" default = 101 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_backwardmandelbrotjuliaswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam complex param start caption = "Initial Z" default = 0 endparam complex param p1 caption = "Parameter 1" default = 2 endparam complex param p2 caption = "Parameter 2" default = 1.5 endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam } class PP_LKM_REB_BurningShip_Switch(Switch) { ; The Burning Ship fractal, first described and created by Michael Michelitsch ; and Otto E. Rössler in 1992. It was converted to UF format by Pasi Piitulainen ; with functionality expanded by Kerry Mitchell. This version converts it to an ; object formula which uses my Switch coding. public: import "common.ulb" ; constructor func PP_LKM_REB_BurningShip_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) x = 0 y = 0 if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @start endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) x = abs(real(@xfun(real(pz))))^@x_power y = abs(real(@yfun(imag(pz))))^@y_power pz=(@x_wt*x + @y_wt*flip(y))^m_power + m_c return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc protected: float x float y default: title = "Burning Ship Switch" int param v_burningshipswitch caption = "Version (Burning Ship Switch)" 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_burningshipswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.89,-1.205) visible = @mans && @stype == "Julia" endparam complex param @start caption = "Initial Z" default = (0,0) endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1000 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) endparam heading caption = "X Components" endheading complex param x_wt caption = "X Weight" default = (1,0) endparam float param x_power caption = "X Power" default = 1 endparam func xfun caption = "X function" default = ident() endfunc heading caption = "Y Components" endheading complex param y_wt caption = "Y Weight" default = (1,0) endparam float param y_power caption = "Y Power" default = 1 endparam func yfun caption = "Y function" default = ident() endfunc } class MT_REB_BifunctionalMandelbrotJulia_Switch(Switch) { ; This is a variant on the Burning Ship when both functions are set ; to abs(). Original code is from Mark Townsend. public: import "common.ulb" ; constructor func MT_REB_BifunctionalMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) x = 0 y = 0 if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @start endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) x = real(@fn1(real(pz))) y = real(@fn2(imag(pz))) pz = x + flip(y) pz = pz^m_power + m_c return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc protected: float x float y default: title = "Bifunctional Mandelbrot Julia Switch" int param v_bifunctionalmandelbrotjuliaswitch caption = "Version (Bifunctional Mandelbrot Julia Switch)" 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_bifunctionalmandelbrotjuliaswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-.73,-0.25) visible = @mans && @stype == "Julia" endparam complex param @start caption = "Initial Z" default = (0,0) endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1000 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) endparam heading text = "Setting both functions to abs() will give the Burning Ship fractal." endheading func fn1 caption = "X function" default = sinh() endfunc func fn2 caption = "Y function" default = ident() endfunc } class REB_ModfunMandelbrotJulia_Switch(Switch) { ; This is a variant on the Burning Ship when both functions are set ; to abs(). Original code is from Mark Townsend. public: $define debug import "common.ulb" ; constructor func REB_ModfunMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) x = 0 y = 0 i = 0 if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @start endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if !@inside && @before x = real(@fn1(real(pz))) y = real(@fn2(imag(pz))) pz = x + flip(y) endif if (i % @modu == 0) if @inside && @before x = real(@fn1(real(pz))) y = real(@fn2(imag(pz))) pz = x + flip(y) endif pz = pz * exp(-1i * pi/360 * @rot) pz = pz / @magn pz = pz + @off if @inside && !@before x = real(@fn1(real(pz))) y = real(@fn2(imag(pz))) pz = x + flip(y) endif endif if !@inside && !@before x = real(@fn1(real(pz))) y = real(@fn2(imag(pz))) pz = x + flip(y) endif pz = pz^m_power + m_c i = i + 1 return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc protected: float x float y int i default: title = "ModfunMandelbrot Julia Switch" int param v_ModfunMandelbrotJuliaSwitch caption = "Version (ModfunMandelbrot Julia Switch)" 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_ModfunMandelbrotJuliaSwitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-.73,-0.25) visible = @mans && @stype == "Julia" endparam complex param @start caption = "Initial Z" default = (0,0) endparam float param rot caption = "Rotation" default = 0 endparam int param modu caption = "Modulus" default = 2 endparam float param magn caption = "Magnification" default = 0.8 endparam complex param off caption = "Offset" default = (0,0) endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1000 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) endparam func fn1 caption = "X function" default = ident() endfunc func fn2 caption = "Y function" default = ident() endfunc heading caption = "Function position" endheading heading text = "To put the functions outside the modulus loop 'inside' should be unchecked. \ To put the functions first (either inside or outside the loop) 'before should \ be checked." endheading bool param inside default = true endparam bool param before default = true endparam } class REB_PolyGen_Switch(Switch) { public: import "common.ulb" ; constructor func REB_PolyGen_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz=(-@p2+(@p2*@p2+(1-m_c)*3*@p1)^0.5)/(3*@p1) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return @fn1(@p1*pz^3)+@fn2(@p2*pz^2)+(m_c-1)* pz - m_c endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "PolyGen Switch" int param v_PolyGenswitch caption = "Version (PolyGen Switch)" 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_PolyGenswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam param p1 caption = "Parameter 1" default = (1.0, 0.0) endparam param p2 caption = "Parameter 2" default = (1.0, 0.0) endparam func fn1 caption = "Function 1" default = ident() endfunc func fn2 caption = "Function 2" default = ident() endfunc float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_ProgressiveMandelbrotJulia_Switch(Switch) { public: import "common.ulb" ; constructor func REB_ProgressiveMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) rot = @rotation*180/(2*#pi) pwr = m_power if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if @progress == true rot = rot + @baserot*180/(2*#pi) pwr = pwr + @incpwr m_c = m_c + @incconst endif pmx = real(m_c)*cos(rot) - imag(m_c)*sin(rot) pmy = imag(m_c)*cos(rot) + real(m_c)*sin(rot) m_c = pmx + flip(pmy) return pz^pwr + m_c endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc protected: complex pwr float rot float pmx float pmy default: title = "Progressive Mandelbrot Julia Switch" int param v_progressivemandelbrotjuliaswitch caption = "Version (Progressive Mandelbrot Julia Switch)" 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_progressivemandelbrotjuliaswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam param rotation caption = "Base rotation" default = 0.0 endparam param progress caption = "Progressive parameters" default = false endparam param baserot caption = "Inc base rotation" default = 0.0 visible=@progress == true endparam param incpwr caption = "Inc power" default = (0.0,0.0) visible=@progress == true endparam param incconst caption = "Inc constant" default = (0.0,0.0) visible=(@progress == true) endparam } class REB_AccelerationMandelbrotJulia_Switch(Switch) { ; modified from the Fractint code od Les St Clair and Sylvie Gallet public: import "common.ulb" ; constructor func REB_AccelerationMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) z2 = r = #pixel if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) l =r, pz = z2 z1 = pz^2 + m_c +@p1 vel1 = z1 - pz z2 = z1^2 + m_c +@p2 vel2 = z2 - z1 acc = vel2 - vel1 r = @fn1(acc) return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false bail = !(real(r) < m_bailout && real(@fn2(l - r)) >= @stalks) return bail endfunc protected: complex z1 complex z2 complex l complex r complex vel1 complex vel2 complex acc default: title = "Acceleration Mandelbrot Julia Switch" int param v_accelerationmandelbrotjuliaswitch caption = "Version (Acceleration Mandelbrot Julia Switch)" 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_accelerationmandelbrotjuliaswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam func fn1 caption = "Function 1" default = cabs() endfunc func fn2 caption = "Function 2" default = abs() endfunc complex param p1 caption = "Parameter 1" default = (0,0) endparam complex param p2 caption = "Parameter 2" default = (0,0) endparam float param stalks caption = "stalks" default = 0.001 endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_EpsilonMandelbrotJulia_Switch(Switch) { public: import "common.ulb" ; constructor func REB_EpsilonMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test epsilon = false endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz=pz^m_power+m_c epsilon = false if ((((real(pz)-imag(pz))>-abs(@esc)) && \ ((real(pz)-imag(pz))-abs(@esc)) && \ ((real(pz)+imag(pz)) m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif endif if @eonly bail = epsilon endif return bail endfunc private: bool epsilon bool bail default: title = "Epsilon Mandelbrot Julia Switch" int param v_epsilonmandelbrotjuliaswitch caption = "Version (Epsilon Mandelbrot Julia Switch)" 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_epsilonmandelbrotjuliaswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.82431250086,0.17987500033) visible = @mans && @stype == "Julia" endparam float param esc caption = "Escape Value" default = 0.01 endparam bool param eonly caption = "Show Epsilon Only" default = false endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam } class REB_BuffaloMandelbrotJulia_Switch(Switch) { ; based upon code from hpzd.net and various other sources including Fractal Forums public: import "common.ulb" ; constructor func REB_BuffaloMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz = abs(real(pz)) + flip(abs(imag(pz))) pz = pz^2 - pz + m_c return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Buffalo Mandelbrot Julia Switch" int param v_buffalomandelbrotjuliaswitch caption = "Version (Buffalo Mandelbrot Julia Switch" 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_buffalomandelbrotjuliaswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.625,-0.5) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_PerpendicularMandelbrotJulia_Switch(Switch) { ; derived from several sources ;This produces slice of the second order Mandelbulb/Juliabult directly ;perpendicular to the regular Mandelbrot/Julia set. public: import "common.ulb" ; constructor func REB_PerpendicularMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) x = real(pz) y = imag(pz) xTemp=x^2 - y^2 + real(m_c) y=-2*y*real(fn1(x)) + imag(m_c) x=xTemp pz=x+flip(y) return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc private: float x float y float xTemp default: title = "Perpendicular Mandelbrot Julia Switch" int param v_perpendicularmandelbrotjuliaswitch caption = "Version (Perpendicular Mandelbrot Julia Switch)" 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_perpendicularmandelbrotjuliaswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.46875,-0.73125) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam func fn1 caption = "Function 1" default = abs() endfunc float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_FGZMandelbrotJulia_Switch(Switch) { ; based upon a formula of Michael Wareman public: import "common.ulb" ; constructor func REB_FGZMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return 3*(pz^2 + m_c)^2/(pz^2 + m_c + @p1) + m_c endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "FGZ Mandelbrot Julia Switch" int param v_fgzmandelbrotjuliaswitch caption = "Version (FGZ Mandelbrot Julia Switch)" 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_fgzmandelbrotjuliaswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param p1 caption = "Parameter 1" default = (3,0) endparam complex param seed caption = "Julia Seed" default = (-0.6882, -0.1729) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_MoebiusMandelJulia_Switch(Switch) { ; Modified from a formula of Andreas Lober public: import "common.ulb" ; constructor func REB_MoebiusMandelJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) xLim = abs(real(@limit)) yLim = abs(imag(@limit)) reZ = 0 imZ = 0 if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @start endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz = pz^m_power + m_c reZ = real(pz) imZ = imag(pz) reZNew = reZ imZNew = imZ if (reZ < -xLim) reZNew = reZNew + 2*xLim if (@mode == 1) imZNew = imZNew - yLim elseif (@mode == 2) imZNew = -imZNew endif elseif (reZ > xLim) reZNew = reZNew - 2*xLim if (@mode == 1) imZNew = imZNew + yLim elseif (@mode == 2) imZNew = -imZNew endif endif if (imZ < -yLim) imZNew = imZNew + 2*yLim if (@mode == 1) reZNew = reZNew - xLim elseif (@mode == 2) reZNew = -reZNew endif elseif (imZ > yLim) imZNew = imZNew - 2*yLim if (@mode == 1) reZNew = reZNew + xLim elseif (@mode == 2) reZNew = reZNew endif endif pz = reZNew + 1i*imZNew return pz endfunc complex func Drcalc(complex pz, complex zd) zd = m_power*pz^(m_power-1)*zd + 1 return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc protected: float xLim float yLim float reZ float imZ default: title = "Moebius MandelJulia Switch" int param v_MoebiusMandelJuliaSwitch caption = "Version (Moebius MandelJulia Switch)" 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_MoebiusMandelJuliaSwitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam param start caption = "Starting point" default = (0,0) hint = "Perturbation. Use (0,0) for the standard Mandelbrot set." endparam param limit caption = "Moebius limits" default = (4,2) endparam param mode caption = "Moebius Mode" enum = "Normal" "Double" "Inverse" default = 0 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam } class REB_PartialCZMandelJulia_Switch(Switch) { ; ; Tweaks z before and/or after iteration, as well as modifying ; how c is added in z^n + c. ; public: import "common.ulb" ; constructor func REB_PartialCZMandelJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) ; partz=(0,0) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz if @manparam == (0,0) pz = m_c else pz = @manparam endif endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) ; ; determine part of z ; if(@parttype=="real") partz=real(pz) elseif(@parttype=="imag") partz=imag(pz) elseif(@parttype=="z") partz=pz elseif(@parttype=="magnitude") partz=cabs(pz) elseif(@parttype=="real/mag") partz=real(pz)/cabs(pz) elseif(@parttype=="imag/mag") partz=imag(pz)/cabs(pz) elseif(@parttype=="z/mag") partz=pz/cabs(pz) elseif(@parttype=="angle") partz=atan2(pz) elseif(@parttype=="real/imag") partz=real(pz)/imag(pz) endif ; ; apply modifying function ; partz=@partscale*@partfunc(partz) ; ; apply partz to z^n ; if(@ztype=="add before") pz=pz+partz pz=pz^m_power elseif(@ztype=="add after") pz=pz^m_power pz=pz+partz elseif(@ztype=="add both") pz=pz+partz pz=pz^m_power pz=pz+partz elseif(@ztype=="add & subtract") pz=pz+partz pz=pz^m_power pz=pz-partz elseif(@ztype=="multiply before") pz=pz*partz pz=pz^m_power elseif(@ztype=="multiply after") pz=pz^m_power pz=pz*partz elseif(@ztype=="multiply both") pz=pz*partz pz=pz^m_power pz=pz*partz elseif(@ztype=="multiply & divide") pz=pz*partz pz=pz^m_power pz=pz/partz else ; none pz=pz^m_power endif ; ; add jacked-up c ; if(@ctype=="add") pz=pz+m_c+partz elseif(@ctype=="subtract") pz=pz+m_c-partz elseif(@ctype=="multiply") pz=pz+m_c*partz elseif(@ctype=="divide") pz=pz+m_c/partz elseif(@ctype=="power") pz=pz+m_c^partz elseif(@ctype=="root") pz=pz+m_c^(1/partz) else ; none pz=pz+m_c endif return pz endfunc complex func Drcalc(complex pz, complex zd) ; zd = m_power*pz^(m_power-1)*zd + 1 return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc protected: complex partz default: title = "Partial CZ MandelJulia Switch" int param v_PartialCZMandelJuliaSwitch caption = "Version (Partial CZ MandelJulia Switch)" 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_PartialCZMandelJuliaSwitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text="Tweaks z before and/or after iteration, as well as modifying \ how c is added in z^n + c." endheading complex param manparam caption="initial z" default=(0,0) endparam bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam param parttype caption="z part type" enum="z" "real" "imag" "magnitude" "angle"\ "real/mag" "imag/mag" "z/mag" "real/imag" default=5 endparam param ztype caption="z tweak type" enum="none" "add before" "add after" "add both" "add & subtract"\ "multiply before" "multiply after" "multiply both" "multiply & divide" default=1 endparam param ctype caption="c tweak type" enum="none" "add" "subtract" "multiply" "divide" "power" "root" default=2 endparam complex param partscale caption="amount" default=0.1 endparam func partfunc caption="modifying function" default=ident() endfunc } class REB_GapMandelJulia_Switch(Switch) { ; ; z^n+c Mandelbrot ; bails out when orbit falls into gap ; either between 2 circles or 2 lines ; ; This formula had some major challenges in adaption, mostly in how to ; handle bailout. ; public: import "common.ulb" ; constructor func REB_GapMandelJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) a=0.0 b=0.0 gap=0.0 radsqr1=sqr(@radius1) radsqr2=sqr(@radius2) x=0.0 y=0.0 tempr=0.0 done = false ; ; set up line/circle parameters ; if(@type==0) ; lines tempr=@theta/180*#pi a=sin(tempr) b=-cos(tempr) gap=@c2-@c1 else ; circles gap=radsqr2-radsqr1 endif if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @manparam endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz=pz^m_power+m_c x=real(pz) y=imag(pz) ; ; check for falling into gap ; if(@type==0) ; lines tempr=a*x+b*y if((tempr>@c1)&&(tempr<@c2)) done=true tempr=(tempr-@c1)/gap pz=tempr*pz/cabs(pz) endif else ; circles tempr=|pz-@center| if((tempr>radsqr1)&&(tempr m_bailout) elseif m_test == 1 bail = done || (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = done || (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = done || (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = done || (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = done || (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = done || (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc protected: bool done float a float b float gap float radsqr1 float radsqr2 float x float y float tempr default: title = "Gap MandelJulia Switch" int param v_GapMandelJuliaSwitch caption = "Version (Gap MandelJulia Switch)" 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_GapMandelJuliaSwitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam param manparam caption="Mandelbrot start" default=(0,0) hint="use (0,0) for basic Mandelbrot set" endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam param type caption="gap type" default=0 enum="between 2 lines" "between 2 circles" endparam param c1 caption="line 1 c value" default=-0.1 hint="must be less than line 2 c value" visible = @type == 0 endparam param c2 caption="line 2 c value" default=0.1 hint="must be more than line 1 c value" visible = @type == 0 endparam param theta caption="line angle" default=45.0 hint="angle to horizontal, degrees" visible = @type == 0 endparam param center caption="circle center" default=(0,0) visible = @type == 1 endparam param radius1 caption="circle 1 radius" default=0.9 hint="must be less than circle 2 radius" visible = @type == 1 endparam param radius2 caption="circle 2 radius" default=1.1 hint="must be more than circle 1 radius" visible = @type == 1 endparam } class REB_MitchMandelJulia_Switch(Switch) { ; ; c*(z^2+1/z^2) Mandelbrot ; ; updated 19feb06 to change bailout variable ; public: import "common.ulb" ; constructor func REB_MitchMandelJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @manparam endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) complex z2=sqr(pz) pz=m_c*(z2+1/z2) return pz endfunc complex func Drcalc(complex pz, complex zd) ; zd = m_power*pz^(m_power-1)*zd + 1 return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 if((@bailtype==0)&&(|pz|>m_bailout)) bail = (|pz| > m_bailout) elseif((@bailtype==1)&&(|pz*m_c|>m_bailout)) bail = (|pz*m_c| > m_bailout) endif elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Mitch MandelJulia Switch" int param v_MitchMandelJuliaSwitch caption = "Version (Mitch MandelJulia Switch)" 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_MitchMandelJuliaSwitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam param manparam caption="Mandelbrot start" default=(1,0) hint="use (1,0) for standard set" endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." visible = false endparam param bailtype caption="bailout type" default=0 enum="|z|" "|z*c|" endparam } class REB_BoostMandelJulia_Switch(Switch) { ; ; This formula is an implementation of Orbit Boosting, ; an idea by Earl Hinrichs. ; ; The basic idea is that we perform a normal Mandelbrot ; iteration, but if the orbit enters a specified region ; of the complex plane (much like an orbit trap) we ; "boost" it in some fashion. A variety of boosting modes ; are included. Boost regions are ALWAYS circular in this ; implementation. public: import "common.ulb" ; constructor func REB_BoostMandelJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) d = 0; distance to boost area radius2 = sqr(@boostradius) iradius = 1/@boostradius if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @start endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz = pz^m_power + m_c; calculate the M-set d = |pz - @boostcenter|; distance to boost area IF (d < radius2); within threshold IF (@boostmode == 0); displace (addition) pz = pz + @boostamount ELSEIF (@boostmode == 1); orbit origin (multiply) pz = pz * @boostamount ELSEIF (@boostmode == 2); orbit boost (multiply) pz = (pz-@boostcenter) * @boostamount + @boostcenter ELSEIF (@boostmode == 3); flip out (reverse distance) d = 2*@boostradius/sqrt(d)-1 pz = @boostcenter + (pz-@boostcenter)*d*@boostamount ELSEIF (@boostmode == 4); repel (reverse distance squared) d = 1-sqr(1-@boostradius/sqrt(d)) pz = @boostcenter + (pz-@boostcenter)*d*@boostamount ELSEIF (@boostmode == 5); exponentiate origin (exponent) pz = pz ^ @boostamount ELSEIF (@boostmode == 6); exponentiate boost (exponent) pz = (pz-@boostcenter) ^ @boostamount + @boostcenter ELSEIF (@boostmode == 7); invert pz = conj(iradius/(pz-@boostcenter)) + @boostcenter ELSEIF (@boostmode == 8); pass through pz = pz + 2*(pz-@boostcenter)*@boostamount ELSEIF (@boostmode == 9); pass through 2 pz = pz + 2*(@boostcenter-pz)/cabs(@boostcenter-pz)*@boostradius*@boostamount ENDIF ENDIF return pz endfunc complex func Drcalc(complex pz, complex zd) zd = m_power*pz^(m_power-1)*zd + 1 return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc protected: float d float radius2 float iradius default: title = "Boost MandelJulia Switch" int param v_boostmandeljuliaswitch caption = "Version (Boost MandelJulia Switch)" 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_boostmandeljuliaswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam param start caption = "Starting Point" default = (0,0) hint = "Starting value for each point. You can use this to \ 'perturb' the fractal." endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam param boostcenter caption = "Boost Center" default = (0,0) hint = "This is the location of the boost area in the complex plane." endparam param boostradius caption = "Boost Radius" default = 0.5 hint = "This is the size of the boost area." endparam param boostmode caption = "Boost Mode" default = 0 enum = "displace" "orbit origin" "orbit boost" "flip out" "repel" \ "exponentiate origin" "exponentiate boost" "invert" "pass through" \ "pass through 2" hint = "Sets the type of effect when the orbit enters the boost area." endparam param boostamount caption = "Boost Amount" default = (1,0) hint = "This is the amount to boost." endparam } class REB_CompoundingTweakedMandelbrotJulia_Switch(Switch) { ; Tweaks either c or z each iteration, so that the tweaking compounds ; Derived from a Kerry Mirchell formula public: import "common.ulb" ; constructor func REB_CompoundingTweakedMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @manparam endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz=pz^m_power+m_c if(@tweaktype==1) m_c=m_c+@tweakage*@tweakfunction(pz) elseif(@tweaktype==2) m_c=m_c+@tweakage*@tweakfunction(m_c*pz) elseif(@tweaktype==3) m_c=m_c+@tweakage*@tweakfunction(pz/m_c) elseif(@tweaktype==4) pz=pz+@tweakage*@tweakfunction(m_c) elseif(@tweaktype==5) pz=pz+@tweakage*@tweakfunction(pz) elseif(@tweaktype==6) pz=pz+@tweakage*@tweakfunction(m_c*pz) elseif(@tweaktype==7) pz=pz+@tweakage*@tweakfunction(pz/m_c) else m_c=m_c+@tweakage*@tweakfunction(m_c) endif return pz endfunc complex func Drcalc(complex pz, complex zd) zd = m_power*pz^(m_power-1)*zd + 1 return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Compounding Tweaked Mandelbrot Switch" int param v_CompoundingTweakedMandelbrotSwitch caption = "Version (Compounding Tweaked Mandelbrot Switch)" 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_CompoundingTweakedMandelbrotSwitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam param manparam caption="initial z" default=(0.0,0.0) hint="Use (0,0) for something resembling the \ standard Mandelbrot set." endparam param tweaktype caption="tweaking type" default=0 enum="c; fn(c)" "c; fn(z)" "c; fn(c*z)" "c; fn(z/c)" \ "z; fn(c)" "z; fn(z)" "z; fn(c*z)" "z; fn(z/c)" hint="Sets what gets tweaked, and how." endparam param tweakage caption="tweaking amount" default=(0.01,0.0) hint="Make small for something resembling the \ standard Mandelbrot set." endparam func tweakfunction caption="tweaking function" default=recip() hint="Function of the tweaking variable." endfunc } class REB_IFSEscape1_Switch(Switch) { ; IFS Escape time July 19, 2013 ; adapted from Fractint code of Ramiro Perez ; two transforms to give a tree ; Fractint style bailout options.
public: import "common.ulb" ; constructor func REB_IFSEscape1_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) k = real(pz) ; transform 1 if k < @t1 pz=pz*@p1+@p2 endif ; transform 2 if @t2 <= k pz=pz*conj(@p1)+@p3 endif return pz endfunc complex func Drcalc(complex pz, complex zd) kk = real(pz) ; transform 1 if kk < @t1 zd=zd*@p1 endif ; transform 2 if @t2 <= kk zd=zd*@p1 endif return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc protected: float k float kk bool bail default: title = "IFS Escape 2 Transform Tree Switch" int param v_IFSEsc2TxTree caption = "Version (IFS Escape 2 Transform Tree Switch)" 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_IFSEsc2TxTree < 100 endparam heading text = "This is a two transform IFS formula that uses an escape time algorithm as first \ presented by Ramiro Perez for Fractint. The default settings produce a tree." endheading heading text = "This formula does not have Mandel like and Julia like forms, but when \ used with formulas that do in a dual formula capacity, interesting \ results can be obtained." endheading param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam heading text = "This formula does not have Mandel like and Julia like forms, but when \ used with formulas that do in a dual formula capacity, interesting \ results can be obtained." endheading bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p1 caption = "IFS parameter 1" default = (0.9,-0.87) endparam complex param p2 caption = "IFS parameter 2" default = (-1,0) endparam complex param p3 caption = "IFS parameter 3" default = (1,0) endparam float param t1 caption = "Threshold 1" default = 0 endparam float param t2 caption = "Threshold 2" default = 0 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." visible = false endparam } class REB_REBRefIndM1MandelbrotJulia_Switch(Switch) { ; Modified from one of my old Fractint formulas (1993) public: import "common.ulb" ; constructor func REB_REBRefIndM1MandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz = (pz^2-@p1)/(pz^2+@p2)*pz^2 + m_c return pz endfunc complex func Drcalc(complex pz, complex zd) zd = (2*pz^5+4*@p2*pz^3-2*@p1*@p2*pz)/(pz^2+@p2)^2*zd + 1 return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "REBRefIndM1 Mandelbrot Julia Switch" int param v_REBRefIndM1mandelbrotjuliaswitch caption = "Version (Mandelbrot Julia Switch)" default = 101 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_REBRefIndM1mandelbrotjuliaswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.1625,0.3125) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." visible = false endparam complex param p1 caption = "param #1" default = (1,0) endparam complex param p2 caption = "param #2" default = (1,0) endparam } class REB_REBRefIndM3MandelbrotJulia_Switch(Switch) { ; Modified from one of my old Fractint formulas (1993) public: import "common.ulb" ; constructor func REB_REBRefIndM3MandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz = flip(pz) pz = (pz^2-@p1)/(pz^2+@p2)*pz^2 + m_c return pz endfunc complex func Drcalc(complex pz, complex zd) pz = flip(pz) zd = (2*pz^5+4*@p2*pz^3-2*@p1*@p2*pz)/(pz^2+@p2)^2*zd + 1 return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "REBRefIndM3 Mandelbrot Julia Switch" int param v_REBRefIndM3mandelbrotjuliaswitch caption = "Version (Mandelbrot Julia Switch)" default = 101 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_REBRefIndM3mandelbrotjuliaswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.25,0.15) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." visible = false endparam complex param p1 caption = "param #1" default = (1,0) endparam complex param p2 caption = "param #2" default = (1,0) endparam } class REB_ExponentialMandelbrotJulia_Switch(Switch) { public: import "common.ulb" ; constructor func REB_ExponentialMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return exp(pz) + m_c endfunc complex func Drcalc(complex pz, complex zd) zd = exp(pz)*zd + 1 return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Exponential Mandelbrot Julia Switch" int param v_exponentialmandelbrotjuliaswitch caption = "Version (Mandelbrot Julia Switch)" default = 101 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_exponentialmandelbrotjuliaswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.65,0.05) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." visible = false endparam } class LKM_RotateMandelbrotJulia_Switch(Switch) { public: import "common.ulb" ; constructor func LKM_RotateMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) t=0.0 trad=@rotfac*#pi/180 rot=(0,0) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz+@manparam endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) ; ; set up the rotation angle ; if(@angletype==1) ; pixel t=@rotfac*atan2(#pixel) elseif(@angletype==2) ; z t=@rotfac*atan2(pz) else ; constant t=trad endif rot=cos(t)+flip(sin(t)) ; ; iterate z, taking into account the rotation type ; if(@rottype==1) ; before pz=pz*rot pz=pz^m_power+m_c elseif(@rottype==2) ; after pz=pz^m_power+m_c if(@angletype==2) t=@rotfac*atan2(pz) rot=cos(t)+flip(sin(t)) endif pz=pz*rot elseif(@rottype==3) ; before & after pz=pz*rot pz=pz^m_power+m_c if(@angletype==2) t=@rotfac*atan2(pz) rot=cos(t)+flip(sin(t)) endif pz=pz*rot elseif(@rottype==4) ; +before, -after pz=pz*rot pz=pz^m_power+m_c if(@angletype==2) t=@rotfac*atan2(pz) rot=cos(t)+flip(sin(t)) endif pz=pz/rot else ; none pz=pz^m_power+m_c endif return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc private: float t float trad complex rot default: title = "Rotate Mandelbrot Julia Switch" int param v_RotateMandelbrotJulia_Switch caption = "Version (Rotate Mandelbrot Julia Switch)" default = 101 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_RotateMandelbrotJulia_Switch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam param manparam caption="perturbation" default=(0,0) endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam param rottype caption="rotation type" default=1 enum="none" "before iterating" "after iterating" \ "before & after" "+before, -after" hint="How z is rotated each iteration." endparam float param rotfac caption="rotation factor" default=1.0 enabled=@rottype!="none" hint="If 'angle type' is 'constant', then this is the \ rotation angle in degrees. Otherwise, it is the factor \ that multiples the pixel or z angle to make the rotation \ angle." endparam param angletype caption="angle type" default=2 enum="constant" "pixel" "z" enabled=@rottype!="none" hint="Use 'constant' to specify a constant angle in degrees. \ Otherwise, the rotation is based on the angle of the pixel \ or the angle of z." endparam } class TAH_StutterMandelbrotJulia_Switch(Switch) { ; modified from the ufm of TAH public: import "common.ulb" ; constructor func TAH_StutterMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) f = @restart if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @start endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if @dmj f = f - 1 if (f <= 0) f = f + @restart m_c = pz*@sign pz = @start endif else f = f - 1 IF (f <= 0) f = @restart oldC = m_c m_c = pz*@sign pz = oldC ENDIF endif pz = pz^m_power + m_c return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc private: float f complex OldC default: title = "Stutter Mandelbrot Julia Switch" int param v_StutterMandelbrotJulia_Switch caption = "Version (Stutter Mandelbrot Julia Switch)" default = 101 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_StutterMandelbrotJulia_Switch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param start caption = "Start Value" default = (0,0) hint = "Starting value for each point. You can use this to \ 'perturb' the fractal." endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam bool param dmj caption = "DMJ formulation" default = false endparam float param restart caption = "Restart Interval" default = 101.0 min = 1 hint = "Specifies the number of iterations before c is reset." endparam param sign caption = "Sign" default = -1.0 hint = "Specifies the sign of the new C." endparam } class TAH_AlterMandelbrotJulia_Switch(Switch) { ; modified from the ufm of TAH public: import "common.ulb" ; constructor func TAH_AlterMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) f = @restart if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @start endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz = pz^m_power + m_c f = f - 1 if (f <= 0) f = f + @restart m_c = -m_c endif return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc private: float f default: title = "Alter Mandelbrot Julia Switch" int param v_AlterMandelbrotJulia_Switch caption = "Version (Alter Mandelbrot Julia Switch)" 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_AlterMandelbrotJulia_Switch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param start caption = "Start Value" default = (0,0) hint = "Starting value for each point. You can use this to \ 'perturb' the fractal." endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam float param restart caption = "Restart Interval" default = 1 hint = "Specifies the number of iterations before c is reset." endparam } class TAH_StutterConjMandelbrotJulia_Switch(Switch) { ; modified from the ufm of TAH public: import "common.ulb" ; constructor func TAH_StutterConjMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) f = @restart if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @start endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz = pz^m_power + m_c f = f - 1 IF (f <= 0) f = f + @restart m_c = conj(m_c)*@sign ENDIF return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc private: float f default: title = "Stutter Conjugate Mandelbrot Julia Switch" int param v_StutterconjMandelbrotJulia_Switch caption = "Version (Stutter Conj Mandelbrot Julia Switch)" default = 101 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_StutterconjMandelbrotJulia_Switch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param start caption = "Start Value" default = (0,0) hint = "Starting value for each point. You can use this to \ 'perturb' the fractal." endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam float param restart caption = "Restart Interval" default = 101.0 min = 1 hint = "Specifies the number of iterations before c is reset." endparam param sign caption = "Sign" default = 1.0 hint = "Specifies the sign of the new C." endparam } class BLB_SkyDiamondsMandelbrotJulia_Switch(Switch) { public: import "common.ulb" ; constructor func BLB_SkyDiamondsMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) zfn = (0,0) zTest = (0,0) rzt = 0 izt = 0 special = false done = false if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif fc = fn1(m_c) return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if (@LoopStyle == "Diamonds") || (@BailoutStyle == "Diamonds") if (@FuncAffects == "Z") zfn = fn1(pz^m_power) + m_c elseif (@FuncAffects == "C") zfn = pz^m_power + fc elseif (@FuncAffects == "Whole") zfn = fn1(pz^m_power + m_c) else ;"Both" zfn = fn1(pz^m_power) + fc endif if @BailoutStyle == "Diamonds" zTest = round(abs(zfn * @Factor)) else ;Normal zTest = round(abs(pz * @Factor)) endif rzt = real(zTest) izt = imag(zTest) if ((@DTest == "Equal") && (rzt == izt) && (@Zeros == "Include")) || \ ((@DTest == "Equal") && (rzt == izt) && (@Zeros == "Exclude") && (rzt > 0)) || \ ((@DTest == "Divisible") && (rzt%izt == 0) && (@Zeros == "Include")) || \ ((@DTest == "Divisible") && (rzt%izt == 0) && (@Zeros == "Exclude") && (rzt > 0) && (izt > 0)) special = true else ;Didn't meet any of the special cases special = false endif else ;Normal styles for looping and bailout special = false endif ;Finally, set z if (@LoopStyle == "Diamonds") && (special == true) pz = zfn else pz = pz^m_power + m_c endif ;Done yet? if @BailoutStyle == "Normal" if |pz| > m_bailout done = true endif else ;"Diamonds" if special == true done = True endif endif return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return done endfunc private: complex fc complex zfn complex zTest float rzt float izt bool special bool done default: title = "Sky Diamonds Mandelbrot Julia Switch" int param v_SkyDiamondsMandelbrotJulia_Switch caption = "Version (Sky Diamonds Mandelbrot Julia Switch)" default = 101 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_SkyDiamondsMandelbrotJulia_Switch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 4 min = 1.0 visible = (@BailoutStyle == "Normal") endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam func fn1 caption = "Diamonds Function" default = sqr() visible = (@LoopStyle == "Diamonds") || (@BailoutStyle == "Diamonds") hint = "For special conditions, the function applied to z and/or c \ (depending on setting of 'Function Affects')" endfunc param FuncAffects caption = "Function Affects" enum = "Z" "C" "Whole" "Both" default = 1 ; "C" is the default visible = (@LoopStyle == "Diamonds") || (@BailoutStyle == "Diamonds") hint = "What part of iterated function is affected by the user function? \ Options are 'Z': [fn(z^power)] + c; 'C': z^power + fn(c); \ 'Whole': fn(z^power + c); and 'Both': fn(z^power) + fn(c)." endparam param DTest caption = "Diamond Test" enum = "Equal" "Divisible" default = 0 ; "Equal" is the default visible = (@LoopStyle == "Diamonds") || (@BailoutStyle == "Diamonds") hint = "What special condition is being looked for? Say x = abs(real(z)) \ and y = abs(imag(z)). For 'Equal', x == y. For 'Divisible', \ x is evenly divisible by y. Also see hints for 'Zeros in Test' and \ 'Precision Factor' for important qualifications." endparam param Zeros caption = "Zeros in Test" enum = "Include" "Exclude" default = 0 ; "Include" is the default visible = (@LoopStyle == "Diamonds") || (@BailoutStyle == "Diamonds") hint = "When looking for special conditions, does a zero in x or y count?" endparam int param Factor caption = "Precision Factor" default = 100 min = 0 visible = (@LoopStyle == "Diamonds") || (@BailoutStyle == "Diamonds") hint = "Fudge factor for diamond test. Tested z is multiplied by this \ factor before being rounded. Higher numbers tend to produce thinner \ strands." endparam param LoopStyle caption = "Loop Style" enum = "Normal" "Diamonds" default = 1 ; "Diamonds" is the default hint = "Chooses the methods used during the iteration process. \ 'Normal' uses the traditional Mandelbrot loop, ignoring special \ conditions. 'Diamonds' looks for special conditions defined \ by 'Diamonds Function' and all parameters that follow it, \ varying the iterated calculations when special conditions are met." endparam param BailoutStyle caption = "Bailout Style" enum = "Normal" "Diamonds" default = 0 ; "Normal" is the default hint = "Chooses bailout method. 'Normal' uses the \ traditional escape-time method, and 'Diamonds' looks \ for special conditions defined by 'Diamonds Function' \ and all parameters that follow it." endparam } class MT_GeneralizedCelticMandelbrotJulia_Switch(Switch) { ; ; Converted by Mark Townsend from a formula by Paul Carlson ;public: import "common.ulb" ; constructor func MT_GeneralizedCelticMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz = pz^m_power pz = pz - @fn1(real(pz)) + @fn2(real(pz)) - m_c return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Generalized Celtic Mandelbrot Julia Switch" int param v_MT_GeneralizedCelticMandelbrotJulia_Switch caption = "Version (Generalized Celtic Mandelbrot Julia Switch)" default = 101 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_MT_GeneralizedCelticMandelbrotJulia_Switch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam func fn1 caption = "First function" default = ident() endfunc func fn2 caption = "Second function" default = abs() endfunc } class MT_DruidMandelbrotJulia_Switch(Switch) { public: import "common.ulb" ; constructor func MT_DruidMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_cpower = @n m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) iter = @first if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if iter % 2 == 0 pz = pz^m_power + m_c else pz = pz^m_cpower pz = pz - real(pz) + abs(real(pz)) + m_c endif iter = iter + 1 return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc private: complex m_cpower int iter default: title = "Druid Mandelbrot Julia Switch" int param v_DruidMandelbrotJuliaSwitch caption = "Version (Druid Mandelbrot Julia Switch)" default = 101 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_DruidMandelbrotJuliaSwitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Standard Exponent" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam param @first caption = "First set" enum = "Mandelbrot" "Celtic" endparam param n caption = "Celtic Exponent" default = (2,0) endparam } class LKM_UnitVectorTweakMandelbrotJulia_Switch(Switch) { ; ; Add a tweak of the unit vector for z at each iteation. ; Either add before the z^power+c step, after, or both. ; ; Based on Asdam's Mandelbrot variation, posted to Fractal Forums 12/30/2011 ; http://www.fractalforums.com/new-theories-and-research/ ; is-there-anything-novel-left-to-do-in-m-like-escape-time-fractals-in-2d/ ; msg38948/#newinit: ; ; Adapted from Kerry Mitchell public: import "common.ulb" ; constructor func LKM_UnitVectorTweakMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) unit_vector=(0,0) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @initial_z endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if((@tweak_type=="before")||(@tweak_type=="both")) if(cabs(pz)==0) unit_vector=1 else unit_vector=pz/cabs(pz) endif pz=pz+@fac_pre*@func_pre(unit_vector) endif pz=pz^m_power+m_c if((@tweak_type=="after")||(@tweak_type=="both")) if(cabs(pz)==0) unit_vector=1 else unit_vector=pz/cabs(pz) endif pz=pz+@fac_post*@func_post(unit_vector) endif return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc private: complex unit_vector default: title = "Unit Vector Tweak Mandelbrot Julia Switch" int param v_UnitVectorTweakMandelbrotJuliaSwitch caption = "Version (Unit Vector Tweak Mandelbrot Julia Switch)" default = 101 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_UnitVectorTweakMandelbrotJuliaSwitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param initial_z caption="initial z" default=(0,0) endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam param tweak_type caption="tweak type" default=1 enum="before" "after" "both" endparam complex param fac_pre caption="before factor" default=(0.1, 0.0) visible=((@tweak_type=="before")||(@tweak_type=="both")) endparam func func_pre caption="before function" default=ident() visible=((@tweak_type=="before")||(@tweak_type=="both")) endfunc complex param fac_post caption="after factor" default=(0.1,0.0) visible=((@tweak_type=="after")||(@tweak_type=="both")) endparam func func_post caption="after function" default=ident() visible=((@tweak_type=="after")||(@tweak_type=="both")) endfunc } class LKM_FibonacciMandelbrotJulia_Switch(Switch) { ; Uses previous z values instead of powers of the last z. ; based upon Kerry Mitchell's fibonacci-mandelbrot public: import "common.ulb" ; constructor func LKM_FibonacciMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_jul z1=pz z2=pz z3=pz z4=pz z5=pz endif if m_mand z1=@initialz z2=@initialz z3=@initialz z4=@initialz z5=@initialz m_c = pz pz = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if(@order==1) pz=@weight1*z1+(1-@weight1)*z3 pz=pz*(@weight2*z2+(1-@weight2)*z3) pz=pz*z3+m_c z1=z2 z2=z3 z3=pz elseif(@order==2) pz=@weight1*z1+(1-@weight1)*z4 pz=pz*(@weight2*z2+(1-@weight2)*z4) pz=pz*(@weight3*z3+(1-@weight3)*z4) pz=pz*z4+m_c z1=z2 z2=z3 z3=z4 z4=pz elseif(@order==3) pz=@weight1*z1+(1-@weight1)*z5 pz=pz*(@weight2*z2+(1-@weight2)*z5) pz=pz*(@weight3*z3+(1-@weight3)*z5) pz=pz*(@weight4*z4+(1-@weight4)*z5) pz=pz*z5+m_c z1=z2 z2=z3 z3=z4 z4=z5 z5=pz else pz=@weight1*z1+(1-@weight1)*z2 pz=pz*z2+m_c z1=z2 z2=pz endif return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc private: complex z1 complex z2 complex z3 complex z4 complex z5 default: title = "Fibonacci Mandelbrot Julia Switch" int param v_Fibonaccimandelbrotjuliaswitch caption = "Version (Fibonacci Mandelbrot Julia Switch)" default = 101 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_Fibonaccimandelbrotjuliaswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam param initialz caption="initial z" default=(0,0) endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." visible = false endparam param order caption="order" hint="Similar to power." default=0 enum="2" "3" "4" "5" endparam param weight1 caption="weight 1" hint="How much of first iterate is used. Use (0,0) for standard \ Mandelbrot." default=(1,0) endparam param weight2 caption="weight 2" hint="How much of second iterate is used. Use (0,0) for standard \ Mandelbrot." default=(1,0) endparam param weight3 caption="weight 3" hint="How much of third iterate is used. Use (0,0) for standard \ Mandelbrot." default=(1,0) endparam param weight4 caption="weight 4" hint="How much of fourth iterate is used. Use (0,0) for standard \ Mandelbrot." default=(1,0) endparam } class LKM_RelativisticAdditionMandelbrotJulia_Switch(Switch) { ; ; Replace the standard addition with relativistic addition ; both addends are treated like velocities ; use the full-blown equation found in wikipedia ; ; http://en.wikipedia.org/wiki/Velocity-addition_formula ; based upon a formula of Kerry Mitchell public: import "common.ulb" ; constructor func LKM_RelativisticAdditionMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) v1=(0,0) v2=(0,0) w=(0,0) fac1=0 fac2=0 fac3=0 recip_speed2=1/sqr(@speed) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @manparam endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) w=pz^m_power if(@vtype=="c frame") v1=m_c v2=w fac1=1+(real(v1)*real(v2)+imag(v1)*imag(v2))*recip_speed2 fac2=recip_speed2*(1+sqrt(1-|v1|*recip_speed2)) fac3=real(v1)*imag(v2)-real(v2)*imag(v1) pz=(v1+v2)/fac1+fac2*(imag(v1)*fac3-flip(real(v1)*fac3))/fac1 elseif(@vtype=="z frame") v2=m_c v1=w fac1=1+(real(v1)*real(v2)+imag(v1)*imag(v2))*recip_speed2 fac2=recip_speed2*(1+sqrt(1-|v1|*recip_speed2)) fac3=real(v1)*imag(v2)-real(v2)*imag(v1) pz=(v1+v2)/fac1+fac2*(imag(v1)*fac3-flip(real(v1)*fac3))/fac1 elseif(@vtype=="collinear c") if(cabs(m_c)==0) pz=w else v1par=m_c v1perp=0 v2par=(real(w)*real(m_c)+imag(w)*imag(m_c))/|m_c|*m_c v2perp=w-v2par pz=(v1par+v2par)/(1+(real(v1par)*real(v2par)+imag(v1par)*imag(v2par))*\ recip_speed2)+v1perp+v2perp endif elseif(@vtype=="collinear z") if(cabs(w)==0) pz=m_c else v1par=w v1perp=0 v2par=(real(m_c)*real(w)+imag(m_c)*imag(w))/|w|*w v2perp=m_c-v2par pz=(v1par+v2par)/(1+(real(v1par)*real(v2par)+imag(v1par)*imag(v2par))*\ recip_speed2)+v1perp+v2perp endif elseif(@vtype=="collinear observer") if(cabs(@observer)==0) pz=w+m_c else v1par=(real(w)*real(@observer)+imag(w)*imag(@observer))/|@observer|*@observer v1perp=w-v1par v2par=(real(m_c)*real(@observer)+imag(m_c)*imag(@observer))/|@observer|*@observer v2perp=m_c-v2par pz=(v1par+v2par)/(1+(real(v1par)*real(v2par)+imag(v1par)*imag(v2par))*\ recip_speed2)+v1perp+v2perp endif endif return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc private: complex v1 complex v2 complex w float fac1 float fac2 float fac3 float recip_speed2 ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Relativistic Addition Mandelbrot Julia Switch" int param v_RelativisticAdditionmandelbrotjuliaswitch caption = "Version (Relativistic Addition Mandelbrot Julia Switch)" default = 101 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_RelativisticAdditionmandelbrotjuliaswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param manparam caption="initial z" default=0 endparam float param speed caption="light speed" default=3 endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam param vtype caption="reference frame" default=0 enum="c frame" "z frame" "collinear c" "collinear z" "collinear observer" endparam complex param observer caption="observer's frame" default=(1,1) visible=(@vtype=="collinear observer") endparam } class REB_IterMandelbrotJulia_Switch(Switch) { public: import "common.ulb" ; constructor func REB_IterMandelbrotJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test rot = 0 i = (0,1) endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) rot=e^(-i*m_iterations)*@rfactor pz=(pz*(1-@s2+@s2*rot))^(m_power*(1-@s3)+@s3*m_iterations)+(1-@s1+@s1*rot)*m_c if @rev1 pz=(pz*(1-@s2+@s2*rot))^(m_power*(1-@s3)+@s3*m_iterations)+(1-@s1+@s1*(-rot))*m_c endif if @rev2 pz=(pz*(1-@s2+@s2*(-rot)))^(m_power*(1-@s3)+@s3*m_iterations)+(1-@s1+@s1*rot)*m_c endif return pz endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc protected: complex rot complex i default: title = "Iteration Mandelbrot Julia Switch" int param v_itermandelbrotjuliaswitch caption = "Version (Iteration Mandelbrot Julia Switch)" 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_itermandelbrotjuliaswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam heading text = "For sliders #1 and #2, The iteration value is transitioned to a \ rotation. For slider #1 the rotation is applied to the \ Mandelbrot constant/Julia seed. For slider #2 the rotaion is \ applied to the z value. The reverse slider check boxes \ reverse the angle. The rotation factor is a modifier of the \ rotation value." endheading complex param rfactor caption = "rotation factor" default = (1,0) visible = @s1 != 0 || @s2 != 0 endparam float param s1 caption = "slider #1" default = 0 min = 0 max = 1 hint = "Slider for the Mandelbrot constant/Julia seed." endparam bool param rev1 caption = "reverse slider #1" default = false endparam float param s2 caption = "slider #2" default = 0 min = 0 max = 1 hint = "Slider for #z" endparam bool param rev2 caption = "reverse slider #2" default = false endparam heading text = "For slider #3 the Mandelbrot/Julia power is transitioned to \ the iteration value." endheading float param s3 caption = "slider #3" default = 0 min = 0 max = 1 hint = "Slider for Power" endparam } class REB_Transcendental_Switch(Switch) { public: import "common.ulb" ; constructor func REB_Transcendental_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if @flavor == "Default" pz = m_c*@fn1(pz) elseif @flavor == "Squared" pz = m_c*@fn1(pz^2) elseif @flavor == "Squared2" pz = m_c*@fn1(pz)^2 else pz = m_c*@fn1(pz) - @p2*@fn1(pz) endif return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Transcendental Switch" int param v_TranscendentalSwitch caption = "Version (Transcendental Switch)" 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_TranscendentalSwitch < 100 endparam heading text = "The transcendental fractals are based upon ideas of Robert Devaney \ as presented in his book 'Chaos, Fractals and Dynamics'." endheading heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.75,0.25) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 10000 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam param p2 caption = "seed 2" default = (1,0) visible = @flavor == "Difference" endparam func fn1 caption = "Function" default = sin() endfunc param flavor caption = "Flavor" default = 0 enum = "Default" "Squared" "Squared2" "Difference" endparam } class REB_MandelbrotMix4_Switch(Switch) { ; Generalization of the MandelbrotMix4 formula ; created by Jim Muth (with his permission). public: import "common.ulb" ; constructor func REB_MandelbrotMix4_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = imag(@p3) + 100 m_bailout2 = @p_lowerbailout m_c = @fn1(@m_c) m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif a = real(@p1) b = imag(@p1) d = real(@p2) f = imag(@p2) k = real(@p3) + 1 if m_mand m_c = @fn1(pz) pz = (-a*b/(f*d))^(1/(f-b)) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return k*(a*pz^b + d*pz^f) + m_c endfunc complex func Drcalc(complex pz, complex zd) zd = k*(a*b*pz^(b-1) + d*f*pz^(f-1))*zd + 1 return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc private: float a float b float d float f float k default: title = "MandelbrotMix4 Switch" int param v_MandelbrotMix4switch caption = "Version (MandelbrotMix4 Switch)" default = 101 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_MandelbrotMix4switch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.38125,-0.08125) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = -1 visible = false endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam param p1 caption = "Parameter 1" default = (1,4) endparam param p2 caption = "Parameter 2" default = (2,2) endparam param p3 caption = "Parameter 3" default = (-0.5,1e10) endparam func fn1 caption = "Function 1" default = abs() endfunc complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_LambdaPower_Switch(Switch) { public: import "common.ulb" ; constructor func REB_LambdaPower_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = (1/(m_power+1))^(1/m_power) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return m_c*pz*(1 - pz^m_power) endfunc complex func Drcalc(complex pz, complex zd) zd = pz*(1-pz^m_power) + (1-(m_power+1)*pz^m_power)*zd*m_c return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Lambda Power Switch" int param v_LambdaPowerswitch caption = "Version (Lambda Power Switch)" default = 101 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_LambdaPowerswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.8965116,-0.5037791) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (1,0) endparam } class REB_FlipLambdaPower_Switch(Switch) { public: import "common.ulb" ; constructor func REB_FlipLambdaPower_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = (1/(m_power+1))^(1/m_power) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return m_c*pz*(1 - flip(pz)^m_power) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Flip Lambda Power Switch" int param v_FlipLambdaPowerswitch caption = "Version (Flip Lambda Power Switch)" default = 101 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_FlipLambdaPowerswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-1.1597384,0.4609012) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (1,0) endparam } class REB_FlipProbabilistic_Switch(Switch) { public: import "common.ulb" ; constructor func REB_FlipProbabilistic_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if @flavor == 0 pz = flip(pz)*(1-pz) + m_c else pz = pz*(m_c-flip(pz)) + m_c endif return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Flip Probabilistic Switch" int param v_FlipProbabilisticswitch caption = "Version (Flip Probabilistic Switch)" default = 101 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_FlipProbabilisticswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.0479651,1.6765988) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam param flavor caption = "Flavor" default = 0 enum = "flavor 1" "flavor 2" endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (1,0) visible = false endparam } class REB_NegativeMandelPower_Switch(Switch) { public: import "common.ulb" ; constructor func REB_NegativeMandelPower_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return (-pz)^m_power + m_c endfunc complex func Drcalc(complex pz, complex zd) return -m_power*pz^(m_power-1)*zd + 1 endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Negative MandelPower Switch" int param v_NegativeMandelPowerswitch caption = "Version (Negative MandelPower Switch)" default = 101 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_NegativeMandelPowerswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.20625,0.6625) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam } class REB_IkeFrRbtGen_Switch(Switch) {; Ron Barnett, 1993 ; Modified and tweaked March 2000 public: import "common.ulb" ; constructor func REB_IkeFrRbtGen_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = 2*(1-m_c)/(3*@p1) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return @p1*@fn1(pz^3) + (m_c-1)*pz^2 - m_c endfunc complex func Drcalc(complex pz, complex zd) return (@p1*@fn1(3*pz^2) + (m_c-1)*pz)*zd -1 endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "IkeFrRbtGen_Switch" int param v_IkeFrRbtGenwitch caption = "Version (IkeFrRbtGen_Switch)" 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_IkeFrRbtGenwitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal when 'function 1' = ident()." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.76875, 0.15625) visible = @mans && @stype == "Julia" endparam func fn1 caption = "Function 1" default = ident() endfunc param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam param p1 caption = "Parameter 1" default = (1.0, 0.0) endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } } class REB_Ikenaga_Switch(Switch) { public: import "common.ulb" ; constructor func REB_Ikenaga_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = ((1-m_c)/3)^0.5 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return pz^3 + (m_c-1)*pz - m_c endfunc complex func Drcalc(complex pz, complex zd) zd = (3*pz^2 + m_c - 1)*zd + pz + 1 return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Ikenaga Switch" int param v_Ikenagaswitch caption = "Version (Ikenaga Switch)" default = 101 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_Ikenagaswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.01875,-0.29375) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_IkeGen_Switch(Switch) { public: import "common.ulb" ; constructor func REB_IkeGen_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = ((1-m_c)/(3*@p1))^0.5 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return @p1*@fn1(pz^3) + (m_c-1)*pz - m_c endfunc complex func Drcalc(complex pz, complex zd) return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "IkeGen Switch" int param v_Ikegenswitch caption = "Version (IkeGen Switch)" 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_Ikegenswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.01875,-0.29375) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam param p1 caption = "Parameter 1" default = (1.0, 0.0) endparam func fn1 caption = "Function 1" default = ident() endfunc float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_Cubic_Switch(Switch) { public: import "common.ulb" ; constructor func REB_Cubic_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_mand = true m_c = pz if @flavor == "Init 1" pz = 1 else pz = -1/3 endif endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz = (pz-1)*(pz-1)*(pz+1) - m_c + 1 return pz endfunc complex func Drcalc(complex pz, complex zd) return (3*pz^2 - 2*pz -1)*zd + 1 endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Cubic Switch" int param v_cubicswitch caption = "Version (Cubic Switch)" 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_cubicswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.525,-0.15) visible = @mans && @stype == "Julia" endparam heading text = "The Initialze options provide two different Mandelbrot initializations \ that give an accurate mapping to the corresponding Julia functions." endheading param flavor caption = "Initialize" default = 0 enum = "Init 1" "Init 2" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_CubicFn_Switch(Switch) { public: import "common.ulb" ; constructor func REB_CubicFn_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_mand = true m_c = pz if @flavor == "Init 1" pz = 1 else pz = -1/3 endif endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz = @fn1((pz-1)*(pz-1)*(pz+1)) - m_c*@p1 + @p2 return pz endfunc complex func Drcalc(complex pz, complex zd) return @fn1(3*pz^2 - 2*pz -1)*zd + @p1 endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "CubicFn Switch" int param v_cubicfnswitch caption = "Version (CubicFn Switch)" 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_cubicfnswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal, but only if the chosen funtion is ident()" endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.525,-0.15) visible = @mans && @stype == "Julia" endparam heading text = "The Initialze options provide two different Mandelbrot initializations \ that give an accurate mapping to the corresponding Julia functions." endheading param p1 caption = "Parameter 1" default = (1.0, 0.0) endparam param p2 caption = "Parameter 2" default = (1.0, 0.0) endparam func fn1 caption = "Function" default = ident() endfunc param flavor caption = "Initialize" default = 0 enum = "Init 1" "Init 2" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_IkenagaPower_Switch(Switch) { public: import "common.ulb" ; constructor func REB_IkenagaPower_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = ((1-m_c)/@power)^(1/(@power-1)) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return pz^@power + (m_c-1)*pz - m_c endfunc complex func Drcalc(complex pz, complex zd) zd = @power*pz^(@power-1)*zd + m_c*zd - zd + pz - 1 return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Ikenaga Power Switch" int param v_IkenagaPowerswitch caption = "Version (Ikenaga Power Switch)" 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_IkenagaPowerswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.01875,-0.29375) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam complex param power caption = "Ikenaga power" default = 3 endparam } class REB_3RDIMIkenaga_Switch(Switch) { public: import "common.ulb" ; constructor func REB_3RDIMIkenaga_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif complex z2 = pz complex z3 = ((1-pz)/3)^0.5 if m_mand pz=@p1*real(z3)+flip(imag(z3)) m_c=@p2+real(z2)+flip(imag(z2)*@p1) endif if m_jul pz=@p1*real(z2)+flip(imag(z2)) m_c=@p2+real(m_c)+flip(imag(m_c)*@p1) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return pz^3 + (m_c-1)*pz - m_c endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "3RDIMIkenaga Switch" int param v_3RDIMIkenagaswitch caption = "Version (3RDIMIkenaga Switch)" default = 101 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_3RDIMIkenagaswitch < 101 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.01875,-0.575) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_SJIkenaga_Switch(Switch) { public: import "common.ulb" ; constructor func REB_SJIkenaga_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif complex z2 = pz complex z3 = ((1-pz)/3)^0.5 if m_mand pz=real(z3)+flip(imag(z3)*@p1) m_c=@p2+@p1*real(z2)+flip(imag(z2)) endif if m_jul pz=real(z2)+flip(imag(z2)*@p1) m_c=@p2+@p1*real(m_c)+flip(imag(m_c)) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return pz^3 + (m_c-1)*pz - m_c endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "SJIkenaga Switch" int param v_SJIkenagaswitch caption = "Version (SJIkenaga Switch)" 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_SJIkenagaswitch < 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.2125,0.3) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_3RDIMMagnet1_Switch(Switch) { public: import "common.ulb" ; constructor func REB_3RDIMMagnet1_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif complex z2 = pz if m_mand pz = 0 m_c=@p2+real(z2)+flip(imag(z2)*@p1) bval = 1 endif if m_jul pz=@p1*real(z2)+flip(imag(z2)) m_c=@p2+real(m_c)+flip(imag(m_c)*@p1) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if m_jul bval = m_zold endif return sqr( (pz^2 + m_c - 1) / (2*pz + m_c - 2) ) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-bval| < m_bailout2 || |pz| > m_bailout endfunc private: complex bval default: title = "3RDIMMagnet 1 Switch" int param v_3RDIMMagnet1switch caption = "Version (3RDIMMagnet 1 Switch)" default = 101 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_3RDIMMagnet1switch < 101 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.14375,-0.1375) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_SJMagnet1_Switch(Switch) { public: import "common.ulb" ; constructor func REB_SJMagnet1_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif complex z2 = pz if m_mand pz = 0 m_c=@p2+@p1*real(z2)+flip(imag(z2)) bval = 1 endif if m_jul pz=real(z2)+flip(imag(z2)*@p1) m_c=@p2+@p1*real(m_c)+flip(imag(m_c)) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if m_jul bval = m_zold endif return sqr( (pz^2 + m_c - 1) / (2*pz + m_c - 2) ) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-bval| < m_bailout2 || |pz| > m_bailout endfunc private: complex bval default: title = "SJMagnet 1 Switch" int param v_SJMagnet1switch caption = "Version (3RDIMMagnet 1 Switch)" 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_SJMagnet1switch < 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (1.382003788,-1.234041212) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_3RDIMMagnet2_Switch(Switch) { public: import "common.ulb" ; constructor func REB_3RDIMMagnet2_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif complex z2 = pz if m_mand pz = 0 m_c=@p2+real(z2)+flip(imag(z2)*@p1) bval = 1 endif if m_jul pz=@p1*real(z2)+flip(imag(z2)) m_c=@p2+real(m_c)+flip(imag(m_c)*@p1) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if m_jul bval = m_zold endif return sqr( (pz^3 + 3*(m_c-1)*pz + (m_c-1)*(m_c-2)) / \ (3*pz^2 + 3*(m_c-2)*pz + (m_c-1)*(m_c-2) + 1) ) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-bval| < m_bailout2 || |pz| > m_bailout endfunc private: complex bval default: title = "3RDIMMagnet 2 Switch" int param v_3RDIMMagnet2switch caption = "Version (3RDIMMagnet 2 Switch)" default = 101 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_3RDIMMagnet2switch < 101 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.3,2.75) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_SJMagnet2_Switch(Switch) { public: import "common.ulb" ; constructor func REB_SJMagnet2_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif complex z2 = pz if m_mand pz = 0 m_c=@p2+@p1*real(z2)+flip(imag(z2)) bval = 1 endif if m_jul pz=real(z2)+flip(imag(z2)*@p1) m_c=@p2+@p1*real(m_c)+flip(imag(m_c)) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if m_jul bval = m_zold endif return sqr( (pz^3 + 3*(m_c-1)*pz + (m_c-1)*(m_c-2)) / \ (3*pz^2 + 3*(m_c-2)*pz + (m_c-1)*(m_c-2) + 1) ) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-bval| < m_bailout2 || |pz| > m_bailout endfunc private: complex bval default: title = "SJMagnet 2 Switch" int param v_SJMagnet2switch caption = "Version (SJMagnet 2 Switch)" 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_SJMagnet2switch < 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.6794420445,-1.370714432) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_Spider_Switch(Switch) { public: import "common.ulb" ; constructor func REB_Spider_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz=pz^2+m_c m_c=m_c/2+pz return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Spider Switch" int param v_Spider_Switchswitch caption = "Version (Spider Switch)" default = 101 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_Spider_Switchswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.05625,0.1) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_JonHornerSpider_Switch(Switch) { public: import "common.ulb" ; constructor func REB_JonHornerSpider_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz=pz^2+m_c m_c=m_c*@sparam+pz return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Jon Horner's Spider Switch" int param v_JonHornerSpider_Switchswitch caption = "Version (Jon Horner Spider Switch)" default = 101 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_JonHornerSpider_Switchswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.10625,0.61875) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam complex param sparam caption = "Spider Parameter" default = (0.5,0) endparam } class REB_RolfFreericksSpider_Switch(Switch) { public: import "common.ulb" ; constructor func REB_RolfFreericksSpider_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif h = m_c return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz=pz^2+m_c-h m_c=m_c*@sparam+pz return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc private: complex h default: title = "Rolf Freericks' Spider Switch" int param v_RolfFreericksSpider_Switchswitch caption = "Version (Rolf Freericks' Spider Switch)" 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_RolfFreericksSpider_Switchswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.00625,0.0375) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam complex param sparam caption = "Spider Parameter" default = (0.5,0) endparam } class REB_CubicRoots_Switch(Switch) { public: import "common.ulb" ; constructor func REB_CubicRoots_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = (0.33333333333333333,0) else pz = pz + (0.33333333333333333,0) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return (2*pz^3 - pz^2 +m_c -2) / (3*pz^2 - 2*pz - 1) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-m_zold| < m_bailout2 endfunc default: title = "Cubic Roots Switch" int param v_CubicRootsswitch caption = "Version (Cubic Roots Switch)" default = 101 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_CubicRootsswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.66131134017,-0.011001586908) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = -1 visible = false endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_FrameRobertRoots_Switch(Switch) { public: import "common.ulb" ; constructor func REB_FrameRobertRoots_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = (0.945,0) else pz = pz + (0.945,0) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return (2*pz^3/5 + pz^2 - m_c) / (3*pz^2/5 + 2*pz) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-m_zold| < m_bailout2 endfunc default: title = "Frame Robert Roots Switch" int param v_FrameRobertRootsswitch caption = "Version (FrameRobert Roots Switch)" default = 101 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_FrameRobertRootsswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (5.39875,-0.0125) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = -1 visible = false endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_MandelbrotRoots_Switch(Switch) { public: import "common.ulb" ; constructor func REB_MandelbrotRoots_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = 0 else m_zold = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return (2*pz^3 - m_c) / (3*pz^2 + 1) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-m_zold| < m_bailout2 endfunc default: title = "Mandelbrot Roots Switch" int param v_MandelbrotRootsswitch caption = "Version (Mandelbrot Roots Switch)" default = 101 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_MandelbrotRootsswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.023568725982,1.4802139283) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = -1 visible = false endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_DoubleHalleyNovaMandelJulia_Switch(Switch) { ; ; This is the DoubleHalleyNova fractal (Mandelbrot form), ; a modified Newtonian-style fractal. DoubleHalleyNova is ; like HalleyNova, but with two terms instead of one. ; public: import "common.ulb" ; constructor func REB_DoubleHalleyNovaMandelJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_power2 = @p_power2 m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) fz = (0,0) f1z = (0,0) f2z = (0,0) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @start else m_zold = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) m_zold = pz fz = @coeff1*pz^m_power + @coeff2*pz^m_power2 - 1 f1z = @coeff1*m_power*pz^(m_power-1) + @coeff2*m_power2*pz^(m_power2-1) f2z = @coeff1*m_power*(m_power-1)*pz^(m_power-2) + @coeff2*m_power2*(m_power2-1)*pz^(m_power2-2) pz = pz - @relax * (2*fz*f1z) / (2*f1z^2 - fz*f2z) + m_c return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-m_zold| < m_bailout2 endfunc protected: complex m_power2 complex fz complex f1z complex f2z default: title = "DoubleHalleyNova MandelJulia Switch" int param v_DoubleHalleyNovaMandelJuliaSwitch caption = "Version (DoubleHalleyNova MandelJulia Switch)" 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_DoubleHalleyNovaMandelJuliaSwitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0,0) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = -1 visible = false endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (4,0) endparam complex param p_power2 caption = "Power" default = (2,0) endparam param start caption = "Start Value" default = (1,0) hint = "Starting value for each point. You can use this to \ 'perturb' the fractal." endparam param coeff1 caption = "Primary Scale" default = (1,0) hint = "Defines the coefficient (multiplier) for the \ primary exponent term." endparam param coeff2 caption = "Secondary Scale" default = (-3,0) hint = "Defines the coefficient (multiplier) for the \ secondary exponent term." endparam param relax caption = "Relaxation" default = (1,0) hint = "This can be used to slow down the convergence of \ the formula." endparam } class REB_HalleyNovaMandelJulia_Switch(Switch) { ; ; This is the Halley Nova fractal ; a modified Halley-style fractal. This ; is an adaptation of Paul Derbyshire's Halley ; Nova formulas for FractInt, which are based ; on his "Nova" formulas derived from classical ; Newton's Method fractals. ;public: import "common.ulb" ; constructor func REB_HalleyNovaMandelJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) nsquaredplusn = sqr(m_power) + m_power nsquaredminusn = sqr(m_power) - m_power zton = (0,0) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @start else m_zold = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) m_zold = pz zton = pz^m_power pz = pz - (2*m_power*pz * (zton-1)) * @relax / \ (nsquaredplusn*zton + nsquaredminusn) + m_c return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-m_zold| < m_bailout2 endfunc protected: complex nsquaredplusn complex nsquaredminusn complex zton default: title = "HalleyNova MandelJulia Switch" int param v_HalleyNovaMandelJuliaSwitch caption = "Version (HalleyNova MandelJulia Switch)" 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_HalleyNovaMandelJuliaSwitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0,0) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = -1 visible = false endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (3,0) endparam param start caption = "Start Value" default = (1,0) hint = "Starting value for each point. You can use this to \ 'perturb' the fractal." endparam param relax caption = "Relaxation" default = (1,0) hint = "This can be used to slow down the convergence of \ the formula." endparam } class REB_NovaMandelJulia_Switch(Switch) { ; ; This is the Nova fractal , a ; modified Newtonian-style fractal. The formula ; was first shown to me by Paul Derbyshire (who ; named it Nova). It has also appeared elsewhere ; under other names. public: import "common.ulb" ; constructor func REB_NovaMandelJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @start else m_zold = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) m_zold = pz pz = pz - @relax * (pz^m_power-1) / (m_power * pz^(m_power-1)) + m_c return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-m_zold| < m_bailout2 endfunc protected: default: title = "Nova MandelJulia Switch" int param v_NovaMandelJuliaSwitch caption = "Version (Nova MandelJulia Switch)" 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_NovaMandelJuliaSwitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0,0) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = -1 visible = false endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (3,0) endparam param start caption = "Start Value" default = (1,0) hint = "Starting value for each point. You can use this to \ 'perturb' the fractal." endparam param relax caption = "Relaxation" default = (1,0) hint = "This can be used to slow down the convergence of \ the formula." endparam } class REB_BoostNovaMandelJulia_Switch(Switch) { ; ; This formula is an implementation of Orbit Boosting, ; an idea by Earl Hinrichs. ; ; The basic idea is that we perform a normal Nova ; iteration, but if the orbit enters a specified region ; of the complex plane (much like an orbit trap) we ; "boost" it in some fashion. A variety of boosting modes ; are included. Boost regions are ALWAYS circular in this ; implementation. public: import "common.ulb" ; constructor func REB_BoostNovaMandelJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) d = 0; distance to boost area radius2 = sqr(@boostradius) iradius = 1/@boostradius if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @start else m_zold = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) m_zold = pz pz = pz - @relax * (pz^m_power-1) / (m_power * pz^(m_power-1)) + m_c d = |pz - @boostcenter|; distance to boost area IF (d < radius2); within threshold IF (@boostmode == 0); displace (addition) pz = pz + @boostamount ELSEIF (@boostmode == 1); orbit origin (multiply) pz = pz * @boostamount ELSEIF (@boostmode == 2); orbit boost (multiply) pz = (pz-@boostcenter) * @boostamount + @boostcenter ELSEIF (@boostmode == 3); flip out (reverse distance) d = 2*@boostradius/sqrt(d)-1 pz = @boostcenter + (pz-@boostcenter)*d*@boostamount ELSEIF (@boostmode == 4); repel (reverse distance squared) d = 1-sqr(1-@boostradius/sqrt(d)) pz = @boostcenter + (pz-@boostcenter)*d*@boostamount ELSEIF (@boostmode == 5); exponentiate origin (exponent) pz = pz ^ @boostamount ELSEIF (@boostmode == 6); exponentiate boost (exponent) pz = (pz-@boostcenter) ^ @boostamount + @boostcenter ELSEIF (@boostmode == 7); invert pz = conj(iradius/(pz-@boostcenter)) + @boostcenter ELSEIF (@boostmode == 8); pass through pz = pz + 2*(pz-@boostcenter)*@boostamount ELSEIF (@boostmode == 9); pass through 2 pz = pz + 2*(@boostcenter-pz)/cabs(@boostcenter-pz)*@boostradius*@boostamount ENDIF ENDIF return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-m_zold| < m_bailout2 endfunc protected: float d float radius2 float iradius default: title = "Boost NovaMandelJulia Switch" int param v_boostNovaMandelJuliaSwitch caption = "Version (Boost NovaMandelJulia Switch)" 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_BoostNovaMandelJuliaSwitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0,0) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = -1 visible = false endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (3,0) endparam param start caption = "Start Value" default = (1,0) hint = "Starting value for each point. You can use this to \ 'perturb' the fractal." endparam param relax caption = "Relaxation" default = (1,0) hint = "This can be used to slow down the convergence of \ the formula." endparam param boostcenter caption = "Boost Center" default = (0,0) hint = "This is the location of the boost area in the complex plane." endparam param boostradius caption = "Boost Radius" default = 0.5 hint = "This is the size of the boost area." endparam param boostmode caption = "Boost Mode" default = 0 enum = "displace" "orbit origin" "orbit boost" "flip out" "repel" \ "exponentiate origin" "exponentiate boost" "invert" "pass through" \ "pass through 2" hint = "Sets the type of effect when the orbit enters the boost area." endparam param boostamount caption = "Boost Amount" default = (1,0) hint = "This is the amount to boost." endparam } class REB_DoubleNovaMandelJulia_Switch(Switch) { ; ; This is the DoubleNova fractal (Mandelbrot form), ; a modified Newtonian-style fractal. DoubleNova is ; like Nova, but with two terms instead of one. ; public: import "common.ulb" ; constructor func REB_DoubleNovaMandelJulia_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_power2 = @p_power2 m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @start if (@usecritical) pz = ( -((m_power2-1)*m_power2*@coeff2) / \ ((m_power-1)*m_power*@coeff1) ) ^ (1/(m_power-m_power2)) endif else m_zold = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) m_zold = pz pz = pz - (@coeff1*pz^m_power + @coeff2*pz^m_power2 - 1) * @relax / \ (@coeff1*m_power*pz^(m_power-1) + @coeff2*m_power2*pz^(m_power2-1)) + m_c return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-m_zold| < m_bailout2 endfunc protected: complex m_power2 default: title = "DoubleNova MandelJulia Switch" int param v_DoubleNovaMandelJuliaSwitch caption = "Version (DoubleNova MandelJulia Switch)" 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_DoubleNovaMandelJuliaSwitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0,0) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = -1 visible = false endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (4,0) endparam complex param p_power2 caption = "Power" default = (2,0) endparam param start caption = "Start Value" default = (1,0) hint = "Starting value for each point. You can use this to \ 'perturb' the fractal." endparam param coeff1 caption = "Primary Scale" default = (1,0) hint = "Defines the coefficient (multiplier) for the \ primary exponent term." endparam param coeff2 caption = "Secondary Scale" default = (-3,0) hint = "Defines the coefficient (multiplier) for the \ secondary exponent term." endparam param usecritical caption = "Use Critical Point" default = false hint = "If set, a critical point for the function will \ be used in place of the Start Value." endparam param relax caption = "Relaxation" default = (1,0) hint = "This can be used to slow down the convergence of \ the formula." endparam } class REB_IkenagaRoots_Switch(Switch) { public: import "common.ulb" ; constructor func REB_IkenagaRoots_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand a = ((1-pz)/3)^0.5 pz = 0 else a = ((1-m_c)/3)^0.5 m_zold = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return (2*pz^3+ a) / (3*pz^2 + a - 1) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-m_zold| < m_bailout2 endfunc private: complex a default: title = "Ikenaga Roots Switch" int param v_IkenagaRootsswitch caption = "Version (Ikenaga Roots Switch)" default = 101 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_IkenagaRootsswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.241143798872,0.000857543948162) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = -1 visible = false endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_Gopalsamy_Switch(Switch) { public: import "common.ulb" ; constructor func REB_Gopalsamy_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return -(0,1)*conj(pz)^m_power + m_c endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Gopalsamy Switch" int param v_Gopalsamyswitch caption = "Version (Gopalsamy Switch)" default = 101 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_Gopalsamyswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.49375,0.2125) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the Julia formula. \ Increasing the real part to 3, 4, and so on, will multiply the \ symmetry of the Julia figure. Non-integer real values and non-zero \ imaginary values will create distorted Julia fractals. Use (2, 0) \ for the standard Julia set." endparam } class REB_Gopalsamy3_Switch(Switch) { public: import "common.ulb" ; constructor func REB_Gopalsamy3_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) float x = real(pz) float y = imag(pz) complex x1 = 3*x*y*y - x*x*x + m_c y = y*y*y - 3*x*x*y return x1 + flip(y) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Gopalsamy 3 Switch" int param v_Gopalsamy3switch caption = "Version (Gopalsamy 3 Switch)" default = 101 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_Gopalsamy3switch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.01875,0.44375) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_Gopalsamy5_Switch(Switch) { public: import "common.ulb" ; constructor func REB_Gopalsamy5_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) float x = real(pz) float y = imag(pz) float x1 = 2*x*y float y1 = x*x - y*y complex x2 = -2*x1*y1 + m_c y = y1*y1 - x1*x1 return x2 + flip(y) endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Gopalsamy 5 Switch" int param v_Gopalsamy5switch caption = "Version (Gopalsamy 5 Switch)" default = 101 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_Gopalsamy5switch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.7125,-0.06875) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_Newton_Switch(Switch) { public: import "common.ulb" ; constructor func REB_Newton_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) m_fz = 0 m_fzp = 0 m_fzp2 = 0 m_pwrtest = 10^(100/cabs(m_power)) m_bTest = false m_isnear = m_bailout2*cabs(@p2)^cabs(m_power) m_cz = 0 return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) m_fz = pz^m_power - @p2 m_fzp = m_power*pz^(m_power-1) m_fzp2 = m_power*(m_power-1)*pz^(m_power-2) if @converge == 0 ; Newton pz = pz - pz/m_power + @p2/m_power*pz^(1-m_power) elseif @converge == 1 ; Householder pz = pz - m_fz/m_fzp*(1 + m_fz*m_fzp2/(2*m_fzp^2)) elseif @converge == 2 ; Halley pz = pz - 2*m_fz*m_fzp/(2*m_fzp^2 - m_fz*m_fzp2) elseif @converge == 3 ; Schroder pz = pz - m_fz*m_fzp/(m_fzp^2 - m_fz*m_fzp2) elseif @converge == 4 ; Ho custom pz = pz - m_fz/m_fzp*(1 + m_fz*m_fzp2/(@custom*m_fzp^2)) elseif @converge == 5 ; Ha custom pz = pz - 2*m_fz*m_fzp/(@custom*m_fzp^2 - m_fz*m_fzp2) elseif @converge == 6 ; H_S custom pz = pz - @custom*m_fz*m_fzp/(@custom*m_fzp^2 - m_fz*m_fzp2) endif m_btest = (|m_zold-pz| < m_isnear) m_cz = |pz| return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return !(!m_btest && (m_cz < m_pwrtest)) endfunc private: complex m_fz complex m_fzp complex m_fzp2 float m_pwrtest bool m_bTest float m_isnear float m_cz default: title = "Newton Switch" int param v_newtonswitch caption = "Version (Newton Switch)" 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_Newtonswitch < 100 endparam heading text = "This formula does not have Mandel like and Julia like forms, but when \ used with formulas that do in a dual formula capacity, interesting \ results can be obtained." endheading bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = -1 visible = false endparam float param p_lowerbailout caption = "Bailout value" default = 1e-12 endparam param p_power caption = "Power" default = (3,0) endparam param p2 caption = "Root" default = (1,0) endparam heading caption = "Convergence Methods" endheading param converge caption = "Convergence Method" default = 0 enum = "Newton" "Householder" "Halley" "Schroder" "Ho Custom" \ "Ha Custom" "H_S Custom" endparam float param custom caption = "H_S Constant" default = 1.5 visible = @converge==4 || @converge==5 || @converge==6 endparam } class REB_TentMap_Switch(Switch) { public: import "common.ulb" ; constructor func REB_TentMap_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test inv = (1e-10,1e-10) endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_jul complex z1 = pz if @invert pz = 1/(z1+inv) endif endif if m_mand m_c = pz if @invert pz = 1/(m_c+inv) else pz = m_c endif endif if @flavor == "Flavor 1" pz = @tentfn(pz) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if @flavor == "Flavor 2" pz = @tentfn(pz) endif if @invert if @type == "cabs" if cabs(@tentfn2(pz)) <= @tent3 pz = @tent1*pz/(m_c+inv) else pz = @tent1*(@tent2-pz)/(m_c+inv) endif elseif @type == "real" if real(@tentfn2(pz)) <= @tent3 pz = @tent1*pz/(m_c+inv) else pz = @tent1*(@tent2-pz)/(m_c+inv) endif elseif @type == "imag" if imag(@tentfn2(pz)) <= @tent3 pz = @tent1*pz/(m_c+inv) else pz = @tent1*(@tent2-pz)/(m_c+inv) endif else if imag(@tentfn2(pz)) > @tent3 pz = @tent1*(@tent2-pz)/(m_c+inv) elseif real(@tentfn2(pz)) > @tent3 pz = @tent1*(@tent2-pz)/(m_c+inv) else pz = @tent1*pz/(m_c+inv) endif endif else if @type == "cabs" if cabs(@tentfn2(pz)) <= @tent3 pz = @tent1*pz*m_c else pz = @tent1*(@tent2-pz)*m_c endif elseif @type == "real" if real(@tentfn2(pz)) <= @tent3 pz = @tent1*pz*m_c else pz = @tent1*(@tent2-pz)*m_c endif elseif @type == "imag" if imag(@tentfn2(pz)) <= @tent3 pz = @tent1*pz*m_c else pz = @tent1*(@tent2-pz)*m_c endif else if imag(@tentfn2(pz)) > @tent3 pz = @tent1*(@tent2-pz)*m_c elseif real(@tentfn2(pz)) > @tent3 pz = @tent1*(@tent2-pz)*m_c else pz = @tent1*pz*m_c endif endif endif return pz endfunc private: complex inv ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "TentMap Switch" int param v_TentMapswitch caption = "Version (TentMap Switch)" default = 101 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_TentMapswitch < 101 endparam heading text = "Based upon the Tent Map function:" endheading heading text = " T(x) = s*x for x <= 0.5" endheading heading text = " T(x) = s*(1-x) for x > 0.5" endheading heading text = "and the code for the Barnsley type fractals." endheading param type caption = "Tent type" default = 3 enum = "cabs" "real" "imag" "Pinsky" endparam param flavor caption = "Flavor" default = 0 enum = "Flavor 1" "Flavor 2" endparam bool param invert caption = "Inversion" default = false endparam float param tent1 caption ="Tent param #1" default = 1 endparam float param tent2 caption ="Tent param #2" default = 1 endparam float param tent3 caption ="Tent param #3" default = 0.5 endparam func tentfn caption = "Tent function" default = ident() endfunc func tentfn2 caption = "Tent function #2" default = ident() endfunc heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.00625,1.26875) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_FrameRobert_Switch(Switch) { public: import "common.ulb" ; constructor func REB_FrameRobert_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return pz^3/5 + pz^2 + m_c endfunc complex func Drcalc(complex pz, complex zd) return (3*pz^2/5 + 2*pz)*zd + 1 endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "FrameRobert Switch" int param v_framerobertswitch caption = "Version (FrameRobert Switch)" default = 101 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_framerobertswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-3.5318151831,0.21727448711) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_FrRbtGen_Switch(Switch) { public: import "common.ulb" ; constructor func REB_FrRbtGen_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return @fn1(@p1*pz^3) + @fn2(pz^2) + m_c endfunc complex func Drcalc(complex pz, complex zd) return (3*@fn1(@p1*pz^2/5) + 2*@fn2(pz))*zd + 1 endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "FrRbtGen Switch" int param v_FrRbtGenswitch caption = "Version (FrRbtGen Switch)" 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_FrRbtGenswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal, but only if 'Function 1' and 'Function 2' \ are set to ident()." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-3.5318151831,0.21727448711) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam param p1 caption = "Parameter 1" default = (0.2,0) endparam func fn1 caption = "Function 1" default = ident() endfunc func fn2 caption = "Function 2" default = ident() endfunc float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_FrameRobertPower_Switch(Switch) { public: import "common.ulb" ; constructor func REB_FrameRobertPower_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return pz^m_power/5 + pz^2 + m_c endfunc complex func Drcalc(complex pz, complex zd) return (m_power*pz^(m_power-1)/5 + 2*pz)*zd + 1 endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "FrameRobert Power Switch" int param v_framerobertpowerswitch caption = "Version (FrameRobert Power Switch)" 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_framerobertpowerswitch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-3.5318151831,0.21727448711) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (3,0) endparam } class REB_3RDIMFrameRobert_Switch(Switch) { public: import "common.ulb" ; constructor func REB_3RDIMFrameRobert_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif complex z2 = pz if m_mand pz=@p1*real(z2)+flip(imag(z2)) m_c=@p2+real(z2)+flip(imag(z2)*@p1) endif if m_jul pz=@p1*real(z2)+flip(imag(z2)) m_c=@p2+real(m_c)+flip(imag(m_c)*@p1) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return pz^3/5 + pz^2 + m_c endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "3RDIMFrameRobert Switch" int param v_3RDIMframerobertswitch caption = "Version (3RDIMFrameRobert Switch)" default = 101 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_3RDIMframerobertswitch < 101 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.99375,0.54375) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_SJFrameRobert_Switch(Switch) { public: import "common.ulb" ; constructor func REB_SJFrameRobert_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif complex z2 = pz if m_mand pz=real(z2)+flip(imag(z2)*@p1) m_c=@p2+@p1*real(z2)+flip(imag(z2)) endif if m_jul pz=real(z2)+flip(imag(z2)*@p1) m_c=@p2+@p1*real(m_c)+flip(imag(m_c)) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return pz^3/5 + pz^2 + m_c endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "SJFrameRobert Switch" int param v_SJframerobertswitch caption = "Version (SJFrameRobert Switch)" 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_SJframerobertswitch < 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-1.475,0.55625) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_3RDIMMandelbrot_Switch(Switch) { public: import "common.ulb" ; constructor func REB_3RDIMMandelbrot_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif complex z2 = pz if m_mand pz=@p1*real(z2)+flip(imag(z2)) m_c=@p2+real(z2)+flip(imag(z2)*@p1) endif if m_jul pz=@p1*real(z2)+flip(imag(z2)) m_c=@p2+real(m_c)+flip(imag(m_c)*@p1) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return pz^m_power + m_c endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "3RDIMMandelbrot Switch" int param v_3RDIMMandelbrotswitch caption = "Version (3RDIMMandelbrot Switch)" default = 101 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_3RDIMMandelbrotswitch < 101 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.8,0.3625) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) endparam } class REB_SJMandelbrot_Switch(Switch) { public: import "common.ulb" ; constructor func REB_SJMandelbrot_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif complex z2 = pz if m_mand pz=real(z2)+flip(imag(z2)*@p1) m_c=@p2+@p1*real(z2)+flip(imag(z2)) endif if m_jul pz=real(z2)+flip(imag(z2)*@p1) m_c=@p2+@p1*real(m_c)+flip(imag(m_c)) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) return pz^m_power + m_c endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "SJMandelbrot Switch" int param v_SJMandelbrotswitch caption = "Version (vMandelbrot Switch)" 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_SJMandelbrotswitch < 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.425,0.68125) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) endparam } class REB_3RDIMManowar_Switch(Switch) { public: import "common.ulb" ; constructor func REB_3RDIMManowar_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif complex z2 = pz if m_mand pz=@p1*real(z2)+flip(imag(z2)) m_c=@p2+real(z2)+flip(imag(z2)*@p1) endif z1 = pz if m_jul pz=@p1*real(z2)+flip(imag(z2)) m_c=@p2+real(m_c)+flip(imag(m_c)*@p1) endif z1 = pz return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz = m_zold^2 + z1 + m_c z1 = m_zold return pz endfunc private: complex z1 ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "3RDIMManowar Switch" int param v_3RDIMManowarswitch caption = "Version (3RDIMManowar Switch)" default = 101 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_3RDIMManowarswitch < 101 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.08125,-0.0625) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_SJManowar_Switch(Switch) { public: import "common.ulb" ; constructor func REB_SJManowar_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif complex z2 = pz if m_mand pz=real(z2)+flip(imag(z2)*@p1) m_c=@p2+@p1*real(z2)+flip(imag(z2)) endif z1 = pz if m_jul pz=real(z2)+flip(imag(z2)*@p1) m_c=@p2+@p1*real(m_c)+flip(imag(m_c)) endif z1 = pz return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz = m_zold^2 + z1 + m_c z1 = m_zold return pz endfunc private: complex z1 ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "SJManowar Switch" int param v_SJManowarswitch caption = "Version (SJManowar Switch)" 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_SJManowarswitch < 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.042505551026,0.01453666683) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_Manowar_Switch(Switch) { public: import "common.ulb" ; constructor func REB_Manowar_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz endif z1 = pz return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz = m_zold^2 + z1 + m_c z1 = m_zold return pz endfunc private: complex z1 ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Manowar Switch" int param v_Manowarswitch caption = "Version (Manowar Switch)" default = 101 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_Manowarswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.00625,0.00625) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_3RDIMSpider_Switch(Switch) { public: import "common.ulb" ; constructor func REB_3RDIMSpider_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif complex z2 = pz if m_mand pz=@p1*real(z2)+flip(imag(z2)) m_c=@p2+real(z2)+flip(imag(z2)*@p1) endif if m_jul pz=@p1*real(z2)+flip(imag(z2)) m_c=@p2+real(m_c)+flip(imag(m_c)*@p1) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz=pz^2+m_c m_c=m_c/2+pz return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "3RDIMSpider Switch" int param v_3RDIMSpiderswitch caption = "Version (3RDIMSpider Switch)" default = 101 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_3RDIMSpiderswitch < 101 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.0625,0.225) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_SJSpider_Switch(Switch) { public: import "common.ulb" ; constructor func REB_SJSpider_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif complex z2 = pz if m_mand pz=real(z2)+flip(imag(z2)*@p1) m_c=@p2+@p1*real(z2)+flip(imag(z2)) endif if m_jul pz=real(z2)+flip(imag(z2)*@p1) m_c=@p2+@p1*real(m_c)+flip(imag(m_c)) endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) pz=pz^2+m_c m_c=m_c/2+pz return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "SJSpider Switch" int param v_SJSpiderswitch caption = "Version (SJSpider Switch)" 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_SJSpiderswitch < 100 endparam heading text = "Most Mandelbrot-type formulas initialize in the z plane and iterate \ in the c plane. Gordon Lamb proposed a geometry which involves iteration \ in the zc plane (type SJ) or in the cz plane (type 3RDIM). A 'Plane \ hybridization' value of zero gives pure zc or cz iteration, while a \ 'Plane hybridization' value of one gives the classical c plane iteration. \ Intermediate values can produce very interesting results." endheading float param p1 caption = "Plane hybridization" default = 0.5 min = 0 max = 1 endparam param p2 caption = "Iteration Plane position" default = (0.0,0.0) endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.64375,-0.34375) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_Magnet1_Switch(Switch) { public: import "common.ulb" ; constructor func REB_Magnet1_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif bval = m_zold if m_mand m_c = pz pz = 0 bval = 1 else bval = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if m_jul bval = m_zold endif return ((pz^2 + m_c - 1)/(2*pz + m_c - 2))^2 endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-bval| < m_bailout2 || |pz| > m_bailout endfunc private: complex bval default: title = "Magnet 1 Switch" int param v_Magnet1switch caption = "Version (Magnet 1 Switch)" default = 101 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_Magnet1switch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.3625,-0.275) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value (Convergent)" default = 1e-10 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_Magnet2_Switch(Switch) { public: import "common.ulb" ; constructor func REB_Magnet2_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif bval = m_zold if m_mand m_c = pz pz = 0 bval = 1 else bval = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if m_jul bval = m_zold endif return ((pz^3 + 3*(m_c-1)*pz + (m_c-1)*(m_c-2))/(3*pz^2 + 3*(m_c-2)*pz + \ (m_c-1)*(m_c-2) + 1))^2 endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-bval| < m_bailout2 || |pz| > m_bailout endfunc private: complex bval default: title = "Magnet 2 Switch" int param v_Magnet2switch caption = "Version (Magnet 2 Switch)" default = 101 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_Magnet2switch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.275,-1.375) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value (Convergent)" default = 1e-10 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam } class REB_Switch_FractalTiler(reb.ulb:Switch) { ; A tiling formula that can be used with any object switch formualas.
;

public: import "common.ulb" func REB_Switch_FractalTiler(Generic pparent) Switch(pparent) m_mand = @p_mand m_jul = @p_jul m_c = @m_c fFormula = new @formulaclass(this) endfunc complex func Init(complex pz) Switch.Init(pz) fFormula.SetParams(m_mand, m_jul, m_c) pz=(@fn1(@fn2(real(pz)))+flip(@fn1(@fn2(imag(pz)))))/@p2 pz = fFormula.Init(pz) return pz endfunc ; call for each iterated point. Overrides the parent Iterate function.
;

complex func Iterate(complex pz) pz = fFormula.Iterate(pz) return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return fFormula.IsBailedOut(pz) endfunc private: switch fFormula default: title = "Switch Fractal Tiler" heading text = "This a formula that can create seamless tiles with any fractal \ object. For the best results, set the magnification on the location \ tab to 0.6366 and do not change the other location tab settings \ other than position. Set the Image width equal to the image height. \ There are other combinations that will give seamless tiles." endheading int param v_switchfractaltiler caption = "Version (Switch Fractal Tiler)" 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_switchfractaltiler < 100 endparam Switch param formulaclass caption = "Fractal Formula" default = REB_MandelbrotJulia_Switch hint = "Sets the actual fractal formula to use for tiing." endparam param p2 caption = "Zoom" default = 2.0 endparam func fn1 caption = "First Function" default = tan() endfunc func fn2 caption = "Second Function" default = sin() endfunc float param p_upperbailout caption = "Bailout value (Divergent)" default = -1 visible = false endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam } class REB_FunBarnsley1_Switch(Switch) { public: import "common.ulb" ; constructor func REB_FunBarnsley1_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz ; pz = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if real(pz) >= 0 pz = @fn1(pz) pz = (pz - 1) * m_c else pz = @fn1(pz) pz = (pz + 1) * m_c endif return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "FunBarnsley 1 Switch" int param v_FunBarnsley1switch caption = "Version (FunBarnsley 1 Switch)" default = 101 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_FunBarnsley1switch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.675,1.2625) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value (Convergent)" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam func fn1 caption = "Function" default = ident() endfunc } class REB_FunBarnsley2_Switch(Switch) { public: import "common.ulb" ; constructor func REB_FunBarnsley2_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz ; pz = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if real(pz) * imag(m_c) + real(m_c) * imag(pz) >= 0 pz = @fn1(pz) pz = (pz - 1) * m_c else pz = @fn1(pz) pz = (pz + 1) * m_c endif return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "FunBarnsley 2 Switch" int param v_FunBarnsley2switch caption = "Version (FunBarnsley 2 Switch)" default = 101 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_FunBarnsley2switch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0.99375,0.95625) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e10 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value (Convergent)" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam func fn1 caption = "Function" default = ident() endfunc } class REB_Cayley_Switch(Switch) { public: import "common.ulb" ; constructor func REB_Cayley_Switch(Generic pparent) Switch.Switch(pparent) m_power = @p_power m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif m_fz = 0 m_fzp = 0 m_fzp2 = 0 m_zold = pz m_iterations = 0 if m_mand m_c = pz pz = 0 else m_zold = 0 endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) m_fz = pz^3 - m_c*pz - m_c + 1 m_fzp = 3*pz^2 - m_c m_fzp2 = 6*pz if @converge == 0 ; Newton pz = pz - m_fz/m_fzp elseif @converge == 1 ; Householder pz = pz - m_fz/m_fzp*(1 + m_fz*m_fzp2/(2*m_fzp^2)) elseif @converge == 2 ; Halley pz = pz - 2*m_fz*m_fzp/(2*m_fzp^2 - m_fz*m_fzp2) elseif @converge == 3 ; Schroder pz = pz - m_fz*m_fzp/(m_fzp^2 - m_fz*m_fzp2) elseif @converge == 4 ; Ho custom pz = pz - m_fz/m_fzp*(1 + m_fz*m_fzp2/(@custom*m_fzp^2)) elseif @converge == 5 ; Ha custom pz = pz - 2*m_fz*m_fzp/(@custom*m_fzp^2 - m_fz*m_fzp2) elseif @converge == 6 ; H_S custom pz = pz - @custom*m_fz*m_fzp/(@custom*m_fzp^2 - m_fz*m_fzp2) elseif @converge == 7 ; Mixed 1 if m_iterations % 2 == 0 pz = pz - m_fz/m_fzp*(1 + m_fz*m_fzp2/(2*m_fzp^2)) else pz = pz - m_fz/m_fzp endif elseif @converge == 8 ; Mixed 2 if m_iterations % 2 == 0 pz = pz - 2*m_fz*m_fzp/(2*m_fzp^2 - m_fz*m_fzp2) else pz = pz - m_fz/m_fzp endif elseif @converge == 9 ; Mixed 3 if m_iterations % 2 == 0 pz = pz - m_fz*m_fzp/(m_fzp^2 - m_fz*m_fzp2) else pz = pz - m_fz/m_fzp endif elseif @converge == 10 ; Mixed 4 if m_iterations % 2 == 0 pz = pz - @custom*m_fz*m_fzp/(@custom*m_fzp^2 - m_fz*m_fzp2) else pz = pz - m_fz/m_fzp endif endif return pz endfunc complex func Drcalc(complex pz, complex zd) zd = zd - ((3*pz^2*zd - m_c*zd - pz - 1)*(3*pz^2 - m_c) - \ (6*pz*zd - 1)*(pz^3 - m_c*pz - m_c +1))/(3*pz^2 - m_c)^2 return zd endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) return |pz-m_zold| < m_bailout2 endfunc protected: complex m_fz complex m_fzp complex m_fzp2 default: title = "Cayley Switch" int param v_cayleyswitch caption = "Version (Cayley Switch)" default = 101 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_cayleyswitch < 101 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading heading text = "For formulas that can use it, this plugin can calculate the analytical \ derivative of the fractal." endheading bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (-0.00489425716426,0.959032440272) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = -1 visible = false endparam float param p_lowerbailout caption = "Bailout value (Convergent)" default = 1e-10 endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam heading caption = "Convergence Methods" endheading param converge caption = "Convergence Method" default = 0 enum = "Newton" "Householder" "Halley" "Schroder" "Ho Custom" \ "Ha Custom" "H_S Custom" "Mixed1" "Mixed2" "Mixed3" "Mixed4" endparam float param custom caption = "H_S Constant" default = 1.5 visible = @converge==4 || @converge==5 || @converge==6 || @converge==10 endparam } class REB_Switch_EmbossedHelper { ; Helper class for Switch_Embossed. public: import "common.ulb" func REB_Switch_EmbossedHelper(REB_Switch_Embossed owner) fOwner = owner fFormula = new @formulaClass(owner) fFormula2 = new @formulaclass2(owner) fTransform = new @transform(owner) fTransform2 = new @transform2(owner) endfunc func Init(const complex pz) fOwner.GetParams(m_mand, m_jul, m_c) fFormula.SetParams(m_mand, m_jul, m_c) fZ = fFormula.Init(pz) if @dual fFormula2.SetParams(m_mand, m_jul, m_c) fFormula2.Init(pz) endif fTransform.init(fZ) fTransform2.init(fZ) fBailedOut = false fResult = 0 m_iter = 0 endfunc complex func Iterate() if !fBailedOut if (m_iter >= @prestart && m_iter < (@prestart+@preend))&& @transform \ != NullTransform fZ = (fZ + fTransform.Iterate(fZ)*@strength)/(1+@strength) endif fZ = fFormula.Iterate(fZ) if @dual fZ = fFormula2.iterate(fZ) endif if (m_iter >= @poststart && m_iter < (@poststart+@postend))&& @transform2 \ != NullTransform fZ = (fZ + fTransform2.Iterate(fZ)*@strength2)/(1+@strength2) endif if @dual if @bailtype == "Formula 1" && fFormula.IsBailedOut(fZ) fBailedOut = true elseif @bailtype == "Formula 2" && fFormula2.IsBailedOut(fZ) fBailedOut = true elseif @bailtype == "Both" && (fFormula.IsBailedOut(fZ) || fFormula2.IsBailedOut(fZ)) fBailedOut = true endif elseif fFormula.IsBailedOut(fZ) fBailedOut = true endif ; if fFormula.IsBailedOut(fZ) ; fBailedOut = true ; Handle emboss types that only work with the last iteration. if fBailedOut if (@parttype == "Iteration") fResult = fOwner.getIteration() elseif (@parttype == "Magnitude") fResult = cabs(ceil(log(fZ))) elseif (@parttype == "Angle") float t = 0.5 * atan2(fZ) / #pi if (t < 0.0) t = t + 1.0 endif t = t * @numsect fResult = real(ceil(t)) endif endif ; Handle emboss types that need to do something for each iteration. if (@parttype == "Real(z) > 0") if (real(fZ) > 0.0) fResult = fResult + 1.0 endif elseif (@parttype == "Imag(z) > 0") if (imag(fZ) > 0.0) fResult = fResult + 1.0 endif elseif (@parttype == "Smallest Magnitude") float r = |fZ| if fOwner.updateRMin(r) fResult = ceil(fOwner.getIteration()) endif elseif @parttype == "Sum(z) > 0" if real(fZ) + imag(fZ) > 0 fResult = fResult + 1.0 endif endif endif m_iter = m_iter + 1 return fZ endfunc bool func IsBailedOut() return fBailedOut endfunc float func GetResult() return fResult endfunc private: bool fBailedOut Switch fFormula Switch fFormula2 UserTransform fTransform UserTransform fTransform2 REB_Switch_Embossed fOwner float fResult complex fZ int m_iter bool m_jul bool m_mand complex m_c default: param parttype caption="Emboss Type" default=0 hint = "Specifies what information from the fractal is used to \ create the embossing effect. This changes the shape of \ the embossing lines." enum="Iteration" "Real(z) > 0" "Imag(z) > 0" "Sum(z) > 0" \ "Smallest Magnitude" "Magnitude" "Angle" endparam param numsect caption="Number of Sections" default=2 min=1 hint = "Specifies the number of sections to use for the Angle \ emboss type." visible = @parttype == "Angle" endparam UserTransform param transform caption = "Pre transform" default = NullTransform expanded = false endparam int param prestart caption = "Start Iter (Pre)" default = 0 visible = @transform != NullTransform endparam int param preend caption = "Iterations (Pre)" default = 1 visible = @transform != NullTransform endparam float param strength caption = "Strength (Pre)" default = 1 visible = @transform != NullTransform endparam bool param dual caption = "Use dual formulas" default = false endparam param bailtype caption = "Bailout type" default = 0 enum = "Formula 1" "Formula 2" "Both" visible = @dual endparam Switch param formulaClass caption = "Fractal formula" default = REB_MandelbrotJulia_Switch hint = "Sets the actual fractal formula to use for the embossing effect." endparam Switch param formulaClass2 caption = "Fractal Formula" default = REB_Ikenaga_Switch visible = @dual endparam UserTransform param transform2 caption = "Post transform" default = NullTransform expanded = false endparam int param poststart caption = "Start Iter (Post)" default = 0 visible = @transform2 != NullTransform endparam int param postend caption = "Iterations (Post)" default = 1 visible = @transform2 != NullTransform endparam float param strength2 caption = "Strength (Post)" default = 1 visible = @transform2 != NullTransform endparam } class REB_Switch_Embossed(reb.ulb:Switch) { ; Switchable Object version of the Embossed* formulas in Standard.ufm ; Originally written by Kerry Mitchell. public: import "common.ulb" func REB_Switch_Embossed(Generic pparent) Switch(pparent) m_mand = @p_mand m_jul = @p_jul m_c = @m_c fHelper[0] = new @helperClass(this) fHelper[1] = new @helperClass(this) endfunc complex func Init(complex pz) Switch.Init(pz) float theta=(90-@lightangle)*pi/180.0 float size=@sizefac*0.0065/#magn dr=size*(cos(theta)+flip(sin(theta))) fHelper[0].Init(pz - dr) fHelper[1].Init(pz + dr) fIteration = 0 fRMin = 1e20 m_BailedOut = false return pz endfunc complex func Iterate(complex pz) Switch.Iterate(pz) ; We can't use the pz value because we need to keep track of two z values. fIteration = fIteration + 1 complex z1 = fHelper[0].Iterate() complex z2 = fHelper[1].Iterate() if fHelper[0].IsBailedOut() z1 = z2 ; Return second z orbit instead of first. m_BailedOut = fHelper[1].IsBailedOut() endif if m_BailedOut || fIteration == #maxiter return fHelper[0].GetResult() + flip(fHelper[1].GetResult()) else ; Return z to keep periodicity checking working. This is a trick that's ; not in the original Embossed formulas, but I borrowed it from Damien's ; Slope formulas because it's such a good idea -FS. return z1 endif endfunc bool func IsBailedOut(complex pz) return m_bailedout endfunc ; Accessor functions for the helper class. int func getIteration() return fIteration endfunc bool func updateRMin(const float r) if r < fRMin fRMin = r return true else return false endif endfunc private: REB_Switch_EmbossedHelper fHelper[2] int fIteration float fRMin default: title = "Switch Embossed" heading text = "For the best embossing effects, decrease the bailout to about 10 for \ divergent fractals, and increase the bailout to about 0.01 for \ convergent fractals." endheading param lightangle caption="Light Angle" default=120 hint="Angle of apparent light source, in degrees. With 0, the light \ comes from above. Positive values give clockwise rotation." endparam param sizefac caption="Contour Size" default=1.0 hint="Specifies the relative size of the contour bands. Larger values \ give thicker bands." exponential = true endparam complex param p_power ; Hide p_power from Formula visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = -1 visible = false endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam REB_Switch_EmbossedHelper param helperClass selectable = false endparam } class REB_Switch_RRLEmbossedHelper { ; Helper class for Switch_RRLEmbossed. Based upon; the RRL Embossed code of ; Kerry Mitchell public: import "common.ulb" func REB_Switch_RRLEmbossedHelper(REB_Switch_RRLEmbossed owner) fOwner = owner fFormula = new @formulaClass(owner) fFormula2 = new @formulaclass2(owner) fTransform = new @transform(owner) fTransform2 = new @transform2(owner) fTrap = new @embossTrap(0) do_last=0 fib1=0 fib2=0 gfac=0 gi=0 gj=0 ; ; set up selected iterations ; ; clear do_this array ; gi=-1 while(gi<#maxiter) gi=gi+1 do_this[gi]=false endwhile ; ; set up counter for final iteration ; if((@dolast==0)||(@dolast>#maxiter)) do_last=#maxiter else do_last=@dolast endif ; ; create array of Fibonacci numbers ; gi=0 while(gi<#maxiter) gi=gi+1 fib[gi]=false endwhile fib1=0 fib2=1 gi=1 while(gi<#maxiter) fib[gi]=true fib1=fib2 fib2=gi gi=fib1+fib2 endwhile ; ; create array of triangular numbers ; gi=0 while(gi<#maxiter) gi=gi+1 tri[gi]=false endwhile gi=0 gj=1 while(gi<#maxiter) tri[gi]=true gi=gi+gj gj=gj+1 endwhile ; ; set do_this flag if that iteration is to be used ; gi=@do_first-1 while(gi<(do_last-1)) gi=gi+1 if(@modtype=="do all") ; do each iteration do_this[gi]=true elseif(@modtype=="do every n") ; do every nth gj=(gi-@do_first+#maxiter*@modbase)%@modbase if(gj==0) do_this[gi]=true endif elseif(@modtype=="skip every n") ; skip every nth gj=(gi-@do_first+#maxiter*@modbase)%@modbase if(gj>0) do_this[gi]=true endif elseif(@modtype=="do primes") ; do if iteration # is prime gj=1 gfac=2 while(gj<(gi-1)) gj=gj+1 if((gi%gj)==0) gfac=gfac+1 endif endwhile if(gfac==2) do_this[gi]=true endif elseif(@modtype=="skip primes") ; do if iteration # is not prime if(gi==1) do_this[gi]=true endif gj=1 gfac=2 while(gj<(gi-1)) gj=gj+1 if((gi%gj)==0) gfac=gfac+1 endif endwhile if(gfac>2) do_this[gi]=true endif elseif(@modtype=="do Fibonacci") ; do if iteration is a Fibonacci # if(fib[gi]==true) do_this[gi]=true endif elseif(@modtype=="skip Fibonacci") ; do if iteration is not a Fibonacci # if(fib[gi]==false) do_this[gi]=true endif elseif(@modtype=="do triangular") ; do if iteration is a triangular # if(tri[gi]==true) do_this[gi]=true endif elseif(@modtype=="skip triangular") ; do if iteration is not a triangular # if(tri[gi]==false) do_this[gi]=true endif elseif(@modtype=="blocks") ; blocks of trap some, then skip some gj=((gi-@do_first)%@block_size)+1 if(gj<=@block_trap) do_this[gi]=true endif endif endwhile endfunc func Init(const complex pz) fOwner.GetParams(m_mand, m_jul, m_c) fFormula.SetParams(m_mand, m_jul, m_c) fZ = fTrap.init(pz) fZ = fFormula.Init(fZ) if @dual fFormula2.SetParams(m_mand, m_jul, m_c) fFormula2.Init(pz) endif fTransform.init(fZ) fTransform2.init(fZ) fBailedOut = false fResult = 0 m_iter = 0 part=0 r1=0 rfaze=@rphase/180*#pi rho=0 rmax=0 rmaxfac=@scale*(1+0.5*@rangewidth) rmin=0 rminfac=@scale*(1-0.5*@rangewidth) rn=0 ; rotangle=-@rotd/180*#pi rw=0 rz=0 t1=0 tn=0 tz=0 iter1=0 itern1=0 rangeiter=0 endfunc complex func Iterate() m_iter = m_iter + 1 if !fBailedOut if (m_iter >= @prestart && m_iter < (@prestart+@preend))&& @transform \ != NullTransform fZ = (fZ + fTransform.Iterate(fZ)*@strength)/(1+@strength) endif fZ = fFormula.Iterate(fZ) if @dual fZ = fFormula2.iterate(fZ) endif if (m_iter >= @poststart && m_iter < (@poststart+@postend))&& @transform2 \ != NullTransform fZ = (fZ + fTransform2.Iterate(fZ)*@strength2)/(1+@strength2) endif if(do_this[m_iter]==true) rz = fTrap.iterate(fZ,tz) if(@vary_width==true) rho=(1-cos(@rfreq*tz+rfaze))/2 rw=rho*(@maxwidth-@minwidth)+@minwidth rminfac=@scale*(1-0.5*rw) rmaxfac=@scale*(1+0.5*rw) endif rmin=rz*rminfac rmax=rz*rmaxfac rz=cabs(fZ-@curvecenter) if((rz>=rmin)&&(rz<=rmax)) rangeiter=rangeiter+1 rn=rz tn=tz itern1=m_iter if(rangeiter==1) r1=rn t1=tn iter1=m_iter endif endif endif endif if @dual if @bailtype == "Formula 1" && fFormula.IsBailedOut(fZ) fBailedOut = true elseif @bailtype == "Formula 2" && fFormula2.IsBailedOut(fZ) fBailedOut = true elseif @bailtype == "Both" && (fFormula.IsBailedOut(fZ) || fFormula2.IsBailedOut(fZ)) fBailedOut = true endif elseif fFormula.IsBailedOut(fZ) fBailedOut = true endif if fBailedout if(@parttype==0) part=rangeiter elseif(@parttype==1) part=iter1 elseif(@parttype==2) part=itern1 elseif(@parttype==3) if @partsolid part=(r1*@sections) else part=ceil(r1*@sections) endif elseif(@parttype==4) if @partsolid part=(rn*@sections) else part=ceil(rn*@sections) endif elseif(@parttype==5) if @partsolid part=(t1*@sections) else part=ceil(t1*@sections) endif elseif(@parttype==6) if @partsolid part=(tn*@sections) else part=ceil(tn*@sections) endif endif fResult = part endif return fZ endfunc bool func IsBailedOut() return fBailedOut endfunc float func GetResult() return fResult endfunc private: bool fBailedOut Switch fFormula Switch fFormula2 UserTransform fTransform UserTransform fTransform2 REB_Switch_RRLEmbossed fOwner REB_EmbossFormula fTrap float fResult complex fZ int m_iter bool m_jul bool m_mand complex m_c float part float r1 float rfaze float rho float rmax float rmaxfac float rmin float rminfac float rn float rw float rz float t1 float tn float tz int iter1 int itern1 int rangeiter bool do_this[round(#maxiter+1)] bool fib[round(#maxiter+1)] bool tri[round(#maxiter+1)] int do_last int fib1 int fib2 int gfac int gi int gj default: heading caption="Embossing parameters" endheading param parttype caption="emboss type" default=0 enum="in range" "first iteration" "last iteration" "first magnitude" \ "last magnitude" "first angle" "last angle" endparam param partsolid caption = "make angle/mag solid" default = false visible = @parttype == "first magnitude" || @parttype == "last magnitude" \ || @parttype =="first angle"|| @parttype =="last angle" endparam float param sections caption="# sections" default=2 visible=(@parttype>2) endparam heading caption="Trap parameters" endheading float param scale caption="range scale" default=1 endparam bool param vary_width caption="vary width" default=false endparam float param rangewidth caption="range width" default=0.1 visible=(@vary_width==false) endparam float param minwidth caption="min range width" default=0.1 visible=(@vary_width==true) endparam float param maxwidth caption="max range width" default=0.4 visible=(@vary_width==true) endparam float param rfreq caption="range frequency" default=1 visible=(@vary_width==true) endparam float param rphase caption="range phase, deg" default=0 visible=(@vary_width==true) endparam REB_EmbossFormula param embossTrap caption = "Fractal formula" default = REB_EmbossRRL hint = "Sets the actual trap type to use for the embossing effect." endparam complex param curvecenter caption="curve center" default=(0,0) endparam ; ; selected iterations paramaters ; heading caption="Selected Iterations parameters" endheading param modtype caption="mod type" default=0 enum="do all" "do every n" "skip every n" "do primes" "skip primes"\ "do Fibonacci" "skip Fibonacci" "do triangular" "skip triangular" \ "blocks" endparam int param modbase caption="n" default=2 min=2 hint="The 'n' for type 'every n'; at least 2." visible=((@modtype=="do every n")||(@modtype=="skip every n")) endparam int param block_size caption="block size" default=4 min=3 visible=(@modtype=="blocks") endparam int param block_trap caption="block trap" default=2 min=1 visible=(@modtype=="blocks") endparam int param do_first caption="first iteration" default=1 min=1 hint="Start with this iteration." endparam int param dolast caption="last iteration" default=0 min=0 hint="End on this iteration; use 0 for maximum iterations." endparam UserTransform param transform caption = "Pre transform" default = NullTransform expanded = false endparam int param prestart caption = "Start Iter (Pre)" default = 0 visible = @transform != NullTransform endparam int param preend caption = "Iterations (Pre)" default = 1 visible = @transform != NullTransform endparam float param strength caption = "Strength (Pre)" default = 1 visible = @transform != NullTransform endparam bool param dual caption = "Use dual formulas" default = false endparam param bailtype caption = "Bailout type" default = 0 enum = "Formula 1" "Formula 2" "Both" visible = @dual endparam Switch param formulaClass caption = "Fractal formula" default = REB_MandelbrotJulia_Switch hint = "Sets the actual fractal formula to use for the embossing effect." endparam Switch param formulaClass2 caption = "Fractal Formula" default = REB_Ikenaga_Switch visible = @dual endparam UserTransform param transform2 caption = "Post transform" default = NullTransform expanded = false endparam int param poststart caption = "Start Iter (Post)" default = 0 visible = @transform2 != NullTransform endparam int param postend caption = "Iterations (Post)" default = 1 visible = @transform2 != NullTransform endparam float param strength2 caption = "Strength (Post)" default = 1 visible = @transform2 != NullTransform endparam } class REB_Switch_RRLEmbossed(reb.ulb:Switch) { ; Switchable Object version of Kerry Mitchell's RRL Embossed formula. public: import "common.ulb" func REB_Switch_RRLEmbossed(Generic pparent) Switch(pparent) m_mand = @p_mand m_jul = @p_jul m_c = @m_c fHelper[0] = new @helperClass(this) fHelper[1] = new @helperClass(this) endfunc complex func Init(complex pz) Switch.Init(pz) float theta=(90-@lightangle)*pi/180.0 float size=@sizefac*0.0065/#magn dr=size*(cos(theta)+flip(sin(theta))) fHelper[0].Init(pz - dr) fHelper[1].Init(pz + dr) m_BailedOut = false return pz endfunc complex func Iterate(complex pz) Switch.Iterate(pz) ; We can't use the pz value because we need to keep track of two z values. fIteration = fIteration + 1 complex z1 = fHelper[0].Iterate() complex z2 = fHelper[1].Iterate() if fHelper[0].IsBailedOut() z1 = z2 ; Return second z orbit instead of first. m_BailedOut = fHelper[1].IsBailedOut() endif if m_BailedOut || fIteration == #maxiter return fHelper[0].GetResult() + flip(fHelper[1].GetResult()) else ; Return z to keep periodicity checking working. This is a trick that's ; not in the original Embossed formulas, but I borrowed it from Damien's ; Slope formulas because it's such a good idea -FS. return z1 endif endfunc bool func IsBailedOut(complex pz) return m_bailedout endfunc private: REB_Switch_RRLEmbossedHelper fHelper[2] default: title = "Switch Trap Embossed" int param v_Switch_RRLEmbossed caption = "Version (Switch RRL Embossed)" default = 101 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_Switch_RRLEmbossed< 101 endparam heading text = "For the best embossing effects, decrease the bailout to about 10 for \ divergent fractals, and increase the bailout to about 0.01 for \ convergent fractals." endheading param lightangle caption="Light Angle" default=120 hint="Angle of apparent light source, in degrees. With 0, the light \ comes from above. Positive values give clockwise rotation." endparam param sizefac caption="Contour Size" default=1.0 hint="Specifies the relative size of the contour bands. Larger values \ give thicker bands." exponential = true endparam complex param p_power ; Hide p_power from Formula visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = -1 visible = false endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam REB_Switch_RRLEmbossedHelper param helperClass selectable = false endparam } class REB_Switch_SlopeHelper { ; Helper class for REB_Slope.
;

; Makes possible the use of any object formula with REB_Slope. Works for both ; convergent and divergent formulas. Manages height values as trap shapes. public: import "common.ulb" import "Standard.ulb" ; constructor func REB_Switch_SlopeHelper(REB_Switch_Slope owner) fOwner = owner fFormula = new @formulaclass(owner) fFormula2 = new @formulaclass2(owner) fTransfer = new @transferclass(owner) fheight = new @heightvalue(owner) fTransform = new @transform(owner) fTransform2 = new @transform2(owner) endfunc ; initialize the object complex func Init(const complex pz) fOwner.Getparams(m_mand, m_jul, m_c) fFormula.SetParams(m_mand, m_jul, m_c) fZ = fFormula.Init(pz) if @dual fFormula2.SetParams(m_mand, m_jul, m_c) fFormula2.Init(pz) endif fTransform.init(fZ) fTransform2.init(fZ) fTransfer.Init(pz) fheight.Init(pz) fMinDist = 1e20 m_sflag = false fIterz = 0 m_zold = 0 m_iter = 0 m_BailedOut = false return fZ endfunc ; call for each iterated point complex func Iterate() m_zold = fZ if (m_iter >= @prestart && m_iter < (@prestart+@preend))&& @transform \ != NullTransform fZ = (fZ + fTransform.Iterate(fZ)*@strength)/(1+@strength) endif fZ = fFormula.Iterate(fZ) if @dual fZ = fFormula2.iterate(fZ) endif if (m_iter >= @poststart && m_iter < (@poststart+@postend))&& @transform2 \ != NullTransform fZ = (fZ + fTransform2.Iterate(fZ)*@strength2)/(1+@strength2) endif m_iter = m_iter + 1 float d = fheight.Iterate(fZ) if d == -10000 m_sflag = true endif if @tx d = cabs(fheight.GetTransformedPoint()) endif if d < fMinDist && !m_sflag fMinDist = d endif if m_sflag fIterz = fIterz + exp(-cabs(fZ)-0.5/(cabs(m_zold - fZ))) endif if @dual if @bailtype == "Formula 1" m_BailedOut = fFormula.IsBailedOut(fZ) elseif @bailtype == "Formula 2" m_BailedOut = fFormula2.IsBailedOut(fZ) else m_BailedOut = (fFormula.IsBailedOut(fZ) || fFormula2.IsBailedOut(fZ)) endif else m_BailedOut = fFormula.IsBailedOut(fZ) endif return fZ endfunc bool func IsBailedOut() ; return fFormula.IsBailedOut(fZ) return m_BailedOut endfunc ; determine continuous iteration (height) float func CalcHeight(int iter) float height = fMinDist if m_sflag height = fIterz endif return fTransfer.Iterate(height) endfunc private: Switch fFormula Switch fFormula2 UserTransform fTransform UserTransform fTransform2 float fMinDist Transfer fTransfer complex fZ TrapShape fheight bool m_sflag complex m_zold float fIterz int m_iter REB_Switch_Slope fOwner bool m_mand bool m_jul complex m_c bool m_BailedOut default: int param v_switchslopehelper caption = "Version (REB Switch Slope Helper)" 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_switchslopehelper < 100 endparam UserTransform param transform caption = "Pre transform" default = NullTransform expanded = false endparam int param prestart caption = "Start Iter (Pre)" default = 0 visible = @transform != NullTransform endparam int param preend caption = "Iterations (Pre)" default = 1 visible = @transform != NullTransform endparam float param strength caption = "Strength (Pre)" default = 1 visible = @transform != NullTransform endparam bool param dual caption = "Use dual formulas" default = false endparam param bailtype caption = "Bailout type" default = 0 enum = "Formula 1" "Formula 2" "Both" visible = @dual endparam Switch param formulaClass caption = "Fractal Formula" default = REB_MandelbrotJulia_switch endparam Switch param formulaClass2 caption = "Fractal Formula" default = REB_Ikenaga_Switch visible = @dual endparam UserTransform param transform2 caption = "Post transform" default = NullTransform expanded = false endparam int param poststart caption = "Start Iter (Post)" default = 0 visible = @transform2 != NullTransform endparam int param postend caption = "Iterations (Post)" default = 1 visible = @transform2 != NullTransform endparam float param strength2 caption = "Strength (Post)" default = 1 visible = @transform2 != NullTransform endparam TrapShape param heightvalue caption = "Height value" default = REB_TrapShapeSlopeBasic endparam Transfer param transferclass caption = "Height Transfer" default = Standard_HeightTransfer hint = "Selects a class that can transform the calculated height value." expanded = false endparam bool param tx caption = "Use transformed value" default = false visible = @heightvalue != REB_TrapShapeSlopeBasic endparam } class REB_Switch_Slope(reb.ulb:Switch) { ; A slope formula that can be used with any object formualas.
;

; Original code modified from Damien M. Jones. ; Uses a special helper class that allows TrapShape plugins for height values public: import "common.ulb" ; constructor func REB_Switch_Slope(Generic pparent) Switch.Switch(pparent) m_mand = @p_mand m_jul = @p_jul m_c = @m_c fHelper[0] = new @helperclass(this) fHelper[1] = new @helperclass(this) fHelper[2] = new @helperclass(this) endfunc ; initialize the object complex func Init(complex pz) Switch.Init(pz) complex z1 = fHelper[0].Init(pz) ; primary iterated point fHelper[1].Init(pz + @offset) ; horizontally offset point fHelper[2].Init(pz + flip(@offset)) ; vertically offset point fIteration = 0 m_BailedOut = false return z1 endfunc ; call for each iterated point. Overrides the parent Iterate function.
;

; We can't use the pz value because we need to keep track of three z values. ; The helper function manages the pz values and bailout. complex func Iterate(complex pz) fIteration = fIteration + 1 complex z1 = fHelper[0].Iterate() fHelper[1].Iterate() fHelper[2].Iterate() m_BailedOut = fHelper[0].IsBailedOut() if @everyiter || m_BailedOut || fIteration == #maxiter ; done, or every iteration, or last float e1 = fHelper[0].CalcHeight(fIteration) float e2 = fHelper[1].CalcHeight(fIteration) float e3 = fHelper[2].CalcHeight(fIteration) ; determine surface normal ; that is, the normal to the surface defined by: ; (real(c1), imag(c1), e1) ; (real(c2), imag(c2), e2) ; (real(c3), imag(c3), e3) float vx = e2-e1 float vy = e3-e1 float vz = -@offset ; normalize vector float vd = 1/sqrt(sqr(vx)+sqr(vy)+sqr(vz)) vx = vx*vd vy = vy*vd vz = vz*vd return vx + flip(vy); fudge z from vector else ; didn't compute z this time ; use primary iteration value to keep periodicity working return z1 endif endfunc bool func IsBailedOut(complex pz) return m_BailedOut endfunc private: REB_Switch_SlopeHelper fHelper[3] int fIteration default: title = "Switch Slope" int param v_switchslope caption = "Version (Switch Slope)" 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_switchslope < 100 endparam float param offset caption = "Orbit Separation" default = 0.00000001 exponential = true hint = "Defines how far apart the simultaneous orbits are. Smaller \ distances will produce more accurate results." endparam bool param everyiter caption = "Every Iteration" default = false hint = "If set, the surface normal will be computed at every \ iteration. If you are using a coloring algorithm which \ processes every iteration, you will need this." endparam complex param p_power ; Hide p_power from Formula visible = false endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = -1 visible = false endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam REB_Switch_SlopeHelper param helperclass selectable = false endparam } ;------------------- ; ; Direct Color Arrays ; ;-------------------------- class REB_DirectColorHelper(common.ulb:Generic) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_DirectColorHelper(Generic pparent) Generic.generic(pparent) int i = 0 while i < 8 direct[i] = rgba(0,0,0,0) i = i + 1 endwhile endfunc func Init() endfunc color direct[8] default: int param v_colorhelper caption = "Version (color helper)" 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_colorhelper < 100 endparam } class REB_Alhambra(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Alhambra(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Alhambra Color Array" int param v_alhambra caption = "Version (Alhambra Direct Colors)" 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_alhambra < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(15/255,222/255,255/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,204/255,75/255,1) endparam color param color3 caption = "Color 3" default = rgba(188/255,152/255,255/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,155/255,109/255,1) endparam color param color5 caption = "Color 5" default = rgba(121/255,180/255,255/255,1) endparam color param color6 caption = "Color 6" default = rgba(255/255,131/255,126/255,1) endparam color param color7 caption = "Color 7" default = rgba(33/255,255/255,220/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,177/255,93/255,1) endparam } class REB_Belvedere(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Belvedere(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Belvedere Color Array" int param v_Belvedere caption = "Version (Belvedere Direct Colors)" 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_Belvedere < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,255/255,255/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,255/255,255/255,1) endparam color param color3 caption = "Color 3" default = rgba(123/255,201/255,254/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,230/255,1/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,230/255,1/255,1) endparam color param color6 caption = "Color 6" default = rgba(0/255,255/255,217/255,1) endparam color param color7 caption = "Color 7" default = rgba(255/255,20/255,70/255,1) endparam color param color8 caption = "Color 8" default = rgba(95/255,84/255,255/255,1) endparam } class REB_Bouquet(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Bouquet(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Bouquet Color Array" int param v_Bouquet caption = "Version (Bouquet Direct Colors)" 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_Bouquet < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(1/255,255/255,131/255,1) endparam color param color2 caption = "Color 2" default = rgba(52/255,255/255,198/255,1) endparam color param color3 caption = "Color 3" default = rgba(1/255,244/255,255/255,1) endparam color param color4 caption = "Color 4" default = rgba(180/255,169/255,255/255,1) endparam color param color5 caption = "Color 5" default = rgba(251/255,148/255,230/255,1) endparam color param color6 caption = "Color 6" default = rgba(255/255,101/255,140/255,1) endparam color param color7 caption = "Color 7" default = rgba(255/255,149/255,111/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,252/255,125/255,1) endparam } class REB_Chill(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Chill(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Chill Color Array" int param v_Chill caption = "Version (Chill Direct Colors)" 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_Chill < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(233/255,245/255,255/255,1) endparam color param color2 caption = "Color 2" default = rgba(182/255,201/255,255/255,1) endparam color param color3 caption = "Color 3" default = rgba(1/255,34/255,136/255,1) endparam color param color4 caption = "Color 4" default = rgba(1/255,75/255,255/255,1) endparam color param color5 caption = "Color 5" default = rgba(233/255,245/255,255/255,1) endparam color param color6 caption = "Color 6" default = rgba(182/255,201/255,255/255,1) endparam color param color7 caption = "Color 7" default = rgba(1/255,34/255,136/255,1) endparam color param color8 caption = "Color 8" default = rgba(1/255,75/255,255/255,1) endparam } class REB_CloudNine(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_CloudNine(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Cloud Nine Color Array" int param v_CloudNine caption = "Version (Cloud Nine Direct Colors)" 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_CloudNine < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,255/255,173/255,1) endparam color param color2 caption = "Color 2" default = rgba(247/255,214/255,255/255,1) endparam color param color3 caption = "Color 3" default = rgba(212/255,255/255,249/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,221/255,217/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,255/255,173/255,1) endparam color param color6 caption = "Color 6" default = rgba(247/255,214/255,255/255,1) endparam color param color7 caption = "Color 7" default = rgba(212/255,255/255,249/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,221/255,217/255,1) endparam } class REB_ColorSwitch(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_ColorSwitch(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Color Switch Color Array" int param v_ColorSwitch caption = "Version (Color Switch Direct Colors)" 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_ColorSwitch < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,33/255,52/255,1) endparam color param color2 caption = "Color 2" default = rgba(61/255,136/255,255/255,1) endparam color param color3 caption = "Color 3" default = rgba(1/255,255/255,44/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,131/255,1/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,27/255,255/255,1) endparam color param color6 caption = "Color 6" default = rgba(168/255,87/255,255/255,1) endparam color param color7 caption = "Color 7" default = rgba(1/255,252/255,252/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,255/255,38/255,1) endparam } class REB_Default(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Default(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Default Color Array" int param v_Default caption = "Version (Default Direct Colors)" 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_Default < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(172/255,96/255,252/255,1) endparam color param color2 caption = "Color 2" default = rgba(252/255,1/255,172/255,1) endparam color param color3 caption = "Color 3" default = rgba(252/255,32/255,32/255,1) endparam color param color4 caption = "Color 4" default = rgba(252/255,128/255,1/255,1) endparam color param color5 caption = "Color 5" default = rgba(252/255,252/255,1/255,1) endparam color param color6 caption = "Color 6" default = rgba(1/255,252/255,128/255,1) endparam color param color7 caption = "Color 7" default = rgba(1/255,252/255,252/255,1) endparam color param color8 caption = "Color 8" default = rgba(64/255,64/255,252/255,1) endparam } class REB_EveningSky(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_EveningSky(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Evening Sky Array" int param v_EveningSky caption = "Version (Evening Sky Direct Colors)" 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_EveningSky < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,238/255,222/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,226/255,85/255,1) endparam color param color3 caption = "Color 3" default = rgba(249/255,148/255,216/255,1) endparam color param color4 caption = "Color 4" default = rgba(159/255,159/255,255/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,175/255,79/255,1) endparam color param color6 caption = "Color 6" default = rgba(124/255,190/255,251/255,1) endparam color param color7 caption = "Color 7" default = rgba(255/255,111/255,123/255,1) endparam color param color8 caption = "Color 8" default = rgba(111/255,255/255,245/255,1) endparam } class REB_Fall(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Fall(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Fall Array" int param v_Fall caption = "Version (Fall Direct Colors)" 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_Fall < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,235/255,1/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,61/255,32/255,1) endparam color param color3 caption = "Color 3" default = rgba(255/255,184/255,26/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,107/255,1/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,235/255,1/255,1) endparam color param color6 caption = "Color 6" default = rgba(255/255,61/255,32/255,1) endparam color param color7 caption = "Color 7" default = rgba(255/255,184/255,26/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,107/255,1/255,1) endparam } class REB_PeruMix(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_PeruMix(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Peru Mix Array" int param v_PeruMix caption = "Version (Peru Mix Colors)" 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_PeruMix < 100 endparam ; heading ; text = "Provides the colors for an internal gradient. Based upon the colors \ ; of Toby Marshall and Ken Childress." ; endheading color param color1 caption = "Color 1" default = rgba(204/255,133/255,63/255,1) endparam color param color2 caption = "Color 2" default = rgba(44/255,102/255,141/255,1) endparam color param color3 caption = "Color 3" default = rgba(204/255,160/255,63/255,1) endparam color param color4 caption = "Color 4" default = rgba(68/255,70/255,144/255,1) endparam color param color5 caption = "Color 5" default = rgba(204/255,90/255,63/255,1) endparam color param color6 caption = "Color 6" default = rgba(136/255,85/255,73/255,1) endparam color param color7 caption = "Color 7" default = rgba(51/255,76/255,94/255,1) endparam color param color8 caption = "Color 8" default = rgba(45/255,144/255,97/255,1) endparam } class REB_Fantasia(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Fantasia(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Fantasia Array" int param v_PFantasia caption = "Version (Fantasia Colors)" 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_PFantasia < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,230/255,103/255,1) endparam color param color2 caption = "Color 2" default = rgba(230/255,78/255,208/255,1) endparam color param color3 caption = "Color 3" default = rgba(180/255,119/255,255/255,1) endparam color param color4 caption = "Color 4" default = rgba(1/255,228/255,150/255,1) endparam color param color5 caption = "Color 5" default = rgba(131/255,148/255,255/255,1) endparam color param color6 caption = "Color 6" default = rgba(255/255,182/255,1/255,1) endparam color param color7 caption = "Color 7" default = rgba(252/255,1/255,113/255,1) endparam color param color8 caption = "Color 8" default = rgba(1/255,232/255,249/255,1) endparam } class REB_FloweringOrchard(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_FloweringOrchard(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Flowering Orchard Array" int param v_FloweringOrchard caption = "Version (Flowering Orchard Colors)" 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_FloweringOrchard < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,188/255,213/255,1) endparam color param color2 caption = "Color 2" default = rgba(240/255,135/255,255/255,1) endparam color param color3 caption = "Color 3" default = rgba(255/255,75/255,153/255,1) endparam color param color4 caption = "Color 4" default = rgba(71/255,213/255,119/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,102/255,209/255,1) endparam color param color6 caption = "Color 6" default = rgba(154/255,199/255,51/255,1) endparam color param color7 caption = "Color 7" default = rgba(255/255,162/255,228/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,201/255,237/255,1) endparam } class REB_GoldGreen(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_GoldGreen(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Gold Green Array" int param v_GoldGreen caption = "Version (Gold Green Colors)" 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_GoldGreen < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,255/255,1/255,1) endparam color param color2 caption = "Color 2" default = rgba(1/255,129/255,8/255,1) endparam color param color3 caption = "Color 3" default = rgba(255/255,255/255,1/255,1) endparam color param color4 caption = "Color 4" default = rgba(1/255,129/255,8/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,255/255,1/255,1) endparam color param color6 caption = "Color 6" default = rgba(1/255,129/255,8/255,1) endparam color param color7 caption = "Color 7" default = rgba(255/255,255/255,1/255,1) endparam color param color8 caption = "Color 8" default = rgba(1/255,129/255,8/255,1) endparam } class REB_GoldSilver(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_GoldSilver(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Gold Silver Array" int param v_GoldSilver caption = "Version (Gold Silver Colors)" 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_GoldSilver < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,255/255,1/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,255/255,255/255,1) endparam color param color3 caption = "Color 3" default = rgba(255/255,255/255,1/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,255/255,255/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,255/255,1/255,1) endparam color param color6 caption = "Color 6" default = rgba(255/255,255/255,255/255,1) endparam color param color7 caption = "Color 7" default = rgba(255/255,255/255,1/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,255/255,255/255,1) endparam } class REB_laTerra(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_laTerra(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "la Terra Array" int param v_laTerra caption = "Version (la Terra Colors)" 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_laTerra < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,174/255,103/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,242/255,39/255,1) endparam color param color3 caption = "Color 3" default = rgba(170/255,86/255,1/255,1) endparam color param color4 caption = "Color 4" default = rgba(190/255,118/255,13/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,174/255,103/255,1) endparam color param color6 caption = "Color 6" default = rgba(255/255,242/255,39/255,1) endparam color param color7 caption = "Color 7" default = rgba(170/255,86/255,1/255,1) endparam color param color8 caption = "Color 8" default = rgba(190/255,118/255,13/255,1) endparam } class REB_Mojave(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Mojave(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Mojave Array" int param v_Mojave caption = "Version (Mojave Colors)" 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_Mojave < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,169/255,50/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,243/255,120/255,1) endparam color param color3 caption = "Color 3" default = rgba(255/255,169/255,50/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,243/255,120/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,169/255,50/255,1) endparam color param color6 caption = "Color 6" default = rgba(255/255,243/255,120/255,1) endparam color param color7 caption = "Color 7" default = rgba(255/255,169/255,50/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,243/255,120/255,1) endparam } class REB_MorningSky(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_MorningSky(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Morning Sky Array" int param v_MorningSky caption = "Version (Morning Sky Colors)" 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_MorningSky < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,178/255,217/255,1) endparam color param color2 caption = "Color 2" default = rgba(107/255,246/255,255/255,1) endparam color param color3 caption = "Color 3" default = rgba(255/255,199/255,137/255,1) endparam color param color4 caption = "Color 4" default = rgba(241/255,245/255,255/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,177/255,188/255,1) endparam color param color6 caption = "Color 6" default = rgba(248/255,236/255,236/255,1) endparam color param color7 caption = "Color 7" default = rgba(129/255,201/255,255/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,255/255,146/255,1) endparam } class REB_Pastel(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Pastel(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Pastel Array" int param v_Pastel caption = "Version (Pastel Colors)" 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_Pastel < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(147/255,255/255,193/255,1) endparam color param color2 caption = "Color 2" default = rgba(147/255,255/255,255/255,1) endparam color param color3 caption = "Color 3" default = rgba(148/255,148/255,253/255,1) endparam color param color4 caption = "Color 4" default = rgba(199/255,149/255,253/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,147/255,221/255,1) endparam color param color6 caption = "Color 6" default = rgba(254/255,148/255,148/255,1) endparam color param color7 caption = "Color 7" default = rgba(255/255,202/255,147/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,255/255,147/255,1) endparam } class REB_PastelRainbow(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_PastelRainbow(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Pastel Rainbow Array" int param v_PastelRainbow caption = "Version (Pastel Rainbow Colors)" 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_PastelRainbow < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(242/255,246/255,174/255,1) endparam color param color2 caption = "Color 2" default = rgba(182/255,242/255,255/255,1) endparam color param color3 caption = "Color 3" default = rgba(202/255,202/255,255/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,170/255,170/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,246/255,178/255,1) endparam color param color6 caption = "Color 6" default = rgba(255/255,238/255,206/255,1) endparam color param color7 caption = "Color 7" default = rgba(214/255,222/255,161/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,230/255,246/255,1) endparam } class REB_SchottkyMix(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_SchottkyMix(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Schottky Mix Array" int param v_Schottky caption = "Version (Schottky Colors)" 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_Schottky < 100 endparam color param color1 caption = "Color 1" default = rgba(227/255,113/255,56/255,1) endparam color param color2 caption = "Color 2" default = rgba(238/255,238/255,1/255,1) endparam color param color3 caption = "Color 3" default = rgba(1/255,216/255,1/255,1) endparam color param color4 caption = "Color 4" default = rgba(114/255,1/255,227/255,1) endparam color param color5 caption = "Color 5" default = rgba(1/255,1/255,216/255,1) endparam color param color6 caption = "Color 6" default = rgba(216/255,1/255,1/255,1) endparam color param color7 caption = "Color 7" default = rgba(1/255,216/255,216/255,1) endparam color param color8 caption = "Color 8" default = rgba(171/255,171/255,171/255,1) endparam } class REB_CrimsonMix(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_CrimsonMix(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Crimson Mix Array" int param v_CrimsonMix caption = "Version (Crimson Mix Colors)" 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_CrimsonMix < 100 endparam color param color1 caption = "Color 1" default = rgba(219/255,20/255,59/255,1) endparam color param color2 caption = "Color 2" default = rgba(38/255,206/255,19/255,1) endparam color param color3 caption = "Color 3" default = rgba(230/255,85/255,21/255,1) endparam color param color4 caption = "Color 4" default = rgba(13/255,149/255,119/255,1) endparam color param color5 caption = "Color 5" default = rgba(146/255,58/255,75/255,1) endparam color param color6 caption = "Color 6" default = rgba(153/255,89/255,60/255,1) endparam color param color7 caption = "Color 7" default = rgba(162/255,15/255,140/255,1) endparam color param color8 caption = "Color 8" default = rgba(166/255,230/255,21/255,1) endparam } class REB_Flowers(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Flowers(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Flowers Array" int param v_flowers caption = "Version (Flowers Colors)" 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_Flowers < 100 endparam color param color1 caption = "Color 1" default = rgba(1/255,255/255,255/255,1) endparam color param color2 caption = "Color 2" default = rgba(138/255,43/255,226/255,1) endparam color param color3 caption = "Color 3" default = rgba(100/255,149/255,237/255,1) endparam color param color4 caption = "Color 4" default = rgba(220/255,20/255,60/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,215/255,1/255,1) endparam color param color6 caption = "Color 6" default = rgba(153/255,50/255,204/255,1) endparam color param color7 caption = "Color 7" default = rgba(255/255,20/255,147/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,140/255,1/255,1) endparam } class REB_GoldMix(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_GoldMix(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Gold Mix Array" int param v_GoldMix caption = "Version (Gold Mix Colors)" 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_GoldMix < 100 endparam color param color1 caption = "Color 1" default = rgba(255/255,216/255,1/255,1) endparam color param color2 caption = "Color 2" default = rgba(57/255,1/255,153/255,1) endparam color param color3 caption = "Color 3" default = rgba(231/255,255/255,1/255,1) endparam color param color4 caption = "Color 4" default = rgba(126/255,1/255,153/255,1) endparam color param color5 caption = "Color 5" default = rgba(170/255,153/255,57/255,1) endparam color param color6 caption = "Color 6" default = rgba(255/255,165/255,1/255,1) endparam color param color7 caption = "Color 7" default = rgba(23/255,49/255,192/255,1) endparam color param color8 caption = "Color 8" default = rgba(159/255,170/255,57/255,1) endparam } class REB_MediumSeaGreenMix(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_MediumSeaGreenMix(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Medium Sea Green Mix Array" int param v_MediumSeaGreenMix caption = "Version (Medium Sea Green Mix Colors)" 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_MediumSeaGreenMix < 100 endparam color param color1 caption = "Color 1" default = rgba(32/255,179/255,169/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,124/255,46/255,1) endparam color param color3 caption = "Color 3" default = rgba(41/255,96/255,230/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,169/255,46/255,1) endparam color param color5 caption = "Color 5" default = rgba(54/255,119/255,115/255,1) endparam color param color6 caption = "Color 6" default = rgba(170/255,112/255,77/255,1) endparam color param color7 caption = "Color 7" default = rgba(50/255,241/255,43/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,46/255,58/255,1) endparam } class REB_Pastels2(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Pastels2(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Pastels2 Array" int param v_Pastels2 caption = "Version (Pastels2 Colors)" 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_Pastels2 < 100 endparam color param color1 caption = "Color 1" default = rgba(173/255,255/255,47/255,1) endparam color param color2 caption = "Color 2" default = rgba(229/255,220/255,133/255,1) endparam color param color3 caption = "Color 3" default = rgba(173/255,216/255,230/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,182/255,193/255,1) endparam color param color5 caption = "Color 5" default = rgba(127/255,255/255,212/255,1) endparam color param color6 caption = "Color 6" default = rgba(222/255,184/255,135/255,1) endparam color param color7 caption = "Color 7" default = rgba(218/255,112/255,214/255,1) endparam color param color8 caption = "Color 8" default = rgba(175/255,196/255,222/255,1) endparam } class REB_Rainbow1(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Rainbow1(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Rainbow1 Array" int param v_Rainbow1 caption = "Version (Rainbow1 Colors)" 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_Rainbow1 < 100 endparam color param color1 caption = "Color 1" default = rgba(255/255,20/255,147/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,99/255,71/255,1) endparam color param color3 caption = "Color 3" default = rgba(255/255,215/255,1/255,1) endparam color param color4 caption = "Color 4" default = rgba(121/255,247/255,1/255,1) endparam color param color5 caption = "Color 5" default = rgba(72/255,209/255,204/255,1) endparam color param color6 caption = "Color 6" default = rgba(30/255,144/255,255/255,1) endparam color param color7 caption = "Color 7" default = rgba(147/255,112/255,219/255,1) endparam color param color8 caption = "Color 8" default = rgba(199/255,21/255,133/255,1) endparam } class REB_Rainbow2(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Rainbow2(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Rainbow2 Array" int param v_Rainbow2 caption = "Version (Rainbow2 Colors)" 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_Rainbow2 < 100 endparam color param color1 caption = "Color 1" default = rgba(255/255,20/255,147/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,1/255,1/255,1) endparam color param color3 caption = "Color 3" default = rgba(250/255,250/255,1/255,1) endparam color param color4 caption = "Color 4" default = rgba(1/255,255/255,1/255,1) endparam color param color5 caption = "Color 5" default = rgba(1/255,255/255,255/255,1) endparam color param color6 caption = "Color 6" default = rgba(1/255,1/255,255/255,1) endparam color param color7 caption = "Color 7" default = rgba(128/255,1/255,128/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,1/255,255/255,1) endparam } class REB_Reb(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Reb(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Reb Array" int param v_Reb caption = "Version (Reb Colors)" 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_Reb < 100 endparam color param color1 caption = "Color 1" default = rgba(220/255,20/255,60/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,215/255,1/255,1) endparam color param color3 caption = "Color 3" default = rgba(34/255,139/255,35/255,1) endparam color param color4 caption = "Color 4" default = rgba(63/255,102/255,220/255,1) endparam color param color5 caption = "Color 5" default = rgba(138/255,43/255,226/255,1) endparam color param color6 caption = "Color 6" default = rgba(180/255,131/255,10/255,1) endparam color param color7 caption = "Color 7" default = rgba(255/255,140/255,1/255,1) endparam color param color8 caption = "Color 8" default = rgba(32/255,178/255,170/255,1) endparam } class REB_RoyalBlueMix(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_RoyalBlueMix(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Royal Blue Mix Array" int param v_RoyalBlueMix caption = "Version (Royal Blue Mix Colors)" 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_RoyalBlueMix < 100 endparam color param color1 caption = "Color 1" default = rgba(65/255,105/255,224/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,183/255,74/255,1) endparam color param color3 caption = "Color 3" default = rgba(89/255,49/255,169/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,219/255,74/255,1) endparam color param color5 caption = "Color 5" default = rgba(79/255,96/255,150/255,1) endparam color param color6 caption = "Color 6" default = rgba(170/255,138/255,90/255,1) endparam color param color7 caption = "Color 7" default = rgba(49/255,168/255,168/255,1) endparam color param color8 caption = "Color 8" default = rgba(162/255,137/255,212/255,1) endparam } class REB_SpringGreenMix(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_SpringGreenMix(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Spring Green Mix Array" int param v_SpringGreenMix caption = "Version (Spring Green Mix Colors)" 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_SpringGreenMix < 100 endparam color param color1 caption = "Color 1" default = rgba(1/255,255/255,124/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,44/255,1/255,1) endparam color param color3 caption = "Color 3" default = rgba(1/255,145/255,247/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,125/255,1/255,1) endparam color param color5 caption = "Color 5" default = rgba(157/255,103/255,52/255,1) endparam color param color6 caption = "Color 6" default = rgba(65/255,255/255,1/255,1) endparam color param color7 caption = "Color 7" default = rgba(57/255,170/255,112/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,150/255,128/255,1) endparam } class REB_WebgenMix(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_WebgenMix(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Webgen Mix Array" int param v_WebgenMix caption = "Version (Webgen Mix Colors)" 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_WebgenMix < 100 endparam color param color1 caption = "Color 1" default = rgba(6/255,59/255,255/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,158/255,1/255,1) endparam color param color3 caption = "Color 3" default = rgba(69/255,1/255,196/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,209/255,1/255,1) endparam color param color5 caption = "Color 5" default = rgba(60/255,83/255,170/255,1) endparam color param color6 caption = "Color 6" default = rgba(170/255,127/255,57/255,1) endparam color param color7 caption = "Color 7" default = rgba(1/255,183/255,202/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,107/255,1/255,1) endparam } class REB_PurpleYellow(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_PurpleYellow(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Purple Yellow Array" int param v_PurpleYellow caption = "Version (Purple Yellow Colors)" 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_PurpleYellow < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(172/255,96/255,252/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,255/255,1/255,1) endparam color param color3 caption = "Color 3" default = rgba(172/255,96/255,252/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,255/255,1/255,1) endparam color param color5 caption = "Color 5" default = rgba(172/255,96/255,252/255,1) endparam color param color6 caption = "Color 6" default = rgba(255/255,255/255,1/255,1) endparam color param color7 caption = "Color 7" default = rgba(172/255,96/255,252/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,255/255,1/255,1) endparam } class REB_RedTan(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_RedTan(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Red Tan Array" int param v_RedTan caption = "Version (Red Tan Colors)" 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_RedTan < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,32/255,32/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,208/255,152/255,1) endparam color param color3 caption = "Color 3" default = rgba(255/255,32/255,32/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,208/255,152/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,32/255,32/255,1) endparam color param color6 caption = "Color 6" default = rgba(255/255,208/255,152/255,1) endparam color param color7 caption = "Color 7" default = rgba(255/255,32/255,32/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,208/255,152/255,1) endparam } class REB_SantaFe(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_SantaFe(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "SantaFe Array" int param v_SantaFe caption = "Version (SantaFe Colors)" 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_SantaFe < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,235/255,76/255,1) endparam color param color2 caption = "Color 2" default = rgba(1/255,229/255,222/255,1) endparam color param color3 caption = "Color 3" default = rgba(255/255,200/255,140/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,157/255,82/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,235/255,76/255,1) endparam color param color6 caption = "Color 6" default = rgba(1/255,229/255,222/255,1) endparam color param color7 caption = "Color 7" default = rgba(255/255,200/255,140/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,157/255,82/255,1) endparam } class REB_Showtime(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Showtime(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Showtime Array" int param v_Showtime caption = "Version (Showtime Colors)" 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_Showtime < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(241/255,53/255,82/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,121/255,52/255,1) endparam color param color3 caption = "Color 3" default = rgba(253/255,168/255,67/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,231/255,21/255,1) endparam color param color5 caption = "Color 5" default = rgba(58/255,219/255,255/255,1) endparam color param color6 caption = "Color 6" default = rgba(9/255,116/255,255/255,1) endparam color param color7 caption = "Color 7" default = rgba(105/255,71/255,255/255,1) endparam color param color8 caption = "Color 8" default = rgba(187/255,32/255,255/255,1) endparam } class REB_Soleil(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Soleil(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Soleil Array" int param v_Soleil caption = "Version (Soleil Colors)" 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_Soleil < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,255/255,35/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,209/255,1/255,1) endparam color param color3 caption = "Color 3" default = rgba(231/255,237/255,255/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,141/255,49/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,255/255,156/255,1) endparam color param color6 caption = "Color 6" default = rgba(255/255,158/255,17/255,1) endparam color param color7 caption = "Color 7" default = rgba(255/255,255/255,217/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,184/255,53/255,1) endparam } class REB_Spring(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Spring(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Spring Array" int param v_Spring caption = "Version (Spring Colors)" 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_Spring < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,255/255,145/255,1) endparam color param color2 caption = "Color 2" default = rgba(215/255,182/255,255/255,1) endparam color param color3 caption = "Color 3" default = rgba(189/255,246/255,255/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,181/255,237/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,255/255,145/255,1) endparam color param color6 caption = "Color 6" default = rgba(215/255,182/255,255/255,1) endparam color param color7 caption = "Color 7" default = rgba(189/255,246/255,255/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,181/255,237/255,1) endparam } class REB_BlueSilver(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_BlueSilver(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Blue Silver Array" int param v_BlueSilver caption = "Version (Blue Silver Colors)" 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_BlueSilver < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(64/255,64/255,255/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,255/255,255/255,1) endparam color param color3 caption = "Color 3" default = rgba(64/255,64/255,255/255,1) endparam color param color4 caption = "Color 4" default = rgba(255/255,255/255,255/255,1) endparam color param color5 caption = "Color 5" default = rgba(64/255,64/255,255/255,1) endparam color param color6 caption = "Color 6" default = rgba(255/255,255/255,255/255,1) endparam color param color7 caption = "Color 7" default = rgba(64/255,64/255,255/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,255/255,255/255,1) endparam } class REB_Summer(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Summer(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Summer Array" int param v_Summer caption = "Version (Summer Colors)" 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_Summer < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,255/255,1/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,64/255,64/255,1) endparam color param color3 caption = "Color 3" default = rgba(1/255,255/255,101/255,1) endparam color param color4 caption = "Color 4" default = rgba(64/255,255/255,255/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,255/255,1/255,1) endparam color param color6 caption = "Color 6" default = rgba(255/255,64/255,64/255,1) endparam color param color7 caption = "Color 7" default = rgba(1/255,255/255,101/255,1) endparam color param color8 caption = "Color 8" default = rgba(64/255,255/255,255/255,1) endparam } class REB_Winter(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Winter(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Winter Array" int param v_Winter caption = "Version (Winter Colors)" 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_Winter < 100 endparam heading text = "Provides the colors for an internal gradient. Based upon the colors \ of Toby Marshall and Ken Childress." endheading color param color1 caption = "Color 1" default = rgba(255/255,255/255,255/255,1) endparam color param color2 caption = "Color 2" default = rgba(163/255,186/255,209/255,1) endparam color param color3 caption = "Color 3" default = rgba(173/255,166/255,157/255,1) endparam color param color4 caption = "Color 4" default = rgba(113/255,118/255,140/255,1) endparam color param color5 caption = "Color 5" default = rgba(255/255,255/255,255/255,1) endparam color param color6 caption = "Color 6" default = rgba(163/255,186/255,209/255,1) endparam color param color7 caption = "Color 7" default = rgba(173/255,166/255,157/255,1) endparam color param color8 caption = "Color 8" default = rgba(113/255,118/255,140/255,1) endparam } class REB_Earth(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Earth(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Earth Array" int param v_earth caption = "Version (Earth Colors)" 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_earth < 100 endparam color param color1 caption = "Color 1" default = rgba(132/255,136/255,80/255,1) endparam color param color2 caption = "Color 2" default = rgba(120/255,80/255,44/255,1) endparam color param color3 caption = "Color 3" default = rgba(220/255,160/255,100/255,1) endparam color param color4 caption = "Color 4" default = rgba(120/255,88/255,36/255,1) endparam color param color5 caption = "Color 5" default = rgba(184/255,44/255,52/255,1) endparam color param color6 caption = "Color 6" default = rgba(120/255,88/255,36/255,1) endparam color param color7 caption = "Color 7" default = rgba(20/255,100/255,108/255,1) endparam color param color8 caption = "Color 8" default = rgba(120/255,72/255,40/255,1) endparam } class REB_Allison(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Allison(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Allison Array" int param v_Allison caption = "Version (Allison Colors)" 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_Allison < 100 endparam color param color1 caption = "Color 1" default = rgba(252/255,120/255,60/255,1) endparam color param color2 caption = "Color 2" default = rgba(198/255,166/255,164/255,1) endparam color param color3 caption = "Color 3" default = rgba(208/255,208/255,228/255,1) endparam color param color4 caption = "Color 4" default = rgba(88/255,88/255,88/255,1) endparam color param color5 caption = "Color 5" default = rgba(188/255,68/255,28/255,1) endparam color param color6 caption = "Color 6" default = rgba(60/255,60/255,40/255,1) endparam color param color7 caption = "Color 7" default = rgba(252/255,248/255,204/255,1) endparam color param color8 caption = "Color 8" default = rgba(168/255,72/255,40/255,1) endparam } class REB_Byre(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Byre(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Byre Array" int param v_Byre caption = "Version (Byre Colors)" 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_Byre < 100 endparam color param color1 caption = "Color 1" default = rgba(203/255,214/255,152/255,1) endparam color param color2 caption = "Color 2" default = rgba(213/255,206/255,126/255,1) endparam color param color3 caption = "Color 3" default = rgba(215/255,167/255,73/255,1) endparam color param color4 caption = "Color 4" default = rgba(188/255,68/255,28/255,1) endparam color param color5 caption = "Color 5" default = rgba(114/255,90/255,52/255,1) endparam color param color6 caption = "Color 6" default = rgba(10/255,44/255,46/255,1) endparam color param color7 caption = "Color 7" default = rgba(116/255,144/255,108/255,1) endparam color param color8 caption = "Color 8" default = rgba(175/255,195/255,140/255,1) endparam } class REB_Clouds(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Clouds(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Clouds Array" int param v_Clouds caption = "Version (Clouds Colors)" 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_Clouds < 100 endparam color param color1 caption = "Color 1" default = rgba(224/255,236/255,248/255,1) endparam color param color2 caption = "Color 2" default = rgba(252/255,252/255,252/255,1) endparam color param color3 caption = "Color 3" default = rgba(200/255,225/255,252/255,1) endparam color param color4 caption = "Color 4" default = rgba(105/255,175/255,252/255,1) endparam color param color5 caption = "Color 5" default = rgba(1/255,120/255,252/255,1) endparam color param color6 caption = "Color 6" default = rgba(4/255,120/255,248/255,1) endparam color param color7 caption = "Color 7" default = rgba(83/255,162/255,248/255,1) endparam color param color8 caption = "Color 8" default = rgba(174/255,211/255,248/255,1) endparam } class REB_SunsetClouds(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_SunsetClouds(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Sunset Clouds Array" int param v_Clouds caption = "Version (Clouds Colors)" 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_Clouds < 100 endparam color param color1 caption = "Color 1" default = rgba(226/255,234/255,248/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,225/255,252/255,1) endparam color param color3 caption = "Color 3" default = rgba(204/255,200/255,252/255,1) endparam color param color4 caption = "Color 4" default = rgba(105/255,175/255,252/255,1) endparam color param color5 caption = "Color 5" default = rgba(1/255,120/255,252/255,1) endparam color param color6 caption = "Color 6" default = rgba(4/255,120/255,248/255,1) endparam color param color7 caption = "Color 7" default = rgba(83/255,162/255,248/255,1) endparam color param color8 caption = "Color 8" default = rgba(174/255,211/255,248/255,1) endparam } class REB_Clover(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Clover(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Clover Array" int param v_Clover caption = "Version (Clover Colors)" 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_Clover < 100 endparam color param color1 caption = "Color 1" default = rgba(204/255,188/255,16/255,1) endparam color param color2 caption = "Color 2" default = rgba(112/255,64/255,56/255,1) endparam color param color3 caption = "Color 3" default = rgba(72/255,16/255,72/255,1) endparam color param color4 caption = "Color 4" default = rgba(45/255,71/255,75/255,1) endparam color param color5 caption = "Color 5" default = rgba(1/255,160/255,80/255,1) endparam color param color6 caption = "Color 6" default = rgba(252/255,252/255,236/255,1) endparam color param color7 caption = "Color 7" default = rgba(252/255,248/255,1/255,1) endparam color param color8 caption = "Color 8" default = rgba(208/255,192/255,16/255,1) endparam } class REB_ColdFire(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_ColdFire(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "ColdFire Array" int param v_ColdFire caption = "Version (ColdFire Colors)" 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_ColdFire < 100 endparam color param color1 caption = "Color 1" default = rgba(1/255,172/255,252/255,1) endparam color param color2 caption = "Color 2" default = rgba(1/255,68/255,252/255,1) endparam color param color3 caption = "Color 3" default = rgba(1/255,4/255,252/255,1) endparam color param color4 caption = "Color 4" default = rgba(74/255,39/255,158/255,1) endparam color param color5 caption = "Color 5" default = rgba(196/255,96/255,4/255,1) endparam color param color6 caption = "Color 6" default = rgba(252/255,252/255,1/255,1) endparam color param color7 caption = "Color 7" default = rgba(252/255,252/255,188/255,1) endparam color param color8 caption = "Color 8" default = rgba(252/255,252/255,252/255,1) endparam } class REB_GrayMatter(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_GrayMatter(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "GrayMatter Array" int param v_GrayMatter caption = "Version (GrayMatter Colors)" 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_GrayMatter < 100 endparam color param color1 caption = "Color 1" default = rgba(212/255,148/255,220/255,1) endparam color param color2 caption = "Color 2" default = rgba(40/255,80/255,120/255,1) endparam color param color3 caption = "Color 3" default = rgba(184/255,172/255,172/255,1) endparam color param color4 caption = "Color 4" default = rgba(212/255,180/255,144/255,1) endparam color param color5 caption = "Color 5" default = rgba(120/255,80/255,1/255,1) endparam color param color6 caption = "Color 6" default = rgba(240/255,160/255,60/255,1) endparam color param color7 caption = "Color 7" default = rgba(120/255,60/255,60/255,1) endparam color param color8 caption = "Color 8" default = rgba(220/255,100/255,112/255,1) endparam } class REB_Berries(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Berries(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Berries Array" int param v_Berries caption = "Version (Berries Colors)" 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_Berries < 100 endparam color param color1 caption = "Color 1" default = rgba(1/255,1/255,252/255,1) endparam color param color2 caption = "Color 2" default = rgba(100/255,232/255,232/255,1) endparam color param color3 caption = "Color 3" default = rgba(1/255,36/255,100/255,1) endparam color param color4 caption = "Color 4" default = rgba(96/255,92/255,192/255,1) endparam color param color5 caption = "Color 5" default = rgba(252/255,252/255,252/255,1) endparam color param color6 caption = "Color 6" default = rgba(252/255,1/255,92/255,1) endparam color param color7 caption = "Color 7" default = rgba(16/255,44/255,28/255,1) endparam color param color8 caption = "Color 8" default = rgba(40/255,144/255,80/255,1) endparam } class REB_Sand(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Sand(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Sand Array" int param v_Sand caption = "Version (Sand Colors)" 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_Sand < 100 endparam color param color1 caption = "Color 1" default = rgba(224/255,152/255,48/255,1) endparam color param color2 caption = "Color 2" default = rgba(1/255,40/255,1/255,1) endparam color param color3 caption = "Color 3" default = rgba(152/255,124/255,76/255,1) endparam color param color4 caption = "Color 4" default = rgba(252/255,212/255,152/255,1) endparam color param color5 caption = "Color 5" default = rgba(128/255,104/255,64/255,1) endparam color param color6 caption = "Color 6" default = rgba(212/255,212/255,212/255,1) endparam color param color7 caption = "Color 7" default = rgba(100/255,60/255,60/255,1) endparam color param color8 caption = "Color 8" default = rgba(252/255,172/255,48/255,1) endparam } class REB_Alien(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Alien(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Alien Array" int param v_Alien caption = "Version (Alien Colors)" 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_Alien < 100 endparam color param color1 caption = "Color 1" default = rgba(140/255,216/255,140/255,1) endparam color param color2 caption = "Color 2" default = rgba(168/255,184/255,140/255,1) endparam color param color3 caption = "Color 3" default = rgba(124/255,116/255,99/255,1) endparam color param color4 caption = "Color 4" default = rgba(77/255,45/255,55/255,1) endparam color param color5 caption = "Color 5" default = rgba(52/255,8/255,32/255,1) endparam color param color6 caption = "Color 6" default = rgba(236/255,192/255,148/255,1) endparam color param color7 caption = "Color 7" default = rgba(44/255,1/255,44/255,1) endparam color param color8 caption = "Color 8" default = rgba(200/255,40/255,140/255,1) endparam } class REB_Sand2(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Sand2(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Sand2 Array" int param v_Sand2 caption = "Version (Sand2 Colors)" 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_Sand2 < 100 endparam color param color1 caption = "Color 1" default = rgba(208/255,168/255,4/255,1) endparam color param color2 caption = "Color 2" default = rgba(100/255,60/255,60/255,1) endparam color param color3 caption = "Color 3" default = rgba(252/255,172/255,52/255,1) endparam color param color4 caption = "Color 4" default = rgba(1/255,60/255,88/255,1) endparam color param color5 caption = "Color 5" default = rgba(80/255,88/255,172/255,1) endparam color param color6 caption = "Color 6" default = rgba(100/255,100/255,1/255,1) endparam color param color7 caption = "Color 7" default = rgba(252/255,212/255,152/255,1) endparam color param color8 caption = "Color 8" default = rgba(100/255,60/255,60/255,1) endparam } class REB_BlueGreen(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_BlueGreen(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "BlueGreen Array" int param v_BlueGreen caption = "Version (BlueGreen Colors)" 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_BlueGreen < 100 endparam color param color1 caption = "Color 1" default = rgba(40/255,188/255,176/255,1) endparam color param color2 caption = "Color 2" default = rgba(152/255,76/255,220/255,1) endparam color param color3 caption = "Color 3" default = rgba(36/255,56/255,184/255,1) endparam color param color4 caption = "Color 4" default = rgba(216/255,252/255,236/255,1) endparam color param color5 caption = "Color 5" default = rgba(60/255,120/255,24/255,1) endparam color param color6 caption = "Color 6" default = rgba(72/255,36/255,216/255,1) endparam color param color7 caption = "Color 7" default = rgba(36/255,28/255,108/255,1) endparam color param color8 caption = "Color 8" default = rgba(56/255,136/255,176/255,1) endparam } class REB_Ocean(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Ocean(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Ocean Array" int param v_Ocean caption = "Version (Ocean Colors)" 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_Ocean < 100 endparam color param color1 caption = "Color 1" default = rgba(60/255,100/255,180/255,1) endparam color param color2 caption = "Color 2" default = rgba(131/255,151/255,170/255,1) endparam color param color3 caption = "Color 3" default = rgba(200/255,200/255,160/255,1) endparam color param color4 caption = "Color 4" default = rgba(252/255,252/255,252/255,1) endparam color param color5 caption = "Color 5" default = rgba(1/255,240/255,160/255,1) endparam color param color6 caption = "Color 6" default = rgba(1/255,102/255,213/255,1) endparam color param color7 caption = "Color 7" default = rgba(1/255,1/255,252/255,1) endparam color param color8 caption = "Color 8" default = rgba(60/255,100/255,180/255,1) endparam } class REB_Volcano(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Volcano(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Volcano Array" int param v_Volcano caption = "Version (Volcano Colors)" 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_Volcano < 100 endparam color param color1 caption = "Color 1" default = rgba(1/255,1/255,121/255,1) endparam color param color2 caption = "Color 2" default = rgba(1/255,1/255,252/255,1) endparam color param color3 caption = "Color 3" default = rgba(89/255,1/255,163/255,1) endparam color param color4 caption = "Color 4" default = rgba(252/255,1/255,1/255,1) endparam color param color5 caption = "Color 5" default = rgba(252/255,71/255,1/255,1) endparam color param color6 caption = "Color 6" default = rgba(252/255,164/255,3/255,1) endparam color param color7 caption = "Color 7" default = rgba(252/255,252/255,4/255,1) endparam color param color8 caption = "Color 8" default = rgba(252/255,252/255,252/255,1) endparam } class REB_SunsetClouds(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_SunsetClouds(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "SunsetClouds Array" int param v_SunsetClouds caption = "Version (SunsetClouds Colors)" 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_SunsetClouds < 100 endparam color param color1 caption = "Color 1" default = rgba(220/255,185/255,248/255,1) endparam color param color2 caption = "Color 2" default = rgba(252/255,211/255,252/255,1) endparam color param color3 caption = "Color 3" default = rgba(198/255,191/255,252/255,1) endparam color param color4 caption = "Color 4" default = rgba(101/255,156/255,252/255,1) endparam color param color5 caption = "Color 5" default = rgba(1/255,120/255,252/255,1) endparam color param color6 caption = "Color 6" default = rgba(4/255,120/255,248/255,1) endparam color param color7 caption = "Color 7" default = rgba(97/255,148/255,248/255,1) endparam color param color8 caption = "Color 8" default = rgba(197/255,178/255,248/255,1) endparam } class REB_Browns(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Browns(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Browns Array" int param v_Browns caption = "Version (Browns Colors)" 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_Browns < 100 endparam color param color1 caption = "Color 1" default = rgba(61/255,1/255,12/255,1) endparam color param color2 caption = "Color 2" default = rgba(255/255,247/255,206/255,1) endparam color param color3 caption = "Color 3" default = rgba(176/255,127/255,90/255,1) endparam color param color4 caption = "Color 4" default = rgba(95/255,32/255,16/255,1) endparam color param color5 caption = "Color 5" default = rgba(61/255,14/255,12/255,1) endparam color param color6 caption = "Color 6" default = rgba(255/255,239/255,164/255,1) endparam color param color7 caption = "Color 7" default = rgba(61/255,14/255,1/255,1) endparam color param color8 caption = "Color 8" default = rgba(255/255,247/255,206/255,1) endparam } class REB_Colors(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Colors(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Colors Array" int param v_Colors caption = "Version (Colors Colors)" 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_Colors < 100 endparam color param color1 caption = "Color 1" default = rgba(252/255,80/255,1/255,1) endparam color param color2 caption = "Color 2" default = rgba(125/255,40/255,1/255,1) endparam color param color3 caption = "Color 3" default = rgba(1/255,1/255,1/255,1) endparam color param color4 caption = "Color 4" default = rgba(120/255,252/255,252/255,1) endparam color param color5 caption = "Color 5" default = rgba(179/255,193/255,252/255,1) endparam color param color6 caption = "Color 6" default = rgba(252/255,120/255,252/255,1) endparam color param color7 caption = "Color 7" default = rgba(1/255,1/255,1/255,1) endparam color param color8 caption = "Color 8" default = rgba(129/255,41/255,1/255,1) endparam } class REB_Embers(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Embers(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Embers Array" int param v_Embers caption = "Version (Embers Colors)" 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_Embers < 100 endparam color param color1 caption = "Color 1" default = rgba(1/255,1/255,1/255,1) endparam color param color2 caption = "Color 2" default = rgba(1/255,1/255,80/255,1) endparam color param color3 caption = "Color 3" default = rgba(32/255,32/255,80/255,1) endparam color param color4 caption = "Color 4" default = rgba(88/255,18/255,45/255,1) endparam color param color5 caption = "Color 5" default = rgba(160/255,1/255,1/255,1) endparam color param color6 caption = "Color 6" default = rgba(144/255,4/255,8/255,1) endparam color param color7 caption = "Color 7" default = rgba(252/255,252/255,1/255,1) endparam color param color8 caption = "Color 8" default = rgba(252/255,252/255,252/255,1) endparam } class REB_Flowers2(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Flowers2(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Flowers2 Array" int param v_Flowers2 caption = "Version (Flowers2 Colors)" 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_Flowers2 < 100 endparam color param color1 caption = "Color 1" default = rgba(36/255,184/255,252/255,1) endparam color param color2 caption = "Color 2" default = rgba(252/255,96/255,84/255,1) endparam color param color3 caption = "Color 3" default = rgba(252/255,240/255,84/255,1) endparam color param color4 caption = "Color 4" default = rgba(56/255,168/255,52/255,1) endparam color param color5 caption = "Color 5" default = rgba(216/255,112/255,164/255,1) endparam color param color6 caption = "Color 6" default = rgba(236/255,28/255,1/255,1) endparam color param color7 caption = "Color 7" default = rgba(40/255,60/255,108/255,1) endparam color param color8 caption = "Color 8" default = rgba(88/255,136/255,96/255,1) endparam } class REB_Guernica(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Guernica(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Guernica Array" int param v_Guernica caption = "Version (Guernica Colors)" 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_Guernica < 100 endparam color param color1 caption = "Color 1" default = rgba(252/255,248/255,124/255,1) endparam color param color2 caption = "Color 2" default = rgba(148/255,165/255,120/255,1) endparam color param color3 caption = "Color 3" default = rgba(60/255,92/255,120/255,1) endparam color param color4 caption = "Color 4" default = rgba(1/255,44/255,88/255,1) endparam color param color5 caption = "Color 5" default = rgba(112/255,140/255,252/255,1) endparam color param color6 caption = "Color 6" default = rgba(252/255,1/255,252/255,1) endparam color param color7 caption = "Color 7" default = rgba(252/255,152/255,172/255,1) endparam color param color8 caption = "Color 8" default = rgba(252/255,244/255,124/255,1) endparam } class REB_IceScape(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_IceScape(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "IceScape Array" int param v_IceScape caption = "Version (IceScape Colors)" 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_IceScape < 100 endparam color param color1 caption = "Color 1" default = rgba(96/255,92/255,192/255,1) endparam color param color2 caption = "Color 2" default = rgba(252/255,252/255,252/255,1) endparam color param color3 caption = "Color 3" default = rgba(252/255,1/255,92/255,1) endparam color param color4 caption = "Color 4" default = rgba(1/255,1/255,1/255,1) endparam color param color5 caption = "Color 5" default = rgba(56/255,132/255,84/255,1) endparam color param color6 caption = "Color 6" default = rgba(252/255,248/255,248/255,1) endparam color param color7 caption = "Color 7" default = rgba(4/255,60/255,20/255,1) endparam color param color8 caption = "Color 8" default = rgba(208/255,244/255,100/255,1) endparam } class REB_SandAndSky(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_SandAndSky(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "SandAndSky Array" int param v_SandAndSky caption = "Version (SandAndSky Colors)" 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_SandAndSky < 100 endparam color param color1 caption = "Color 1" default = rgba(124/255,60/255,1/255,1) endparam color param color2 caption = "Color 2" default = rgba(187/255,123/255,63/255,1) endparam color param color3 caption = "Color 3" default = rgba(248/255,184/255,124/255,1) endparam color param color4 caption = "Color 4" default = rgba(188/255,248/255,184/255,1) endparam color param color5 caption = "Color 5" default = rgba(124/255,188/255,248/255,1) endparam color param color6 caption = "Color 6" default = rgba(65/255,127/255,189/255,1) endparam color param color7 caption = "Color 7" default = rgba(1/255,60/255,124/255,1) endparam color param color8 caption = "Color 8" default = rgba(64/255,0/255,60/255,1) endparam } class REB_Desert(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Desert(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Desert Array" int param v_Desert caption = "Version (Desert Colors)" 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_Desert < 100 endparam color param color1 caption = "Color 1" default = rgba(159/255,113/255,89/255,1) endparam color param color2 caption = "Color 2" default = rgba(75/255,87/255,99/255,1) endparam color param color3 caption = "Color 3" default = rgba(127/255,139/255,137/255,1) endparam color param color4 caption = "Color 4" default = rgba(183/255,124/255,92/255,1) endparam color param color5 caption = "Color 5" default = rgba(234/255,180/255,133/255,1) endparam color param color6 caption = "Color 6" default = rgba(135/255,178/255,212/255,1) endparam color param color7 caption = "Color 7" default = rgba(60/255,68/255,71/255,1) endparam color param color8 caption = "Color 8" default = rgba(179/255,119/255,82/255,1) endparam } class REB_Oasis(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Oasis(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Oasis Array" int param v_Oasis caption = "Version (Oasis Colors)" 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_Oasis < 100 endparam color param color1 caption = "Color 1" default = rgba(160/255,144/255,119/255,1) endparam color param color2 caption = "Color 2" default = rgba(98/255,141/255,113/255,1) endparam color param color3 caption = "Color 3" default = rgba(146/255,169/255,149/255,1) endparam color param color4 caption = "Color 4" default = rgba(216/255,194/255,196/255,1) endparam color param color5 caption = "Color 5" default = rgba(99/255,90/255,85/255,1) endparam color param color6 caption = "Color 6" default = rgba(190/255,184/255,198/255,1) endparam color param color7 caption = "Color 7" default = rgba(253/255,243/255,218/255,1) endparam color param color8 caption = "Color 8" default = rgba(228/255,210/255,206/255,1) endparam } class REB_Ocean2(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Ocean2(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Ocean2 Array" int param v_Ocean2 caption = "Version (Ocean2 Colors)" 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_Ocean2 < 100 endparam color param color1 caption = "Color 1" default = rgba(120/255,200/255,224/255,1) endparam color param color2 caption = "Color 2" default = rgba(180/255,220/255,240/255,1) endparam color param color3 caption = "Color 3" default = rgba(95/255,95/255,197/255,1) endparam color param color4 caption = "Color 4" default = rgba(240/255,240/255,200/255,1) endparam color param color5 caption = "Color 5" default = rgba(36/255,164/255,152/255,1) endparam color param color6 caption = "Color 6" default = rgba(1/255,120/255,100/255,1) endparam color param color7 caption = "Color 7" default = rgba(128/255,208/255,160/255,1) endparam color param color8 caption = "Color 8" default = rgba(86/255,111/255,2/255,1) endparam } class REB_Sunset(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Sunset(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Sunset Array" int param v_Sunset caption = "Version (Sunset Colors)" 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_Sunset < 100 endparam color param color1 caption = "Color 1" default = rgba(252/255,208/255,244/255,1) endparam color param color2 caption = "Color 2" default = rgba(252/255,37/255,69/255,1) endparam color param color3 caption = "Color 3" default = rgba(240/255,220/255,40/255,1) endparam color param color4 caption = "Color 4" default = rgba(109/255,104/255,206/255,1) endparam color param color5 caption = "Color 5" default = rgba(252/255,200/255,228/255,1) endparam color param color6 caption = "Color 6" default = rgba(252/255,132/255,156/255,1) endparam color param color7 caption = "Color 7" default = rgba(45/255,80/255,219/255,1) endparam color param color8 caption = "Color 8" default = rgba(97/255,24/255,74/255,1) endparam } class REB_Flowers3(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Flowers3(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Flowers3 Array" int param v_Flowers3 caption = "Version (Flowers3 Colors)" 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_Flowers3 < 100 endparam color param color1 caption = "Color 1" default = rgba(164/255,36/255,68/255,1) endparam color param color2 caption = "Color 2" default = rgba(252/255,220/255,80/255,1) endparam color param color3 caption = "Color 3" default = rgba(108/255,20/255,32/255,1) endparam color param color4 caption = "Color 4" default = rgba(120/255,184/255,152/255,1) endparam color param color5 caption = "Color 5" default = rgba(80/255,130/255,74/255,1) endparam color param color6 caption = "Color 6" default = rgba(120/255,12/255,1/255,1) endparam color param color7 caption = "Color 7" default = rgba(240/255,160/255,200/255,1) endparam color param color8 caption = "Color 8" default = rgba(243/255,41/255,133/255,1) endparam } class REB_DesertNight(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_DesertNight(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "DesertNight Array" int param v_DesertNight caption = "Version (DesertNight Colors)" 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_DesertNight < 100 endparam color param color1 caption = "Color 1" default = rgba(156/255,108/255,24/255,1) endparam color param color2 caption = "Color 2" default = rgba(128/255,97/255,84/255,1) endparam color param color3 caption = "Color 3" default = rgba(140/255,128/255,98/255,1) endparam color param color4 caption = "Color 4" default = rgba(28/255,20/255,104/255,1) endparam color param color5 caption = "Color 5" default = rgba(140/255,208/255,240/255,1) endparam color param color6 caption = "Color 6" default = rgba(88/255,112/255,120/255,1) endparam color param color7 caption = "Color 7" default = rgba(68/255,84/255,76/255,1) endparam color param color8 caption = "Color 8" default = rgba(100/255,136/255,124/255,1) endparam } class REB_QuietForest(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_QuietForest(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "QuietForest Array" int param v_QuietForest caption = "Version (QuietForest Colors)" 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_QuietForest < 100 endparam color param color1 caption = "Color 1" default = rgba(152/255,152/255,114/255,1) endparam color param color2 caption = "Color 2" default = rgba(84/255,63/255,18/255,1) endparam color param color3 caption = "Color 3" default = rgba(113/255,142/255,60/255,1) endparam color param color4 caption = "Color 4" default = rgba(179/255,156/255,102/255,1) endparam color param color5 caption = "Color 5" default = rgba(54/255,75/255,96/255,1) endparam color param color6 caption = "Color 6" default = rgba(92/255,129/255,77/255,1) endparam color param color7 caption = "Color 7" default = rgba(156/255,160/255,146/255,1) endparam color param color8 caption = "Color 8" default = rgba(119/255,144/255,89/255,1) endparam } class REB_Sahara(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Sahara(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Sahara Array" int param v_Sahara caption = "Version (Sahara Colors)" 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_Sahara < 100 endparam color param color1 caption = "Color 1" default = rgba(198/255,204/255,168/255,1) endparam color param color2 caption = "Color 2" default = rgba(49/255,118/255,147/255,1) endparam color param color3 caption = "Color 3" default = rgba(93/255,73/255,38/255,1) endparam color param color4 caption = "Color 4" default = rgba(158/255,153/255,111/255,1) endparam color param color5 caption = "Color 5" default = rgba(212/255,220/255,183/255,1) endparam color param color6 caption = "Color 6" default = rgba(194/255,184/255,133/255,1) endparam color param color7 caption = "Color 7" default = rgba(193/255,171/255,111/255,1) endparam color param color8 caption = "Color 8" default = rgba(190/255,196/255,160/255,1) endparam } class REB_Inca(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Inca(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Inca Array" int param v_Inca caption = "Version (Inca Colors)" 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_Inca < 100 endparam color param color1 caption = "Color 1" default = rgba(72/255,92/255,41/255,1) endparam color param color2 caption = "Color 2" default = rgba(127/255,136/255,43/255,1) endparam color param color3 caption = "Color 3" default = rgba(127/255,167/255,175/255,1) endparam color param color4 caption = "Color 4" default = rgba(181/255,181/255,157/255,1) endparam color param color5 caption = "Color 5" default = rgba(152/255,21/255,1/255,1) endparam color param color6 caption = "Color 6" default = rgba(165/255,145/255,32/255,1) endparam color param color7 caption = "Color 7" default = rgba(110/255,1/255,15/255,1) endparam color param color8 caption = "Color 8" default = rgba(128/255,173/255,179/255,1) endparam } class REB_Meso(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Meso(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Meso Array" int param v_Meso caption = "Version (Meso Colors)" 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_Meso < 100 endparam color param color1 caption = "Color 1" default = rgba(185/255,147/255,111/255,1) endparam color param color2 caption = "Color 2" default = rgba(148/255,166/255,92/255,1) endparam color param color3 caption = "Color 3" default = rgba(119/255,138/255,136/255,1) endparam color param color4 caption = "Color 4" default = rgba(135/255,74/255,53/255,1) endparam color param color5 caption = "Color 5" default = rgba(1/255,107/255,135/255,1) endparam color param color6 caption = "Color 6" default = rgba(195/255,216/255,151/255,1) endparam color param color7 caption = "Color 7" default = rgba(169/255,116/255,76/255,1) endparam color param color8 caption = "Color 8" default = rgba(204/255,220/255,171/255,1) endparam } class REB_Native(REB_DirectColorHelper) { ; Provides colors to use with some Direct Coloring classes
public: import "common.ulb" ; constructor func REB_Native(Generic pparent) REB_DirectColorHelper(pparent) endfunc func Init() direct[0] = @color1 direct[1] = @color2 direct[2] = @color3 direct[3] = @color4 direct[4] = @color5 direct[5] = @color6 direct[6] = @color7 direct[7] = @color8 endfunc default: title = "Native Array" int param v_Native caption = "Version (Native Colors)" 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_Native < 100 endparam color param color1 caption = "Color 1" default = rgba(149/255,42/255,22/255,1) endparam color param color2 caption = "Color 2" default = rgba(75/255,32/255,23/255,1) endparam color param color3 caption = "Color 3" default = rgba(214/255,227/255,183/255,1) endparam color param color4 caption = "Color 4" default = rgba(94/255,215/255,200/255,1) endparam color param color5 caption = "Color 5" default = rgba(124/255,59/255,37/255,1) endparam color param color6 caption = "Color 6" default = rgba(179/255,120/255,62/255,1) endparam color param color7 caption = "Color 7" default = rgba(94/255,24/255,24/255,1) endparam color param color8 caption = "Color 8" default = rgba(169/255,123/255,71/255,1) endparam } ;------------------- ; ; Direct Coloring Classes ; ;-------------------------- class REB_FractalFunctionTraps(common.ulb:DirectColoring) { ; Modified from the code of Kerry Mitchell.
;
; This code is based upon Kerry Mitchell's Mandelbrot/Julia Trap, which has ; been modified to use fractal formula, image and texture plugins. Some other ; changes have been made in the code, which include: ; 1. Setting a threshold user parameter for all the "max" colorings. This ; dramatically expands the capabilites of the "max" colorings. ; 2. Adding an option to the "magnitude" and "angle" colorings to use ; either the untransformed or transformed points for the "min" ; coloring, similar to Orbit Traps. ; 3. Adding an option to the "magnitude" and "angle" coloring for both ; "min" and "max" coloring to use or not use the last iterated point ; for the fractal formula plugin. ; 4. Adding all the special effects coloring that are in my other coloring ; ulbs such as Image Traps. ; 5. Replaced the "power" and "expnential" algorithms with the one used ; in the Fibers and Things ucl and ulb which was created with the help ; of Jussi Harkonen. It can be thought of as a variant of the "power" ; or Vepstas algorithm except that it works for both convergent and ; divergent fractals, and for most fractals which don't have a ; clearly defined fractal power. $define debug public: import "common.ulb" import "dmj5.ulb" ; constructor func REB_FractalFunctionTraps(Generic pparent) DirectColoring.DirectColoring(pparent) m_Texture = new @ftexture(this) m_MergeColor = new @f_colormerge(this) m_TrapColor = new @f_trapcolor(this) f = new @f_formula(this) t=@rotd/180*#pi rot=(cos(t)-flip(sin(t)))/@scale ; ; find the bailout for the fractal formula. ; bail = f.GetUpperBailout() if bail == -1 || bail == 256 ; convergent fractal bail = f.GetLowerBailout() endif endfunc ; initialize the objects func Init(complex pz, complex ppixel) DirectColoring.Init(pz, ppixel) c=(0,0) zm=(0,0) zmin=(0,0) zmax=(0,0) zrangefirst=(0,0) zrangelast=(0,0) ztrans=(0,0) dist=0 distfirst=0 distlast=0 distmin=1e20 distmax=0 iterfirst=0 iterlast=0 itermin=0 itermax=0 sum=0 inrange=0 iter=0 nmin=0 nmax=0 m_zold = 0 m_zold2 = 0 pcolor = rgba(0,0,0,0) pwcolor = rgba(0,0,0,0) ptexture = 0 trapped = false endfunc ; call for each iterated point func Iterate(complex pz) DirectColoring.Iterate(pz) ztrans=rot*pz-@offset zm = f.Init(ztrans) m_TrapColor.Init(ztrans) m_Texture.Init(ztrans) iter=0 sum=0 m_zold = 0 m_zold2 = 0 ; ; iterate and calculate smoothing function ; while((iter<@niter) && !f.IsBailedOut(zm)) m_zold2 = m_zold m_zold = zm iter=iter+1 zm = f.Iterate(zm) if @f_trapcolor == ColorTrapNoColor m_empty = true else pwcolor = m_TrapColor.Iterate(pz) m_empty = false endif ptexture = m_Texture.Iterate(pz) sum=sum+(cabs(zm))^@smoothpower endwhile ; ; determine distance from set with texture offset ; postexture = ptexture*@txamt if @posval postexture = abs(postexture) endif dist=sum^@smoothpower+ postexture ; ; Harkonen incremental params ; ; calculate the apparent power exponent of the formula power = log(|zm - m_zold|) / log(|m_zold - m_zold2|) ; ; calculate the incremental iteration inciter = (log(log(bail)) - log(log(1/(|(m_zold - pz)|))))/log(power) ; ; minimum distance ; if(distdistmax+postexture)&& dm <= @thresh+postexture nmax=nmax+1 distmax=dm if @usemax zmax=pz+postexture endif if @colorby >= 5 && @colorby <= 9 pcolor = pwcolor trapped = true endif if(iter==@niter) itermax=@niter+postexture else itermax=iter+inciter+postexture if !@usemax zmax = pz+postexture endif endif endif ; ; distance within range ; if((dist>=@rangemin+postexture)&&(dist<=@rangemax+postexture)) inrange=inrange+1 zrangelast=zm+postexture distlast=dist iterlast=iter+inciter+postexture if @colorby > 9 && inrange !=1 pcolor = pwcolor endif if(inrange==1) zrangefirst=zm+postexture distfirst=dist iterfirst=iterlast if @colorby > 9 pcolor = pwcolor endif endif endif endfunc ; override the parent and call in the final section of the coloring formula.
color func Result(complex pz) color return_color = rgba(0,0,0,0) if(@colorby=="min: distance") if !trapped m_solid = true else return_color=gradient(distmin) endif elseif(@colorby=="min: magnitude") if !trapped m_solid = true else return_color=gradient(cabs(zmin)) endif elseif(@colorby=="min: angle") if !trapped m_solid = true else return_color=gradient((atan2(zmin)/#pi+1)/2) endif elseif(@colorby=="min: iterations") if !trapped m_solid = true else return_color=gradient(itermin/@niter) endif elseif(@colorby=="min: # changes") if !trapped m_solid = true else return_color=gradient((nmin+postexture)/@niter) endif ; elseif(@colorby=="max: distance") if !trapped m_solid = true else return_color=gradient(distmax) endif elseif(@colorby=="max: magnitude") if !trapped m_solid = true else return_color=gradient(cabs(zmax)) endif elseif(@colorby=="max: angle") if !trapped m_solid = true else return_color=gradient((atan2(zmax)/#pi+1)/2) endif elseif(@colorby=="max: iterations") if !trapped m_solid = true else return_color=gradient(itermax/@niter) endif elseif(@colorby=="max: # changes") if !trapped m_solid = true else return_color=gradient((nmax+postexture)/@niter) endif ; elseif(@colorby=="range: first distance") if(inrange==0) m_solid=true else return_color=gradient(distfirst) endif elseif(@colorby=="range: first magnitude") if(inrange==0) m_solid=true else return_color=gradient(cabs(zrangefirst)) endif elseif(@colorby=="range: first angle") if(inrange==0) m_solid=true else return_color=gradient((atan2(zrangefirst)/#pi+1)/2) endif elseif(@colorby=="range: first iterations") return_color=gradient(iterfirst/@niter) elseif(@colorby=="range: last distance") if(inrange==0) m_solid=true else return_color=gradient(distlast) endif elseif(@colorby=="range: last magnitude") if(inrange==0) m_solid=true else return_color=gradient(cabs(zrangelast)) endif elseif(@colorby=="range: last angle") if(inrange==0) m_solid=true else return_color=gradient((atan2(zrangelast)/#pi+1)/2) endif elseif(@colorby=="range: last iterations") return_color=gradient(iterlast/@niter) elseif(@colorby=="range: # in") if(inrange==0) m_solid=true else return_color=gradient((inrange+postexture)/@niter) endif endif if @ahue pcolor = hsla(hue(pcolor), sat(pcolor), lum(pcolor), \ hue(pcolor)/6*alpha(pcolor)) endif if @alum pcolor = hsla(hue(pcolor), sat(pcolor), lum(pcolor), \ lum(pcolor)*alpha(pcolor)) endif if @asat pcolor = hsla(hue(pcolor), sat(pcolor), lum(pcolor), \ sat(pcolor)*alpha(pcolor)) endif float opacity = 0 color temp = rgba(0,0,0,0) if @nmerge == 1 || m_empty temp = pcolor pcolor = return_color return_color = temp endif if !m_empty opacity = @opacity else opacity = 1 endif color rcolor = m_MergeColor.FullMerge(return_color, pcolor, opacity) float br = (0.5-@p_bright)*2 int sign = 0 if br < 0 sign = -1 else sign = 1 endif br = br^2*sign float cr = (@p_contrast-0.5)*2 if cr < 0 sign = -1 else sign = 1 endif cr = cr^2*sign+1 float st = (0.5-@p_sat)*2 if st < 0 sign = -1 else sign = 1 endif st = st^2*sign*2 float hu = @p_hue*6 float rd = red(rcolor)-br float gr = green(rcolor)-br float bl = blue(rcolor)-br if rd > 1 rd = 1 endif if gr > 1 gr = 1 endif if bl > 1 bl = 1 endif if rd < 0 rd = 0 endif if gr < 0 gr = 0 endif if bl < 0 bl = 0 endif rcolor = rgba(rd,gr,bl,alpha(rcolor)) rd = red(rcolor)^cr gr = green(rcolor)^cr bl = blue(rcolor)^cr rcolor = rgba(rd,gr,bl,alpha(rcolor)) float satval = sat(rcolor)-st if satval > 1 satval = 1 endif if satval < 0 satval = 0 endif rcolor = hsla(hue(rcolor), satval, lum(rcolor), alpha(rcolor)) float hueval = (hue(rcolor)+hu) % 6 rcolor = hsla(hueval, sat(rcolor), lum(rcolor), alpha(rcolor)) if @p_poster float rd = floor(red(rcolor)*@p_chan)/@p_chan + 0.5/@p_chan float gr = floor(green(rcolor)*@p_chan)/@p_chan + 0.5/@p_chan float bl = floor(blue(rcolor)*@p_chan)/@p_chan + 0.5/@p_chan rcolor = rgba(rd,gr,bl,alpha(rcolor)) endif if @p_gray float gry = 0.3 * red(rcolor)+ 0.59 * green(rcolor) + 0.11 * blue(rcolor) rcolor = rgba(gry,gry,gry,alpha(rcolor)) endif if @p_solar float rd = red(rcolor) float gr = green(rcolor) float bl = blue(rcolor) if rd > @p_thresh rd = 1-rd endif if gr > @p_thresh gr = 1-gr endif if bl > @p_thresh bl = 1-bl endif rcolor = rgba(rd,gr,bl,alpha(rcolor)) endif if @p_bw float gry = 0.3 * red(rcolor)+ 0.59 * green(rcolor) + 0.11 * blue(rcolor) if gry < @p_bwt rcolor = rgba(0,0,0,alpha(rcolor)) else rcolor = rgba(1,1,1,alpha(rcolor)) endif endif return rcolor endfunc protected: complex rot float r Formula f complex c complex zm complex zmin complex zmax complex zrangefirst complex zrangelast complex ztrans float dist float distfirst float distlast float distmin float distmax float iterfirst float iterlast float itermin float itermax float sum int inrange int iter int nmin int nmax complex m_zold complex m_zold2 float bail float power float inciter ColorTrap m_TrapColor DefaultColorMerge m_MergeColor bool m_empty color pcolor color pwcolor float ptexture TrapShape m_Texture bool trapped float postexture default: title = "Fractal Function Traps" int param v_REB_FractalFunctionTrap caption = "Version (Fractal Function Traps)" 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_REB_FractalFunctionTrap < 100 endparam heading caption="Trap function" endheading Formula param f_formula caption = "Fractal function" default = REB_Mandelbrot endparam int param niter caption="# iterations" default=100 endparam heading caption="Trap size, location" endheading float param scale caption="scale" default=1 endparam float param rotd caption="rotation, deg" default=0 endparam complex param offset caption="center" default=(0,0) endparam heading caption="Distance parameters" endheading float param smoothpower caption="smoothing power" default=-1 max=0 endparam heading caption="Trap coloring" endheading param colorby caption="color by" default=0 enum="min: distance" "min: magnitude" "min: angle" "min: iterations"\ "min: # changes" "max: distance" "max: magnitude" "max: angle" \ "max: iterations" "max: # changes" "range: first distance" \ "range: first magnitude" "range: first angle" "range: first iterations"\ "range: last distance" "range: last magnitude" "range: last angle"\ "range: last iterations" "range: # in" endparam float param thresh caption = "Threshold" default = 0.25 visible = @colorby <= 9 endparam bool param pretrans caption = "Use value before transformation" default = true visible = @colorby == 1 || @colorby == 2 endparam bool param usemax caption = "Use max iteration" default = true visible = @colorby == 1 || @colorby == 2 || @colorby == 6 || @colorby == 7 endparam float param rangemin caption="range minimum" default=0 visible=(@colorby>9) endparam float param rangemax caption="range maximum" default=0.01 visible=(@colorby>9) endparam heading caption = "Textures" endheading float param txamt caption = "Texture amount" default = 0.25 visible = @fTexture != DMJ_TrapShapeFlat endparam bool param posval caption ="Positive values only" default = false visible = @fTexture != DMJ_TrapShapeFlat endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam heading caption = "Images and Colorings" endheading ColorTrap param f_trapcolor caption = "Colors" default = ColorTrapNoColor expanded = false endparam heading caption = "Color Merging" endheading DefaultColorMerge param f_colormerge caption = "Color Merge" default = DefaultColorMerge endparam param nmerge caption = "Merge order" default = 0 enum = "Image on Top" "Image on Bottom" endparam float param opacity caption = "Merge Opacity" default = 1.0 endparam heading text = "Make image transparent by: " visible = @f_trapcolor != ColorTrapNoColor endheading bool param ahue caption = "Hue value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam bool param alum caption = "Luminance value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam bool param asat caption = "Saturation value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam heading caption = "Special Effects" endheading float param p_bright caption = "Brightness" default = 0.5 min = 0 max = 1 endparam float param p_contrast caption = "Contrast" default = 0.5 min = 0 max = 1 endparam float param p_sat caption = "Saturation" default = 0.5 min = 0 max = 1 endparam float param p_hue caption = "Hue" default = 0.0 min = 0 max = 1 endparam bool param p_gray caption = "Grayscale" default = false endparam bool param p_solar caption = "Solarize" default = false endparam float param p_thresh caption = "Threshold" default = 0.5 endparam bool param p_poster caption = "Posterize" default = false endparam int param p_chan caption = "Colors per channel" default = 4 min = 2 visible = @p_poster endparam bool param p_bw caption = "Black and White" default = false endparam float param p_bwt caption = "Threshold" default = 0.5 min = 0 max = 1 endparam } class REB_LightingDirect(common.ulb:DirectColoring) { ; Direct Coloring Lighting with textures and images.
;

; Code modified from Damien M. Jones. Includes options for iteration and height ; trapping, and variable transparency as a function of the height value. public: import "common.ulb" import "dmj5.ulb" ; constructor func REB_LightingDirect(Generic pparent) Coloring.Coloring(pparent) m_Texture = new @ftexture(this) m_TrapColor = new @f_trapcolor(this) m_MergeColor = new @f_colormerge(0) endfunc ; initialize the object func Init(complex pz, complex ppixel) Coloring.Init(pz,ppixel) m_Texture.Init(pz) m_TrapColor.Init(pz) m_empty = true endfunc ; call for each iterated point func Iterate(complex pz) Coloring.Iterate(pz) if ((@fiter && m_iterations == @iternum)&& @v_lightingwithtexturesdirect < 104) \ || ((@mtile == "Fixed Iteration" && m_iterations == @iternum2) || \ (@mtile == "Cabs(z)" && cabs(pz) < @tcabs)) if @ftexture != DMJ_TrapShapeFlat ptexture = m_Texture.Iterate(pz) ctexture = m_texture.GetTransformedPoint() endif if @v_lightingwithtexturesdirect >= 103 && @f_trapcolor != ColorTrapNoColor m_empty = false m_color = m_TrapColor.Iterate(pz) endif endif endfunc ; call in final section of coloring formula/class color func Result(complex pz) color return_color = rgba(0,0,0,0) color temp = rgba(0,0,0,0) if (!@fiter && @v_lightingwithtexturesdirect < 104) || (@mtile == "none" \ && @v_lightingwithtexturesdirect >= 104) if @ftexture != DMJ_TrapShapeFlat ptexture = m_Texture.Iterate(pz) ctexture = m_texture.GetTransformedPoint() endif if @f_trapcolor == ColorTrapNoColor m_empty = true else m_color = m_TrapColor.Iterate(pz) m_empty = false endif if @v_lightingwithtexturesdirect >= 102 && m_empty == false if @ahue m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ hue(m_color)/6*alpha(m_color)) endif if @alum m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ lum(m_color)*alpha(m_color)) endif if @asat m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ sat(m_color)*alpha(m_color)) endif endif endif float res=0 float lowtrap=abs(round(real(@itrap)*#maxiter)) float hightrap=abs(round(imag(@itrap)*#maxiter)) if lowtrap>hightrap res=lowtrap lowtrap=hightrap hightrap=res endif if @trapsum lowtrap=real(@itrap) hightrap=imag(@itrap) if lowtrap>hightrap res=lowtrap lowtrap=hightrap hightrap=res endif endif if @utx pz = pz*(1+ctexture*@txamt) endif float vz = -sqrt(1-|pz|) ; extract implied portion of normal float d2r = #pi/180 ; degrees to radians conversion factor ; light origin float lpointx = @lpointx float lpointy = @lpointy float lpointz = @lplane ; light point at float lightx = @lightx float lighty = @lighty float lightz = @lightz ; create vector for light direction float lx = 0 float ly = 0 float lz = 0 if @ltype == "Infinite light" if @v_lightingwithtexturesdirect > 105 lx = cos(@angle*d2r) * cos(@elevation*d2r) ly = sin(@angle*d2r) * cos(@elevation*d2r) lz = -sin(@elevation*d2r) else lx = cos((270-@angle)*d2r) * cos(@elevation*d2r) ly = sin((270-@angle)*d2r) * cos(@elevation*d2r) lz = -sin(@elevation*d2r) endif else lx = lightx-lpointx ly = -lighty+lpointy lz = lightz-lpointz endif float vd = sqrt(lx^2+ly^2+lz^2) lx = lx/vd ly = ly/vd lz = lz/vd ; compute cosine of angle between these vectors ; (this is the amount of lighting on the surface) if @v_lightingwithtexturesdirect > 105 float l = abs(lx*real(pz) + ly*imag(pz) + lz*vz) else float l = lx*real(pz) + ly*imag(pz) + lz*vz endif if (l < @ambient) ; light is below the ambient level l = @ambient ; set it to the ambient level endif if (@ambient < 0) ; the ambient level is negative l = l + 1 ; offset to prevent clipping at 0 endif if !@utx return_color = gradient(l + ptexture*@txamt) else return_color = gradient(l) endif float ht = abs(vz) if @trap m_solid = true if (m_iterations>=lowtrap)&&(m_iterations<=hightrap) m_solid = false endif elseif @trapsum m_solid = true if (ht>=lowtrap)&&(ht<=hightrap) m_solid = false endif endif if @fuzz return_color = rgba(red(return_color),green(return_color),\ blue(return_color),1-ht^@fpwr) endif if !m_empty || @f_trapcolor != ColorTrapNoColor if @nmerge == 1 temp = m_color m_color = return_color return_color = temp endif return_color = m_MergeColor.FullMerge(return_color, m_color, @opacity) endif if @v_lightingwithtexturesdirect >= 105 float br = (0.5-@p_bright)*2 int sign = 0 if br < 0 sign = -1 else sign = 1 endif br = br^2*sign float cr = (@p_contrast-0.5)*2 if cr < 0 sign = -1 else sign = 1 endif cr = cr^2*sign+1 float st = (0.5-@p_sat)*2 if st < 0 sign = -1 else sign = 1 endif st = st^2*sign*2 float hu = @p_hue*6 float rd = red(return_color)-br float gr = green(return_color)-br float bl = blue(return_color)-br if rd > 1 rd = 1 endif if gr > 1 gr = 1 endif if bl > 1 bl = 1 endif if rd < 0 rd = 0 endif if gr < 0 gr = 0 endif if bl < 0 bl = 0 endif return_color = rgba(rd,gr,bl,alpha(return_color)) rd = red(return_color)^cr gr = green(return_color)^cr bl = blue(return_color)^cr return_color = rgba(rd,gr,bl,alpha(return_color)) float satval = sat(return_color)-st if satval > 1 satval = 1 endif if satval < 0 satval = 0 endif return_color = hsla(hue(return_color), satval, lum(return_color), alpha(return_color)) float hueval = (hue(return_color)+hu) % 6 return_color = hsla(hueval, sat(return_color), lum(return_color), alpha(return_color)) if @p_poster float rd = floor(red(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float gr = floor(green(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float bl = floor(blue(return_color)*@p_chan)/@p_chan + 0.5/@p_chan return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_gray float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) return_color = rgba(gry,gry,gry,alpha(return_color)) endif if @p_solar float rd = red(return_color) float gr = green(return_color) float bl = blue(return_color) if rd > @p_thresh rd = 1-rd endif if gr > @p_thresh gr = 1-gr endif if bl > @p_thresh bl = 1-bl endif return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_bw float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) if gry < @p_bwt return_color = rgba(0,0,0,alpha(return_color)) else return_color = rgba(1,1,1,alpha(return_color)) endif endif endif return return_color endfunc protected: TrapShape m_Texture ColorTrap m_TrapColor DefaultColorMerge m_MergeColor complex ctexture float ptexture color m_color bool m_empty default: title = "Lighting with Textures Direct" int param v_lightingwithtexturesdirect caption = "Version (Lighting With Textures Direct)" default = 106 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_lightingwithtexturesdirect < 106 endparam heading text = "This is a lighting formula with an iteration trap, a height \ trap, textures and color trap/image import capabilites." endheading heading caption = "Slope Lighting" endheading param ltype caption = "Light type" enum = "Point source" "Infinite light" default = 0 endparam param angle caption = "Light Rotation" default = 90.0 hint = "Gives the rotation of the light source, in degrees." visible=@ltype == "Infinite light" endparam param elevation caption = "Light Elevation" default = 30.0 hint = "Gives the elevation of the light source, in degrees." visible=@ltype == "Infinite light" endparam heading text = "Light Origin" visible=@ltype == "Point source" endheading float param lpointx caption = " X" default = 1.5 visible=@ltype == "Point source" endparam float param lpointy caption = " Y" default = 2 visible=@ltype == "Point source" endparam float param lplane caption = " Z" default = 5 visible=@ltype == "Point source" endparam heading text = "Light Point At" visible=@ltype == "Point source" endheading float param lightx caption = " X" default = 0.0 visible=@ltype == "Point source" endparam float param lighty caption = " Y" default = 0.0 visible=@ltype == "Point source" endparam float param lightz caption = " Z" default = 0.0 visible=@ltype == "Point source" endparam param ambient caption = "Ambient Light" default = 0.0 min = -1.0 max = 1.0 hint = "Specifies the level of ambient light. Use -1.0 to \ color all surfaces." endparam param trap caption="Use Trap by Iteration" default = false endparam param trapsum caption="Use Trap by Height" default = false endparam param itrap caption="Trap Limits" default=(0.0,1.0) hint="Between 0.0 and 1.0" endparam float param txamt caption = "Texture amount" default = 0.0 visible = @fTexture != DMJ_TrapShapeFlat endparam bool param utx caption = "Use Transformed" default = false visible = @fTexture != DMJ_TrapShapeFlat endparam bool param fiter caption = "Use Fixed Iteration" default = false visible = (@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) \ && @v_lightingwithtexturesdirect < 104 hint = "Changes the texture and color mapping." endparam int param iternum caption = "Iter number" default = 1 visible = ((@fTexture != DMJ_TrapShapeFlat&& @fiter || @f_trapcolor != \ ColorTrapNoColor) && @fiter)&& @v_lightingwithtexturesdirect < 104 hint = "Changes the texture and color mapping." endparam param mtile caption = "Tile method" default = 0 enum = "None" "Fixed Iteration" "Cabs(z)" visible = (@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) \ && @v_lightingwithtexturesdirect >= 104 endparam int param iternum2 caption = "Iter number" default = 1 hint = "Changes the texture/image mapping." visible = ((@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) && \ @mtile == "Fixed iteration") && @v_lightingwithtexturesdirect >= 104 endparam float param tcabs caption = "Cabs limit" default = 1.0 hint = "Changes the texture/image mapping." visible = ((@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) && \ @mtile == "Cabs(z)") && @v_lightingwithtexturesdirect >= 104 endparam bool param fuzz caption = "Soften edges" default = false hint = "Adjust using 'Height transfer' in the slope formula." endparam float param fpwr caption = "Fuzz power" default = 100 visible = @fuzz endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam heading caption = "Images and Colorings" endheading ColorTrap param f_trapcolor caption = "Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." endparam DefaultColorMerge param f_colormerge caption = "Color Merge" default = DefaultColorMerge visible = @f_trapcolor != ColorTrapNoColor endparam param nmerge caption = "Merge order" default = 0 enum = "Image on Top" "Image on Bottom" visible = @f_trapcolor != ColorTrapNoColor endparam float param opacity caption = "Merge Opacity" default = 0.2 visible = @f_trapcolor != ColorTrapNoColor endparam heading text = "Make image transparent by: " visible = @v_lightingwithtexturesdirect >= 102 \ && @f_trapcolor != ColorTrapNoColor endheading bool param ahue caption = "Hue value" default = false visible = @v_lightingwithtexturesdirect >= 102 \ && @f_trapcolor != ColorTrapNoColor endparam bool param alum caption = "Luminance value" default = false visible = @v_lightingwithtexturesdirect >= 102 \ && @f_trapcolor != ColorTrapNoColor endparam bool param asat caption = "Saturation value" default = false visible = @v_lightingwithtexturesdirect >= 102 \ && @f_trapcolor != ColorTrapNoColor endparam heading caption = "Special Effects" visible = @v_lightingwithtexturesdirect >= 105 endheading float param p_bright caption = "Brightness" default = 0.5 min = 0 max = 1 visible = @v_lightingwithtexturesdirect >= 105 endparam float param p_contrast caption = "Contrast" default = 0.5 min = 0 max = 1 visible = @v_lightingwithtexturesdirect >= 105 endparam float param p_sat caption = "Saturation" default = 0.5 min = 0 max = 1 visible = @v_lightingwithtexturesdirect >= 105 endparam float param p_hue caption = "Hue" default = 0.0 min = 0 max = 1 visible = @v_lightingwithtexturesdirect >= 105 endparam bool param p_gray caption = "Grayscale" default = false visible = @v_lightingwithtexturesdirect >= 105 endparam bool param p_solar caption = "Solarize" default = false visible = @v_lightingwithtexturesdirect >= 105 endparam float param p_thresh caption = "Threshold" default = 0.5 visible = @v_lightingwithtexturesdirect >= 105 && @p_solar endparam bool param p_poster caption = "Posterize" default = false visible = @v_lightingwithtexturesdirect >= 105 endparam int param p_chan caption = "Colors per channel" default = 4 min = 2 visible = @p_poster && @v_lightingwithtexturesdirect >= 105 endparam bool param p_bw caption = "Black and White" default = false visible = @v_lightingwithtexturesdirect >= 105 endparam float param p_bwt caption = "Threshold" default = 0.5 min = 0 max = 1 visible = @p_bw && @v_lightingwithtexturesdirect >= 105 endparam } class REB_TextureLightingDirect(common.ulb:DirectColoring) { ; Direct Coloring Lighting with textures and images, and color ptrsets.
;

; Code modified from Damien M. Jones. Includes options for iteration and height ; trapping, and variable transparency as a function of the height value. public: $define debug import "common.ulb" import "dmj5.ulb" ; constructor func REB_TextureLightingDirect(Generic pparent) DirectColoring.Coloring(pparent) m_Texture = new @ftexture(this) m_TrapColor = new @f_trapcolor(this) m_MergeColor = new @f_colormerge(0) m_preset = new @f_preset(this) if (@colorPreset == "Preset") colorMap[0,1] = m_preset.getHI() colorMap[0,0] = m_preset.getLOW() elseif (@colorPreset == "Generate") ; Compute the color ranges using the gradient. color gradientColor = gradient(0.475) colorMap [0,1] = hsl(hue(gradientColor), sat(gradientColor), @luminanceUpper) colorMap [0,0] = hsl(hue(gradientColor), sat(gradientColor), @luminanceLower) endif endfunc ; initialize the object func Init(complex pz, complex ppixel) DirectColoring.Init(pz,ppixel) m_Texture.Init(pz) m_TrapColor.Init(pz) m_empty = true extent = 1.0 - @extent hval = 0 colorPos = 0 colr = 0 luminance = 0 alpha1 = 0 alpha2 = 0 color2 = rgba(0,0,0,1) color3 = rgba(0,0,0,1) endfunc ; call for each iterated point func Iterate(complex pz) DirectColoring.Iterate(pz) if ((@mtile == "Fixed Iteration" && m_iterations == @iternum) || \ (@mtile == "Cabs(z)" && cabs(pz) < @tcabs)) if @ftexture != DMJ_TrapShapeFlat ptexture = m_Texture.Iterate(pz) ctexture = m_texture.GetTransformedPoint() endif if @f_trapcolor != ColorTrapNoColor m_empty = false m_color = m_TrapColor.Iterate(pz) endif endif endfunc ; call in final section of coloring formula/class color func Result(complex pz) color return_color = rgba(0,0,0,0) color temp = rgba(0,0,0,0) if@mtile == "none" if @ftexture != DMJ_TrapShapeFlat ptexture = m_Texture.Iterate(pz) ctexture = m_texture.GetTransformedPoint() endif if @f_trapcolor == ColorTrapNoColor m_empty = true else m_color = m_TrapColor.Iterate(pz) m_empty = false endif if m_empty == false if @ahue m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ hue(m_color)/6*alpha(m_color)) endif if @alum m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ lum(m_color)*alpha(m_color)) endif if @asat m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ sat(m_color)*alpha(m_color)) endif endif endif float res=0 float lowtrap=abs(round(real(@itrap)*#maxiter)) float hightrap=abs(round(imag(@itrap)*#maxiter)) if lowtrap>hightrap res=lowtrap lowtrap=hightrap hightrap=res endif if @trapsum lowtrap=real(@itrap) hightrap=imag(@itrap) if lowtrap>hightrap res=lowtrap lowtrap=hightrap hightrap=res endif endif if @utx pz = pz*(1+ctexture*@txamt) endif float vz = -sqrt(1-|pz|) ; extract implied portion of normal float d2r = #pi/180 ; degrees to radians conversion factor ; light origin float lpointx = @lpointx float lpointy = @lpointy float lpointz = @lplane ; light point at float lightx = @lightx float lighty = @lighty float lightz = @lightz ; create vector for light direction float lx = 0 float ly = 0 float lz = 0 if @ltype == "Infinite light" ; lx = cos((270-@angle)*d2r) * cos(@elevation*d2r) ; ly = sin((270-@angle)*d2r) * cos(@elevation*d2r) ; lz = -sin(@elevation*d2r) lx = cos(@angle*d2r) * cos(@elevation*d2r) ly = sin(@angle*d2r) * cos(@elevation*d2r) lz = -sin(@elevation*d2r) else lx = lightx-lpointx ly = -lighty+lpointy lz = lightz-lpointz endif float vd = sqrt(lx^2+ly^2+lz^2) lx = lx/vd ly = ly/vd lz = lz/vd ; compute cosine of angle between these vectors ; (this is the amount of lighting on the surface) float l = abs(lx*real(pz) + ly*imag(pz) + lz*vz) if (l < @ambient) ; light is below the ambient level l = @ambient ; set it to the ambient level endif if (@ambient < 0) ; the ambient level is negative l = l + 1 ; offset to prevent clipping at 0 endif colorPos = @scale*(1-l)/2 colr = @scale*(1-l)/2 if colorPos > 0.5 while colorPos > 0.5 colorPos = colorPos - 0.5 endwhile colorPos = colorPos/2 else colorPos = colorPos / 0.5 endif if @reverse colorPos = 1-ColorPos endif if @highlight_type == "none" hval = 0 elseif @highlight_type == "linear" if colorPos > extent hval = (5*@highlight*(colorPos-extent)/(1-extent)+1)/(5*@highlight + 1) else hval = 0 endif elseif @highlight_type == "log" if colorPos > extent hval = (5*@highlight*log(colorPos-extent+1)/log(2-extent)+1)/(5*@highlight + 1) else hval = 0 endif elseif @highlight_type == "exponential" if colorPos > extent hval = (5*@highlight*(exp(colorPos-extent)-1)/(exp(1-extent)-1)+1)/(5*@highlight + 1) else hval = 0 endif endif if @colorpreset == "Gradient" color3 = gradient(colr+ptexture*@txamt) else color3 = blend(colorMap[0,0], blend(colorMap[0,1],@hcolor,hval^@hblend), \ colorPos^@cblend+ptexture*@txamt) endif luminance = lum(color3) float ht = abs(vz) if (@trap == true) if (m_iterations>=lowtrap)&&(m_iterations<=hightrap) ; Is pixel in trap? if luminance < @ambient color2 = hsl(hue(@ambcolor),sat(@ambcolor),@ambient) return_color = blend(color3,color2,0.5) else return_color = color3 endif else m_solid = true endif elseif (@trapsum == true) if (ht>=lowtrap)&&(ht<=hightrap) ; Is pixel in trap? if luminance < @ambient color2 = hsl(hue(@ambcolor),sat(@ambcolor),@ambient) return_color = blend(color3,color2,0.5) else return_color = color3 endif else m_solid = true endif else if luminance < @ambient color2 = hsl(hue(@ambcolor),sat(@ambcolor),@ambient) return_color = blend(color3,color2,0.5) else return_color = color3 endif endif float ht = abs(vz) if @trap m_solid = true if (m_iterations>=lowtrap)&&(m_iterations<=hightrap) m_solid = false endif elseif @trapsum m_solid = true if (ht>=lowtrap)&&(ht<=hightrap) m_solid = false endif endif if @fuzz return_color = rgba(red(return_color),green(return_color),\ blue(return_color),1-ht^@fpwr) endif if !m_empty || @f_trapcolor != ColorTrapNoColor if @nmerge == 1 temp = m_color m_color = return_color return_color = temp endif return_color = m_MergeColor.FullMerge(return_color, m_color, @opacity) endif float br = (0.5-@p_bright)*2 int sign = 0 if br < 0 sign = -1 else sign = 1 endif br = br^2*sign float cr = (@p_contrast-0.5)*2 if cr < 0 sign = -1 else sign = 1 endif cr = cr^2*sign+1 float st = (0.5-@p_sat)*2 if st < 0 sign = -1 else sign = 1 endif st = st^2*sign*2 float hu = @p_hue*6 float rd = red(return_color)-br float gr = green(return_color)-br float bl = blue(return_color)-br if rd > 1 rd = 1 endif if gr > 1 gr = 1 endif if bl > 1 bl = 1 endif if rd < 0 rd = 0 endif if gr < 0 gr = 0 endif if bl < 0 bl = 0 endif return_color = rgba(rd,gr,bl,alpha(return_color)) rd = red(return_color)^cr gr = green(return_color)^cr bl = blue(return_color)^cr return_color = rgba(rd,gr,bl,alpha(return_color)) float satval = sat(return_color)-st if satval > 1 satval = 1 endif if satval < 0 satval = 0 endif return_color = hsla(hue(return_color), satval, lum(return_color), alpha(return_color)) float hueval = (hue(return_color)+hu) % 6 return_color = hsla(hueval, sat(return_color), lum(return_color), alpha(return_color)) if @p_poster float rd = floor(red(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float gr = floor(green(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float bl = floor(blue(return_color)*@p_chan)/@p_chan + 0.5/@p_chan return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_gray float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) return_color = rgba(gry,gry,gry,alpha(return_color)) endif if @p_solar float rd = red(return_color) float gr = green(return_color) float bl = blue(return_color) if rd > @p_thresh rd = 1-rd endif if gr > @p_thresh gr = 1-gr endif if bl > @p_thresh bl = 1-bl endif return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_bw float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) if gry < @p_bwt return_color = rgba(0,0,0,alpha(return_color)) else return_color = rgba(1,1,1,alpha(return_color)) endif endif return return_color endfunc ; Is the coloring solid? - used by the coloring ucl. bool func IsSolid() return m_Solid endfunc protected: TrapShape m_Texture ColorTrap m_TrapColor DefaultColorMerge m_MergeColor complex ctexture float ptexture color m_color bool m_empty color colormap[2,2] float extent float hval float colorPos float colr float luminance float alpha1 float alpha2 color color1 color color2 color color3 float ltfac ImageImport m_img REB_DirectColorPreset m_preset default: title = "Lighting with Textures Direct II" int param v_lightingwithtexturesdirectII caption = "Version (Lighting With Textures Direct II)" 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_lightingwithtexturesdirectII < 100 endparam heading text = "This is a lighting formula with an iteration trap, a height \ trap, textures, color trap/image import capabilites and color presets." endheading heading caption = "Color Settings" endheading param colorPreset caption = "Color Options" enum = "Gradient" "Generate" "Preset" default = 2 hint = "Use 'Gradient' for colors from the gradient. \ Use 'Generate' to use the gradient to define the raytrace gradient." endparam float param luminanceUpper caption = "Lum. Upper Value" default = 0.6 min = 0.0 max = 1.0 hint = "The value of the Luminance component for the upper value \ when generating the ranges from the gradient. This value \ is used with the brighter end of the color range." visible = (@colorPreset == "Generate") endparam float param luminanceLower caption = "Lum. Lower Value" default = 0.2 min = 0.0 max = 1.0 hint = "The value of the Luminance component for the lower value \ when generating the ranges from the gradient. This value \ is used with the darker end of the color range." visible = (@colorPreset == "Generate") endparam REB_DirectColorPreset param f_preset caption = "Color Preset" default = TwoColorPresets visible = (@colorPreset == "Preset") endparam heading caption = "Color Parameters" visible = @colorPreset != "Gradient" endheading color param hcolor caption = "Highlight color" default = rgba(255/255,255/255,255/255,1) visible = @colorPreset != "Gradient" && @highlight_type != "none" endparam param highlight_type caption = "Color Highlight Type" default = 1 enum = "none" "linear" "log" "exponential" hint = "Use to generate a 'shiny' hightlight." visible = @colorPreset != "Gradient" endparam param highlight caption = "Highlight Value" default = 5.0 hint = "Use to generate a 'shiny' hightlight." visible = @colorPreset != "Gradient" && @highlight_type != "none" endparam param extent caption = "Highlight Extent" default = 0.1 min = 0.0 max = 0.5 hint = "Use to generate a 'shiny' hightlight." visible = @colorPreset != "Gradient" && @highlight_type != "none" endparam float param hblend caption = "Highlight power" default = 2.0 visible = @colorPreset != "Gradient" && @highlight_type != "none" endparam float param scale caption = "color scale adj" default = 1.0 endparam float param cblend caption = "color blend power" default = 1.0 visible = @colorPreset != "Gradient" endparam bool param reverse caption = "Reverse Colors" default = false endparam float param ambient caption = "Ambient light" default = 0.05 endparam color param ambcolor caption = "Ambient color" default = rgba(192/255,192/255,192/255,1) endparam heading caption = "Slope Lighting" endheading param ltype caption = "Light type" enum = "Point source" "Infinite light" default = 0 endparam param angle caption = "Light Rotation" default = 90.0 hint = "Gives the rotation of the light source, in degrees." visible=@ltype == "Infinite light" endparam param elevation caption = "Light Elevation" default = 30.0 hint = "Gives the elevation of the light source, in degrees." visible=@ltype == "Infinite light" endparam heading text = "Light Origin" visible=@ltype == "Point source" endheading float param lpointx caption = " X" default = 1.5 visible=@ltype == "Point source" endparam float param lpointy caption = " Y" default = 2 visible=@ltype == "Point source" endparam float param lplane caption = " Z" default = 5 visible=@ltype == "Point source" endparam heading text = "Light Point At" visible=@ltype == "Point source" endheading float param lightx caption = " X" default = 0.0 visible=@ltype == "Point source" endparam float param lighty caption = " Y" default = 0.0 visible=@ltype == "Point source" endparam float param lightz caption = " Z" default = 0.0 visible=@ltype == "Point source" endparam param trap caption="Use Trap by Iteration" default = false endparam param trapsum caption="Use Trap by Height" default = false endparam param itrap caption="Trap Limits" default=(0.0,1.0) hint="Between 0.0 and 1.0" endparam float param txamt caption = "Texture amount" default = 0.0 visible = @fTexture != DMJ_TrapShapeFlat endparam bool param utx caption = "Use Transformed" default = false visible = @fTexture != DMJ_TrapShapeFlat endparam param mtile caption = "Tile method" default = 0 enum = "None" "Fixed Iteration" "Cabs(z)" visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endparam int param iternum caption = "Iter number" default = 1 hint = "Changes the texture/image mapping." visible = ((@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) && \ @mtile == "Fixed iteration") endparam float param tcabs caption = "Cabs limit" default = 1.0 hint = "Changes the texture/image mapping." visible = ((@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) && \ @mtile == "Cabs(z)") endparam bool param fuzz caption = "Soften edges" default = false hint = "Adjust using 'Height transfer' in the slope formula." endparam float param fpwr caption = "Fuzz power" default = 100 visible = @fuzz endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam heading caption = "Images and Colorings" endheading ColorTrap param f_trapcolor caption = "Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." endparam DefaultColorMerge param f_colormerge caption = "Color Merge" default = DefaultColorMerge visible = @f_trapcolor != ColorTrapNoColor endparam param nmerge caption = "Merge order" default = 0 enum = "Image on Top" "Image on Bottom" visible = @f_trapcolor != ColorTrapNoColor endparam float param opacity caption = "Merge Opacity" default = 0.2 visible = @f_trapcolor != ColorTrapNoColor endparam heading text = "Make image transparent by: " visible = @f_trapcolor != ColorTrapNoColor endheading bool param ahue caption = "Hue value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam bool param alum caption = "Luminance value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam bool param asat caption = "Saturation value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam heading caption = "Special Effects" endheading float param p_bright caption = "Brightness" default = 0.5 min = 0 max = 1 endparam float param p_contrast caption = "Contrast" default = 0.5 min = 0 max = 1 endparam float param p_sat caption = "Saturation" default = 0.5 min = 0 max = 1 endparam float param p_hue caption = "Hue" default = 0.0 min = 0 max = 1 endparam bool param p_gray caption = "Grayscale" default = false endparam bool param p_solar caption = "Solarize" default = false endparam float param p_thresh caption = "Threshold" default = 0.5 visible = @p_solar endparam bool param p_poster caption = "Posterize" default = false endparam int param p_chan caption = "Colors per channel" default = 4 min = 2 visible = @p_poster endparam bool param p_bw caption = "Black and White" default = false endparam float param p_bwt caption = "Threshold" default = 0.5 min = 0 max = 1 visible = @p_bw endparam } class REB_ExponentialSmoothing(common.ulb:DirectColoring) { ; Based on the original 1994 algorithm of Ron Barnett.
;

; This is a direct coloring formula that supports trap shape textures and ; colortrap coloring, including image import. public: import "common.ulb" import "dmj5.ulb" ; constructor func REB_ExponentialSmoothing(Generic pparent) DirectColoring.DirectColoring(pparent) m_Texture = new @ftexture(this) m_MergeColor = new @f_colormerge(0) m_TrapColor = new @f_trapcolor(this) endfunc ; initialize the objects func Init(complex pz, complex ppixel) DirectColoring.Init(pz, ppixel) m_Texture.Init(pz) m_TrapColor.Init(pz) m_iterexp = 0 m_zold = (0,0) m_empty = true endfunc ; call for each iterated point func Iterate(complex pz) DirectColoring.Iterate(pz) if (@mtile == "Fixed Iteration" && m_iterations == @iternum) || \ (@mtile == "Cabs(z)" && cabs(pz) < @tcabs)|| @mtile == "none" ptexture = m_Texture.Iterate(pz) if @v_exponentialsmoothing < 101 m_img = new @f_image(0) m_empty = m_img.GetEmpty() endif if @v_exponentialsmoothing >= 101 if @f_trapcolor == ColorTrapNoColor m_empty = true else m_color = m_TrapColor.Iterate(pz) m_empty = false endif else if !m_empty complex m_zi = (0,1)^(@iangle/90.0) complex m_zs = (0,1)^(@sangle/90.0) complex pzi = pz ; aspect ratio pzi = real(pzi) + flip(imag(pzi)*@iaspect) ; rotation pzi = pzi*m_zi ; skew pzi = real(pzi)*m_zs + flip(imag(pzi)) float width = m_img.getWidth() float height = m_img.getHeight() complex pzi = (pzi+(100,100))*@scale*1000 complex c = @adjx-2*((real(pzi) % (width-1))/width) + \ flip(@adjy-2*((imag(pzi) % (height-1))/height)) m_color = m_img.getColor(c) endif endif endif if (@converge > 0) m_iterexp = m_iterexp + exp(-cabs(pz)) else m_iterexp = m_iterexp + exp(-1/(cabs(m_zold - pz))) endif m_zold = pz endfunc ; override the parent and call in the final section of the coloring formula.
color func Result(complex pz) color return_color = gradient(0.01*m_iterexp +ptexture*@txamt) if @v_exponentialsmoothing >= 103 if @ahue m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ hue(m_color)/6*alpha(m_color)) endif if @alum m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ lum(m_color)*alpha(m_color)) endif if @asat m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ sat(m_color)*alpha(m_color)) endif endif color temp = rgba(0,0,0,0) if !m_empty if @nmerge == 1 temp = m_color m_color = return_color return_color = temp endif return_color = m_MergeColor.FullMerge(return_color, m_color, @opacity) endif if @v_exponentialsmoothing >= 104 float br = (0.5-@p_bright)*2 int sign = 0 if br < 0 sign = -1 else sign = 1 endif br = br^2*sign float cr = (@p_contrast-0.5)*2 if cr < 0 sign = -1 else sign = 1 endif cr = cr^2*sign+1 float st = (0.5-@p_sat)*2 if st < 0 sign = -1 else sign = 1 endif st = st^2*sign*2 float hu = @p_hue*6 float rd = red(return_color)-br float gr = green(return_color)-br float bl = blue(return_color)-br if rd > 1 rd = 1 endif if gr > 1 gr = 1 endif if bl > 1 bl = 1 endif if rd < 0 rd = 0 endif if gr < 0 gr = 0 endif if bl < 0 bl = 0 endif return_color = rgba(rd,gr,bl,alpha(return_color)) rd = red(return_color)^cr gr = green(return_color)^cr bl = blue(return_color)^cr return_color = rgba(rd,gr,bl,alpha(return_color)) float satval = sat(return_color)-st if satval > 1 satval = 1 endif if satval < 0 satval = 0 endif return_color = hsla(hue(return_color), satval, lum(return_color), alpha(return_color)) float hueval = (hue(return_color)+hu) % 6 return_color = hsla(hueval, sat(return_color), lum(return_color), alpha(return_color)) if @p_poster float rd = floor(red(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float gr = floor(green(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float bl = floor(blue(return_color)*@p_chan)/@p_chan + 0.5/@p_chan return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_gray float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) return_color = rgba(gry,gry,gry,alpha(return_color)) endif if @p_solar float rd = red(return_color) float gr = green(return_color) float bl = blue(return_color) if rd > @p_thresh rd = 1-rd endif if gr > @p_thresh gr = 1-gr endif if bl > @p_thresh bl = 1-bl endif return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_bw float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) if gry < @p_bwt return_color = rgba(0,0,0,alpha(return_color)) else return_color = rgba(1,1,1,alpha(return_color)) endif endif endif return return_color endfunc protected: float ptexture TrapShape m_Texture float m_iterexp complex m_zold ImageImport m_img bool m_empty color m_color ColorTrap m_TrapColor DefaultColorMerge m_MergeColor default: title = "Exponential Smoothing" int param v_exponentialsmoothing caption = "Version (Exponential Smoothing)" default = 104 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_exponentialsmoothing < 104 endparam heading text = "This is a direct coloring formula with textures and image import \ capabilities" endheading param converge caption = "Fractal Type" default = 1 enum = "Convergent" "Divergent" hint = "Mandelbrot is Divergent, Newton is Convergent." endparam float param txamt caption = "Texture amount" default = 0.0 visible = @fTexture != DMJ_TrapShapeFlat endparam heading text = "The 'Tile method' applies to both textures and images. Fixed Iteration \ will give a smoother tiling, while 'Cabs(z)' will more consistently \ follow the fractal shape." visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endheading param mtile caption = "Tile method" default = 1 enum = "None" "Fixed Iteration" "Cabs(z)" visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endparam int param iternum caption = "Iter number" default = 1 hint = "Changes the texture/image mapping." visible = (@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) && \ @mtile == "Fixed iteration" endparam float param tcabs caption = "Cabs limit" default = 1.0 visible = @mtile == "Cabs(z)" hint = "Changes the texture/image mapping." visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam heading caption = "Images and Colorings" endheading ColorTrap param f_trapcolor caption = "Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." visible = @v_exponentialsmoothing >= 101 endparam ImageImport param f_image caption = "Image" default = ImageImport visible = @v_exponentialsmoothing < 101 endparam float param scale caption = "Image scale" default = 1 min = 0 hint = "Changes the scale of the image." visible = @v_exponentialsmoothing < 101 endparam float param adjx caption = "Tile adj x" default = 0.99 min = 0.9 max = 1.1 visible = @v_exponentialsmoothing < 101 endparam float param adjy caption = "Tile adj y" default = 0.999 min = 0.9 max = 1.1 visible = @v_exponentialsmoothing < 101 endparam float param iaspect caption = "Image aspect" default = 1.0 visible = @v_exponentialsmoothing < 101 endparam float param iangle caption = "Image rotation" default = 0 hint = "Rotates the image" visible = @v_exponentialsmoothing < 101 endparam float param sangle caption = "Image skew" default = 0 hint = "Skews the image" visible = @v_exponentialsmoothing < 101 endparam DefaultColorMerge param f_colormerge caption = "Color Merge" default = DefaultColorMerge visible = @v_exponentialsmoothing < 101 || \ (@f_trapcolor != ColorTrapNoColor && @v_exponentialsmoothing >= 101) endparam param nmerge caption = "Merge order" default = 0 enum = "Image on Top" "Image on Bottom" visible = @v_exponentialsmoothing < 101 || \ (@f_trapcolor != ColorTrapNoColor && @v_exponentialsmoothing >= 101) endparam float param opacity caption = "Merge Opacity" default = 0.2 visible = @v_exponentialsmoothing < 101 || \ (@f_trapcolor != ColorTrapNoColor && @v_exponentialsmoothing >= 101) endparam heading text = "Make image transparent by: " visible = @v_exponentialsmoothing >= 103 && @f_trapcolor != ColorTrapNoColor endheading bool param ahue caption = "Hue value" default = false visible = @v_exponentialsmoothing >= 103 && !@alum && !@asat && \ @f_trapcolor != ColorTrapNoColor endparam bool param alum caption = "Luminance value" default = false visible = @v_exponentialsmoothing >= 103 && !@ahue && !@asat && \ @f_trapcolor != ColorTrapNoColor endparam bool param asat caption = "Saturation value" default = false visible = @v_exponentialsmoothing >= 103 && !@alum && !@ahue && \ @f_trapcolor != ColorTrapNoColor endparam heading caption = "Special Effects" visible = @v_exponentialsmoothing >= 103 endheading float param p_bright caption = "Brightness" default = 0.5 min = 0 max = 1 visible = @v_exponentialsmoothing >= 103 endparam float param p_contrast caption = "Contrast" default = 0.5 min = 0 max = 1 visible = @v_exponentialsmoothing >= 103 endparam float param p_sat caption = "Saturation" default = 0.5 min = 0 max = 1 visible = @v_exponentialsmoothing >= 103 endparam float param p_hue caption = "Hue" default = 0.0 min = 0 max = 1 visible = @v_exponentialsmoothing >= 103 endparam bool param p_gray caption = "Grayscale" default = false visible = @v_exponentialsmoothing >= 103 endparam bool param p_solar caption = "Solarize" default = false visible = @v_exponentialsmoothing >= 103 endparam float param p_thresh caption = "Threshold" default = 0.5 visible = @p_solar visible = @v_exponentialsmoothing >= 103 endparam bool param p_poster caption = "Posterize" default = false visible = @v_exponentialsmoothing >= 103 endparam int param p_chan caption = "Colors per channel" default = 4 min = 2 visible = @p_poster && @v_exponentialsmoothing >= 103 endparam bool param p_bw caption = "Black and White" default = false visible = @v_exponentialsmoothing >= 103 endparam float param p_bwt caption = "Threshold" default = 0.5 min = 0 max = 1 visible = @p_bw && @v_exponentialsmoothing >= 103 endparam } class REB_GeneralSmoothing(common.ulb:DirectColoring) { ; A smoothing algorithm that works for both convergent and divergen fractals.
public: import "common.ulb" import "dmj5.ulb" ; constructor func REB_GeneralSmoothing(Generic pparent) DirectColoring.DirectColoring(pparent) m_Texture = new @ftexture(this) m_MergeColor = new @f_colormerge(0) m_TrapColor = new @f_trapcolor(this) endfunc ; initialize the objects func Init(complex pz, complex ppixel) DirectColoring.Init(pz, ppixel) m_Texture.Init(pz) m_TrapColor.Init(pz) m_iterexp = 0 m_zold = pz m_empty = true ptexture = 0 endfunc ; call for each iterated point func Iterate(complex pz) DirectColoring.Iterate(pz) m_iterexp = m_iterexp + exp(-cabs(pz)-0.5/(cabs(m_zold - pz))) if (@mtile == "Fixed Iteration" && m_iterations == @iternum) || \ (@mtile == "Cabs(z)" && cabs(pz) < @tcabs)|| @mtile == "none" ptexture = m_Texture.Iterate(pz) if @f_trapcolor == ColorTrapNoColor m_empty = true else m_color = m_TrapColor.Iterate(pz) m_empty = false endif endif m_zold = pz endfunc ; override the parent and call in the final section of the coloring formula.
color func Result(complex pz) color return_color = gradient(0.2*m_iterexp + ptexture*@txamt) if @ahue m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ hue(m_color)/6*alpha(m_color)) endif if @alum m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ lum(m_color)*alpha(m_color)) endif if @asat m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ sat(m_color)*alpha(m_color)) endif color temp = rgba(0,0,0,0) if !m_empty if @nmerge == 1 temp = m_color m_color = return_color return_color = temp endif return_color = m_MergeColor.FullMerge(return_color, m_color, @opacity) endif if @v_generalsmoothing >= 101 float br = (0.5-@p_bright)*2 int sign = 0 if br < 0 sign = -1 else sign = 1 endif br = br^2*sign float cr = (@p_contrast-0.5)*2 if cr < 0 sign = -1 else sign = 1 endif cr = cr^2*sign+1 float st = (0.5-@p_sat)*2 if st < 0 sign = -1 else sign = 1 endif st = st^2*sign*2 float hu = @p_hue*6 float rd = red(return_color)-br float gr = green(return_color)-br float bl = blue(return_color)-br if rd > 1 rd = 1 endif if gr > 1 gr = 1 endif if bl > 1 bl = 1 endif if rd < 0 rd = 0 endif if gr < 0 gr = 0 endif if bl < 0 bl = 0 endif return_color = rgba(rd,gr,bl,alpha(return_color)) rd = red(return_color)^cr gr = green(return_color)^cr bl = blue(return_color)^cr return_color = rgba(rd,gr,bl,alpha(return_color)) float satval = sat(return_color)-st if satval > 1 satval = 1 endif if satval < 0 satval = 0 endif return_color = hsla(hue(return_color), satval, lum(return_color), alpha(return_color)) float hueval = (hue(return_color)+hu) % 6 return_color = hsla(hueval, sat(return_color), lum(return_color), alpha(return_color)) if @p_poster float rd = floor(red(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float gr = floor(green(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float bl = floor(blue(return_color)*@p_chan)/@p_chan + 0.5/@p_chan return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_gray float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) return_color = rgba(gry,gry,gry,alpha(return_color)) endif if @p_solar float rd = red(return_color) float gr = green(return_color) float bl = blue(return_color) if rd > @p_thresh rd = 1-rd endif if gr > @p_thresh gr = 1-gr endif if bl > @p_thresh bl = 1-bl endif return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_bw float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) if gry < @p_bwt return_color = rgba(0,0,0,alpha(return_color)) else return_color = rgba(1,1,1,alpha(return_color)) endif endif endif return return_color endfunc protected: float ptexture TrapShape m_Texture float m_iterexp complex m_zold ImageImport m_img bool m_empty color m_color ColorTrap m_TrapColor DefaultColorMerge m_MergeColor default: title = "General Smoothing" int param v_generalsmoothing caption = "Version (General Smoothing)" default = 101 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_generalsmoothing < 101 endparam heading text = "This is a direct coloring formula with textures and image import \ capabilities, and which works for both convergent and divergent \ fractals. It is highly recommended that the divergent bailout be \ set to at least 1e8 and the convergent bailout be set to no more than \ 1e-8. If this is not done then the smoothing may be unsatisfactory. \ It works with fractals that have both divergent and convergent regions, \ such as the Magnet fractals." endheading float param txamt caption = "Texture amount" default = 0.0 visible = @fTexture != DMJ_TrapShapeFlat endparam heading text = "The 'Tile method' applies to both textures and images. Fixed Iteration \ will give a smoother tiling, while 'Cabs(z)' will more consistently \ follow the fractal shape." visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endheading param mtile caption = "Tile method" default = 1 enum = "None" "Fixed Iteration" "Cabs(z)" visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endparam int param iternum caption = "Iter number" default = 1 hint = "Changes the texture/image mapping." visible = (@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) && \ @mtile == "Fixed iteration" endparam float param tcabs caption = "Cabs limit" default = 1.0 visible = @mtile == "Cabs(z)" hint = "Changes the texture/image mapping." visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam heading caption = "Images and Colorings" endheading ColorTrap param f_trapcolor caption = "Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." endparam DefaultColorMerge param f_colormerge caption = "Color Merge" default = DefaultColorMerge visible = @f_trapcolor != ColorTrapNoColor endparam param nmerge caption = "Merge order" default = 0 enum = "Image on Top" "Image on Bottom" visible = @f_trapcolor != ColorTrapNoColor endparam float param opacity caption = "Merge Opacity" default = 0.2 visible = @f_trapcolor != ColorTrapNoColor endparam heading text = "Make image transparent by: " visible = @f_trapcolor != ColorTrapNoColor endheading bool param ahue caption = "Hue value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam bool param alum caption = "Luminance value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam bool param asat caption = "Saturation value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam heading caption = "Special Effects" visible = @v_generalsmoothing >= 101 endheading float param p_bright caption = "Brightness" default = 0.5 min = 0 max = 1 visible = @v_generalsmoothing >= 101 endparam float param p_contrast caption = "Contrast" default = 0.5 min = 0 max = 1 visible = @v_generalsmoothing >= 101 endparam float param p_sat caption = "Saturation" default = 0.5 min = 0 max = 1 visible = @v_generalsmoothing >= 101 endparam float param p_hue caption = "Hue" default = 0.0 min = 0 max = 1 visible = @v_generalsmoothing >= 101 endparam bool param p_gray caption = "Grayscale" default = false visible = @v_generalsmoothing >= 101 endparam bool param p_solar caption = "Solarize" default = false visible = @v_generalsmoothing >= 101 endparam float param p_thresh caption = "Threshold" default = 0.5 visible = @p_solar && @v_generalsmoothing >= 101 endparam bool param p_poster caption = "Posterize" default = false visible = @v_generalsmoothing >= 101 endparam int param p_chan caption = "Colors per channel" default = 4 min = 2 visible = @p_poster && @v_generalsmoothing >= 101 endparam bool param p_bw caption = "Black and White" default = false visible = @v_generalsmoothing >= 101 endparam float param p_bwt caption = "Threshold" default = 0.5 min = 0 max = 1 visible = @p_bw && @v_generalsmoothing >= 101 endparam } class REB_SmoothAlterations(common.ulb:DirectColoring) { ; A smoothing algorithm that works for both convergent and divergen fractals.
public: $define debug import "common.ulb" import "dmj5.ulb" ; constructor func REB_SmoothAlterations(Generic pparent) DirectColoring.DirectColoring(pparent) m_Texture = new @ftexture(this) m_MergeColor = new @f_colormerge(0) m_TrapColor = new @f_trapcolor(this) endfunc ; initialize the objects func Init(complex pz, complex ppixel) DirectColoring.Init(pz, ppixel) ci = (0,1) rot = ci^(@ang/90) skew = ci^(@skew/90) center = @center m_Texture.Init(pz) m_TrapColor.Init(pz) m_iterexp = 0 m_empty = true ptexture = 0 mask = false m_zold = 0 if @usefirst first = false else first = true endif i = 0 m_zold2 = 0 a = 0 a2 = 0 f = 0 power = 0 endfunc ; call for each iterated point func Iterate(complex pz) DirectColoring.Iterate(pz) a2 =a pz = real(pz)*skew + flip(imag(pz)) pz = pz*rot pz = pz*@mult if @fn2 == "none" pz = pz elseif @fn2 == "real" pz = real(pz) elseif @fn2 == "imag" pz = imag(pz) elseif @fn2 == "sum" pz = real(pz) + imag(pz) elseif @fn2 == "difference" pz = real(pz) - imag(pz) elseif @fn2 == "abs" pz = abs(pz) elseif @fn2 == "cabs" pz = cabs(pz) elseif @fn2 == "|pz|" pz = |pz| elseif @fn2 == "ceil" pz = ceil(pz) elseif @fn2 == "floor" pz = floor(pz) elseif @fn2 == "trunc" pz = trunc(pz) elseif @fn2 == "round" pz = round(pz) endif if @alter == "Power" || @alter == "All" if !@mix pz = pz^@p else pz = pz^@ps endif endif if @alter == "Function" || @alter == "All" if @fn == "sin" pz = sin(pz) elseif @fn == "sinxx" pz = conj(sin(pz)) elseif @fn == "cosec" pz = 1/sin(pz) elseif @fn == "sinc" if cabs(pz) != 0 pz = sin(pz)/pz else pz = 1 endif elseif @fn == "haversin" pz = (1-cos(pz))/2 elseif @fn == "versin" pz = 1-cos(pz) elseif @fn == "sinh" pz = sinh(pz) elseif @fn == "sinhc" if cabs(pz) != 0 pz = sinh(pz)/pz else pz = 1 endif elseif @fn == "asin" pz = asin(pz) elseif @fn == "ahaversin" pz = 2*asin(sqrt(pz)) elseif @fn == "aversin" pz = acos(1-pz) elseif @fn == "asinh" pz = asinh(pz) elseif @fn == "cos" pz = cos(pz) elseif @fn == "cosxx" pz = conj(cos(pz)) elseif @fn == "havercos" pz = (1+cos(pz))/2 elseif @fn == "exsec" pz = 1/cos(pz) -1 elseif @fn == "excsc" pz = 1/sin(pz) -1 elseif @fn == "aexsec" pz = acos(1/(pz+1)) elseif @fn == "aexcsc" pz = asin(1/(pz+1)) elseif @fn == "vercos" pz = 1+cos(pz) elseif @fn == "sec" pz = 1/cos(pz) elseif @fn == "asec" pz = acos(1/pz) elseif @fn == "acsc" pz = -ci*log(sqrt(1-1/sqr(pz)) + ci/pz) elseif @fn == "cosh" pz = cosh(pz) elseif @fn == "acos" pz = acos(pz) elseif @fn == "ahavercos" pz = 2*acos(sqrt(pz)) elseif @fn == "avercos" pz = acos(1+pz) elseif @fn == "acosh" pz = acosh(pz) elseif @fn == "tan" pz = tan(pz) elseif @fn == "tanc" if cabs(pz) != 0 pz = tan(pz)/pz else pz = 1 endif elseif @fn == "tanh" pz = tanh(pz) elseif @fn == "tanhc" if cabs(pz) != 0 pz = tanh(pz)/pz else pz = 1 endif elseif @fn == "coversin" pz = 1-sin(pz) elseif @fn == "acoversin" pz = asin(1-pz) elseif @fn == "hacoversin" pz = (1-sin(pz))/2 elseif @fn == "covercos" pz = 1 + sin(pz) elseif @fn == "acovercos" pz = asin(1+pz) elseif @fn == "hacovercos" pz = (1+sin(pz))/2 elseif @fn == "acotan" pz = atan(1/pz) elseif @fn == "acotanh" pz = atanh(1/pz) elseif @fn == "sech" pz = 1/(cosh(pz)) elseif @fn == "crd" pz = 2*sin(pz/2) elseif @fn == "acrd" pz = 2*asin(pz/2) elseif @fn == "asech" pz = acosh(1/pz) elseif @fn == "cosech" pz = 1/sinh(pz) elseif @fn == "acosech" pz = asinh(1/pz) elseif @fn == "coshc" if cabs(pz) != 0 pz = cosh(pz)/pz else pz = 1 endif elseif @fn == "cosc" if cabs(pz) != 0 pz = cos(pz)/pz else pz = 1 endif elseif @fn == "cotanc" if cabs(pz) != 0 pz = cotan(pz)/pz else pz = 1 endif elseif @fn == "cotanhc" if cabs(pz) != 0 pz = cotanh(pz)/pz else pz = 1 endif elseif @fn == "secc" if cabs(pz) != 0 pz = 1/(pz*cos(pz)) else pz = 1 endif elseif @fn == "sechc" if cabs(pz) != 0 pz = 1/(pz*cosh(pz)) else pz = 1 endif elseif @fn == "cosecc" if cabs(pz) != 0 pz = 1/(pz*sin(pz)) else pz = 1 endif elseif @fn == "cosechc" if cabs(pz) != 0 pz = 1/(pz*sinh(pz)) else pz = 1 endif elseif @fn == "logistic" pz = 1/(1+exp(-pz)) elseif @fn == "softplus" pz = log(1+exp(pz)) elseif @fn == "primecount" pz = pz/log(pz) elseif @fn == "atan" pz = atan(pz) elseif @fn == "atan2" pz = atan2(pz) elseif @fn == "atanh" pz = atanh(pz) elseif @fn == "cotan" pz = cotan(pz) elseif @fn == "cotanh" pz = cotanh(pz) elseif @fn == "sqr" pz = sqr(pz) elseif @fn == "sqrt" pz = sqrt(pz) elseif @fn == "cube" pz = pz^3 elseif @fn == "cuberoot" pz = pz^(1/3) elseif @fn == "log" pz = log(pz) elseif @fn == "logit" pz = log(pz/(1-pz)) elseif @fn == "colog" pz = -log(pz) elseif @fn == "exp" pz = exp(pz) elseif @fn == "gauss" pz = exp(-sqr(pz)) elseif @fn == "gd" pz = 2*atan(tanh(0.5*pz)) elseif @fn == "agd" pz = 2*atanh(tan(0.5*pz)) elseif @fn == "sigmoid" pz = 1/(1+exp(-pz)) elseif @fn == "abs" pz = abs(pz) elseif @fn == "cabs" pz = cabs(pz) elseif @fn == "conj" pz = conj(pz) elseif @fn == "flip" pz = flip(pz) elseif @fn == "recip" pz = recip(pz) elseif @fn == "ceil" pz = ceil(pz) elseif @fn == "floor" pz = floor(pz) elseif @fn == "trunc" pz = trunc(pz) elseif @fn == "round" pz = round(pz) endif endif if isNAN(cabs(pz)) pz = m_zold elseif isINF(cabs(pz)) pz = 1e10 endif if !first if @mix a = a + cabs(sin(@density*(atan2(#z-m_zold-center)))) endif if isNAN(a) a = a2 elseif isINF(a) a = 1e10 endif m_iterexp = m_iterexp + exp(-cabs(pz-center)-(@mod/(cabs(m_zold - pz-center)))) else first = false endif if (@mtile == "Fixed Iteration" && m_iterations == @iternum) || \ (@mtile == "Cabs(z)" && cabs(pz) < @tcabs)|| @mtile == "none" ptexture = m_Texture.Iterate(pz) if @f_trapcolor == ColorTrapNoColor m_empty = true else m_color = m_TrapColor.Iterate(pz) m_empty = false endif endif m_zold2 = m_zold m_zold = pz i = i + 1 endfunc ; override the parent and call in the final section of the coloring formula.
color func Result(complex pz) color return_color = rgba(0,0,0,0) if @solid if m_iterexp < @thresh mask = true endif endif if mask m_solid = true else if @mix power = log(|#z - m_zold|) / log(|m_zold - m_zold2|) f = (log(log(@bailout)) - log(log(1/(|(m_zold - #z)|))))/log(power)*@fudge a = a/i a2 = a2/(i-1) float adi = a2 + (a-a2)*(f+1) if @mixmethod == "sum" float mw =@mixweight float iw = mw float aw = 1 - iw m_iterexp = (iw*m_iterexp+aw*adi) else m_iterexp = sqrt(m_iterexp*adi) endif endif color return_color = gradient(0.2*m_iterexp + ptexture*@txamt) if @ahue m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ hue(m_color)/6*alpha(m_color)) endif if @alum m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ lum(m_color)*alpha(m_color)) endif if @asat m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ sat(m_color)*alpha(m_color)) endif color temp = rgba(0,0,0,0) if !m_empty if @nmerge == 1 temp = m_color m_color = return_color return_color = temp endif return_color = m_MergeColor.FullMerge(return_color, m_color, @opacity) endif float br = (0.5-@p_bright)*2 int sign = 0 if br < 0 sign = -1 else sign = 1 endif br = br^2*sign float cr = (@p_contrast-0.5)*2 if cr < 0 sign = -1 else sign = 1 endif cr = cr^2*sign+1 float st = (0.5-@p_sat)*2 if st < 0 sign = -1 else sign = 1 endif st = st^2*sign*2 float hu = @p_hue*6 float rd = red(return_color)-br float gr = green(return_color)-br float bl = blue(return_color)-br if rd > 1 rd = 1 endif if gr > 1 gr = 1 endif if bl > 1 bl = 1 endif if rd < 0 rd = 0 endif if gr < 0 gr = 0 endif if bl < 0 bl = 0 endif return_color = rgba(rd,gr,bl,alpha(return_color)) rd = red(return_color)^cr gr = green(return_color)^cr bl = blue(return_color)^cr return_color = rgba(rd,gr,bl,alpha(return_color)) float satval = sat(return_color)-st if satval > 1 satval = 1 endif if satval < 0 satval = 0 endif return_color = hsla(hue(return_color), satval, lum(return_color), alpha(return_color)) float hueval = (hue(return_color)+hu) % 6 return_color = hsla(hueval, sat(return_color), lum(return_color), alpha(return_color)) if @p_poster float rd = floor(red(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float gr = floor(green(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float bl = floor(blue(return_color)*@p_chan)/@p_chan + 0.5/@p_chan return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_gray float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) return_color = rgba(gry,gry,gry,alpha(return_color)) endif if @p_solar float rd = red(return_color) float gr = green(return_color) float bl = blue(return_color) if rd > @p_thresh rd = 1-rd endif if gr > @p_thresh gr = 1-gr endif if bl > @p_thresh bl = 1-bl endif return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_bw float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) if gry < @p_bwt return_color = rgba(0,0,0,alpha(return_color)) else return_color = rgba(1,1,1,alpha(return_color)) endif endif endif return return_color endfunc ; Is the coloring solid? - used by the coloring ucl. bool func IsSolid() return m_solid endfunc protected: float ptexture TrapShape m_Texture float m_iterexp complex m_zold ImageImport m_img bool m_empty bool mask color m_color ColorTrap m_TrapColor DefaultColorMerge m_MergeColor complex ci complex rot complex skew complex center bool first int i complex m_zold2 float a float a2 float f float power default: title = "Smooth Alterations" int param v_smoothalterations caption = "Version (Smooth Alterations)" 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_smoothalterations < 100 endparam heading text = "This is a direct coloring formula with textures and image import \ capabilities, and which works for both convergent and divergent \ fractals. Optimal smoothing occurs when the bailout is large. \ Image appearance is also dependent upon the bailout value(s). \ It works with fractals that have both divergent and convergent regions, \ such as the Magnet fractals." endheading heading text = "Skipping the first iteration in color calculations may eliminate or reduce \ some coloring artifacts." endheading bool param usefirst caption = "Use first iteration" default = false endparam heading text = "This option mixes in a component very similar to 'Triangle Inequality Average'. \ or 'Curvature'. It doesn't work for all parameter settings and fractal types, but has a broader \ range of applicability than the original TIA. Setting a large bailout, e.g. \ 1e10 or greater is important, and the same value should be used with the coloring \ formula. For convergent fractals set the bailout to 1e-10 or smaller. Fewer \ banding artifacts will generally be seen with the 'product' mix method." endheading bool param mix caption = "Mix Strings and Alterations" default = false endparam param mixmethod caption = "Mix method" enum = "sum" "product" default = 0 visible = @mix endparam float param mixweight caption = "Mix weight" default = 0.5 min = 0 max = 1 visible = @mixmethod == "sum" && @mix endparam float param bailout caption = "bailout" default = 1e10 visible = @mix endparam float param density caption = "fiber density" default = 1 visible = @mix endparam heading text = "The 'fudge factor' can be used to reduce banding artifacts that are \ sometimes created when mixing 'Strings' and 'Alterations'." visible = @mix endheading float param fudge caption = "fudge factor" default = 1 visible = @mix endparam complex param mult caption = "Z scaler" default = (2,0) endparam param Alter caption = "Alterations" default = 3 enum = "None" "Power" "Function" "All" endparam complex param center caption = "Center" default = (0,0) endparam float param ang caption ="z rotation" default = 0 endparam float param skew caption ="z skew" default = 0 endparam complex param p caption = "Power" default = (2,0.1) visible = (@alter == "Power" || @alter == "All") && !@mix endparam complex param ps caption = "Power" default = (-1,0.1) visible = (@alter == "Power" || @alter == "All") && @mix endparam heading text = "'Smooth alterations' has an extended set of single arguemt functions, \ mostly taken from from the special functions section of Wolfram Mathworld \ and some were suggested by Ottomagus" visible = @alter == "Function" || @alter == "All" endheading param fn caption = "Function" default = 24 ; enum = "sin" "sinxx" "cosec" "sinc" "haversin" "versin" "sinh" "sinhc" "asin" "ahaversin" \ ; "aversin" "asinh" "cos" "cosxx" "havercos" "exsec" "excsc" "aexsec" "aexcsc" \ ; "vercos" "sec" "asec" "acsc" "cosh" "acos" "ahavercos" "avercos" "acosh" "tan" "tanc" "tanh" "tanhc" \ ; "coversin" "acoversin" "hacoversin" "covercos" "acovercos" "hacovercos" \ ; "acotan" "acotanh" "sech" "crd" "acrd" "asech" "cosech" "acosech" "coshc" "cosc" "cotanc" \ ; "cotanhc" "secc" "sechc" "cosecc" "cosechc" "softplus" "primecount" \ ; "atan" "atan2" "atanh" "cotan" "cotanh" "sqr" "sqrt" "cube" "cuberoot" \ ; "log" "logit" "colog" "exp" "gauss" "gd" "agd" "sigmoid" "abs" "cabs" "conj" "flip" \ ; "ident" "recip" "ceil" "floor" "trunc" "round" enum = "sin" "sinxx" "cosec" "sinc" "haversin" "versin" "sinh" "sinhc" "asin" "ahaversin" \ "aversin" "asinh" "cos" "cosxx" "havercos" "exsec" "excsc" "aexsec" "aexcsc" \ "vercos" "sec" "asec" "acsc" "cosh" "acos" "ahavercos" "avercos" "acosh" "tan" "tanc" "tanh" "tanhc" \ "atan" "atan2" "atanh" "cotan" "cotanh" "sqr" "sqrt" "cube" "cuberoot" \ "log" "logit" "colog" "exp" "gauss" "gd" "agd" "sigmoid" "abs" "cabs" "conj" "flip" \ "ident" "recip" "ceil" "floor" "trunc" "round" \ "coversin" "acoversin" "hacoversin" "covercos" "acovercos" "hacovercos" \ "acotan" "acotanh" "sech" "crd" "acrd" "asech" "cosech" "acosech" "coshc" "cosc" "cotanc" \ "cotanhc" "secc" "sechc" "cosecc" "cosechc" "softplus" "primecount" "logistic" visible = @alter == "Function" || @alter == "All" endparam param fn2 caption = "Pre-Function" default = 3 enum = "none" "real" "imag" "sum" "difference" "abs" "cabs" "|pz|" "ceil" "floor" "trunc" "round" endparam float param mod caption = "Modulator" default = 0.5 endparam bool param solid caption = "Solid background" default = false endparam float param thresh caption = "Threshold" default = 0.75 visible = @solid endparam float param txamt caption = "Texture amount" default = 0.0 visible = @fTexture != DMJ_TrapShapeFlat endparam heading text = "The 'Tile method' applies to both textures and images. Fixed Iteration \ will give a smoother tiling, while 'Cabs(z)' will more consistently \ follow the fractal shape." visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endheading param mtile caption = "Tile method" default = 1 enum = "None" "Fixed Iteration" "Cabs(z)" visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endparam int param iternum caption = "Iter number" default = 1 hint = "Changes the texture/image mapping." visible = (@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) && \ @mtile == "Fixed iteration" endparam float param tcabs caption = "Cabs limit" default = 1.0 visible = @mtile == "Cabs(z)" hint = "Changes the texture/image mapping." visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam heading caption = "Images and Colorings" endheading ColorTrap param f_trapcolor caption = "Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." endparam DefaultColorMerge param f_colormerge caption = "Color Merge" default = DefaultColorMerge visible = @f_trapcolor != ColorTrapNoColor endparam param nmerge caption = "Merge order" default = 0 enum = "Image on Top" "Image on Bottom" visible = @f_trapcolor != ColorTrapNoColor endparam float param opacity caption = "Merge Opacity" default = 0.2 visible = @f_trapcolor != ColorTrapNoColor endparam heading text = "Make image transparent by: " visible = @f_trapcolor != ColorTrapNoColor endheading bool param ahue caption = "Hue value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam bool param alum caption = "Luminance value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam bool param asat caption = "Saturation value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam heading caption = "Special Effects" endheading float param p_bright caption = "Brightness" default = 0.5 min = 0 max = 1 endparam float param p_contrast caption = "Contrast" default = 0.5 min = 0 max = 1 endparam float param p_sat caption = "Saturation" default = 0.5 min = 0 max = 1 endparam float param p_hue caption = "Hue" default = 0.0 min = 0 max = 1 endparam bool param p_gray caption = "Grayscale" default = false endparam bool param p_solar caption = "Solarize" default = false endparam float param p_thresh caption = "Threshold" default = 0.5 visible = @p_solar endparam bool param p_poster caption = "Posterize" default = false endparam int param p_chan caption = "Colors per channel" default = 4 min = 2 visible = @p_poster endparam bool param p_bw caption = "Black and White" default = false endparam float param p_bwt caption = "Threshold" default = 0.5 min = 0 max = 1 visible = @p_bw endparam } class REB_ImageFilterColoring(common.ulb:DirectColoring) { public: import "common.ulb" import "dmj5.ulb" ; constructor func REB_ImageFilterColoring(Generic pparent) DirectColoring.DirectColoring(pparent) m_TrapColor = new @f_trapcolor(this) endfunc ; initialize the objects func Init(complex pz, complex ppixel) DirectColoring.Init(pz, ppixel) m_TrapColor.Init(pz) endfunc ; call for each iterated point func Iterate(complex pz) DirectColoring.Iterate(pz) m_color = m_TrapColor.Iterate(pz) endfunc ; override the parent and call in the final section of the coloring formula.
color func Result(complex pz) color return_color = rgba(0,0,0,0) if @ahue m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ hue(m_color)/6*alpha(m_color)) endif if @alum m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ lum(m_color)*alpha(m_color)) endif if @asat m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ sat(m_color)*alpha(m_color)) endif return_color = m_color return return_color endfunc protected: ImageImport m_img color m_color ColorTrap m_TrapColor default: title = "Image Filter Coloring" int param v_imagefiltercoloring caption = "Version (Image Filter Coloring)" 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_imagefiltercoloring < 100 endparam ColorTrap param f_trapcolor caption = "Colors" default = REB_ImageFilter selectable = false endparam heading text = "Make image transparent by: " endheading bool param ahue caption = "Hue value" default = false endparam bool param alum caption = "Luminance value" default = false endparam bool param asat caption = "Saturation value" default = false endparam } class REB_Harkonen_VepstasSmoothing(common.ulb:DirectColoring) { ; Based upon the smoothing code in Fibers and Things.
;

; The code originated with Jussi Härkönen and was modified with help from ; Härkönen to work for both convergent and divergent fractals. ; The class supports trapshape textures and ; colortrap coloring, including image import. import "common.ulb" import "dmj5.ulb" ; constructor func REB_Harkonen_VepstasSmoothing(Generic pparent) DirectColoring.DirectColoring(pparent) m_Texture = new @ftexture(this) m_MergeColor = new @f_colormerge(this) m_TrapColor = new @f_trapcolor(this) endfunc ; initialize the objects func Init(complex pz, complex ppixel) DirectColoring.Init(pz, ppixel) m_Texture.Init(pz) m_TrapColor.Init(pz) power = 0 m_empty = true endfunc func Iterate(complex pz) DirectColoring.Iterate(pz) if (@mtile == "Fixed Iteration" && m_iterations == @iternum) || \ (@mtile == "Cabs(z)" && @bailout < 1 && cabs(zold-pz) > @tcabs) || \ (@mtile == "Cabs(z)" && @bailout > 1 && cabs(pz) < @tcabs) || @mtile == "None" ptexture = m_Texture.Iterate(pz) if @f_trapcolor == ColorTrapNoColor m_empty = true else pcolor = m_TrapColor.Iterate(pz) m_empty = false endif endif ; z2 = pz zold2 = zold ; zold = z2 zold = pz endfunc color func Result(complex pz) power = log(|pz - zold|) / log(|zold - zold2|) f = (log(log(@bailout)) - log(log(1/(|(zold - pz)|))))/log(power) color return_color = gradient(0.05*(m_iterations+f) + ptexture*@txamt) if @ahue pcolor = hsla(hue(pcolor), sat(pcolor), lum(pcolor), \ hue(pcolor)/6*alpha(pcolor)) endif if @alum pcolor = hsla(hue(pcolor), sat(pcolor), lum(pcolor), \ lum(pcolor)*alpha(pcolor)) endif if @asat pcolor = hsla(hue(pcolor), sat(pcolor), lum(pcolor), \ sat(pcolor)*alpha(pcolor)) endif float opacity = 0 color temp = rgba(0,0,0,0) if @nmerge == 1 || m_empty temp = pcolor pcolor = return_color return_color = temp endif if !m_empty opacity = @opacity else opacity = 1 endif color rcolor = m_MergeColor.FullMerge(return_color, pcolor, opacity) float br = (0.5-@p_bright)*2 int sign = 0 if br < 0 sign = -1 else sign = 1 endif br = br^2*sign float cr = (@p_contrast-0.5)*2 if cr < 0 sign = -1 else sign = 1 endif cr = cr^2*sign+1 float st = (0.5-@p_sat)*2 if st < 0 sign = -1 else sign = 1 endif st = st^2*sign*2 float hu = @p_hue*6 float rd = red(rcolor)-br float gr = green(rcolor)-br float bl = blue(rcolor)-br if rd > 1 rd = 1 endif if gr > 1 gr = 1 endif if bl > 1 bl = 1 endif if rd < 0 rd = 0 endif if gr < 0 gr = 0 endif if bl < 0 bl = 0 endif rcolor = rgba(rd,gr,bl,alpha(rcolor)) rd = red(rcolor)^cr gr = green(rcolor)^cr bl = blue(rcolor)^cr rcolor = rgba(rd,gr,bl,alpha(rcolor)) float satval = sat(rcolor)-st if satval > 1 satval = 1 endif if satval < 0 satval = 0 endif rcolor = hsla(hue(rcolor), satval, lum(rcolor), alpha(rcolor)) float hueval = (hue(rcolor)+hu) % 6 rcolor = hsla(hueval, sat(rcolor), lum(rcolor), alpha(rcolor)) if @p_poster float rd = floor(red(rcolor)*@p_chan)/@p_chan + 0.5/@p_chan float gr = floor(green(rcolor)*@p_chan)/@p_chan + 0.5/@p_chan float bl = floor(blue(rcolor)*@p_chan)/@p_chan + 0.5/@p_chan rcolor = rgba(rd,gr,bl,alpha(rcolor)) endif if @p_gray float gry = 0.3 * red(rcolor)+ 0.59 * green(rcolor) + 0.11 * blue(rcolor) rcolor = rgba(gry,gry,gry,alpha(rcolor)) endif if @p_solar float rd = red(rcolor) float gr = green(rcolor) float bl = blue(rcolor) if rd > @p_thresh rd = 1-rd endif if gr > @p_thresh gr = 1-gr endif if bl > @p_thresh bl = 1-bl endif rcolor = rgba(rd,gr,bl,alpha(rcolor)) endif if @p_bw float gry = 0.3 * red(rcolor)+ 0.59 * green(rcolor) + 0.11 * blue(rcolor) if gry < @p_bwt rcolor = rgba(0,0,0,alpha(rcolor)) else rcolor = rgba(1,1,1,alpha(rcolor)) endif endif return rcolor endfunc protected: TrapShape m_Texture float ptexture ; ImageImport m_img bool m_empty color pcolor DefaultColorMerge m_MergeColor ColorTrap m_TrapColor ; complex z2 complex zold complex zold2 float f float power default: title = "Härkönen/Vepstas Smoothing" int param v_Harkonen_VepstasSmoothing caption = "Version (Härkönen/Vepstas Smoothing)" 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_Harkonen_VepstasSmoothing < 100 endparam heading text = "The bailout should be set to be the same as for the fractal formula." endheading param bailout caption = "bailout" default = 1e10 endparam float param txamt caption = "Texture amount" default = 0.0 visible = @fTexture != DMJ_TrapShapeFlat endparam heading text = "The 'Tile method' applies to both textures and images. Fixed Iteration \ will give a smoother tiling, while 'Cabs(z)' will more consistently \ follow the fractal shape." visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endheading param mtile caption = "Tile method" default = 1 enum = "None" "Fixed Iteration" "Cabs(z)" visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endparam int param iternum caption = "Iter number" default = 1 hint = "Changes the texture/image mapping." visible = (@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) && \ @mtile == "Fixed iteration" endparam float param tcabs caption = "Cabs limit" default = 0.5 visible = @mtile == "Cabs(z)" hint = "Changes the texture/image mapping." visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam heading caption = "Images and Colorings" endheading ColorTrap param f_trapcolor caption = "Colors" default = ColorTrapNoColor ; expanded = false hint = "A trap shape that is used as a color or pattern." endparam DefaultColorMerge param f_colormerge caption = "Color Merge" default = DefaultColorMerge visible = @f_trapcolor != ColorTrapNoColor endparam param nmerge caption = "Merge order" default = 0 enum = "Image on Top" "Image on Bottom" visible = @f_trapcolor != ColorTrapNoColor endparam float param opacity caption = "Merge Opacity" default = 0.2 visible = @f_trapcolor != ColorTrapNoColor endparam heading text = "Make image transparent by: " visible = @f_trapcolor != ColorTrapNoColor endheading bool param ahue caption = "Hue value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam bool param alum caption = "Luminance value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam bool param asat caption = "Saturation value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam heading caption = "Special Effects" endheading float param p_bright caption = "Brightness" default = 0.5 min = 0 max = 1 endparam float param p_contrast caption = "Contrast" default = 0.5 min = 0 max = 1 endparam float param p_sat caption = "Saturation" default = 0.5 min = 0 max = 1 endparam float param p_hue caption = "Hue" default = 0.0 min = 0 max = 1 endparam bool param p_gray caption = "Grayscale" default = false endparam bool param p_solar caption = "Solarize" default = false endparam float param p_thresh caption = "Threshold" default = 0.5 visible = @p_solar endparam bool param p_poster caption = "Posterize" default = false endparam int param p_chan caption = "Colors per channel" default = 4 min = 2 visible = @p_poster endparam bool param p_bw caption = "Black and White" default = false endparam float param p_bwt caption = "Threshold" default = 0.5 min = 0 max = 1 visible = @p_bw endparam } class REB_FibersThings(common.ulb:DirectColoring) { ; Based upon the divergent formula code of Jussi Härkönen, but for convergent formulas.
;

; Direct Coloring method that looks like triange inequality average ; or curvature average but which works specifically for convergent ; fractals like Cayley Julia and Cayley Mandelbrot. The smoothing code is ; modified from Linas Vepstas and Damien Jones. Some of the code ideas came ; from the work of Jussi Härkönen. Corrections to the fractional iteration ; count made by Jussi Härkönen. The class supports trapshape textures and ; colortrap coloring, including image import. public: import "common.ulb" import "dmj5.ulb" ; constructor func REB_FibersThings(Generic pparent) DirectColoring.DirectColoring(pparent) m_Texture = new @ftexture(this) m_MergeColor = new @f_colormerge(this) m_TrapColor = new @f_trapcolor(this) endfunc ; initialize the objects func Init(complex pz, complex ppixel) DirectColoring.Init(pz, ppixel) m_Texture.Init(pz) m_TrapColor.Init(pz) ci = (0,1) rot = ci^(@ang/90) skew = ci^(@skew/90) prot = ci^(@prot/90) z2 = 0 zold = (0,0) zold2 = (0,0) i = 0 a = 0 a2 = 0 f = 0 ztype = (0,0) if @zmod == "point" || @zmod == "rot point" ztype = @spoint endif power = 0 m_empty = true endfunc func Iterate(complex pz) DirectColoring.Iterate(pz) if (@mtile == "Fixed Iteration" && m_iterations == @iternum) || \ (@mtile == "Cabs(z)" && @bailout < 1 && cabs(zold-pz) > @tcabs) || \ (@mtile == "Cabs(z)" && @bailout > 1 && cabs(pz) < @tcabs) || @mtile == "None" ptexture = m_Texture.Iterate(pz) if @v_fibersandthings < 101 m_img = new @f_image(0) m_empty = m_img.GetEmpty() endif if @v_fibersandthings >= 101 if @f_trapcolor == ColorTrapNoColor m_empty = true else m_color = m_TrapColor.Iterate(pz) m_empty = false endif else if !m_empty complex m_zi = (0,1)^(@iangle/90.0) complex m_zs = (0,1)^(@sangle/90.0) complex pzi = pz ; aspect ratio pzi = real(pzi) + flip(imag(pzi)*@iaspect) ; rotation pzi = pzi*m_zi ; skew pzi = real(pzi)*m_zs + flip(imag(pzi)) float width = m_img.getWidth() float height = m_img.getHeight() complex pzi = (pzi+(100,100))*@scale*1000 complex c = @adjx-2*((real(pzi) % (width-1))/width) + \ flip(@adjy-2*((imag(pzi) % (height-1))/height)) m_color = m_img.getColor(c) endif endif endif a2 = a if @flavor != "smooth" z2 = real(pz)*skew + flip(imag(pz)) z2 = z2*rot else z2 = pz endif if @zmod == "rot point" && |ztype| != 0 ztype = ztype*prot endif if @flavor == "Standard" a = a + cabs(fn1(@density*(atan2(fn2(z2-zold-ztype)))+@colorshift*#pi)) elseif @flavor == "Curvature" a = a + cabs(fn1(@density*(atan2(fn2((z2-zold)/(zold-zold2)-ztype)))+@colorshift*#pi)) elseif @flavor == "Decomposition" a = a + cabs(fn1(@density*(atan2(fn2(z2-ztype)))+@colorshift*#pi)) elseif @flavor == "Decomp multiply" a = a + cabs(fn1(@density*(atan2(fn2(z2*zold-ztype)))+@colorshift*#pi)) elseif @flavor == "Decomp divide" a = a + cabs(fn1(@density*(atan2(fn2(z2/zold-ztype)))+@colorshift*#pi)) elseif @flavor == "Magnitude" a = a + cabs(fn1(@density*(cabs(fn2(z2-ztype)))+@colorshift*#pi)) elseif @flavor == "Magnitude 2" a = a + cabs(fn1(@density*(cabs(fn2(z2-zold-ztype)))+@colorshift*#pi)) elseif @flavor == "Magnitude 3" a = a + cabs(fn1(@density*(|fn2(z2-ztype)|)+@colorshift*#pi)) elseif @flavor == "Magnitude 4" a = a + cabs(fn1(@density*(|fn2(z2-zold-ztype)|)+@colorshift*#pi)) endif zold2 = zold zold = z2 i = i + 1 endfunc color func Result(complex pz) power = log(|pz - zold|) / log(|zold - zold2|) z2 = real(pz)*skew + flip(imag(pz)) z2 = z2*rot f = (log(log(@bailout)) - log(log(1/(|(zold - z2)|))))/log(power) a = a/i a2 = a2/(i-1) color return_color = gradient(a2 + (a-a2)*(f+1) + ptexture*@txamt) if @v_fibersandthings >= 102 if @ahue m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ hue(m_color)/6*alpha(m_color)) endif if @alum m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ lum(m_color)*alpha(m_color)) endif if @asat m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ sat(m_color)*alpha(m_color)) endif endif if @flavor == "Smooth" return_color = gradient(0.05*(m_iterations+f) + ptexture*@txamt) endif color temp = rgba(0,0,0,0) if !m_empty if @nmerge == 1 temp = m_color m_color = return_color return_color = temp endif return m_MergeColor.FullMerge(return_color, m_color, @opacity) endif if @v_fibersandthings >= 103 float br = (0.5-@p_bright)*2 int sign = 0 if br < 0 sign = -1 else sign = 1 endif br = br^2*sign float cr = (@p_contrast-0.5)*2 if cr < 0 sign = -1 else sign = 1 endif cr = cr^2*sign+1 float st = (0.5-@p_sat)*2 if st < 0 sign = -1 else sign = 1 endif st = st^2*sign*2 float hu = @p_hue*6 float rd = red(return_color)-br float gr = green(return_color)-br float bl = blue(return_color)-br if rd > 1 rd = 1 endif if gr > 1 gr = 1 endif if bl > 1 bl = 1 endif if rd < 0 rd = 0 endif if gr < 0 gr = 0 endif if bl < 0 bl = 0 endif return_color = rgba(rd,gr,bl,alpha(return_color)) rd = red(return_color)^cr gr = green(return_color)^cr bl = blue(return_color)^cr return_color = rgba(rd,gr,bl,alpha(return_color)) float satval = sat(return_color)-st if satval > 1 satval = 1 endif if satval < 0 satval = 0 endif return_color = hsla(hue(return_color), satval, lum(return_color), alpha(return_color)) float hueval = (hue(return_color)+hu) % 6 return_color = hsla(hueval, sat(return_color), lum(return_color), alpha(return_color)) if @p_poster float rd = floor(red(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float gr = floor(green(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float bl = floor(blue(return_color)*@p_chan)/@p_chan + 0.5/@p_chan return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_gray float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) return_color = rgba(gry,gry,gry,alpha(return_color)) endif if @p_solar float rd = red(return_color) float gr = green(return_color) float bl = blue(return_color) if rd > @p_thresh rd = 1-rd endif if gr > @p_thresh gr = 1-gr endif if bl > @p_thresh bl = 1-bl endif return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_bw float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) if gry < @p_bwt return_color = rgba(0,0,0,alpha(return_color)) else return_color = rgba(1,1,1,alpha(return_color)) endif endif endif return return_color endfunc protected: TrapShape m_Texture float ptexture ImageImport m_img bool m_empty color m_color DefaultColorMerge m_MergeColor ColorTrap m_TrapColor complex ci complex rot complex skew complex prot complex z2 complex zold complex zold2 int i float a float a2 float f complex ztype float power default: title = "Fibers and Things" int param v_fibersandthings caption = "Version (Fibers And Things)" default = 103 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_fibersandthings < 103 endparam heading text = "This coloring method was designed for use with convergent fractals. \ It was specifically designed for the convergent formulas in reb.ufm \ and may not work with all convergent fractals. The bailout should \ be the same for both the coloring formula and the ufm. Some coding ideas \ came from the work of Jussi Härkönen as did corrections \ to the convergent smoothing algorithm." endheading param bailout caption = "bailout" default = 1e-12 endparam param flavor caption = "flavor" default = 0 enum = "standard" "curvature" "decomposition" "decomp multiply" \ "decomp divide" "magnitude" "magnitude 2" "magnitude 3" \ "magnitude 4" "smooth" endparam param zmod caption ="z modifier" enum = "none" "point" "rot point" default = 0 visible = @flavor != "smooth" endparam float param prot caption = "point rotation" default = 0 visible = @flavor != "smooth"&&@zmod == "rot point" endparam complex param spoint caption = "point val" default = (1,-1) visible = @flavor != "smooth"&&(@zmod == "point" || @zmod == "rot point") endparam float param ang caption ="z rotation" default = 0 visible = @flavor != "smooth" endparam float param skew caption ="z skew" default = 0 visible = @flavor != "smooth" endparam func fn1 caption = "fiber function #1" default = cos() visible = @flavor != "smooth" endfunc func fn2 caption = "fiber function #2" default = ident() visible = @flavor != "smooth" endfunc complex param density caption = "fiber density" default = 10.0 visible = @flavor != "smooth" endparam float param colorshift caption = "color shift" default = 0.0 min = 0 max = 1 visible = @flavor != "smooth" endparam float param txamt caption = "Texture amount" default = 0.0 visible = @fTexture != DMJ_TrapShapeFlat endparam heading text = "The 'Tile method' applies to both textures and images. Fixed Iteration \ will give a smoother tiling, while 'Cabs(z)' will more consistently \ follow the fractal shape." visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endheading param mtile caption = "Tile method" default = 1 enum = "None" "Fixed Iteration" "Cabs(z)" visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endparam int param iternum caption = "Iter number" default = 1 hint = "Changes the texture/image mapping." visible = (@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) && \ @mtile == "Fixed iteration" endparam float param tcabs caption = "Cabs limit" default = 0.5 visible = @mtile == "Cabs(z)" hint = "Changes the texture/image mapping." visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam heading caption = "Images and Colorings" endheading ColorTrap param f_trapcolor caption = "Colors" default = ColorTrapNoColor ; expanded = false hint = "A trap shape that is used as a color or pattern." visible = @v_fibersandthings >= 101 endparam ImageImport param f_image caption = "Image" default = ImageImport visible = @v_fibersandthings < 101 endparam float param scale caption = "Image scale" default = 1 min = 0 hint = "Changes the scale of the image." visible = @v_fibersandthings < 101 endparam float param adjx caption = "Tile adj x" default = 0.99 min = 0.9 max = 1.1 visible = @v_fibersandthings < 101 endparam float param adjy caption = "Tile adj y" default = 0.999 min = 0.9 max = 1.1 visible = @v_fibersandthings < 101 endparam float param iaspect caption = "Image aspect" default = 1.0 visible = @v_fibersandthings < 101 endparam float param iangle caption = "Image rotation" default = 0 hint = "Rotates the image" visible = @v_fibersandthings < 101 endparam float param sangle caption = "Image skew" default = 0 hint = "Skews the image" visible = @v_fibersandthings < 101 endparam DefaultColorMerge param f_colormerge caption = "Color Merge" default = DefaultColorMerge visible = @v_fibersandthings < 101 || (@v_fibersandthings >= 101 \ && @f_trapcolor != ColorTrapNoColor) endparam param nmerge caption = "Merge order" default = 0 enum = "Image on Top" "Image on Bottom" visible = @v_fibersandthings < 101 || (@v_fibersandthings >= 101 \ && @f_trapcolor != ColorTrapNoColor) endparam float param opacity caption = "Merge Opacity" default = 0.2 visible = @v_fibersandthings < 101 || (@v_fibersandthings >= 101 \ && @f_trapcolor != ColorTrapNoColor) endparam heading text = "Make image transparent by: " visible = @v_fibersandthings >= 102 && @f_trapcolor != ColorTrapNoColor endheading bool param ahue caption = "Hue value" default = false visible = @v_fibersandthings >= 102 && \ @f_trapcolor != ColorTrapNoColor endparam bool param alum caption = "Luminance value" default = false visible = @v_fibersandthings >= 102 && \ @f_trapcolor != ColorTrapNoColor endparam bool param asat caption = "Saturation value" default = false visible = @v_fibersandthings >= 102 && \ @f_trapcolor != ColorTrapNoColor endparam heading caption = "Special Effects" visible = @v_fibersandthings >= 103 endheading float param p_bright caption = "Brightness" default = 0.5 min = 0 max = 1 visible = @v_fibersandthings >= 103 endparam float param p_contrast caption = "Contrast" default = 0.5 min = 0 max = 1 visible = @v_fibersandthings >= 103 endparam float param p_sat caption = "Saturation" default = 0.5 min = 0 max = 1 visible = @v_fibersandthings >= 103 endparam float param p_hue caption = "Hue" default = 0.0 min = 0 max = 1 visible = @v_fibersandthings >= 103 endparam bool param p_gray caption = "Grayscale" default = false visible = @v_fibersandthings >= 103 endparam bool param p_solar caption = "Solarize" default = false visible = @v_fibersandthings >= 103 endparam float param p_thresh caption = "Threshold" default = 0.5 visible = @p_solar && @v_fibersandthings >= 103 endparam bool param p_poster caption = "Posterize" default = false visible = @v_fibersandthings >= 103 endparam int param p_chan caption = "Colors per channel" default = 4 min = 2 visible = @p_poster && @v_fibersandthings >= 103 endparam bool param p_bw caption = "Black and White" default = false visible = @v_fibersandthings >= 103 endparam float param p_bwt caption = "Threshold" default = 0.5 min = 0 max = 1 visible = @p_bw && @v_fibersandthings >= 103 endparam } ;----------------------------------- ; ; Gradient Coloring classes ; ;-------------------------------------- class REB_3DFractalColoringGradientProgressive(common.ulb:GradientColoring) { $define debug public: import "common.ulb" import "dmj5.ulb" ;constructor func REB_3DFractalColoringGradientProgressive(Generic pparent) GradientColoring.GradientColoring(pparent) m_Texture = new @ftexture(this) endfunc ; Initialize the coloring formula func Init(complex pz, complex ppixel) GradientColoring.Init(pz,ppixel) m_Texture.Init(pz) TwoDflag = false m_expiter = 0 m_oldz = 0 endfunc ; call for each iterated point func Iterate(complex pz) GradientColoring.Iterate(pz) if @colorpreset == "2D Smoothing" TwoDFlag = false float m = abs(real(pz)) float n = 2.0^ceil(log(m)/log(2.0)-9) int k = floor(m/n) m = 512.0*(m - n*k) if k-256 == 100 TwoDflag = true if real(pz)<0.0 m = -m endif pz = m + flip(imag(pz)) m_expiter = m_expiter + exp(-cabs(pz)-0.5/(cabs(m_oldz - pz))) if (@mtile == "Fixed Iteration" && m_iterations == @iternum) || \ (@mtile == "Cabs(z)" && cabs(pz) < @tcabs)|| @mtile == "none" ptexture = m_Texture.Iterate(pz) endif m_oldz = pz endif endif endfunc ; override the parent and call in the final section of the coloring formula.
float func ResultIndex(complex pz) complex pzflavor = 0 if @colorpreset != "2D Smoothing" if @flavor == 0 pzflavor = (pz+@wt)*#pixel/(1+@wt) elseif @flavor == 1 pzflavor = (real(pz)+@wt)*#pixel/(1+@wt) elseif @flavor == 2 pzflavor = real(pz) + flip(cabs(pz)) elseif @flavor == 3 pzflavor = real(pz) + flip(real(pz)) else pzflavor = pz endif ptexture = m_Texture.Iterate(pzflavor) if imag(pz) == 1 colr = @scale*real(pz) elseif imag(pz) == 2 float input = real(pz) float rt = trunc(input)/2^20 float iter = (input - trunc(input))*2^20 colr = @scale*iter + rt elseif imag(pz) < 0 colr = @scale*real(pz)/2 endif if imag(pz) == -2 ; apply shadow value if @colorpreset == "Gradient" colr = @scale*real(pz)*@shad endif else if @colorpreset == "Gradient" colr = colr+ptexture*@txamt endif endif else if TwoDflag colr = 0.05*m_expiter + ptexture*@txamt endif endif if cabs(pz) == 0 m_Solid = true endif return colr endfunc ; Is the coloring solid? - used by the coloring ucl. bool func IsSolid() return m_Solid endfunc protected: float colr float ptexture TrapShape m_Texture bool TwoDFlag float m_expiter complex m_oldz default: title = "3D Fractal Coloring Gradient progressive" int param v_REB_3DFractalColoringGradientProgressive caption = "Version (3D Fractal Coloring Gradient Proressive" default = 101 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_REB_3DFractalColoringGradientProgressive < 101 endparam heading text = "This formula is intended for use with 3D Fractal Raytrace \ Progressive, and has plugin options for textures and colors." endheading heading caption = "Color Settings" endheading heading text = "If '3D Fractal Raytrace Progressive' is in the Distance mode, the recommended \ 'Color Options' setting is 'Gradient'. If '3D Fractal Raytrace Progressive' is \ in the 2D mode with compatibility for '3D Fractal Coloring Direct' checked, \ 'Color Options' must set to '2D Smoothing'. This will color the fractal \ using the gradient and the general smoothing algorithm." endheading param colorPreset caption = "Color Options" enum = "Gradient" "2D Smoothing" default = 0 endparam float param scale caption = "color scale adj" default = 1.0 visible = @colorPreset != "2D Smoothing" endparam heading caption = "Shadows" visible = @colorpreset != "2D Smoothing" endheading heading text = "'Add Shadows' must be selected in the ufm for this option to do \ anything." visible = @colorPreset != "2D Smoothing" endheading float param shad caption = "Shadow level" default = 0.4 min = 0.0 max = 1.0 visible = @colorPreset != "2D Smoothing" endparam heading caption = "Textures and Colors" endheading float param txamt caption = "Texture amount" default = 0.0 visible = @fTexture != DMJ_TrapShapeFlat endparam heading text = "The 'Tile method' applies to both textures and images. Fixed Iteration \ will give a smoother tiling, while 'Cabs(z)' will more consistently \ follow the fractal shape." visible = (@fTexture != DMJ_TrapShapeFlat) \ && @colorpreset == "2D Smoothing" endheading param mtile caption = "Tile method" default = 1 enum = "None" "Fixed Iteration" "Cabs(z)" visible = (@fTexture != DMJ_TrapShapeFlat) \ && @colorpreset == "2D Smoothing" endparam int param iternum caption = "Iter number" default = 1 hint = "Changes the texture/image mapping." visible = ((@fTexture != DMJ_TrapShapeFlat) && \ @mtile == "Fixed iteration") \ && @colorpreset == "2D Smoothing" endparam float param tcabs caption = "Cabs limit" default = 1.0 visible = @mtile == "Cabs(z)" hint = "Changes the texture/image mapping." visible = (@fTexture != DMJ_TrapShapeFlat) \ && @colorpreset == "2D Smoothing" endparam param flavor caption = "Texture/color flavor" default = 0 enum = "flavor1" "flavor2" "flavor3" "flavor4" "flavor5" visible = (@fTexture != DMJ_TrapShapeFlat) \ && @colorpreset != "2D Smoothing" endparam float param wt caption = "Weight" default = 2.0 visible = (@flavor == "flavor1" || @flavor == "flavor2") && ( (@fTexture != \ DMJ_TrapShapeFlat)) \ && @colorpreset != "2D Smoothing" endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam } class REB_ExponentialSmoothing_Gradient(common.ulb:GradientColoring) { ; Based on the original 1994 algorithm of Ron Barnett.
;

; This is a direct coloring formula that supports trap shape textures and ; colortrap coloring, including image import. public: import "common.ulb" import "dmj5.ulb" ; constructor func REB_ExponentialSmoothing_Gradient(Generic pparent) GradientColoring.GradientColoring(pparent) m_Texture = new @ftexture(this) endfunc ; initialize the objects func Init(complex pz, complex ppixel) GradientColoring.Init(pz, ppixel) m_Texture.Init(pz) m_iterexp = 0 m_zold = (0,0) endfunc ; call for each iterated point func Iterate(complex pz) GradientColoring.Iterate(pz) if (@mtile == "Fixed Iteration" && m_iterations == @iternum) || \ (@mtile == "Cabs(z)" && cabs(pz) < @tcabs)|| @mtile == "none" ptexture = m_Texture.Iterate(pz) endif if (@converge > 0) m_iterexp = m_iterexp + exp(-cabs(pz)) else m_iterexp = m_iterexp + exp(-1/(cabs(m_zold - pz))) endif m_zold = pz endfunc ; override the parent and call in the final section of the coloring formula.
float func ResultIndex(complex pz) return 0.01*m_iterexp + ptexture*@txamt endfunc protected: float ptexture TrapShape m_Texture float m_iterexp complex m_zold default: title = "Exponential Smoothing Gradient" int param v_exponentialsmoothinggrad caption = "Version (Exponential Smoothing Gradient)" 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_exponentialsmoothinggrad < 100 endparam heading text = "This is a direct gradient formula with textures" endheading param converge caption = "Fractal Type" default = 1 enum = "Convergent" "Divergent" hint = "Mandelbrot is Divergent, Newton is Convergent." endparam float param txamt caption = "Texture amount" default = 0.0 visible = @fTexture != DMJ_TrapShapeFlat endparam heading text = "The 'Tile method' applies to textures. Fixed Iteration \ will give a smoother tiling, while 'Cabs(z)' will more consistently \ follow the fractal shape." visible = @fTexture != DMJ_TrapShapeFlat endheading param mtile caption = "Tile method" default = 1 enum = "None" "Fixed Iteration" "Cabs(z)" visible = @fTexture != DMJ_TrapShapeFlat endparam int param iternum caption = "Iter number" default = 1 visible = @mtile == "Fixed iteration" && @fTexture != DMJ_TrapShapeFlat hint = "Changes the texture/image mapping." endparam float param tcabs caption = "Cabs limit" default = 1.0 visible = @mtile == "Cabs(z)" hint = "Changes the texture/image mapping." visible = @fTexture != DMJ_TrapShapeFlat endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam } class REB_GeneralSmoothingGradient(common.ulb:GradientColoring) { ; A smoothing algorithm that works for both convergent and divergent fractals.
public: import "common.ulb" import "dmj5.ulb" ; constructor func REB_GeneralSmoothingGradient(Generic pparent) GradientColoring.GradientColoring(pparent) m_Texture = new @ftexture(this) endfunc ; initialize the objects func Init(complex pz, complex ppixel) GradientColoring.Init(pz, ppixel) m_Texture.Init(pz) m_iterexp = 0 m_zold = pz endfunc ; call for each iterated point func Iterate(complex pz) GradientColoring.Iterate(pz) m_iterexp = m_iterexp + exp(-cabs(pz)-0.5/(cabs(m_zold - pz))) if (@mtile == "Fixed Iteration" && m_iterations == @iternum) || \ (@mtile == "Cabs(z)" && cabs(pz) < @tcabs)|| @mtile == "none" ptexture = m_Texture.Iterate(pz) endif m_zold = pz endfunc ; override the parent and call in the final section of the coloring formula.
float func ResultIndex(complex pz) return 0.2*m_iterexp + ptexture*@txamt endfunc protected: float ptexture TrapShape m_Texture float m_iterexp complex m_zold default: title = "General Smoothing Gradient" int param v_generalsmoothinggrad caption = "Version (General Smoothing Gradient)" 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_generalsmoothinggrad < 100 endparam heading text = "This is a gradient coloring formula with textures which works \ for both convergent and divergent \ fractals. It is highly recommended that the divergent bailout be \ set to at least 1e8 and the convergent bailout be set to no more than \ 1e-8. If this is not done then the smoothing may be unsatisfactory. \ It works with fractals that have both divergent and convergent regions, \ such as the Magnet fractals." endheading float param txamt caption = "Texture amount" default = 0.0 visible = @fTexture != DMJ_TrapShapeFlat endparam heading text = "Fixed Iteration will give a smoother tiling, while 'Cabs(z)' \ will more consistently follow the fractal shape." visible = @fTexture != DMJ_TrapShapeFlat endheading param mtile caption = "Tile method" default = 1 enum = "None" "Fixed Iteration" "Cabs(z)" visible = @fTexture != DMJ_TrapShapeFlat endparam int param iternum caption = "Iter number" default = 1 hint = "Changes the texture mapping." visible = @fTexture != DMJ_TrapShapeFlat && \ @mtile == "Fixed iteration" endparam float param tcabs caption = "Cabs limit" default = 1.0 visible = @mtile == "Cabs(z)" hint = "Changes the texture/image mapping." visible = @fTexture != DMJ_TrapShapeFlat endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam } class REB_DistanceEstimateGradient(common.ulb:GradientColoring) { ; A smoothing algorithm that works for both convergent and divergent fractals.
public: import "common.ulb" import "dmj5.ulb" ; constructor func REB_DistanceEstimateGradient(Generic pparent) GradientColoring.GradientColoring(pparent) m_Texture = new @ftexture(this) endfunc ; initialize the objects func Init(complex pz, complex ppixel) GradientColoring.Init(pz, ppixel) m_Texture.Init(pz) m_iterexp = 0 m_zold = pz dist = 0 pot = 0 grad = 0 inc = 0 endfunc ; call for each iterated point func Iterate(complex pz) GradientColoring.Iterate(pz) m_iterexp = m_iterexp + exp(-cabs(pz)-0.5/(cabs(m_zold - pz))) inc = exp(-cabs(pz)-0.5/(cabs(m_zold - pz))) if (@mtile == "Fixed Iteration" && m_iterations == @iternum) || \ (@mtile == "Cabs(z)" && cabs(pz) < @tcabs)|| @mtile == "none" ptexture = m_Texture.Iterate(pz) endif m_zold = pz endfunc ; override the parent and call in the final section of the coloring formula.
float func ResultIndex(complex pz) pot = exp(-m_iterexp*log(2)) grad = exp(-inc*log(2))*@gradcorr dist = sinh(pot)/(2*exp(pot)*grad) float returnval = 0 if @showborder if dist < @border returnval = ptexture*@txamt else m_solid = true endif else returnval = dist + ptexture*@txamt endif return returnval endfunc protected: float ptexture TrapShape m_Texture float m_iterexp complex m_zold float dist float inc float pot float grad default: title = "Distance Estimate Gradient" int param v_distanceestimategrad caption = "Version (Distance Estimate Gradient)" 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_distanceestimategrad < 100 endparam heading text = "This is a gradient coloring formula with textures which works \ for both convergent and divergent \ fractals. It is highly recommended that the divergent bailout be \ set to at least 1e8 and the convergent bailout be set to no more than \ 1e-8. If this is not done then the smoothing may be unsatisfactory. \ It works with fractals that have both divergent and convergent regions, \ such as the Magnet fractals." endheading float param gradcorr caption = "Gradient Correction" default = 1.0 endparam bool param showborder caption = "Show border only" default = false endparam float param border caption = "borderwidth" default = 0.01 visible = @showborder endparam float param txamt caption = "Texture amount" default = 0.0 visible = @fTexture != DMJ_TrapShapeFlat endparam heading text = "Fixed Iteration will give a smoother tiling, while 'Cabs(z)' \ will more consistently follow the fractal shape." visible = @fTexture != DMJ_TrapShapeFlat endheading param mtile caption = "Tile method" default = 1 enum = "None" "Fixed Iteration" "Cabs(z)" visible = @fTexture != DMJ_TrapShapeFlat endparam int param iternum caption = "Iter number" default = 1 hint = "Changes the texture mapping." visible = @fTexture != DMJ_TrapShapeFlat && \ @mtile == "Fixed iteration" endparam float param tcabs caption = "Cabs limit" default = 1.0 visible = @mtile == "Cabs(z)" hint = "Changes the texture/image mapping." visible = @fTexture != DMJ_TrapShapeFlat endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam } class REB_FibersThings_Gradient(common.ulb:GradientColoring) { ; Based upon the divergent formula code of Jussi Härkönen, but for convergent formulas.
;

; Gradient Coloring method that looks like triange inequality average ; or curvature average but which works specifically for convergent ; fractals like Cayley Julia and Cayley Mandelbrot. The smoothing code is ; modified from Linas Vepstas and Damien Jones. Some of the code ideas came ; from the work of Jussi Härkönen. Corrections to the fractional iteration ; count made by Jussi Härkönen. The class supports trapshape textures and ; colortrap coloring, including image import. public: import "common.ulb" import "dmj5.ulb" ; constructor func REB_FibersThings_Gradient(Generic pparent) GradientColoring.GradientColoring(pparent) m_Texture = new @ftexture(this) endfunc ; initialize the objects func Init(complex pz, complex ppixel) GradientColoring.Init(pz, ppixel) m_Texture.Init(pz) ci = (0,1) rot = ci^(@ang/90) skew = ci^(@skew/90) prot = ci^(@prot/90) z2 = 0 zold = (0,0) zold2 = (0,0) i = 0 a = 0 a2 = 0 f = 0 ztype = (0,0) if @zmod == "point" || @zmod == "rot point" ztype = @spoint endif power = 0 endfunc func Iterate(complex pz) GradientColoring.Iterate(pz) if (@mtile == "Fixed Iteration" && m_iterations == @iternum) || \ (@mtile == "Cabs(z)" && @bailout < 1 && cabs(zold-pz) > @tcabs) || \ (@mtile == "Cabs(z)" && @bailout > 1 && cabs(pz) < @tcabs) || @mtile == "None" ptexture = m_Texture.Iterate(pz) endif a2 = a if @flavor != "smooth" z2 = real(pz)*skew + flip(imag(pz)) z2 = z2*rot else z2 = pz endif if @zmod == "rot point" && |ztype| != 0 ztype = ztype*prot endif if @flavor == "Standard" a = a + cabs(fn1(@density*(atan2(fn2(z2-zold-ztype)))+@colorshift*#pi)) elseif @flavor == "Curvature" a = a + cabs(fn1(@density*(atan2(fn2((z2-zold)/(zold-zold2)-ztype)))+@colorshift*#pi)) elseif @flavor == "Decomposition" a = a + cabs(fn1(@density*(atan2(fn2(z2-ztype)))+@colorshift*#pi)) elseif @flavor == "Decomp multiply" a = a + cabs(fn1(@density*(atan2(fn2(z2*zold-ztype)))+@colorshift*#pi)) elseif @flavor == "Decomp divide" a = a + cabs(fn1(@density*(atan2(fn2(z2/zold-ztype)))+@colorshift*#pi)) elseif @flavor == "Magnitude" a = a + cabs(fn1(@density*(cabs(fn2(z2-ztype)))+@colorshift*#pi)) elseif @flavor == "Magnitude 2" a = a + cabs(fn1(@density*(cabs(fn2(z2-zold-ztype)))+@colorshift*#pi)) elseif @flavor == "Magnitude 3" a = a + cabs(fn1(@density*(|fn2(z2-ztype)|)+@colorshift*#pi)) elseif @flavor == "Magnitude 4" a = a + cabs(fn1(@density*(|fn2(z2-zold-ztype)|)+@colorshift*#pi)) endif zold2 = zold zold = z2 i = i + 1 endfunc float func ResultIndex(complex pz) power = log(|pz - zold|) / log(|zold - zold2|) z2 = real(pz)*skew + flip(imag(pz)) z2 = z2*rot f = (log(log(@bailout)) - log(log(1/(|(zold - z2)|))))/log(power) a = a/i a2 = a2/(i-1) if @flavor == "Smooth" return (0.05*(m_iterations+f) + ptexture*@txamt) else return (a2 + (a-a2)*(f+1) + ptexture*@txamt) endif endfunc protected: TrapShape m_Texture float ptexture complex ci complex rot complex skew complex prot complex z2 complex zold complex zold2 int i float a float a2 float f complex ztype float power default: title = "Fibers and Things Gradient" int param v_fibersandthingsgrad caption = "Version (Fibers And Things)" 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_fibersandthingsgrad < 100 endparam heading text = "This coloring method was designed for use with convergent fractals. \ It was specifically designed for the convergent formulas in reb.ufm \ and may not work with all convergent fractals. The bailout should \ be the same for both the coloring formula and the ufm. Some coding ideas \ came from the work of Jussi Härkönen as did corrections \ to the convergent smoothing algorithm." endheading param bailout caption = "bailout" default = 1e-12 endparam param flavor caption = "flavor" default = 0 enum = "standard" "curvature" "decomposition" "decomp multiply" \ "decomp divide" "magnitude" "magnitude 2" "magnitude 3" \ "magnitude 4" "smooth" endparam param zmod caption ="z modifier" enum = "none" "point" "rot point" default = 0 visible = @flavor != "smooth" endparam float param prot caption = "point rotation" default = 0 visible = @flavor != "smooth"&&@zmod == "rot point" endparam complex param spoint caption = "point val" default = (1,-1) visible = @flavor != "smooth"&&(@zmod == "point" || @zmod == "rot point") endparam float param ang caption ="z rotation" default = 0 visible = @flavor != "smooth" endparam float param skew caption ="z skew" default = 0 visible = @flavor != "smooth" endparam func fn1 caption = "fiber function #1" default = cos() visible = @flavor != "smooth" endfunc func fn2 caption = "fiber function #2" default = ident() visible = @flavor != "smooth" endfunc complex param density caption = "fiber density" default = 10.0 visible = @flavor != "smooth" endparam float param colorshift caption = "color shift" default = 0.0 min = 0 max = 1 visible = @flavor != "smooth" endparam float param txamt caption = "Texture amount" default = 0.0 visible = @fTexture != DMJ_TrapShapeFlat endparam heading text = "The 'Tile method' applies to both textures and images. Fixed Iteration \ will give a smoother tiling, while 'Cabs(z)' will more consistently \ follow the fractal shape." visible = @fTexture != DMJ_TrapShapeFlat endheading param mtile caption = "Tile method" default = 1 enum = "None" "Fixed Iteration" "Cabs(z)" visible = @fTexture != DMJ_TrapShapeFlat endparam int param iternum caption = "Iter number" default = 1 hint = "Changes the texture/image mapping." visible = @fTexture != DMJ_TrapShapeFlat && @mtile == "Fixed iteration" endparam float param tcabs caption = "Cabs limit" default = 0.5 visible = @mtile == "Cabs(z)" hint = "Changes the texture/image mapping." visible = @fTexture != DMJ_TrapShapeFlat endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam } class REB_Emboss(common.ulb:DirectColoring) { ; Modified from the code of Kerry Mitchell.
public: import "common.ulb" import "dmj5.ulb" ; constructor func REB_Emboss(Generic pparent) DirectColoring.DirectColoring(pparent) m_Texture = new @ftexture(this) m_MergeColor = new @f_colormerge(0) m_TrapColor = new @f_trapcolor(this) endfunc ; initialize the objects func Init(complex pz, complex ppixel) DirectColoring.Init(pz, ppixel) m_Texture.Init(pz) m_TrapColor.Init(pz) m_empty = true ptexture = 0 endfunc ; call for each iterated point func Iterate(complex pz) DirectColoring.Iterate(pz) if (@mtile == "Fixed Iteration" && m_iterations == @iternum) || \ (@mtile == "Cabs(z)" && cabs(pz) < @tcabs)|| @mtile == "none" ptexture = m_Texture.Iterate(pz) if @f_trapcolor == ColorTrapNoColor m_empty = true else m_color = m_TrapColor.Iterate(pz) m_empty = false endif endif endfunc ; override the parent and call in the final section of the coloring formula.
color func Result(complex pz) color return_color = rgba(0,0,0,0) if(real(pz) 1 rd = 1 endif if gr > 1 gr = 1 endif if bl > 1 bl = 1 endif if rd < 0 rd = 0 endif if gr < 0 gr = 0 endif if bl < 0 bl = 0 endif return_color = rgba(rd,gr,bl,alpha(return_color)) rd = red(return_color)^cr gr = green(return_color)^cr bl = blue(return_color)^cr return_color = rgba(rd,gr,bl,alpha(return_color)) float satval = sat(return_color)-st if satval > 1 satval = 1 endif if satval < 0 satval = 0 endif return_color = hsla(hue(return_color), satval, lum(return_color), alpha(return_color)) float hueval = (hue(return_color)+hu) % 6 return_color = hsla(hueval, sat(return_color), lum(return_color), alpha(return_color)) if @p_poster float rd = floor(red(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float gr = floor(green(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float bl = floor(blue(return_color)*@p_chan)/@p_chan + 0.5/@p_chan return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_gray float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) return_color = rgba(gry,gry,gry,alpha(return_color)) endif if @p_solar float rd = red(return_color) float gr = green(return_color) float bl = blue(return_color) if rd > @p_thresh rd = 1-rd endif if gr > @p_thresh gr = 1-gr endif if bl > @p_thresh bl = 1-bl endif return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_bw float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) if gry < @p_bwt return_color = rgba(0,0,0,alpha(return_color)) else return_color = rgba(1,1,1,alpha(return_color)) endif endif return return_color endfunc protected: float ptexture TrapShape m_Texture ImageImport m_img bool m_empty color m_color ColorTrap m_TrapColor DefaultColorMerge m_MergeColor default: title = "Emboss with Textures" int param v_embosswithtexture caption = "Version (Emboss With Textures)" 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_embosswithtexture < 100 endparam heading text = "This is a direct coloring formula with textures and image import \ capabilities that is intended for use with emboss formulas." endheading float param txamt caption = "Texture amount" default = 0.0 visible = @fTexture != DMJ_TrapShapeFlat endparam heading text = "The 'Tile method' applies to both textures and images. Fixed Iteration \ will give a smoother tiling, while 'Cabs(z)' will more consistently \ follow the fractal shape." visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endheading param mtile caption = "Tile method" default = 1 enum = "None" "Fixed Iteration" "Cabs(z)" visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endparam int param iternum caption = "Iter number" default = 1 hint = "Changes the texture/image mapping." visible = (@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) && \ @mtile == "Fixed iteration" endparam float param tcabs caption = "Cabs limit" default = 1.0 visible = @mtile == "Cabs(z)" hint = "Changes the texture/image mapping." visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam heading caption = "Images and Colorings" endheading ColorTrap param f_trapcolor caption = "Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." endparam DefaultColorMerge param f_colormerge caption = "Color Merge" default = DefaultColorMerge visible = @f_trapcolor != ColorTrapNoColor endparam param nmerge caption = "Merge order" default = 0 enum = "Image on Top" "Image on Bottom" visible = @f_trapcolor != ColorTrapNoColor endparam float param opacity caption = "Merge Opacity" default = 0.2 visible = @f_trapcolor != ColorTrapNoColor endparam heading text = "Make image transparent by: " visible = @f_trapcolor != ColorTrapNoColor endheading bool param ahue caption = "Hue value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam bool param alum caption = "Luminance value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam bool param asat caption = "Saturation value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam heading caption = "Special Effects" endheading float param p_bright caption = "Brightness" default = 0.5 min = 0 max = 1 endparam float param p_contrast caption = "Contrast" default = 0.5 min = 0 max = 1 endparam float param p_sat caption = "Saturation" default = 0.5 min = 0 max = 1 endparam float param p_hue caption = "Hue" default = 0.0 min = 0 max = 1 endparam bool param p_gray caption = "Grayscale" default = false endparam bool param p_solar caption = "Solarize" default = false endparam float param p_thresh caption = "Threshold" default = 0.5 endparam bool param p_poster caption = "Posterize" default = false endparam int param p_chan caption = "Colors per channel" default = 4 min = 2 visible = @p_poster endparam bool param p_bw caption = "Black and White" default = false endparam float param p_bwt caption = "Threshold" default = 0.5 min = 0 max = 1 endparam } class REB_GaussianInteger(common.ulb:DirectColoring) { ; Modified from the code of Kerry Mitchell.
public: import "common.ulb" import "dmj5.ulb" ; constructor func REB_GaussianInteger(Generic pparent) DirectColoring.DirectColoring(pparent) fTransform = new @transform(this) m_Texture = new @ftexture(this) m_MergeColor = new @f_colormerge(0) m_TrapColor = new @f_trapcolor(this) endfunc ; initialize the objects func Init(complex pz, complex ppixel) DirectColoring.Init(pz, ppixel) fTransform.init(pz) m_Texture.Init(pz) m_TrapColor.Init(pz) m_empty = true ptexture = 0 r=0.0 rmin=1.0e12 rmax=0.0 rave=0.0 total=0.0 t=0.0 iter=0 itermin=0 itermax=0 zmin=(0.0,0.0) zmax=(0.0,0.0) if(@norm==1) ; pixel normalization normfac=ppixel elseif(@norm==2) ; factor normalization normfac=@fac elseif(@norm==3) ; f(z) normalization normfac=@normfunc(pz) else ; no normalization normfac=(1.0,0.0) endif logfac=@logseed endfunc ; call for each iterated point func Iterate(complex pz) DirectColoring.Iterate(pz) iter=iter+1 complex m_zr = fTransform.Iterate(pz) complex temp2=pz+@fstren1*m_zr if @randomize logfac=4*logfac*(1-logfac) temp2=temp2*(1-@randomsize*logfac) endif if(@inttype==1) ; trunc temp=trunc(temp2/normfac) elseif(@inttype==2) ; floor temp=floor(temp2/normfac) elseif(@inttype==3) ; ceil temp=ceil(temp2/normfac) else ; round temp=round(temp2/normfac) endif remain=temp2-temp*normfac r=cabs(remain) total=total+r rave=total/iter if(rrmax) rmax=r zmax=temp2 itermax=iter endif if (@mtile == "Fixed Iteration" && m_iterations == @iternum) || \ (@mtile == "Cabs(z)" && cabs(pz) < @tcabs)|| @mtile == "none" ptexture = m_Texture.Iterate(pz) if @f_trapcolor == ColorTrapNoColor m_empty = true else m_color = m_TrapColor.Iterate(pz) m_empty = false endif endif endfunc ; override the parent and call in the final section of the coloring formula.
color func Result(complex pz) color return_color = rgba(0,0,0,0) if(@colorby==1) ; iteration @ min return_color=gradient(0.01*itermin + ptexture*@txamt) elseif(@colorby==2) ; angle @ min t=atan2(zmin) t=t/pi if(t<0.0) t=t+2.0 endif return_color=gradient(0.5*t + ptexture*@txamt) elseif(@colorby==3) ; maximum distance return_color=gradient(rmax + ptexture*@txamt) elseif(@colorby==4) ; iteration @ max return_color=gradient(0.01*itermax + ptexture*@txamt) elseif(@colorby==5) ; angle @ max t=atan2(zmax) t=t/pi if(t<0.0) t=t+2.0 endif return_color=gradient(0.5*t + ptexture*@txamt) elseif(@colorby==6) ; average distance return_color=gradient(rave + ptexture*@txamt) elseif(@colorby==7) ; min/mean/max angle zmax=(rave-rmin)+flip(rmax-rave) t=atan2(zmax) t=t/pi if(t<0.0) t=t+2.0 endif return_color=gradient(0.5*t + ptexture*@txamt) elseif(@colorby==8) ; max/min ratio return_color=gradient(rmax/(rmin+1.e-12) + ptexture*@txamt) else ; minimum distance return_color=gradient(rmin + ptexture*@txamt) endif if @ahue m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ hue(m_color)/6*alpha(m_color)) endif if @alum m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ lum(m_color)*alpha(m_color)) endif if @asat m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ sat(m_color)*alpha(m_color)) endif color temp = rgba(0,0,0,0) if !m_empty if @nmerge == 1 temp = m_color m_color = return_color return_color = temp endif return_color = m_MergeColor.FullMerge(return_color, m_color, @opacity) endif float br = (0.5-@p_bright)*2 int sign = 0 if br < 0 sign = -1 else sign = 1 endif br = br^2*sign float cr = (@p_contrast-0.5)*2 if cr < 0 sign = -1 else sign = 1 endif cr = cr^2*sign+1 float st = (0.5-@p_sat)*2 if st < 0 sign = -1 else sign = 1 endif st = st^2*sign*2 float hu = @p_hue*6 float rd = red(return_color)-br float gr = green(return_color)-br float bl = blue(return_color)-br if rd > 1 rd = 1 endif if gr > 1 gr = 1 endif if bl > 1 bl = 1 endif if rd < 0 rd = 0 endif if gr < 0 gr = 0 endif if bl < 0 bl = 0 endif return_color = rgba(rd,gr,bl,alpha(return_color)) rd = red(return_color)^cr gr = green(return_color)^cr bl = blue(return_color)^cr return_color = rgba(rd,gr,bl,alpha(return_color)) float satval = sat(return_color)-st if satval > 1 satval = 1 endif if satval < 0 satval = 0 endif return_color = hsla(hue(return_color), satval, lum(return_color), alpha(return_color)) float hueval = (hue(return_color)+hu) % 6 return_color = hsla(hueval, sat(return_color), lum(return_color), alpha(return_color)) if @p_poster float rd = floor(red(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float gr = floor(green(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float bl = floor(blue(return_color)*@p_chan)/@p_chan + 0.5/@p_chan return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_gray float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) return_color = rgba(gry,gry,gry,alpha(return_color)) endif if @p_solar float rd = red(return_color) float gr = green(return_color) float bl = blue(return_color) if rd > @p_thresh rd = 1-rd endif if gr > @p_thresh gr = 1-gr endif if bl > @p_thresh bl = 1-bl endif return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_bw float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) if gry < @p_bwt return_color = rgba(0,0,0,alpha(return_color)) else return_color = rgba(1,1,1,alpha(return_color)) endif endif return return_color endfunc protected: float ptexture TrapShape m_Texture ImageImport m_img bool m_empty color m_color ColorTrap m_TrapColor DefaultColorMerge m_MergeColor UserTransform fTransform float r float rmin float rmax float rave float total float t int iter int itermin int itermax complex zmin complex zmax float logfac complex normfac default: title = "Gaussian Integer with Textures" int param v_GaussianIntegerwithtexture caption = "Version (Gaussian Integer With Textures)" 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_GaussianIntegerwithtexture < 100 endparam heading text = "This is a direct coloring formula with textures and image import \ capabilities." endheading UserTransform param transform caption = "Pre-transform" default = NullTransform expanded = false endparam float param fstren1 caption = "Transform strength" default = 0.25 visible = @transform != NullTransform endparam param inttype caption="Integer Type" default=0 enum="round(z)" "trunc(z)" "floor(z)" "ceil(z)" hint="Selects between four ways of reducing the orbit value z to an \ integer. Each will produce different effects." endparam param colorby caption="Color By" default=0 enum="minimum distance" "iteration @ min" "angle @ min" \ "maximum distance" "iteration @ max" "angle @ max" "average distance"\ "min/mean/max angle" "max/min ratio" hint="Selects what information from the fractal calculation is used to \ calculate the color of each point." endparam param norm caption="Normalization" default=0 enum="none" "pixel" "factor" "f(z)" hint="Selects an optional normalization algorithm that is applied to the \ integer values." endparam param fac caption=" Factor" default=(2.0,1.0) visible = @norm == "factor" hint="Specifies the normalization factor that is used if Normalization is \ set to 'factor'." endparam func normfunc caption=" Function" default=ident() hint="Selects the normalization function that is used if Normalization is \ set to 'f(z)'." visible = @norm == "f(z)" endfunc param randomize caption="Randomize" default=false hint="If checked, a random factor is applied to z at every iteration \ before finding the Gaussian integer." endparam param randomsize caption="Random Size" default=(0.1,0) hint="Specifies the size of the random factor to use if Randomize is \ checked. Larger values give more randomization." visible = @randomize endparam param logseed caption="Random Seed" default=0.1 min=0.0 max=1.0 hint="Specifies the randomization seed, between 0 and 1, to use if \ Randomize is checked. Every seed gives a different image." visible = @randomize endparam float param txamt caption = "Texture amount" default = 0.0 visible = @fTexture != DMJ_TrapShapeFlat endparam heading text = "The 'Tile method' applies to both textures and images. Fixed Iteration \ will give a smoother tiling, while 'Cabs(z)' will more consistently \ follow the fractal shape." visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endheading param mtile caption = "Tile method" default = 1 enum = "None" "Fixed Iteration" "Cabs(z)" visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endparam int param iternum caption = "Iter number" default = 1 hint = "Changes the texture/image mapping." visible = (@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) && \ @mtile == "Fixed iteration" endparam float param tcabs caption = "Cabs limit" default = 1.0 visible = @mtile == "Cabs(z)" hint = "Changes the texture/image mapping." visible = @fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam heading caption = "Images and Colorings" endheading ColorTrap param f_trapcolor caption = "Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." endparam DefaultColorMerge param f_colormerge caption = "Color Merge" default = DefaultColorMerge visible = @f_trapcolor != ColorTrapNoColor endparam param nmerge caption = "Merge order" default = 0 enum = "Image on Top" "Image on Bottom" visible = @f_trapcolor != ColorTrapNoColor endparam float param opacity caption = "Merge Opacity" default = 0.2 visible = @f_trapcolor != ColorTrapNoColor endparam heading text = "Make image transparent by: " visible = @f_trapcolor != ColorTrapNoColor endheading bool param ahue caption = "Hue value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam bool param alum caption = "Luminance value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam bool param asat caption = "Saturation value" default = false visible = @f_trapcolor != ColorTrapNoColor endparam heading caption = "Special Effects" endheading float param p_bright caption = "Brightness" default = 0.5 min = 0 max = 1 endparam float param p_contrast caption = "Contrast" default = 0.5 min = 0 max = 1 endparam float param p_sat caption = "Saturation" default = 0.5 min = 0 max = 1 endparam float param p_hue caption = "Hue" default = 0.0 min = 0 max = 1 endparam bool param p_gray caption = "Grayscale" default = false endparam bool param p_solar caption = "Solarize" default = false endparam float param p_thresh caption = "Threshold" default = 0.5 endparam bool param p_poster caption = "Posterize" default = false endparam int param p_chan caption = "Colors per channel" default = 4 min = 2 visible = @p_poster endparam bool param p_bw caption = "Black and White" default = false endparam float param p_bwt caption = "Threshold" default = 0.5 min = 0 max = 1 endparam } class REB_LineArt_Gradient(common.ulb:GradientColoring) { ; Based on the original 2007 algorithm of Ron Barnett.
;

public: import "common.ulb" ; constructor func REB_LineArt_Gradient(Generic pparent) GradientColoring.GradientColoring(pparent) m_fnc = new @fnc(0) x = m_fnc.x y = m_fnc.y z = m_fnc.z use = m_fnc.use asize = m_fnc.asize zmax = m_fnc.zmax zmin = m_fnc.zmin k = m_fnc.k endfunc ; initialize the objects func Init(complex pz, complex ppixel) GradientColoring.Init(pz, ppixel) setlength(t,asize) setlength(r,asize) rt = 0 pt2 = 0 pt1 = 0 ii = 0 xx = 0 yy = 0 rtmax = -1e100 endfunc ; override the parent and call in the final section of the coloring formula.
float func ResultIndex(complex pz) ; ; Determine if the pixel is on a line ; float idx = 0 ii = 0 repeat if use.m_elements[ii] pt1 = x.m_elements[ii] + flip(y.m_elements[ii]) pt2 = x.m_elements[ii+1] + flip(y.m_elements[ii+1]) t[ii]=(pz-pt1)/(pt2-pt1) xx=real(t[ii]) yy=imag(t[ii]) if(xx<0.0) r[ii]=sqr(xx)+sqr(yy) elseif(xx>1.0) r[ii]=sqr(xx-1.0)+sqr(yy) else r[ii]=sqr(yy) endif r[ii]=sqrt(r[ii])*cabs(pt2-pt1) if @colormode == "By side" t[ii] = (ii+1)/(k+1) elseif @colormode == "By z value" t[ii] = (z.m_elements[ii]-zmin)/(zmax-zmin)+0.01 endif else t[ii] = 0 r[ii] = 0 endif ii = ii + 1 until ii == k ii = 0 ; ; Load rt with color values ; repeat if r[ii] < @thick && r[ii] != 0 rt = cabs(t[ii]) endif if rt > rtmax rtmax = rt endif ii = ii + 1 until ii == k rt = rtmax ; ; Color the lines ; if rt != 0 if @colormode != "Solid" idx = rt else idx = @gradval endif else m_solid = true endif return idx endfunc protected: ThreeD m_fnc FloatArray x FloatArray y FloatArray z BooleanArray use complex t[] float r[] float rt complex pt2 complex pt1 int ii float xx float yy int asize int k float zmax float zmin float rtmax default: title = "Line Art (Gradient)" int param v_lineartgrad caption = "Version (Line Art (Gradient))" 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_lineartgrad < 100 endparam heading text = "This formula plots 3D formulas in a wire mesh format. Several coloring \ options are available. The 3D formulas are available as object plugins." endheading ThreeD param fnc caption = "3D Function" default = AstroidalEllipsoid endparam float param thick caption = "Curve width" default = 0.005 endparam param colormode caption = "Color mode" default = 3 enum = "Solid" "Use gradient" "By side" "By z value" endparam float param gradval caption = "Grad val (0-1)" default = 0.5 visible = @colormode == "Solid" endparam } ;------------------------------------------- ; Line Art Plugins ;------------------------------------------- ; references for 3D surfaces: ; www.3d-meier.de ; www.mathcurve.com ; mathworld.wolfram.com ; local.wasp.uwa.edu.au/~pbourke/geometry ; www.atlantis23.com/ei_parmsurf/parametricsurfaces_catalog.html class ThreeD(generic) { public: import "common.ulb" ; constructor func ThreeD(Generic pparent) Generic.Generic(pparent) asize = @asize x = new FloatArray(asize) y = new FloatArray(asize) z = new FloatArray(asize) use = new BooleanArray(asize) zmin = 1e100 zmax = -1e100 endfunc FloatArray x FloatArray y FloatArray z BooleanArray use int asize float zmin float zmax int k protected: int i int j int l float u float v float ru float rv float sr float kr int xlimit int ylimit float umin float vmin float ustep float vstep int outlimit int inlimit float scale default: int param v_threed caption = "Version (threed)" 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_threed < 100 endparam int param asize caption = "Array size" default = 1000000 endparam } class AstroidalEllipsoid(ThreeD) { public: import "common.ulb" ; constructor func AstroidalEllipsoid(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (@aa*cos(u)*cos(v))^3*scale y.m_elements[k] = (@ab*sin(u)*cos(v))^3*scale z.m_elements[k] = (@ac*sin(v))^3*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Astroidal Ellipsoid" int param v_astroidalellipseoid caption = "Version (Astroidal Ellipseoid)" 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_astroidalellipseoid < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1.8 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam float param aa caption = "param a" default = 1.0 endparam float param ab caption = "param b" default = 1.0 endparam float param ac caption = "param c" default = 1.0 endparam } class AntisymmetricTorus(ThreeD) { public: import "common.ulb" ; constructor func AntisymmetricTorus(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (@r1 + @r2*cos(v)*(@a + sin(u)))*cos(u)*scale y.m_elements[k] = (@r1 + @r2*cos(v)*(@a + sin(u)))*sin(u)*scale z.m_elements[k] = @r2*sin(v)*(@a + sin(u))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Antisymmetric Torus" int param v_AntisymmetricTorus caption = "Version (Antisymmetric Torus)" 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_AntisymmetricTorus < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.2 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam float param a caption = "param a" default = 1.5 endparam float param r1 caption = "radius #1" default = 5.0 endparam float param r2 caption = "radius #2" default = 1.0 endparam } class TurnedEightTorus(ThreeD) { public: import "common.ulb" ; constructor func TurnedEightTorus(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = ((@r1+@r2*(cos(u/2)*sin(v)-sin(u/2)*sin(2*v)))*cos(u))*scale y.m_elements[k] = ((@r1+@r2*(cos(u/2)*sin(v)-sin(u/2)*sin(2*v)))*sin(u))*scale z.m_elements[k] = (@r2*(sin(u/2)*sin(v) + cos(u/2)*sin(2*v)))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Turned Eight Torus" int param v_TurnedEightTorus caption = "Version (Turned Eight Torus)" 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_TurnedEightTorus < 100 endparam float param xang caption = "X rotation" default = -60 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.3 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam float param r1 caption = "radius #1" default = 5.0 endparam float param r2 caption = "radius #2" default = 1.0 endparam } class Drop(ThreeD) { public: import "common.ulb" ; constructor func Drop(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = @a*(@b - cos(u))*sin(u)*cos(v)*scale y.m_elements[k] = @a*(@b - cos(u))*sin(u)*sin(v)*scale z.m_elements[k] = cos(u)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Drop" int param v_Drop caption = "Version (Drop)" 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_Drop < 100 endparam float param xang caption = "X rotation" default = 90 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 1.25 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam float param a caption = "param a" default = 0.5 endparam float param b caption = "param b" default = 1.0 endparam } class Pillow(ThreeD) { public: import "common.ulb" ; constructor func Pillow(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = cos(u)*scale y.m_elements[k] = cos(v)*scale z.m_elements[k] = @a*sin(u)*sin(v)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Pillow" int param v_Pillow caption = "Version (Pillow)" 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_Pillow < 100 endparam float param xang caption = "X rotation" default = -30 endparam float param yang caption = "Y rotation" default = 20 endparam float param fscale caption = "Scale" default = 1.25 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam float param a caption = "param a" default = 1.0 endparam } class Seashell2(ThreeD) { public: import "common.ulb" ; constructor func Seashell2(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif float h = exp(u/(6*#pi)) x.m_elements[k] = @a*(1 - h)*cos(u)*cos(0.5*v)^2*scale y.m_elements[k] = ((1 - exp(u/(@b*#pi)) - sin(v) + h*sin(v))+3.75)*scale z.m_elements[k] = @a*(-1 + h)*sin(u)*cos(0.5*v)^2*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Seashell #2" int param v_Seashell2 caption = "Version (Seashell #2)" 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_Seashell2 < 100 endparam float param xang caption = "X rotation" default = 0 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.4 endparam float param xmax caption = "Max X" default = 18.84 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.25 endparam float param ystep caption = "Y increment" default = 0.25 endparam float param a caption = "param a" default = 1.0 endparam float param b caption = "param b" default = 3 endparam } class RomanSurface(ThreeD) { public: import "common.ulb" ; constructor func RomanSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (2*u*cos(v)*sqrt(1-u^2))*scale y.m_elements[k] = (2*u*sin(v)*sqrt(1-u^2))*scale z.m_elements[k] = (1-2*u^2*cos(v)^2)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Roman Surface" int param v_RomanSurface caption = "Version (Roman Surface)" 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_RomanSurface < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1.2 endparam float param xmax caption = "Max X" default = 1 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class RichmondSurface(ThreeD) { public: import "common.ulb" ; constructor func RichmondSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (-3*u - u^5 + 2*u^3*v^2 + 3*u*v^4)/(6*(u^2 + v^2))*scale y.m_elements[k] = (-3*v - 3*u^4*v - 2*u^2*v^3 + v^5)/(6*(u^2 + v^2))*scale z.m_elements[k] = u*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; if z.m_elements[k] < zmin ; zmin = z.m_elements[k] ; endif ; if z.m_elements[k] > zmax ; zmax = z.m_elements[k] ; endif zmin = 0 zmax = 1 k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Richmond Surface" int param v_RichmondSurface caption = "Version (RRichmond Surface)" 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_RichmondSurface < 100 endparam float param xang caption = "X rotation" default = 60 endparam float param yang caption = "Y rotation" default = 20 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 1 endparam float param xmin caption = "Min X" default = -1 endparam float param ymax caption = "Max Y" default = 1 endparam float param ymin caption = "Min Y" default = -1 endparam float param xstep caption = "X increment" default = 0.05 endparam float param ystep caption = "Y increment" default = 0.05 endparam } class PluckersConoid(ThreeD) { public: import "common.ulb" ; constructor func PluckersConoid(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (u*sqrt(1-v^2))*scale y.m_elements[k] = u*v*scale z.m_elements[k] = (1-v^2)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Plucker's Conoid" int param v_PluckersConoid caption = "Version (Plucker's Conoid)" 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_PluckersConoid < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 2 endparam float param xmin caption = "Min X" default = -2 endparam float param ymax caption = "Max Y" default = 1 endparam float param ymin caption = "Min Y" default = -1 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class Mandala(ThreeD) { public: import "common.ulb" ; constructor func Mandala(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = u*cos(v)*scale y.m_elements[k] = u*sin(v)*scale z.m_elements[k] = v*cos(u)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Mandala" int param v_mandala caption = "Version (Mandala)" 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_mandala < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.1 endparam float param xmax caption = "Max X" default = 16 endparam float param xmin caption = "Min X" default = -8 endparam float param ymax caption = "Max Y" default = 12.56 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class Wiwianka(ThreeD) { public: import "common.ulb" ; constructor func Wiwianka(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (1+exp(-100*u^2))*sin(#pi*u)*sin(#pi*v)*scale y.m_elements[k] = (1+exp(-100*u^2))*sin(#pi*u)*cos(#pi*v)*scale z.m_elements[k] = (1+exp(-100*u^2))*cos(#pi*u)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Wiwianka" int param v_wiwianka caption = "Version (Wiwianka)" 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_wiwianka < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1.5 endparam float param xmax caption = "Max X" default = 1.0 endparam float param xmin caption = "Min X" default = 0.0 endparam float param ymax caption = "Max Y" default = 2.0 endparam float param ymin caption = "Min Y" default = 0.0 endparam float param xstep caption = "X increment" default = 0.025 endparam float param ystep caption = "Y increment" default = 0.05 endparam } class BanchoffKleinBottle(ThreeD) { public: import "common.ulb" ; constructor func BanchoffKleinBottle(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (cos(u/@banc)*(cos(u/@banb)*(@bana+cos(v))+ \ (sin(u/@banb)*sin(v)*cos(v))))*scale y.m_elements[k] = (sin(u/@banc)*(cos(u/@banb)*(@bana+cos(v))+ \ (sin(u/@banb)*sin(v)*cos(v))))*scale z.m_elements[k] = (-sin(u/@banb)*(@bana+cos(v))+cos(u/@banb)*sin(v)*cos(v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Banchoff Klein Bottle" int param v_BanchoffKleinBottle caption = "Version (Banchoff Klein Bottl)" 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_BanchoffKleinBottle < 100 endparam float param xang caption = "X rotation" default = -90 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.75 endparam float param xmax caption = "Max X" default = 9.56 endparam float param xmin caption = "Min X" default = 0.0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0.0 endparam float param xstep caption = "X increment" default = 0.15 endparam float param ystep caption = "Y increment" default = 0.1 endparam float param bana caption = "Parameter a" default = 1.414213 endparam float param banb caption = "Parameter b" default = 2.0 endparam float param banc caption = "Parameter c" default = 1.0 endparam } class BentHOrns(ThreeD) { public: import "common.ulb" ; constructor func BentHOrns(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = ((2+cos(u))*(v/3-sin(v)))*scale y.m_elements[k] = ((2+cos(u-2*#pi/3))*(cos(v)-1))*scale z.m_elements[k] = ((2+cos(u+2*#pi/3))*(cos(v)-1))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Bent Horns" int param v_BentHOrns caption = "Version (Bent HOrns)" 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_BentHOrns < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.25 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = -6.28 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class BohemianDome(ThreeD) { public: import "common.ulb" ; constructor func BohemianDome(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (@ba*cos(u))*scale y.m_elements[k] = (@bb*cos(v) + @ba*sin(u))*scale z.m_elements[k] = (@bc*sin(v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Bohemian Dome" int param v_BohemianDome caption = "Version (Bohemian Dome)" 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_BohemianDome < 100 endparam float param xang caption = "X rotation" default = -30 endparam float param yang caption = "Y rotation" default = 60 endparam float param fscale caption = "Scale" default = 1.0 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0.0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0.0 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam float param ba caption = "param a" default = 0.5 endparam float param bb caption = "param b" default = 1.5 endparam float param bc caption = "param c" default = 1.0 endparam } class MennsSurface(ThreeD) { public: import "common.ulb" ; constructor func MennsSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = @a*u*scale y.m_elements[k] = @a*v*scale z.m_elements[k] = @a*u^4 + u^2 * v - v^2*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Menns Surface" int param v_MennsSurface caption = "Version (Menns Surface)" 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_MennsSurface < 100 endparam float param xang caption = "X rotation" default = -10 endparam float param yang caption = "Y rotation" default = 60 endparam float param fscale caption = "Scale" default = 1.5 endparam float param xmax caption = "Max X" default = 1 endparam float param xmin caption = "Min X" default = -1 endparam float param ymax caption = "Max Y" default = 1 endparam float param ymin caption = "Min Y" default = -1 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam float param a caption = "param a" default = 1 endparam } class EightSurface(ThreeD) { public: import "common.ulb" ; constructor func EightSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = cos(u)* sin(2*v)*scale y.m_elements[k] = sin(u)* sin(2*v)*scale z.m_elements[k] = sin(v)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Eight Surface" int param v_EightSurface caption = "Version (Eight Surface)" 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_EightSurface < 100 endparam float param xang caption = "X rotation" default = 20 endparam float param yang caption = "Y rotation" default = 60 endparam float param fscale caption = "Scale" default = 1.5 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class KissSurface(ThreeD) { public: import "common.ulb" ; constructor func KissSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = v^2*sqrt((1-v)/2)*cos(u)*scale y.m_elements[k] = v^2*sqrt((1-v)/2)*sin(u)*scale z.m_elements[k] = v*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Kiss Surface" int param v_KissSurface caption = "Version (Kiss Surface)" 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_KissSurface < 100 endparam float param xang caption = "X rotation" default = -60 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 1.5 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 1 endparam float param ymin caption = "Min Y" default = -1 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.05 endparam } class HandkerchiefSurface(ThreeD) { public: import "common.ulb" ; constructor func HandkerchiefSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = u*scale y.m_elements[k] = v*scale z.m_elements[k] = ((1/3)*u^3 + u*v^2 + 2*(u^2-v^2))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Handkerchief Surface" int param v_HandkerchiefSurface caption = "Version (Handkerchief Surface)" 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_HandkerchiefSurface < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 1 endparam float param xmin caption = "Min X" default = -1 endparam float param ymax caption = "Max Y" default = 1 endparam float param ymin caption = "Min Y" default = -1 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class ShoeSurface(ThreeD) { public: import "common.ulb" ; constructor func ShoeSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = u*scale y.m_elements[k] = v*scale z.m_elements[k] = ((1/3)*u^3 - (1/2)*v^2)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Shoe Surface" int param v_ShoeSurface caption = "Version (Shoe Surface)" 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_ShoeSurface < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 2 endparam float param xmin caption = "Min X" default = -2 endparam float param ymax caption = "Max Y" default = 1 endparam float param ymin caption = "Min Y" default = -1 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class Horn(ThreeD) { public: import "common.ulb" ; constructor func Horn(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (2+u*cos(v))*(sin(2*#pi*u))*scale y.m_elements[k] = ((2+u*cos(v))*cos(2*#pi*u)+2*u)*scale z.m_elements[k] = u*sin(v)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Horn" int param v_Horn caption = "Version (Horn)" 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_Horn < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.5 endparam float param xmax caption = "Max X" default = 1 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.025 endparam float param ystep caption = "Y increment" default = 0.4 endparam } class AppleSurface(ThreeD) { public: import "common.ulb" ; constructor func AppleSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (cos(u)*(4 + 3.8*cos(v)))*scale y.m_elements[k] = (sin(u)*(4 + 3.8*cos(v)))*scale z.m_elements[k] = ((cos(v) + sin(v) - 1)+(1 + sin(v))*log(1 - #pi*v / 10) + 7.5*sin(v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Apple Surface" int param v_AppleSurface caption = "Version (Apple Surface)" 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_AppleSurface < 100 endparam float param xang caption = "X rotation" default = -75 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.2 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class BowTie(ThreeD) { public: import "common.ulb" ; constructor func BowTie(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (sin(u)/(sqrt(2)+sin(v)))*scale y.m_elements[k] = (sin(u)/(sqrt(2)+cos(v)))*scale z.m_elements[k] = (cos(u)/(sqrt(2)+1))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Bow Tie" int param v_BowTie caption = "Version (Bow Tie)" 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_BowTie < 100 endparam float param xang caption = "X rotation" default = -45 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.75 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class BoySurface(ThreeD) { public: import "common.ulb" ; constructor func BoySurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = ((2/3)*(cos(u)*cos(2*v)+sqrt(2)*sin(u)*cos(v))*cos(u) \ /(sqrt(2) - sin(2*u)*sin(3*v)))*scale y.m_elements[k] = ((2/3)*(cos(u)*sin(2*v)-sqrt(2)*sin(u)*sin(v))*cos(u) \ /(sqrt(2)-sin(2*u)*sin(3*v)))*scale z.m_elements[k] = (sqrt(2)*cos(u)^2 / (sqrt(2) - sin(2*u)*sin(2*v)))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Boy Surface" int param v_BoySurface caption = "Version (Boy Surface)" 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_BoySurface < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.05 endparam float param ystep caption = "Y increment" default = 0.05 endparam } class CatalansSurface(ThreeD) { public: import "common.ulb" ; constructor func CatalansSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (u-sin(u)*cosh(v))*scale y.m_elements[k] = (1-cos(u)*cosh(v))*scale z.m_elements[k] = (4*sin(u/2)*sinh(v/2))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Catalan's Surface" int param v_CatalansSurface caption = "Version (Catalan's Surface)" 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_CatalansSurface < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.1 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = -6.26 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.15 endparam float param ystep caption = "Y increment" default = 0.075 endparam } class Corkscrew(ThreeD) { public: import "common.ulb" ; constructor func Corkscrew(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (@ta*cos(u)*cos(v))*scale y.m_elements[k] = (@ta*sin(u)*cos(v))*scale z.m_elements[k] = (@ta*sin(v)+@tb*u)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Corkscrew" int param v_Corkscrew caption = "Version (Corkscrew)" 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_Corkscrew < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam float param ta caption = "param a" default = 1.0 endparam float param tb caption = "param b" default = 0.5 endparam } class Cresent(ThreeD) { public: import "common.ulb" ; constructor func Cresent(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = ((2+sin(2*#pi*u)*sin(2*#pi*v))*sin(3*#pi*v))*scale y.m_elements[k] = ((2+sin(2*#pi*u)*sin(2*#pi*v))*cos(3*#pi*v))*scale z.m_elements[k] = (cos(2*#pi*u)*sin(2*#pi*v)+4*v-2)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Cresent" int param v_Cresent caption = "Version (Cresent)" 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_Cresent < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.6 endparam float param xmax caption = "Max X" default = 1 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 1 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.03 endparam float param ystep caption = "Y increment" default = 0.015 endparam } class KinkyTorus(ThreeD) { public: import "common.ulb" ; constructor func KinkyTorus(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (1/cosh(u) - cos(v))*scale y.m_elements[k] = sin(v)*scale z.m_elements[k] = (u / #pi - tanh(u))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Kinky Torus" int param v_KinkyTorus caption = "Version (Kinky Torus)" 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_KinkyTorus < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 70 endparam float param fscale caption = "Scale" default = 1.4 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = -6.28 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class CatenoidMinimalSurface(ThreeD) { public: import "common.ulb" ; constructor func CatenoidMinimalSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (@c*cosh(v/@c)*cos(u))*scale y.m_elements[k] = (@c*cosh(v/@c)*sin(u))*scale z.m_elements[k] = v*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Catenoid Minimal Surface" int param v_CatenoidMinimalSurface caption = "Version (Catenoid Minimal Surface)" 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_CatenoidMinimalSurface < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 1 endparam float param ymin caption = "Min Y" default = -1 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam float param c caption = "Parameter c" default = 0.5 endparam } class HelicoidMinimalSurface(ThreeD) { public: import "common.ulb" ; constructor func HelicoidMinimalSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = v*cos(u)*scale y.m_elements[k] = v*sin(u)*scale z.m_elements[k] = u*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Helicoid Minimal Surface" int param v_HelicoidMinimalSurface caption = "Version (Helicoid Minimal Surface)" 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_HelicoidMinimalSurface < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = .3 endparam float param xmax caption = "Max X" default = 5 endparam float param xmin caption = "Min X" default = -5 endparam float param ymax caption = "Max Y" default = 5 endparam float param ymin caption = "Min Y" default = -5 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class BourMinimalSurface(ThreeD) { public: import "common.ulb" ; constructor func BourMinimalSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (u^(@n-1)* cos((@n-1)*v)/(2*(@n-1)) - u^(@n+1)* cos((@n+1)*v)/(2*(@n+1)))*scale y.m_elements[k] = (u^(@n-1)* sin((@n-1)*v)/(2*(@n-1)) + u^(@n+1)* sin((@n+1)*v)/(2*(@n+1)))*scale z.m_elements[k] = (u^@n*cos(@n*v) / @n)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Bour Minimal Surface" int param v_BourMinimalSurface caption = "Version (Bour Minimal Surface)" 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_BourMinimalSurface < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 5 endparam float param xmax caption = "Max X" default = 1 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.05 endparam float param ystep caption = "Y increment" default = 0.05 endparam int param n caption = "Integer parameter" default = 3 min = 2 endparam } class ScherkMinimalSurface(ThreeD) { public: import "common.ulb" ; constructor func ScherkMinimalSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = u*scale y.m_elements[k] = v*scale z.m_elements[k] = (log(cos(@c*u) / cos(@c*v)) / @c)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Scherk Minimal Surface" int param v_ScherkMinimalSurface caption = "Version (Scherk Minimal Surface)" 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_ScherkMinimalSurface < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.4 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param c caption = "c parameter" default = 1 endparam } class KidneySurface(ThreeD) { public: import "common.ulb" ; constructor func KidneySurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (cos(u)*(3*cos(v) - cos(3*v)))*scale y.m_elements[k] = (sin(u)*(3*cos(v) - cos(3*v)))*scale z.m_elements[k] = (3*sin(v) - sin(3*v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Kidney Surface" int param v_KidneySurface caption = "Version (Kidney Surface)" 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_KidneySurface < 100 endparam float param xang caption = "X rotation" default = 0 endparam float param yang caption = "Y rotation" default = 80 endparam float param fscale caption = "Scale" default = 0.5 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 1.57 endparam float param ymin caption = "Min Y" default = -1.57 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class MonkeySaddle(ThreeD) { public: import "common.ulb" ; constructor func MonkeySaddle(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = u*scale y.m_elements[k] = v*scale z.m_elements[k] = (u^3 - 3*u*v^2)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Monkey Saddle" int param v_MonkeySaddle caption = "Version (Monkey Saddle)" 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_MonkeySaddle < 100 endparam float param xang caption = "X rotation" default = -30 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.7 endparam float param xmax caption = "Max X" default = 1.1 endparam float param xmin caption = "Min X" default = -1.1 endparam float param ymax caption = "Max Y" default = 1.1 endparam float param ymin caption = "Min Y" default = -1.1 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class DoubleCone(ThreeD) { public: import "common.ulb" ; constructor func DoubleCone(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = v*cos(u)*scale y.m_elements[k] = ((v - 1)*cos(u + 2*#pi / 3))*scale z.m_elements[k] = ((1 - v)*cos(u - 2*#pi / 3))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Double Cone" int param v_DoubleCone caption = "Version (Double Cone)" 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_DoubleCone < 100 endparam float param xang caption = "X rotation" default = 20 endparam float param yang caption = "Y rotation" default = -20 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 1 endparam float param ymin caption = "Min Y" default = -1 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class SnailSurface(ThreeD) { public: import "common.ulb" ; constructor func SnailSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = u*cos(v)*sin(u)*scale y.m_elements[k] = u*cos(u)*cos(v)*scale z.m_elements[k] = -u*sin(v)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Snail Surface" int param v_SnailSurface caption = "Version (Snail Surface)" 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_SnailSurface < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.3 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 1.76 endparam float param ymin caption = "Min Y" default = -1.76 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class BowSurface(ThreeD) { public: import "common.ulb" ; constructor func BowSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = ((2 + @T*sin(2*#pi*u))*sin(4*#pi*v))*scale y.m_elements[k] = ((2 + @T*sin(2*#pi*u))*cos(4*#pi*v))*scale z.m_elements[k] = (@T*cos(2*#pi*u) + 3*cos(2*#pi*v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Bow Surface" int param v_BowSurface caption = "Version (Bow Surface)" 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_BowSurface < 100 endparam float param xang caption = "X rotation" default = -100 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.4 endparam float param xmax caption = "Max X" default = 1 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 1 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.05 endparam float param ystep caption = "Y increment" default = 0.01 endparam float param T caption = "Bow thickness" default = 1 endparam } class BraidedTorus(ThreeD) { public: import "common.ulb" ; constructor func BraidedTorus(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (@r2*cos(v)*cos(u) + @r1*cos(u)*(1+@a*cos(@n*u)))*scale y.m_elements[k] = (2.5*(@r2*sin(v)+@a*sin(@n*u)))*scale z.m_elements[k] = (@r2*cos(v)*sin(u)+@r1*sin(u)*(1+@a*cos(@n*u)))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Braided Torus" int param v_BraidedTorus caption = "Version (Braided Torus)" 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_BraidedTorus < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 20 endparam float param fscale caption = "Scale" default = 0.5 endparam float param xmax caption = "Max X" default = 26 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.4 endparam float param a caption = "twist amplitude" default = 0.5 endparam float param n caption = "# of twists" default = 1.25 endparam float param r1 caption = "major radius" default = 2 endparam float param r2 caption = "minor radius" default = 0.3 endparam } class TrefoilKnot(ThreeD) { public: import "common.ulb" ; constructor func TrefoilKnot(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (@r2*cos(v)*cos(u) + @r1*cos(u)*(1+@a*cos(@n*u)))*scale y.m_elements[k] = (@r2*sin(v) + @a*sin(@n*u))*scale z.m_elements[k] = (@r2*cos(v)*sin(u)+@r1*sin(u)*(1+@a*cos(@n*u)))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Trefoil Knot" int param v_TrefoilKnot caption = "Version (Trefoil Knot)" 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_TrefoilKnot < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 20 endparam float param fscale caption = "Scale" default = 0.5 endparam float param xmax caption = "Max X" default = 12.57 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.4 endparam float param a caption = "twist amplitude" default = 0.4 endparam float param n caption = "# of twists" default = 1.5 endparam float param r1 caption = "major radius" default = 2 endparam float param r2 caption = "minor radius" default = 0.5 endparam } class CrossCap(ThreeD) { public: import "common.ulb" ; constructor func CrossCap(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (cos(u)*sin(2*v))*scale y.m_elements[k] = (sin(u)*sin(2*v))*scale z.m_elements[k] = (cos(v)*cos(v)-cos(u)*cos(u)*sin(v)*sin(v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Cross Cap" int param v_CrossCap caption = "Version (Cross Cap)" 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_CrossCap < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1.5 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 1.571 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.025 endparam } class DinisSurface(ThreeD) { public: import "common.ulb" ; constructor func DinisSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (@da*cos(u)*sin(v))*scale y.m_elements[k] = (@da*sin(u)*sin(v))*scale z.m_elements[k] = (@da*(cos(v)+log(tan((v/2))))+@db*u)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Dini's Surface" int param v_DinisSurface caption = "Version (Dini's Surface)" 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_DinisSurface < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 12.56 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 2 endparam float param ymin caption = "Min Y" default = 0.001 endparam float param xstep caption = "X increment" default = 0.3 endparam float param ystep caption = "Y increment" default = 0.05 endparam float param da caption = "param a" default = 1.0 endparam float param db caption = "param b" default = 0.2 endparam } class EllipticTorus(ThreeD) { public: import "common.ulb" ; constructor func EllipticTorus(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (@ec+cos(v))*cos(u)*scale y.m_elements[k] = (@ec+cos(v))*sin(u)*scale z.m_elements[k] = (sin(v)+cos(v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Elliptic Torus" int param v_EllipticTorus caption = "Version (Elliptic Torus)" 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_EllipticTorus < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 20 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam float param ec caption = "Parameter c" default = 0.5 endparam } class EnnepersSurface(ThreeD) { public: import "common.ulb" ; constructor func EnnepersSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (u-(u*u*u/3)+u*v*v)*scale y.m_elements[k] = (v-(v*v*v/3)+u*u*v)*scale z.m_elements[k] = (u*u-v*v)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Enneper's Surface" int param v_EnnepersSurface caption = "Version (Enneper's Surface)" 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_EnnepersSurface < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.25 endparam float param xmax caption = "Max X" default = 2 endparam float param xmin caption = "Min X" default = -2 endparam float param ymax caption = "Max Y" default = 2 endparam float param ymin caption = "Min Y" default = -2 endparam float param xstep caption = "X increment" default = 0.05 endparam float param ystep caption = "Y increment" default = 0.05 endparam } class EnnepersSurface2(ThreeD) { public: import "common.ulb" ; constructor func EnnepersSurface2(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif float s = v*cos(u) float t = v*sin(u) x.m_elements[k] = (s - s^3/3 + s*t^2)*scale y.m_elements[k] = (t - t^3/3 + t*s^2)*scale z.m_elements[k] = (s^2 - t^2)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Enneper's Surface #2" int param v_EnnepersSurface2 caption = "Version (Enneper's Surface #2)" 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_EnnepersSurface2 < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.4 endparam float param xmax caption = "Max X" default = 2 endparam float param xmin caption = "Min X" default = -2 endparam float param ymax caption = "Max Y" default = 2 endparam float param ymin caption = "Min Y" default = -2 endparam float param xstep caption = "X increment" default = 0.05 endparam float param ystep caption = "Y increment" default = 0.05 endparam } class FanoPlanes(ThreeD) { public: import "common.ulb" ; constructor func FanoPlanes(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (cos(2*#pi*(u-v/3))*cos(2*#pi*(-u-v/3))*cos(2*#pi*(u-sqrt(3))))*scale y.m_elements[k] = (cos(2*#pi*(u-v/3+2/3))*cos(2*#pi*(-u-v/3+2/3))*cos(2*#pi*(-u-v+1)))*scale z.m_elements[k] = (cos(2*#pi*(u-v/3-2/3))*cos(2*#pi*(-u-v/3-2/3))*cos(2*#pi*(-u+v+1)))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Fano Planes" int param v_FanoPlanes caption = "Version (Fano Planes)" 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_FanoPlanes < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 20 endparam float param fscale caption = "Scale" default = 1.7 endparam float param xmax caption = "Max X" default = 1 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 2 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.015 endparam float param ystep caption = "Y increment" default = 0.03 endparam } class Figure8Torus(ThreeD) { public: import "common.ulb" ; constructor func Figure8Torus(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (cos(u)*(@ftc+sin(v)*cos(u)-sin(2*v)*sin(u)/2))*scale y.m_elements[k] = (sin(u)*(@ftc+sin(v)*cos(u)-sin(2*v)*sin(u)/2))*scale z.m_elements[k] = (sin(u)*sin(v)+cos(u)*sin(2*v)/2)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Figure 8 Torus" int param v_Figure8Torus caption = "Version (Figure 8 Torus)" 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_Figure8Torus < 100 endparam float param xang caption = "X rotation" default = -45 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.8 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam float param ftc caption = "parameter c" default = 1.0 endparam } class FishSurface(ThreeD) { public: import "common.ulb" ; constructor func FishSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = ((cos(u)-cos(2*u))*cos(v)/4)*scale y.m_elements[k] = ((sin(u)-sin(2*u))*sin(v)/4)*scale z.m_elements[k] = (cos(u))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Fish Surface" int param v_FishSurface caption = "Version (Fish Surface)" 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_FishSurface < 100 endparam float param xang caption = "X rotation" default = 80 endparam float param yang caption = "Y rotation" default = 80 endparam float param fscale caption = "Scale" default = 1.7 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = -0 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class Folium(ThreeD) { public: import "common.ulb" ; constructor func Folium(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (cos(u)*(2*v/#pi-tanh(v)))*scale y.m_elements[k] = (cos(u+2*#pi/3)/cosh(v))*scale z.m_elements[k] = (cos(u-2*#pi/3)/cosh(v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Folium" int param v_Folium caption = "Version (Foliume)" 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_Folium < 100 endparam float param xang caption = "X rotation" default = 0 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1.75 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class HennenbergsSurface(ThreeD) { public: import "common.ulb" ; constructor func HennenbergsSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (2*sinh(u)*cos(v)-2/3*sinh(3*u)*cos(3*v))*scale y.m_elements[k] = (2*sinh(u)*sin(v)+2/3*sinh(3*u)*sin(3*v))*scale z.m_elements[k] = (2*cosh(2*u)*cos(2*v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Hennenberg's Surface" int param v_HennenbergsSurface caption = "Version (Hennenberg's Surface)" 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_HennenbergsSurface < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 70 endparam float param fscale caption = "Scale" default = 0.2 endparam float param xmax caption = "Max X" default = 1 endparam float param xmin caption = "Min X" default = -1 endparam float param ymax caption = "Max Y" default = 3 endparam float param ymin caption = "Min Y" default = -3 endparam float param xstep caption = "X increment" default = 0.04 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class HyperbolicHelicoid(ThreeD) { public: import "common.ulb" ; constructor func HyperbolicHelicoid(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (sinh(v)*cos(@tau*u)/(1+cosh(u)*cosh(v)))*scale y.m_elements[k] = (sinh(v)*sin(@tau*u)/(1+cosh(u)*cosh(v)))*scale z.m_elements[k] = (cosh(v)*sinh(u)/(1+cosh(u)*cosh(v)))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Hyperbolic Helicoid" int param v_HyperbolicHelicoid caption = "Version (Hyperbolic Helicoid)" 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_HyperbolicHelicoid < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 1.7 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = -6.28 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = -6.28 endparam float param xstep caption = "X increment" default = 0.03 endparam float param ystep caption = "Y increment" default = 0.4 endparam float param tau caption = "torsion" default = 6.0 endparam } class KleinBottle(ThreeD) { public: import "common.ulb" ; constructor func KleinBottle(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif kr = 4*(1-cos(u)/2) if u < #pi x.m_elements[k] = (6*cos(u)*(1+sin(u))+kr*cos(u)*cos(v))*scale y.m_elements[k] = (16*sin(u)+kr*sin(u)*cos(v))*scale else x.m_elements[k] = (6*cos(u)*(1+sin(u))+kr*cos(v+#pi))*scale y.m_elements[k] = (16*sin(u))*scale endif z.m_elements[k] = (kr*sin(v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Klein Bottle" int param v_KleinBottle caption = "Version (Klein Bottle)" 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_KleinBottle < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.1 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class KuensSurface(ThreeD) { public: import "common.ulb" ; constructor func KuensSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (2*(cos(u)+u*sin(u))*sin(v)/(1+u*u*sin(v)*sin(v)))*scale y.m_elements[k] = (2*(sin(u)-u*cos(u))*sin(v)/(1+u*u*sin(v)*sin(v)))*scale z.m_elements[k] = (log(tan(v/2))+2*cos(v)/(1+u*u*sin(v)*sin(v)))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Kuen's Surface" int param v_KuensSurface caption = "Version (Kuen's Surface)" 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_KuensSurface < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1.0 endparam float param xmax caption = "Max X" default = 4 endparam float param xmin caption = "Min X" default = -4 endparam float param ymax caption = "Max Y" default = 3.09 endparam float param ymin caption = "Min Y" default = 0.05 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.08 endparam } class Lemniscape(ThreeD) { public: import "common.ulb" ; constructor func Lemniscape(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (cos(v)*sqrt(abs(sin(2*u)))*cos(u))*scale y.m_elements[k] = (cos(v)*sqrt(abs(sin(2*u)))*sin(u))*scale z.m_elements[k] = ((x.m_elements[k]/scale)^2-(y.m_elements[k]/scale)^2+ \ 2*x.m_elements[k]/scale*y.m_elements[k]/scale*tan(v)^2)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Lemniscape" int param v_Lemniscape caption = "Version (Lemniscape)" 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_Lemniscape < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 2 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.05 endparam float param ystep caption = "Y increment" default = 0.05 endparam } class LimpetTorus(ThreeD) { public: import "common.ulb" ; constructor func LimpetTorus(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (cos(u)/(sqrt(2)+sin(v)))*scale y.m_elements[k] = (sin(u)/(sqrt(2)+sin(v)))*scale z.m_elements[k] = (1/(sqrt(2)+cos(v)))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Limpet Torus" int param v_LimpetTorus caption = "Version (Limpet Torus)" 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_LimpetTorus < 100 endparam float param xang caption = "X rotation" default = -60 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.75 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class MaedersOwl(ThreeD) { public: import "common.ulb" ; constructor func MaedersOwl(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (v*cos(u)-0.5*v^2*cos(2*u))*scale y.m_elements[k] = (-v*sin(u)-0.5*v^2*sin(2*u))*scale z.m_elements[k] = (4*v^1.5*cos(3*u/2)/3)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Maeder's Owl" int param v_MaedersOwl caption = "Version (Maeder's Owl)" 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_MaedersOwl < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1.25 endparam float param xmax caption = "Max X" default = 12.56 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 1 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.05 endparam } class MobiusBand(ThreeD) { public: import "common.ulb" ; constructor func MobiusBand(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (cos(u)+v*cos(u/2)*cos(u))*scale y.m_elements[k] = (sin(u)+v*cos(u/2)*sin(u))*scale z.m_elements[k] = (v*sin(u/2))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Mobius Band" int param v_MobiusBand caption = "Version (Mobius Band)" 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_MobiusBand < 100 endparam float param xang caption = "X rotation" default = 20 endparam float param yang caption = "Y rotation" default = -30 endparam float param fscale caption = "Scale" default = 1.5 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 0.3 endparam float param ymin caption = "Min Y" default = -0.275 endparam float param xstep caption = "X increment" default = 0.05 endparam float param ystep caption = "Y increment" default = 0.05 endparam } class PisotTriaxial(ThreeD) { public: import "common.ulb" ; constructor func PisotTriaxial(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (0.655866*cos(1.03002+u)*(2+cos(v)))*scale y.m_elements[k] = (0.754878*cos(1.40772-u)*(2+0.868837*cos(2.43773+v)))*scale z.m_elements[k] = (0.868837*cos(2.43773+u)*(2+0.495098*cos(0.377696-v)))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Pisot Triaxial" int param v_PisotTriaxial caption = "Version (Pisot Triaxial)" 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_PisotTriaxial < 100 endparam float param xang caption = "X rotation" default = 0 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.75 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class SaddleTorus(ThreeD) { public: import "common.ulb" ; constructor func SaddleTorus(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = ((2+cos(u))*cos(v))*scale y.m_elements[k] = ((2+cos(u+2*#pi/3))*cos(v+2*#pi/3))*scale z.m_elements[k] = ((2+(1-cos(u)^2-cos(u+2*#pi/3)^2)/abs(1-cos(u)^2-cos(u+2*#pi/3)^2)* \ sqrt(abs(1-cos(u)^2-cos(u+2*#pi/3)^2)))* \ (1-cos(v)^2-cos(v+2*#pi/3)^2)/abs(1-cos(v)^2-cos(v+2*#pi/3)^2)* \ sqrt(abs(1-cos(v)^2-cos(v+2*#pi/3)^2)))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Saddle Torus" int param v_SaddleTorus caption = "Version (Saddle Torus)" 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_SaddleTorus < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 20 endparam float param fscale caption = "Scale" default = 0.5 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class Seashell(ThreeD) { public: import "common.ulb" ; constructor func Seashell(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (@seaa*(1-v/(2*pi))*cos(@sean*v)*(1+cos(u))+ \ @seac*cos(@sean*v))*scale y.m_elements[k] = (@seaa*(1-v/(2*pi))*sin(@sean*v)*(1+cos(u))+ \ @seac*sin(@sean*v))*scale z.m_elements[k] = (@seab*v/(2*pi)+@seaa*(1-v/(2*pi))*sin(u))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Seashell" int param v_Seashell caption = "Version (Seashell)" 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_Seashell < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 3 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.15 endparam float param seaa caption = "param a" default = 0.2 endparam float param seab caption = "param b" default = 1.0 endparam float param seac caption = "param c" default = 0.1 endparam float param sean caption = "param n" default = 2.0 endparam } class SineSurface(ThreeD) { public: import "common.ulb" ; constructor func SineSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (@sa*sin(u))*scale y.m_elements[k] = (@sa*sin(v))*scale z.m_elements[k] = (@sa*sin(u+v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Sine Surface" int param v_SineSurface caption = "Version (Sine Surface)" 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_SineSurface < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1.25 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.15 endparam float param sa caption = "parameter a" default = 1.0 endparam } class SlippersSurface(ThreeD) { public: import "common.ulb" ; constructor func SlippersSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = ((2+cos(u)*cos(v)^3*sin(v)))*scale-6 y.m_elements[k] = ((2+cos(u+2*#pi/3))*cos(2*#pi/3+v)^2*sin(2*#pi/3+v)^2)*scale-1 z.m_elements[k] = (-(2+cos(u-2*#pi/3))*cos(2*#pi/3-v)^2*sin(2*#pi/3-v)^3)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Slipper's Surface" int param v_SlippersSurface caption = "Version (Slipper's Surface)" 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_SlippersSurface < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 3 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class SphericalHarmonics(ThreeD) { public: import "common.ulb" ; constructor func SphericalHarmonics(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif sr = sin(@m1*u)^@m2+cos(@m3*u)^@m4+sin(@m5*v)^@m6+cos(@m7*v)^@m8 x.m_elements[k] = (sr*sin(u)*cos(v))*scale y.m_elements[k] = (sr*cos(u))*scale z.m_elements[k] = (sr*sin(u)*sin(v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Spherical Harmonics" int param v_SphericalHarmonics caption = "Version (Spherical Harmonics)" 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_SphericalHarmonics < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.75 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.05 endparam float param ystep caption = "Y increment" default = 0.05 endparam int param m1 caption = "Harmonic #1" default = 2 endparam int param m2 caption = "Harmonic #2" default = 3 endparam int param m3 caption = "Harmonic #3" default =3 endparam int param m4 caption = "Harmonic #4" default = 4 endparam int param m5 caption = "Harmonic #5" default = 4 endparam int param m6 caption = "Harmonic #6" default = 2 endparam int param m7 caption = "Harmonic #7" default = 5 endparam int param m8 caption = "Harmonic #8" default = 3 endparam } class SteinerSurface(ThreeD) { public: import "common.ulb" ; constructor func SteinerSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = cos(v)^2*sin(2*u)*scale y.m_elements[k] = sin(u)*sin(2*v)*scale z.m_elements[k] = cos(u)*sin(2*v)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Steiner Surface" int param v_SteinerSurface caption = "Version (Steiner Surface)" 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_SteinerSurface < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1.5 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.05 endparam float param ystep caption = "Y increment" default = 0.05 endparam } class StilettoSurface(ThreeD) { public: import "common.ulb" ; constructor func StilettoSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = ((2+cos(u))*cos(v)^3*sin(v))*scale y.m_elements[k] = ((2+cos(u+2*#pi/3))*cos(v+2*#pi/3)^2*sin(v+2*#pi/3)^2)*scale z.m_elements[k] = (-(2+cos(u-2*#pi/3))*cos(v+2*#pi/3)^2*sin(v+2*#pi/3)^2) ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Stiletto Surface" int param v_StilettoSurface caption = "Version (Stiletto Surface)" 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_StilettoSurface < 100 endparam float param xang caption = "X rotation" default = 0 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 1.8 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class SuperShape(ThreeD) { public: import "common.ulb" ; constructor func SuperShape(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif ru = ((1/@ssa*cos(@ssm*u/4))^@ssn2+(1/@ssb*sin(@ssm*u/4))^@ssn3)^(-1/@ssn1) rv = ((1/@ssa*cos(@ssm*v/4))^@ssn2+(1/@ssb*sin(@ssm*v/4))^@ssn3)^(-1/@ssn1) x.m_elements[k] = (ru*cos(u)*rv*cos(v))*scale y.m_elements[k] = (ru*sin(u)*rv*cos(v))*scale z.m_elements[k] = (rv*sin(v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "SuperShape" int param v_SuperShape caption = "Version (SuperShape)" 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_SuperShape < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 2 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = -6.28 endparam float param xstep caption = "X increment" default = 0.05 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param ssa caption = "parameter a" default = 1.0 endparam float param ssb caption = "parameter b" default = 1.0 endparam float param ssm caption = "parameter m" default = 7.0 endparam float param ssn1 caption = "parameter n1" default = 0.2 endparam float param ssn2 caption = "parameter n2" default = 1.7 endparam float param ssn3 caption = "parameter n3" default = 1.7 endparam } class Swallowtail(ThreeD) { public: import "common.ulb" ; constructor func Swallowtail(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (u*v^2+3*v^4)*scale y.m_elements[k] = (-2*u*v-4*v^3)*scale z.m_elements[k] = (u)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Swallowtail" int param v_Swallowtail caption = "Version (Swallowtail)" 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_Swallowtail < 100 endparam float param xang caption = "X rotation" default = 0 endparam float param yang caption = "Y rotation" default = -30 endparam float param fscale caption = "Scale" default = 0.4 endparam float param xmax caption = "Max X" default = 2 endparam float param xmin caption = "Min X" default = -2 endparam float param ymax caption = "Max Y" default = 0.8 endparam float param ymin caption = "Min Y" default = -0.8 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class Tractrix(ThreeD) { public: import "common.ulb" ; constructor func Tractrix(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (cos(u)*(v-tanh(v)))*scale y.m_elements[k] = (cos(u)/cosh(v))*scale z.m_elements[k] = ((x.m_elements[k]/scale)^2-(y.m_elements[k]/scale)^2+ \ 2*x.m_elements[k]/scale*y.m_elements[k]/scale*tanh(u)^2)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Tractrix" int param v_Tractrix caption = "Version (Tractrix)" 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_Tractrix < 100 endparam float param xang caption = "X rotation" default = -45 endparam float param yang caption = "Y rotation" default = -60 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class TriangularTrefoil(ThreeD) { public: import "common.ulb" ; constructor func TriangularTrefoil(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (2*sin(3*u)/(2+cos(v)))*scale y.m_elements[k] = (2*(sin(u)+2*sin(2*u))/(2+cos(v+2*#pi/3)))*scale z.m_elements[k] = ((cos(u)-2*cos(2*u))*(2+cos(v))*(2+cos(v+2*#pi/3))/4)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Triangular Trefoil" int param v_TriangularTrefoil caption = "Version (Triangular Trefoil)" 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_TriangularTrefoil < 100 endparam float param xang caption = "X rotation" default = 20 endparam float param yang caption = "Y rotation" default = 90 endparam float param fscale caption = "Scale" default = 0.35 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.3 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class TriaxialHexatorus(ThreeD) { public: import "common.ulb" ; constructor func TriaxialHexatorus(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (sin(u)/(sqrt(2)+cos(v)))*scale y.m_elements[k] = (sin(u+2*#pi/3)/(sqrt(2)+cos(v+2*#pi/3)))*scale z.m_elements[k] = (cos(u-2*#pi/3)/(sqrt(2)+cos(v-2*#pi/3)))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Triaxial Hexatorus" int param v_TriaxialHexatorus caption = "Version (Triaxial Hexatorus)" 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_TriaxialHexatorus < 100 endparam float param xang caption = "X rotation" default = 30 endparam float param yang caption = "Y rotation" default = -70 endparam float param fscale caption = "Scale" default = 0.75 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class TriaxialTeardrop(ThreeD) { public: import "common.ulb" ; constructor func TriaxialTeardrop(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = ((1-cos(u))*cos(u+2*#pi/3)*cos(v+2*#pi/3)/2)*scale y.m_elements[k] = ((1-cos(u))*cos(u+2*#pi/3)*cos(v-2*#pi/3)/2)*scale z.m_elements[k] = (cos(u-2*#pi/3))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Triaxial Teardrop" int param v_TriaxialTeardrop caption = "Version (Triaxial Teardrop)" 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_TriaxialTeardrop < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 2 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class TriaxialTritorus(ThreeD) { public: import "common.ulb" ; constructor func TriaxialTritorus(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (sin(u)*(1+cos(v)))*scale y.m_elements[k] = (sin(u+2*#pi/3)*(1+cos(v+2*#pi/3)))*scale z.m_elements[k] = (sin(u+4*#pi/3)*(1+cos(v+4*#pi/3)))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Triaxial Tritorus" int param v_TriaxialTritorus caption = "Version (Triaxial Tritorus)" 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_TriaxialTritorus < 100 endparam float param xang caption = "X rotation" default = -30 endparam float param yang caption = "Y rotation" default = -45 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class TwistedFano(ThreeD) { public: import "common.ulb" ; constructor func TwistedFano(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (cos(2*#pi*(u-v/3))*cos(2*#pi*(-u-v/3))*cos(2*#pi*v)*cos(2*#pi*u))*scale y.m_elements[k] = (cos(2*#pi*(u-v/3)+2*#pi/3)*cos(2*#pi*(-u-v/3)+2*#pi/3)*cos(2*#pi*(-u-v)+2*#pi/3)*cos(2*#pi*(u-1)))*scale z.m_elements[k] = (cos(2*#pi*(u-v/3)-2*#pi/3)*cos(2*#pi*(-u-v/3)-2*#pi/3)*cos(2*#pi*(-u+v)+2*#pi/3)*cos(2*#pi*(u-2)))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Twisted Fano" int param v_TwistedFano caption = "Version (Twisted Fano)" 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_TwistedFano < 100 endparam float param xang caption = "X rotation" default = -60 endparam float param yang caption = "Y rotation" default = 45 endparam float param fscale caption = "Scale" default = 2 endparam float param xmax caption = "Max X" default = 1 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 2 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.02 endparam float param ystep caption = "Y increment" default = 0.02 endparam } class TwistedHeart(ThreeD) { public: import "common.ulb" ; constructor func TwistedHeart(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = ((abs(v)-abs(u) - abs(tanh(u/sqrt(2))*sqrt(2))+abs(tanh(v/sqrt(2))*sqrt(2)))*sin(v))*scale y.m_elements[k] = ((abs(v)+abs(u) - abs(tanh(u/sqrt(2))*sqrt(2))-abs(tanh(v/sqrt(2))*sqrt(2)))*cos(v))*scale z.m_elements[k] = ((u^2+v^2)/(cosh(u/sqrt(2))+cosh(v/sqrt(2)))/sqrt(2))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Twisted Heart" int param v_TwistedHeart caption = "Version (Twisted Heart)" 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_TwistedHeart < 100 endparam float param xang caption = "X rotation" default = 0 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.6 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class TwistedPipe(ThreeD) { public: import "common.ulb" ; constructor func TwistedPipe(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (cos(v)*(2+cos(u))/sqrt(1+sin(v)^2))*scale y.m_elements[k] = (sin(v+2*#pi/3)*(2+cos(u+2*#pi/3))/sqrt(1+sin(v)^2))*scale z.m_elements[k] = (sin(v-2*#pi/3)*(2+cos(u-2*#pi/3))/sqrt(1+sin(v)^2))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Twisted Pipe" int param v_TwistedPipe caption = "Version (Twisted Pipe)" 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_TwistedPipe < 100 endparam float param xang caption = "X rotation" default = 0 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.6 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class TwistedTriaxial(ThreeD) { public: import "common.ulb" ; constructor func TwistedTriaxial(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = ((1-((u*u+v*v)/2)^0.5/#pi)*cos(u)*cos(v)+((u*u+v*v)/2)^0.5/#pi*sin(u)*sin(v))*scale y.m_elements[k] = ((1-((u*u+v*v)/2)^0.5/#pi)*cos(u+2*#pi/3)*cos(v+2*#pi/3)+((u*u+v*v)/2)^0.5/#pi*sin(u+2*#pi/3)*sin(v+2*#pi/3))*scale z.m_elements[k] = ((1-((u*u+v*v)/2)^0.5/#pi)*cos(u+4*#pi/3)*cos(v+4*#pi/3)+((u*u+v*v)/2)^0.5/#pi*sin(u+4*#pi/3)*sin(v+4*#pi/3))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Twisted Triaxial" int param v_TwistedTriaxial caption = "Version (Twisted Triaxial)" 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_TwistedTriaxial < 100 endparam float param xang caption = "X rotation" default = 0 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 1.8 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class VerrillSurface(ThreeD) { public: import "common.ulb" ; constructor func VerrillSurface(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (-2*u*cos(v)+2*cos(v)/u-2*u^3*cos(3*v)/3)*scale y.m_elements[k] = (6*u*sin(v)-2*sin(v)/u-2*u^3*sin(3*v)/3)*scale z.m_elements[k] = (4*log(u))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Verrill Surface" int param v_VerrillSurface caption = "Version (Verrill Surface)" 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_VerrillSurface < 100 endparam float param xang caption = "X rotation" default = 45 endparam float param yang caption = "Y rotation" default = 20 endparam float param fscale caption = "Scale" default = 0.5 endparam float param xmax caption = "Max X" default = 1 endparam float param xmin caption = "Min X" default = 0.5 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.01 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class WhitneyUmbrella(ThreeD) { public: import "common.ulb" ; constructor func WhitneyUmbrella(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (0.5*sin(u)^2*cos(2*v))*scale y.m_elements[k] = (0.5*sin(u)^2*sin(2*v))*scale z.m_elements[k] = (sin(u)*sin(v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Whitney Umbrella" int param v_WhitneyUmbrella caption = "Version (Whitney Umbrella)" 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_WhitneyUmbrella < 100 endparam float param xang caption = "X rotation" default = 30 endparam float param yang caption = "Y rotation" default = -70 endparam float param fscale caption = "Scale" default = 1.8 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 6.28 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class WallissConicalEdge(ThreeD) { public: import "common.ulb" ; constructor func WallissConicalEdge(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = v*cos(u)*scale y.m_elements[k] = v*sin(u)*scale z.m_elements[k] = @c*sqrt(@a^2-@b^2*cos(u)^2)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Wallis's Conical Edge" int param v_WallissConicalEdge caption = "Version (Wallis's Conical Edge)" 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_WallissConicalEdge < 100 endparam float param xang caption = "X rotation" default = -45 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.6 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "parameter a" default = 1.01 endparam float param b caption = "parameter b" default = 1 endparam float param c caption = "parameter c" default = 1 endparam } class Pseudocrosscap(ThreeD) { public: import "common.ulb" ; constructor func Pseudocrosscap(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (1-u^2)*sin(v)*scale y.m_elements[k] = (1-u^2)*sin(2*v)*scale z.m_elements[k] = u*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Pseudocrosscap" int param v_Pseudocrosscap caption = "Version (Pseudocrosscap)" 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_Pseudocrosscap < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = .5 endparam float param xmax caption = "Max X" default = 2 endparam float param xmin caption = "Min X" default = -2 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class Funnel(ThreeD) { public: import "common.ulb" ; constructor func Funnel(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = u*cos(v)*scale y.m_elements[k] = u*sin(v)*scale z.m_elements[k] = @a*log(u)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Funnel" int param v_Funnel caption = "Version (Funnel)" 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_Funnel < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.5 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "paramater a" default = 1 endparam } class GabrielsHorn(ThreeD) { public: import "common.ulb" ; constructor func GabrielsHorn(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = u*scale y.m_elements[k] = @a*cos(v)/u*scale z.m_elements[k] = @a*sin(v)/u*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Gabriel's Horn" int param v_GabrielsHorn caption = "Version (Gabriel's Horn)" 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_GabrielsHorn < 100 endparam float param xang caption = "X rotation" default = 0 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 3.5 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "paramater a" default = 0.3 endparam } class SpindleTorus(ThreeD) { public: import "common.ulb" ; constructor func SpindleTorus(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (@c+@a*cos(v))*cos(u)*scale y.m_elements[k] = (@c+@a*cos(v))*sin(u)*scale z.m_elements[k] = @a*sin(v)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Spindle Torus" int param v_SpindleTorus caption = "Version (Spindle Torus)" 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_SpindleTorus < 100 endparam float param xang caption = "X rotation" default = -45 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "paramater a" default = 1 endparam float param c caption = "paramater c" default = 1 endparam } class Pseudosphere(ThreeD) { public: import "common.ulb" ; constructor func Pseudosphere(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = 1/cosh(u)*cos(v)*scale y.m_elements[k] = 1/cosh(u)*sin(v)*scale z.m_elements[k] = (u - tanh(u))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Pseudosphere" int param v_Pseudosphere caption = "Version (Pseudosphere)" 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_Pseudosphere < 100 endparam float param xang caption = "X rotation" default = -60 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class Hyperboloid(ThreeD) { public: import "common.ulb" ; constructor func Hyperboloid(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = @a*sqrt(1+u^2)*cos(v)*scale y.m_elements[k] = @a*sqrt(1+u^2)*sin(v)*scale z.m_elements[k] = @c*u*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Hyperboloid" int param v_Hyperboloid caption = "Version (Hyperboloid)" 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_Hyperboloid < 100 endparam float param xang caption = "X rotation" default = -60 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "parameter a" default = 1 endparam float param c caption = "parameter c" default = 1 endparam } class EllipticCylinder(ThreeD) { public: import "common.ulb" ; constructor func EllipticCylinder(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = @a*cos(u)*scale y.m_elements[k] = @b*sin(u)*scale z.m_elements[k] = v*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Elliptic Cylinder" int param v_EllipticCylinder caption = "Version (Elliptic Cylinder)" 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_EllipticCylinder < 100 endparam float param xang caption = "X rotation" default = -60 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 1 endparam float param ymin caption = "Min Y" default = -1 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "parameter a" default = 1.5 endparam float param b caption = "parameter b" default = 1 endparam } class Spheroid(ThreeD) { public: import "common.ulb" ; constructor func Spheroid(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = @a*sin(v)*cos(u)*scale y.m_elements[k] = @a*sin(v)*sin(u)*scale z.m_elements[k] = @c*cos(v)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Spheroid" int param v_Spheroid caption = "Version (Spheroid)" 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_Spheroid < 100 endparam float param xang caption = "X rotation" default = -60 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = 0 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "parameter a" default = 1.5 endparam float param c caption = "parameter c" default = 1 endparam } class EllipticCone(ThreeD) { public: import "common.ulb" ; constructor func EllipticCone(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = @a*(@h-u)/@h*cos(v)*scale y.m_elements[k] = @b*(@h-u)/@h*sin(v)*scale z.m_elements[k] = u*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Elliptic Cone" int param v_EllipticCone caption = "Version (Elliptic Cone)" 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_EllipticCone < 100 endparam float param xang caption = "X rotation" default = -60 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.8 endparam float param xmax caption = "Max X" default = 1 endparam float param xmin caption = "Min X" default = -1 endparam float param ymax caption = "Max Y" default = 1 endparam float param ymin caption = "Min Y" default = -1 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "parameter a" default = 1.5 endparam float param b caption = "parameter b" default = 1 endparam float param h caption = "parameter h" default = 2 endparam } class EllipticHelicoid(ThreeD) { public: import "common.ulb" ; constructor func EllipticHelicoid(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = @a*v*cos(u)*scale y.m_elements[k] = @b*v*sin(u)*scale z.m_elements[k] = @c*u*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Elliptic Helicoid" int param v_EllipticHelicoid caption = "Version (Elliptic Helicoid)" 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_EllipticHelicoid < 100 endparam float param xang caption = "X rotation" default = 0 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.6 endparam float param xmax caption = "Max X" default = 6.28 endparam float param xmin caption = "Min X" default = -6.28 endparam float param ymax caption = "Max Y" default = 1 endparam float param ymin caption = "Min Y" default = -1 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "parameter a" default = 2 endparam float param b caption = "parameter b" default = 1 endparam float param c caption = "parameter c" default = 0.5 endparam } class HornTorus(ThreeD) { public: import "common.ulb" ; constructor func HornTorus(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (1+cos(v))*cos(u)*scale y.m_elements[k] = (1+cos(v))*sin(u)*scale z.m_elements[k] = sin(v)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Horn Torus" int param v_HornTorus caption = "Version (Horn Torus)" 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_HornTorus < 100 endparam float param xang caption = "X rotation" default = -60 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default = 3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class HyperbolicCylinder(ThreeD) { public: import "common.ulb" ; constructor func HyperbolicCylinder(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = @a*sinh(u)*scale y.m_elements[k] = @b*cosh(u)*scale z.m_elements[k] = v*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Hyperbolic Cylinder" int param v_HyperbolicCylinder caption = "Version (Hyperbolic Cylinder)" 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_HyperbolicCylinder < 100 endparam float param xang caption = "X rotation" default = 20 endparam float param yang caption = "Y rotation" default = -30 endparam float param fscale caption = "Scale" default = .5 endparam float param xmax caption = "Max X" default = 2 endparam float param xmin caption = "Min X" default = -2 endparam float param ymax caption = "Max Y" default = 2 endparam float param ymin caption = "Min Y" default = -2 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "parameter a" default = 1 endparam float param b caption = "parameter b" default = 1 endparam } class Paraboloid(ThreeD) { public: import "common.ulb" ; constructor func Paraboloid(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = @a*sqrt(u/@h)*cos(v)*scale y.m_elements[k] = @a*sqrt(u/@h)*sin(v)*scale z.m_elements[k] = u*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Paraboloid" int param v_Paraboloid caption = "Version (Paraboloid)" 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_Paraboloid < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 1.5 endparam float param xmax caption = "Max X" default =2 endparam float param xmin caption = "Min X" default = -2 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "parameter a" default = 1 endparam float param h caption = "parameter h" default = 2 endparam } class EllipticHyperboloid(ThreeD) { public: import "common.ulb" ; constructor func EllipticHyperboloid(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = @a*sqrt(1+u^2)*cos(v)*scale y.m_elements[k] = @b*sqrt(1+u^2)*sin(v)*scale z.m_elements[k] = @c*u*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Elliptic Hyperboloid" int param v_EllipticHyperboloid caption = "Version (Elliptic Hyperboloid)" 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_EllipticHyperboloid < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 1 endparam float param xmax caption = "Max X" default =1 endparam float param xmin caption = "Min X" default = -1 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "parameter a" default = 1 endparam float param b caption = "parameter b" default =1 endparam float param c caption = "parameter c" default = 1 endparam } class Cornucopia(ThreeD) { public: import "common.ulb" ; constructor func Cornucopia(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (exp(@b*v)*cos(v) + exp(@a*v)*cos(u)*cos(v))*scale y.m_elements[k] = (exp(@b*v)*sin(v) + exp(@a*v)*cos(u)*sin(v))*scale z.m_elements[k] = exp(@a*v)*sin(u)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Cornucopia" int param v_Cornucopia caption = "Version (Cornucopia)" 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_Cornucopia < 100 endparam float param xang caption = "X rotation" default = -30 endparam float param yang caption = "Y rotation" default = -30 endparam float param fscale caption = "Scale" default = 0.1 endparam float param xmax caption = "Max X" default =3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "parameter a" default = 0.9 endparam float param b caption = "parameter b" default =1 endparam } class Ellipsoid(ThreeD) { public: import "common.ulb" ; constructor func Ellipsoid(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = @a*cos(u)*sin(v)*scale y.m_elements[k] = @b*sin(u)*sin(v)*scale z.m_elements[k] = @c*cos(v)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Ellipsoid" int param v_Ellipsoid caption = "Version (Ellipsoid)" 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_Ellipsoid < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 1.5 endparam float param xmax caption = "Max X" default =3.14 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "parameter a" default = 1 endparam float param b caption = "parameter b" default =0.75 endparam float param c caption = "parameter c" default =2 endparam } class EllipticParaboloid(ThreeD) { public: import "common.ulb" ; constructor func EllipticParaboloid(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = @a*sqrt(u)*cos(v)*scale y.m_elements[k] = @b*sqrt(u)*sin(v)*scale z.m_elements[k] = u*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Elliptic Paraboloid" int param v_EllipticParaboloid caption = "Version (Elliptic Paraboloid)" 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_EllipticParaboloid < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 3 endparam float param xmax caption = "Max X" default =1 endparam float param xmin caption = "Min X" default = -1 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "parameter a" default = .5 endparam float param b caption = "parameter b" default =1 endparam } class Snake(ThreeD) { public: import "common.ulb" ; constructor func Snake(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (1-u)*(3+cos(v))*cos(2*#pi*u)*scale y.m_elements[k] = (1-u)*(3+cos(v))*sin(2*#pi*u)*scale z.m_elements[k] = (6*u + (1-u)*sin(v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Snake" int param v_Snake caption = "Version (Snake)" 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_Snake < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.125 endparam float param xmax caption = "Max X" default =0.5 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.05 endparam float param ystep caption = "Y increment" default = 0.4 endparam } class RadialWaves(ThreeD) { public: import "common.ulb" ; constructor func RadialWaves(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = u*scale y.m_elements[k] = v*scale z.m_elements[k] = cos(sqrt(u^2+v^2))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Radial Waves" int param v_RadialWaves caption = "Version (Radial Waves)" 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_RadialWaves < 100 endparam float param xang caption = "X rotation" default = -45 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.15 endparam float param xmax caption = "Max X" default =12.54 endparam float param xmin caption = "Min X" default = -12.54 endparam float param ymax caption = "Max Y" default = 12.54 endparam float param ymin caption = "Min Y" default = -12.54 endparam float param xstep caption = "X increment" default = 0.4 endparam float param ystep caption = "Y increment" default = 0.4 endparam } class WiggleCone(ThreeD) { public: import "common.ulb" ; constructor func WiggleCone(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = v*cos(u)*scale y.m_elements[k] = v*sin(u)*scale z.m_elements[k] = (v*cos(7*u)/2)/2*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Wiggle Cone" int param v_WiggleCone caption = "Version (Wiggle Cone)" 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_WiggleCone < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 1.75 endparam float param xmax caption = "Max X" default =3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 1 endparam float param ymin caption = "Min Y" default = -1 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class SpiralWaves(ThreeD) { public: import "common.ulb" ; constructor func SpiralWaves(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = v*cos(u)*scale y.m_elements[k] = v*sin(u)*scale z.m_elements[k] = (v*cos(7*u)/2)/2*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Spiral Waves" int param v_SpiralWaves caption = "Version (Spiral Waves)" 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_SpiralWaves < 100 endparam float param xang caption = "X rotation" default = -30 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.6 endparam float param xmax caption = "Max X" default =3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class StereographicSphere(ThreeD) { public: import "common.ulb" ; constructor func StereographicSphere(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = 2*u/(1+u^2+v^2)*scale y.m_elements[k] = 2*v/(1+u^2+v^2)*scale z.m_elements[k] = (u^2+v^2-1)/(1+u^2+v^2)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Stereographic Sphere" int param v_StereographicSphere caption = "Version (Stereographic Sphere)" 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_StereographicSphere < 100 endparam heading text = "A Stereographic Sphere is a projection of a plane, including infinity, \ onto a sphere. The projection is hyperbolic in nature." endheading float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 1.75 endparam float param xmax caption = "Max X" default =5 endparam float param xmin caption = "Min X" default = -5 endparam float param ymax caption = "Max Y" default = 5 endparam float param ymin caption = "Min Y" default = -5 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.1 endparam } class TwistedSphere(ThreeD) { public: import "common.ulb" ; constructor func TwistedSphere(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = @a*cos(u)*cos(v)*scale y.m_elements[k] = @a*sin(u)*sin(v)*scale z.m_elements[k] = (@a*sin(v) + @b*u)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Twisted Sphere" int param v_TwistedSphere caption = "Version (Twisted Sphere)" 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_TwistedSphere < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.25 endparam float param xmax caption = "Max X" default =3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "parameter a" default = 3 endparam float param b caption = "parameter b" default = 2 endparam } class ToruswithDumbbell(ThreeD) { public: import "common.ulb" ; constructor func ToruswithDumbbell(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = cos(2*u)*sin(u)*cos(v)*scale y.m_elements[k] = cos(2*u)*sin(u)*sin(v)*scale z.m_elements[k] = cos(2*u)*cos(u)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Torus with Dumbbell" int param v_ToruswithDumbbell caption = "Version (Torus with Dumbbell)" 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_ToruswithDumbbell < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 2 endparam float param xmax caption = "Max X" default =3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class HelicalTorus(ThreeD) { public: import "common.ulb" ; constructor func HelicalTorus(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = cos(u)*(@a+sin(v))*scale y.m_elements[k] = sin(u)*(@a+sin(v))*scale z.m_elements[k] = (@b*u + cos(v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Helical Torus" int param v_HelicalTorus caption = "Version (Helical Torus)" 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_HelicalTorus < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.35 endparam float param xmax caption = "Max X" default =12.56 endparam float param xmin caption = "Min X" default = -12.56 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param a caption = "parameter a" default = 3 endparam float param b caption = "parameter b" default = 0.5 endparam } class ShellTorus(ThreeD) { public: import "common.ulb" ; constructor func ShellTorus(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = u*cos(u)*(@c+cos(v))*scale y.m_elements[k] = u*sin(u)*(@c+cos(v))*scale z.m_elements[k] = (u*sin(v) - 7*u)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Shell Torus" int param v_ShellTorus caption = "Version (Shell Torus)" 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_ShellTorus < 100 endparam float param xang caption = "X rotation" default = -30 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.04 endparam float param xmax caption = "Max X" default =12.54 endparam float param xmin caption = "Min X" default = 0 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam float param c caption = "parameter c" default = 3 endparam } class HelicoidtoCatenoid(ThreeD) { public: import "common.ulb" ; constructor func HelicoidtoCatenoid(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (cos(@a)*sinh(v)*sin(u) + sin(@a)*cosh(v)*cos(u))*scale y.m_elements[k] = (-cos(@a)*sinh(v)*cos(u) + sin(@a)*cosh(v)*sin(u))*scale z.m_elements[k] = (u*cos(@a) + v*sin(@a))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Helicoid to Catenoid" int param v_HelicoidtoCatenoid caption = "Version (Helicoid to Catenoid)" 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_HelicoidtoCatenoid < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.17 endparam float param xmax caption = "Max X" default =3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam heading text = "With parameter a = 0 the surface is a Helicoid while with \ parameter a = #pi/2 the surface is a catenoid." endheading float param a caption = "parameter a" default = 0.785 endparam } class UmbilicTorus(ThreeD) { public: import "common.ulb" ; constructor func UmbilicTorus(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (sin(u)*(7+cos(u/3-2*v)+2*cos(u/3+v)))*scale y.m_elements[k] = (cos(u)*(7+cos(u/3-2*v)+2*cos(u/3+v)))*scale z.m_elements[k] = (sin(u/3-2*v) + 2*sin(u/3+v))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Umbilic Torus" int param v_UmbilicTorus caption = "Version (Umbilic Torus)" 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_UmbilicTorus < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.2 endparam float param xmax caption = "Max X" default =3.14 endparam float param xmin caption = "Min X" default = -3.3 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class JeenersKleinBottle(ThreeD) { public: import "common.ulb" ; constructor func JeenersKleinBottle(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif float w = (@s+1)/4*(cos((@s+1)*u+#pi/@t)+sqrt(2)) x.m_elements[k] = (@s*cos(u)+cos(@s*u)-w*sin((@s-1)/2*u)*cos(v))*scale y.m_elements[k] = (@s*sin(u)+sin(@s*u)-w*cos((@s-1)/2*u)*cos(v))*scale z.m_elements[k] = w*sin(v)*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Jeener's Klein Bottle" int param v_JeenersKleinBottle caption = "Version (Jeener's Klein Bottle)" 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_JeenersKleinBottle < 100 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.4 endparam float param xmax caption = "Max X" default =3.14 endparam float param xmin caption = "Min X" default = -3.3 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.2 endparam int param s caption = "parameter s" default = 3 hint = "An integer that controls how many necks." endparam float param t caption = "parameter t" default = 5 endparam } class InvertedHelicoid(ThreeD) { public: import "common.ulb" ; constructor func InvertedHelicoid(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = v*cos(u)*scale y.m_elements[k] = v*sin(u)*scale z.m_elements[k] = 0.2*u*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Inverted Helicoid" int param v_InvertedHelicoid caption = "Version (Inverted Helicoid)" 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_InvertedHelicoid < 100 endparam float param xang caption = "X rotation" default = -70 endparam float param yang caption = "Y rotation" default = 0 endparam float param fscale caption = "Scale" default = 0.6 endparam float param xmax caption = "Max X" default =3.14 endparam float param xmin caption = "Min X" default = -3.14 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.2 endparam float param ystep caption = "Y increment" default = 0.2 endparam } class InvertedTrefoilKnot(ThreeD) { public: import "common.ulb" ; constructor func InvertedTrefoilKnot(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 l = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile i = 0 xlimit = trunc((@xmax-@xmin)/@xstep) ylimit = trunc((@ymax-@ymin)/@ystep) umin = @xmin vmin = @ymin ustep = @xstep vstep = @ystep scale = @fscale complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines for a full mesh grid ; while l < 2 if l == 0 outlimit = xlimit inlimit = ylimit else outlimit = ylimit inlimit = xlimit endif while i <= outlimit if l == 0 u = umin + i*ustep else v = vmin + i*vstep endif while j <= inlimit if l == 0 v = vmin + j*vstep else u = umin + j*ustep endif ; ; No line between loops ; if j == inlimit use.m_elements[k] = false endif x.m_elements[k] = (@r2*cos(v)*cos(u) + @r1*cos(u)*(1+@a*cos(@n*u)))*scale y.m_elements[k] = (@r2*sin(v) + @a*sin(@n*u))*scale z.m_elements[k] = (@r2*cos(v)*sin(u) + @r1*sin(u)*(1+@a*cos(@n*u)))*scale ; ; Y axis rotation ; temp = x.m_elements[k] + flip(z.m_elements[k]) temp = temp*yrot x.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[k] + flip(z.m_elements[k]) temp = temp*xrot y.m_elements[k] = real(temp) z.m_elements[k] = imag(temp) if z.m_elements[k] < zmin zmin = z.m_elements[k] endif if z.m_elements[k] > zmax zmax = z.m_elements[k] endif k = k + 1 j = j + 1 endwhile i = i + 1 j = 0 endwhile l = l + 1 i = 0 j = 0 endwhile endfunc default: title = "Inverted Trefoil Knot" int param v_InvertedTrefoilKnot caption = "Version (Inverted Trefoil Knot)" 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_InvertedTrefoilKnot < 100 endparam float param xang caption = "X rotation" default = -45 endparam float param yang caption = "Y rotation" default = 30 endparam float param fscale caption = "Scale" default = 0.6 endparam float param xmax caption = "Max X" default =6.28 endparam float param xmin caption = "Min X" default = -6.28 endparam float param ymax caption = "Max Y" default = 3.14 endparam float param ymin caption = "Min Y" default = -3.14 endparam float param xstep caption = "X increment" default = 0.1 endparam float param ystep caption = "Y increment" default = 0.4 endparam float param a caption = "twist amplitude" default = 0.4 endparam float param n caption = "# of twists" default = 1.5 endparam float param r1 caption = "major axis" default = 2 endparam float param r2 caption = "minor axis" default = 0.5 endparam } ;------------------------------------------- ; Transformation classes ;------------------------------------------- class TrapTransformMod(common.ulb:UserTransform) { ; Basic trap shape transform with trap modifier added.
;

; the trap modifier field reproduces a parameter used in my old UF4 formulas. public: import "common.ulb" $define debug ; constuctor func TrapTransformMod(Generic pparent) UserTransform.UserTransform(pparent) endfunc ; initialize the transform func Init(complex pz) UserTransform.Init(pz) m_Rotation = (0,1) ^ (@p_traprotation / 90.0) m_Skew = (0,1) ^ (@p_trapskew / 90.0) m_TrapCenter = @p_trapcenter if (@p_trapcentermoves) m_TrapCenter = m_TrapCenter + pz endif m_tmod = @tmod m_aspect = @p_trapaspect m_seed = @seed m_seed = random(m_seed) endfunc ; call for each iterated point complex func Iterate(complex pz) UserTransform.Iterate(pz) ; apply per-iteration steps if (@p_trapdrift != (0,0)) if !@p_driftrandom m_TrapCenter = m_TrapCenter + @p_trapdrift else m_seed = random(m_seed) m_scaledseed = abs(m_seed)/#randomrange m_seed = random(m_seed) m_scaledseed2 = abs(m_seed)/#randomrange m_TrapCenter = m_TrapCenter + 2*(real(@p_trapdrift)*m_scaledseed + \ flip(imag(@p_trapdrift)*m_scaledseed2)) endif endif if (@p_traprotationstep != 0.0) if !@p_rotationrandom m_Rotation = (0,1) ^ ((@p_traprotation + @p_traprotationstep*(m_Iterations-1)) / 90.0) else m_seed = random(m_seed) m_scaledseed = abs(m_seed)/#randomrange m_Rotation = (0,1) ^ ((@p_traprotation + 2*m_scaledseed*@p_traprotationstep*(m_Iterations-1)) / 90.0) endif endif if (@p_trapskewstep != 0.0) if !@p_skewrandom m_Skew = (0,1) ^ ((@p_trapskew + @p_trapskewstep*(m_Iterations-1)) / 90.0) else m_seed = random(m_seed) m_scaledseed = abs(m_seed)/#randomrange m_Skew = (0,1) ^ ((@p_trapskew + 2*m_scaledseed*@p_trapskewstep*(m_Iterations-1)) / 90.0) endif endif if @p_trapaspectstep != 0 if !@p_aspectrandom m_aspect = m_aspect + @p_trapaspectstep else m_seed = random(m_seed) m_scaledseed = abs(m_seed)/#randomrange m_aspect = m_aspect + 2*@p_trapaspectstep*m_scaledseed endif endif ; apply offset and rotation and size pz = (pz - m_TrapCenter) * m_Rotation * recip(@p_trapscale) ; apply aspect pz = real(pz) + flip(imag(pz) * m_aspect) ; apply skew pz = real(pz*m_Skew) + flip(imag(pz)) ; apply trap modifier if @v_trappositionmod < 102 pz = real(pz) + flip(imag(pz)*m_tmod) endif return pz endfunc protected: complex m_Rotation complex m_Skew complex m_TrapCenter float m_tmod float m_aspect int m_seed float m_scaledseed float m_scaledseed2 default: title = "Trap Position Mod" int param v_trappositionmod caption = "Version (Trap Position mod)" default = 102 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_trappositionmod < 102 endparam heading text = "Implements aspect steps analogous to steps for rototation and skew. \ All step parameters including trap drift can be randomized." visible = @v_trappositionmod >= 102 endheading float param tmod caption = "Trap Modifier" default = 1.0 visible = @v_trappositionmod < 102 hint = "Modifies the shape of the trap." endparam int param seed caption = "Random step seed" default = 123456789 visible = (@p_driftrandom && @p_trapdrift != (0,0)) \ || (@p_aspectrandom && @p_trapaspectstep != 0 ) \ || (@p_rotationrandom && @p_traprotationstep !=0) \ || (@p_skewrandom && @p_trapskewstep !=0) endparam complex param p_trapcenter caption = "Trap Center" default = (0,0) hint = "This is the location of the trap in the complex plane." endparam bool param p_trapcentermoves caption = "Follows pixel location" default = false hint = "If this is enabled, the trap center will follow the pixel location, offset by the Trap Center amount." endparam complex param p_trapdrift caption = "Trap Drift" default = (0,0) hint = "This is the amount the trap center will move with each iteration." endparam bool param p_driftrandom caption = "Randomize drift" default = false visible = @p_trapdrift != (0,0) endparam float param p_trapscale caption = "Trap Scale" default = 1.0 hint = "This can be used to resize the entire trap shape. This is different from adjusting the trap threshold because this resizes the complete trap evenly; adjusting the threshold may change the trap shape in unexpected ways (for some trap shapes). Use values smaller than 1.0 to shrink the trap shape, larger than 1.0 to enlarge it." endparam float param p_traprotation caption = "Rotation" default = 0.0 hint = "This is the angle, in degrees, that the trap should be rotated." endparam float param p_traprotationstep caption = "Rotation Step" default = 0.0 hint = "This is the angle, in degrees, that the trap will be rotated with each iteration." endparam bool param p_rotationrandom caption = "Randomize rotation step" default = false visible = @p_traprotationstep != 0 endparam float param p_trapskew caption = "Skew" default = 0.0 hint = "This is the angle, in degrees, to skew the vertical axis of the trap shape." endparam float param p_trapskewstep caption = "Skew Step" default = 0.0 hint = "This is the angle, in degrees, that the skew angle should be increased by with each iteration." endparam bool param p_skewrandom caption = "Randomize skew step" default = false visible = @p_trapskewstep != 0 endparam float param p_trapaspect caption = "Aspect Ratio" default = 1.0 hint = "This is how square the trap is. You can distort the trap by using a value other than 1.0." endparam float param p_trapaspectstep caption = "Aspect Step" default = 0.0 endparam bool param p_aspectrandom caption = "Randomize aspect step" default = false visible = @p_trapaspectstep != 0 endparam } class TobysMorph(common.ulb:UserTransform) { ; A transform based upon the Morph code of Toby Marshall public: import "common.ulb" ; Constructor func TobysMorph(Generic pparent) UserTransform.UserTransform(pparent) z2m = 0 z3 = 0 z4 = 0 pzp = 0 pzq = 0 qw = 0 er = 0 ty = 0 nuvar = 0 endfunc ; Transform a single point within a sequence complex func Iterate(complex pz) UserTransform.Iterate(pz) if @tha2 == false qw = @nufunc(pz-@tw)^@exp3 er = @nufunc2((pz-@tw2)^@exp1) ty = @nufunc3((pz-@tw3)^@exp2) if @change == "1" pz = @nufunc(pz-@tw)^@exp1 elseif @change == "2" pz = qw+er elseif @change == "3" pz = qw-er elseif @change == "4" pz = qw*er elseif @change == "5" pz = qw/er elseif @change == "6" pz = qw^er elseif @change == "7" if @op == "+" pz = qw+(er+ty) elseif @op == "-" pz = qw+(er-ty) elseif @op == "*" pz = qw+(er*ty) elseif @op == "/" pz = qw+(er/ty) elseif @op == "^" pz = qw+(er^ty) endif elseif @change == "8" if @op == "+" pz = qw-(er+ty) elseif @op == "-" pz = qw-(er-ty) elseif @op == "*" pz = qw-(er*ty) elseif @op == "/" pz = qw-(er/ty) elseif @op == "^" pz = qw-(er^ty) endif elseif @change == "9" if @op == "+" pz = qw*(er+ty) elseif @op == "-" pz = qw*(er-ty) elseif @op == "*" pz = qw*(er*ty) elseif @op == "/" pz = qw*(er/ty) elseif @op == "^" pz = qw*(er^ty) endif elseif @change == "10" if @op == "+" pz = qw/(er+ty) elseif @op == "-" pz = qw/(er-ty) elseif @op == "*" pz = qw/(er*ty) elseif @op == "/" pz = qw/(er/ty) elseif @op == "^" pz = qw/(er^ty) endif elseif @change == "11" if @op == "+" pz = qw^(er+ty) elseif @op == "-" pz = qw^(er-ty) elseif @op == "*" pz = qw^(er*ty) elseif @op == "/" pz = qw^(er/ty) elseif @op == "^" pz = qw^(er^ty) endif endif else if @zchange1 == "|z|" z2m = |pz| elseif @zchange1 == "atan2(z)" z2m = atan2(pz) elseif @zchange1 == "real(z)" z2m = real(pz) elseif @zchange1 == "imag(z)" z2m = imag(pz) endif if @zchange2 == "|z|" z3 = |pz| elseif @zchange2 == "atan2(z)" z3 = atan2(pz) elseif @zchange2 == "real(z)" z3 = real(pz) elseif @zchange2 == "imag(z)" z3 = imag(pz) endif if @zchange3 == "|z|" z4 = |pz| elseif @zchange3 == "atan2(z)" z4 = atan2(pz) elseif @zchange3 == "real(z)" z4 = real(pz) elseif @zchange3 == "imag(z)" z4 = imag(pz) endif aa = @nufunc((pz-@tw)+@nufunc4(z2m-@tw4)^@exp4) bb = @nufunc((pz-@tw)-@nufunc4(z2m-@tw4)^@exp4) cc = @nufunc4((z2m-@tw4)^@exp4-@nufunc(pz-@tw)) ff = real((z3-@tw5)^@exp5) dd = @nufunc5(ff) jj = (z4-@tw6) kk = (pz-@tw2) oo = (pz-@tw3) gg = @nufunc2(kk) hh = @nufunc6(jj)^@exp6 ppp = @nufunc3(oo) if @mmode == "z+|z|" nuvar = aa elseif @mmode == "z-|z|" nuvar = bb elseif @mmode == "|z|-z" nuvar = cc endif if @change == "1" pz = nuvar^@exp1 elseif @change == "2" if @mmode2 == "z+|z|" pz = nuvar^@exp3+@nufunc2(kk+dd)^@exp1 elseif @mmode2 == "z-|z|" pz = nuvar^@exp3+@nufunc2(kk-dd)^@exp1 elseif @mmode2 == "|z|-z" pz = nuvar^@exp3+@nufunc5(ff-gg)^@exp1 elseif @mmode2 == "z*|z|" pz = nuvar^@exp3+@nufunc2(kk*dd)^@exp1 elseif @mmode2 == "z/|z|" pz = nuvar^@exp3+@nufunc2(kk/dd)^@exp1 elseif @mmode2 == "|z|/z" pz = nuvar^@exp3+@nufunc5(ff/gg)^@exp1 endif elseif @change == "3" if @mmode2 == "z+|z|" pz = nuvar^@exp3-@nufunc2(kk+dd)^@exp1 elseif @mmode2 == "z-|z|" pz = nuvar^@exp3-@nufunc2(kk-dd)^@exp1 elseif @mmode2 == "|z|-z" pz = nuvar^@exp3-@nufunc5(ff-gg)^@exp1 elseif @mmode2 == "z*|z|" pz = nuvar^@exp3-@nufunc2(kk*dd)^@exp1 elseif @mmode2 == "z/|z|" pz = nuvar^@exp3-@nufunc2(kk/dd)^@exp1 elseif @mmode2 == "|z|/z" pz = nuvar^@exp3-@nufunc5(ff/gg)^@exp1 endif elseif @change == "4" if @mmode2 == "z+|z|" pz = nuvar^@exp3*@nufunc2(kk+dd)^@exp1 elseif @mmode2 == "z-|z|" pz = nuvar^@exp3*@nufunc2(kk-dd)^@exp1 elseif @mmode2 == "|z|-z" pz = nuvar^@exp3*@nufunc5(ff-gg)^@exp1 elseif @mmode2 == "z*|z|" pz = nuvar^@exp3*@nufunc2(kk*dd)^@exp1 elseif @mmode2 == "z/|z|" pz = nuvar^@exp3*@nufunc2(kk/dd)^@exp1 elseif @mmode2 == "|z|/z" pz = nuvar^@exp3*@nufunc5(ff/gg)^@exp1 endif elseif @change == "5" if @mmode2 == "z+|z|" pz = nuvar^@exp3/@nufunc2(kk+dd)^@exp1 elseif @mmode2 == "z-|z|" pz = nuvar^@exp3/@nufunc2(kk-dd)^@exp1 elseif @mmode2 == "|z|-z" pz = nuvar^@exp3/@nufunc5(ff-gg)^@exp1 elseif @mmode2 == "z*|z|" pz = nuvar^@exp3/@nufunc2(kk*dd)^@exp1 elseif @mmode2 == "z/|z|" pz = nuvar^@exp3/@nufunc2(kk/dd)^@exp1 elseif @mmode2 == "|z|/z" pz = nuvar^@exp3/@nufunc5(ff/gg)^@exp1 endif elseif @change == "6" if @mmode2 == "z+|z|" pz = nuvar^@exp3^@nufunc2(kk+dd)^@exp1 elseif @mmode2 == "z-|z|" pz = nuvar^@exp3^@nufunc2(kk-dd)^@exp1 elseif @mmode2 == "|z|-z" pz = nuvar^@exp3^@nufunc5(ff-gg)^@exp1 elseif @mmode2 == "z*|z|" pz = nuvar^@exp3^@nufunc2(kk*dd)^@exp1 elseif @mmode2 == "z/|z|" pz = nuvar^@exp3^@nufunc2(kk/dd)^@exp1 elseif @mmode2 == "|z|/z" pz = nuvar^@exp3^@nufunc5(ff/gg)^@exp1 endif elseif @change == "7" if @mmode3 == "z+|z|" pzq = @nufunc3(oo+hh)^@exp2 elseif @mmode3 == "z-|z|" pzq = @nufunc3(oo-hh)^@exp2 elseif @mmode3 == "|z|-z" pzq = @nufunc6(jj^@exp6-ppp)^@exp2 elseif @mmode3 == "z*|z|" pzq = @nufunc3(oo*hh)^@exp2 elseif @mmode3 == "z/|z|" pzq = @nufunc3(oo/hh)^@exp2 elseif @mmode3 == "|z|/z" pzq = @nufunc6(jj^@exp6/ppp)^@exp2 endif if @mmode2 == "z+|z|" pzp = nuvar^@exp3+@nufunc2(kk+dd)^@exp1 elseif @mmode2 == "z-|z|" pzp = nuvar^@exp3+@nufunc2(kk-dd)^@exp1 elseif @mmode2 == "|z|-z" pzp = nuvar^@exp3+@nufunc5(ff-gg)^@exp1 elseif @mmode2 == "z*|z|" pzp = nuvar^@exp3+@nufunc2(kk*dd)^@exp1 elseif @mmode2 == "z/|z|" pzp = nuvar^@exp3+@nufunc2(kk/dd)^@exp1 elseif @mmode2 == "|z|/z" pzp = nuvar^@exp3+@nufunc5(ff/gg)^@exp1 endif if @op == "+" pz = pzq + pzp elseif @op == "-" pz = pzq - pzp elseif @op == "*" pz = pzq * pzp elseif @op == "/" pz = pzq / pzp elseif @op == "^" pz = pzq ^ pzp endif elseif @change == "8" if @mmode3 == "z+|z|" pzq = @nufunc3(oo+hh)^@exp2 elseif @mmode3 == "z-|z|" pzq = @nufunc3(oo-hh)^@exp2 elseif @mmode3 == "|z|-z" pzq = @nufunc6(jj^@exp6-ppp)^@exp2 elseif @mmode3 == "z*|z|" pzq = @nufunc3(oo*hh)^@exp2 elseif @mmode3 == "z/|z|" pzq = @nufunc3(oo/hh)^@exp2 elseif @mmode3 == "|z|/z" pzq = @nufunc6(jj^@exp6/ppp)^@exp2 endif if @mmode2 == "z+|z|" pzp = nuvar^@exp3-@nufunc2(kk+dd)^@exp1 elseif @mmode2 == "z-|z|" pzp = nuvar^@exp3-@nufunc2(kk-dd)^@exp1 elseif @mmode2 == "|z|-z" pzp = nuvar^@exp3-@nufunc5(ff-gg)^@exp1 elseif @mmode2 == "z*|z|" pzp = nuvar^@exp3-@nufunc2(kk*dd)^@exp1 elseif @mmode2 == "z/|z|" pzp = nuvar^@exp3-@nufunc2(kk/dd)^@exp1 elseif @mmode2 == "|z|/z" pzp = nuvar^@exp3-@nufunc5(ff/gg)^@exp1 endif if @op == "+" pz = pzq + pzp elseif @op == "-" pz = pzq - pzp elseif @op == "*" pz = pzq * pzp elseif @op == "/" pz = pzq / pzp elseif @op == "^" pz = pzq ^ pzp endif elseif @change == "9" if @mmode3 == "z+|z|" pzq = @nufunc3(oo+hh)^@exp2 elseif @mmode3 == "z-|z|" pzq = @nufunc3(oo-hh)^@exp2 elseif @mmode3 == "|z|-z" pzq = @nufunc6(jj^@exp6-ppp)^@exp2 elseif @mmode3 == "z*|z|" pzq = @nufunc3(oo*hh)^@exp2 elseif @mmode3 == "z/|z|" pzq = @nufunc3(oo/hh)^@exp2 elseif @mmode3 == "|z|/z" pzq = @nufunc6(jj^@exp6/ppp)^@exp2 endif if @mmode2 == "z+|z|" pzp = nuvar^@exp3*@nufunc2(kk+dd)^@exp1 elseif @mmode2 == "z-|z|" pzp = nuvar^@exp3*@nufunc2(kk-dd)^@exp1 elseif @mmode2 == "|z|-z" pzp = nuvar^@exp3*@nufunc5(ff-gg)^@exp1 elseif @mmode2 == "z*|z|" pzp = nuvar^@exp3*@nufunc2(kk*dd)^@exp1 elseif @mmode2 == "z/|z|" pzp = nuvar^@exp3*@nufunc2(kk/dd)^@exp1 elseif @mmode2 == "|z|/z" pzp = nuvar^@exp3*@nufunc5(ff/gg)^@exp1 endif if @op == "+" pz = pzq + pzp elseif @op == "-" pz = pzq - pzp elseif @op == "*" pz = pzq * pzp elseif @op == "/" pz = pzq / pzp elseif @op == "^" pz = pzq ^ pzp endif elseif @change == "10" if @mmode3 == "z+|z|" pzq = @nufunc3(oo+hh)^@exp2 elseif @mmode3 == "z-|z|" pzq = @nufunc3(oo-hh)^@exp2 elseif @mmode3 == "|z|-z" pzq = @nufunc6(jj^@exp6-ppp)^@exp2 elseif @mmode3 == "z*|z|" pzq = @nufunc3(oo*hh)^@exp2 elseif @mmode3 == "z/|z|" pzq = @nufunc3(oo/hh)^@exp2 elseif @mmode3 == "|z|/z" pzq = @nufunc6(jj^@exp6/ppp)^@exp2 endif if @mmode2 == "z+|z|" pzp = nuvar^@exp3/@nufunc2(kk+dd)^@exp1 elseif @mmode2 == "z-|z|" pzp = nuvar^@exp3/@nufunc2(kk-dd)^@exp1 elseif @mmode2 == "|z|-z" pzp = nuvar^@exp3/@nufunc5(ff-gg)^@exp1 elseif @mmode2 == "z*|z|" pzp = nuvar^@exp3/@nufunc2(kk*dd)^@exp1 elseif @mmode2 == "z/|z|" pzp = nuvar^@exp3/@nufunc2(kk/dd)^@exp1 elseif @mmode2 == "|z|/z" pzp = nuvar^@exp3/@nufunc5(ff/gg)^@exp1 endif if @op == "+" pz = pzq + pzp elseif @op == "-" pz = pzq - pzp elseif @op == "*" pz = pzq * pzp elseif @op == "/" pz = pzq / pzp elseif @op == "^" pz = pzq ^ pzp endif elseif @change == "11" if @mmode3 == "z+|z|" pzq = @nufunc3(oo+hh)^@exp2 elseif @mmode3 == "z-|z|" pzq = @nufunc3(oo-hh)^@exp2 elseif @mmode3 == "|z|-z" pzq = @nufunc6(jj^@exp6-ppp)^@exp2 elseif @mmode3 == "z*|z|" pzq = @nufunc3(oo*hh)^@exp2 elseif @mmode3 == "z/|z|" pzq = @nufunc3(oo/hh)^@exp2 elseif @mmode3 == "|z|/z" pzq = @nufunc6(jj^@exp6/ppp)^@exp2 endif if @mmode2 == "z+|z|" pzp = nuvar^@exp3^@nufunc2(kk+dd)^@exp1 elseif @mmode2 == "z-|z|" pzp = nuvar^@exp3^@nufunc2(kk-dd)^@exp1 elseif @mmode2 == "|z|-z" pzp = nuvar^@exp3^@nufunc5(ff-gg)^@exp1 elseif @mmode2 == "z*|z|" pzp = nuvar^@exp3^@nufunc2(kk*dd)^@exp1 elseif @mmode2 == "z/|z|" pzp = nuvar^@exp3^@nufunc2(kk/dd)^@exp1 elseif @mmode2 == "|z|/z" pzp = nuvar^@exp3^@nufunc5(ff/gg)^@exp1 endif if @op == "+" pz = pzq + pzp elseif @op == "-" pz = pzq - pzp elseif @op == "*" pz = pzq * pzp elseif @op == "/" pz = pzq / pzp elseif @op == "^" pz = pzq ^ pzp endif endif endif return pz endfunc protected: complex z2m complex z3 complex z4 complex pzp complex pzq complex qw complex er complex ty complex nuvar default: title = "Toby's Morph" int param v_tobysmorph caption = "Version (Toby's Morph)" default = 101 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_tobysmorph < 101 endparam param tha2 caption = "Morph -> Morph II" default = false endparam param change caption = "Morph" enum = "1""2""3""4""5""6""7""8""9""10""11" default = 0 endparam param mmode caption = "Z1 Mode" enum = "z+|z|""z-|z|""|z|-z" default = 0 hint = "Defines relationship of z1 to z in 1st z block" visible = @tha2 endparam param zchange1 caption = "Z1 type" enum = "|z|""atan2(z)""real(z)""imag(z)" default = 0 hint = "Determines the character of z1 variable " visible = @tha2 endparam param mmode2 caption = "Z2 Mode" enum = "z+|z|""z-|z|""|z|-z""z*|z|""z/|z|""|z|/z" default = 0 hint = "Defines relationship of z2 to z in 2nd z block" visible = @tha2 && @change > 0 endparam param zchange2 caption = "Z2 type" enum = "|z|""atan2(z)""real(z)""imag(z)" default = 0 hint = "Determines the character of z2 variable " visible = @tha2 && @change > 0 endparam param mmode3 caption = "Z3 Mode" enum = "z+|z|""z-|z|""|z|-z""z*|z|""z/|z|""|z|/z" default = 0 hint = "Defines relationship of z3 to z in 3rd z block" visible = @tha2 && @change > 5 endparam param zchange3 caption = "Z3 type" enum = "|z|""atan2(z)""real(z)""imag(z)" hint = "Determines the character of z3 variable " default = 0 visible = @tha2 && @change > 5 endparam complex param exp1 caption = "Bias 1" default = (1,0) endparam complex param exp3 caption = "Bias 2" default = (1,0) visible = @change > 0 endparam complex param exp2 caption = "Bias 3" default = (1,0) visible = @change > 5 endparam complex param exp4 caption = "Bias Z1" default = (1,0) visible = @tha2 endparam complex param exp5 caption = "Bias Z2" default = (1,0) visible = @tha2 && @change > 0 endparam complex param exp6 caption = "Bias Z3" default = (1,0) visible = @tha2 && @change > 5 endparam complex param tw caption = "Twist 1" default = (0,0) endparam complex param tw2 caption = "Twist 2" default = (0,0) visible = @change > 0 endparam complex param tw3 caption = "Twist 3" default = (0,0) visible = @change > 5 endparam complex param tw4 caption = "Twist Z1" default = (0,0) visible = @tha2 endparam complex param tw5 caption = "Twist Z2" default = (0,0) visible = @tha2 && @change > 0 endparam complex param tw6 caption = "Twist Z3" default = (0,0) visible = @tha2 && @change > 5 endparam param op caption = "Operator" enum = "+""-""*""/""^" default = 0 visible = @change > 5 endparam func nufunc caption = "Morph function 1" default = ident() endfunc func nufunc2 caption = "Morph function 2" default = ident () visible = @change > 0 endfunc func nufunc3 caption = "Morph function 3" default = ident () visible = @change > 5 endfunc func nufunc4 caption = "Morph function Z1" default = ident () visible = @tha2 endfunc func nufunc5 caption = "Morph function Z2" default = zero () visible = @tha2 && @change > 0 endfunc func nufunc6 caption = "Morph function Z3" default = zero () visible = @tha2 && @change > 5 endfunc } class Monnier_HyperbolicTiling(common.ulb:UserTransform) { ; Based upon the uxf of Samuel Monnier and used with his permission.
public: import "common.ulb" ; constructor func Monnier_HyperbolicTiling(Generic pparent) UserTransform.UserTransform(pparent) endfunc ; initialize the objects func Init(complex pz) UserTransform.Init(pz) if !@itertx complex z = pz zt = 0 nz = 0 if cabs(z) > 1 && @mode != 1 m_solid = true endif h = sqrt(cos(pi/@k)^2/(cos(pi/@k)^2-sin(pi/@n)^2)) r = sqrt(h^2-1) arg = 0 arg2 = 0 ratio = 0 int i = 0 if @mode == 1 i = @niter endif while i < @niter i = i + 1 arg = atan2(z) arg = -round(arg/(2*pi)*@n)/@n*(2*pi) zt = z*exp(1i*arg) if cabs(zt-h) > r if @sym == 0 nz = abs(zt) elseif @sym == 1 nz = zt elseif @sym == 2 nz = z endif i = @niter else z = h+r^2/(zt-h) endif endwhile endif endfunc ; call for each iterated point complex func Iterate(complex pz) UserTransform.Iterate(pz) if @itertx complex z = pz zt = 0 nz = 0 if cabs(z) > 1 && @mode != 1 m_solid = true endif h = sqrt(cos(pi/@k)^2/(cos(pi/@k)^2-sin(pi/@n)^2)) r = sqrt(h^2-1) arg = 0 arg2 = 0 ratio = 0 int i = 0 if @mode == 1 i = @niter endif while i < @niter i = i + 1 arg = atan2(z) arg = -round(arg/(2*pi)*@n)/@n*(2*pi) zt = z*exp(1i*arg) if cabs(zt-h) > r if @sym == 0 nz = abs(zt) elseif @sym == 1 nz = zt elseif @sym == 2 nz = z endif i = @niter else z = h+r^2/(zt-h) endif endwhile endif if @mode == 1 nz = 0.4*pz + 0.2 + 0.1i arg = atan2(nz) if @sym == 0 if arg < 0 || arg > pi/@n || cabs(nz-h) < r || cabs(nz) > 1 if (real(#screenpixel + imag(#screenpixel))%2) == 0 m_solid = true endif endif elseif @sym == 1 if abs(arg) > pi/@n || cabs(nz-h) < r if (real(#screenpixel + imag(#screenpixel))%2) == 0 m_solid = true endif endif elseif @sym == 2 arg = -round(arg/(2*pi)*@n)/@n*(2*pi) zt = nz*exp(1i*arg) if cabs(zt-h) < r if (real(#screenpixel + imag(#screenpixel))%2) == 0 m_solid = true endif endif endif endif nz = nz*exp(-1i*pi/180*@rot)/@magn + @center if @corrmap arg = atan2(nz) arg = -round(arg/(2*pi)*@n)/@n*(2*pi) nz = nz*exp(1i*arg) arg2 = atan2(nz) ratio = (cos(arg2)*h-sqrt(r^2-h^2*sin(arg2)^2))*cos(arg2) nz = nz/ratio*exp(-1i*(arg-pi/2)) endif return nz endfunc protected: complex nz complex zt float arg float arg2 float h float ratio float r default: title = "Monnier Hyperbolic Tiling" int param v_monnierhyperbolictiling caption = "Version (Hyperbolic Tiling)" 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_monnierhyperbolictiling < 100 endparam heading text = "Iterates the transform initialization for each iterated value of the \ pixel. May give very interesting effects but may dramatically slow \ the transform." visible = @itertx endheading param itertx caption = "Iterate transform" default = false endparam param mode caption = "Mode" default = 0 enum = "Mapping" "One Tile" endparam param n caption = "n" default = 3 endparam param k caption = "k" default = 7 endparam param sym caption = "Symetry" default = 2 enum = "Mirror+Rotation" "Rotation only" "None" endparam param center caption = "Mapping Center" default = (0,0) endparam param rot caption = "Mapping Rotation" default = 0.0 endparam param magn caption = "Mapping Magnification" default = 1.0 endparam param corrmap caption = "Correct Mapping ?" default = true endparam param niter caption = "Iteration Number" default = 1000 endparam } class REB_attract_formula_tx(common.ulb:UserTransform) { ; Strange attractor transforms.
; Object version of Attractor Formula Transforms in reb.uxf.
public: import "common.ulb" ; constructor func REB_attract_formula_tx(Generic pparent) UserTransform.UserTransform(pparent) endfunc ; initialize the objects func Init(complex pz) UserTransform.Init(pz) ; Sprott attractor data qd[0,1]=1,qd[0,2]=-1.1,qd[0,3]=-0.2,qd[0,4]=-0.1,qd[0,5]=-0.4,qd[0,6]=0.1,qd[0,7]=-0.3,qd[0,8]=0.8,qd[0,9]=-0.1,qd[0,10]=0.3,qd[0,11]=-1,qd[0,12]=-0.9 qd[1,1]=0.9,qd[1,2]=-0.1,qd[1,3]=0.2,qd[1,4]=0.5,qd[1,5]=-0.6,qd[1,6]=-1.0,qd[1,7]=-0.9,qd[1,8]=-0.8,qd[1,9]=1.0,qd[1,10]=-0.2,qd[1,11]=0.4,qd[1,12]=-0.2 qd[2,1]=-0.8,qd[2,2]=1.1,qd[2,3]=0.5,qd[2,4]=1.1,qd[2,5]=1.1,qd[2,6]=1.1,qd[2,7]=-0.6,qd[2,8]=-0.1,qd[2,9]=-0.6,qd[2,10]=-0.1,qd[2,11]=0.2,qd[2,12]=0.5 qd[3,1]=-0.8,qd[3,2]=-0.7,qd[3,3]=0.4,qd[3,4]=0.8,qd[3,5]=0.4,qd[3,6]=1.1,qd[3,7]=0.9,qd[3,8]=0.9,qd[3,9]=0.4,qd[3,10]=0.6,qd[3,11]=0.9,qd[3,12]=0.1 qd[4,1]=0.9,qd[4,2]=0.5,qd[4,3]=-1.2,qd[4,4]=0.0,qd[4,5]=-0.3,qd[4,6]=0.0,qd[4,7]=0.2,qd[4,8]=0.4,qd[4,9]=0.9,qd[4,10]=-0.1,qd[4,11]=-1.1,qd[4,12]=-0.1 qd[5,1]=0.6,qd[5,2]=-0.1,qd[5,3]=-0.5,qd[5,4]=-1.2,qd[5,5]=-0.3,qd[5,6]=-0.6,qd[5,7]=0.8,qd[5,8]=0.4,qd[5,9]=-0.1,qd[5,10]=1.0,qd[5,11]=-0.8,qd[5,12]=-1.0 qd[6,1]=-0.8,qd[6,2]=0.5,qd[6,3]=0.5,qd[6,4]=-0.7,qd[6,5]=-0.9,qd[6,6]=1.0,qd[6,7]=-0.1,qd[6,8]=-0.4,qd[6,9]=1.1,qd[6,10]=-0.4,qd[6,11]=0.0,qd[6,12]=-0.3 qd[7,1]=-0.6,qd[7,2]=0.8,qd[7,3]=0.4,qd[7,4]=-0.8,qd[7,5]=-1.0,qd[7,6]=-1.1,qd[7,7]=-0.8,qd[7,8]=1.0,qd[7,9]=0.3,qd[7,10]=1.0,qd[7,11]=0.8,qd[7,12]=0.4 qd[8,1]=-0.9,qd[8,2]=-0.4,qd[8,3]=-1.1,qd[8,4]=-0.4,qd[8,5]=0.8,qd[8,6]=0.9,qd[8,7]=0.9,qd[8,8]=-0.2,qd[8,9]=-1.1,qd[8,10]=-0.7,qd[8,11]=-0.2,qd[8,12]=0.1 qd[9,1]=-0.2,qd[9,2]=0.8,qd[9,3]=-0.4,qd[9,4]=-0.3,qd[9,5]=-0.8,qd[9,6]=1.0,qd[9,7]=0.5,qd[9,8]=-0.9,qd[9,9]=0.9,qd[9,10]=-0.6,qd[9,11]=0.4,qd[9,12]=-0.3 qd[10,1]=0.7,qd[10,2]=-0.3,qd[10,3]=-1.1,qd[10,4]=0.5,qd[10,5]=0.3,qd[10,6]=-0.7,qd[10,7]=0.0,qd[10,8]=0.9,qd[10,9]=-0.4,qd[10,10]=0.3,qd[10,11]=0.7,qd[10,12]=0.2 qd[11,1]=1.1,qd[11,2]=-0.4,qd[11,3]=-0.1,qd[11,4]=-1.1,qd[11,5]=-0.8,qd[11,6]=-0.9,qd[11,7]=-0.7,qd[11,8]=-0.7,qd[11,9]=0.7,qd[11,10]=0.4,qd[11,11]=0.0,qd[11,12]=-0.1 qd[12,1]=-1.2,qd[12,2]=-0.1,qd[12,3]=-0.5,qd[12,4]=0.6,qd[12,5]=-1.0,qd[12,6]=-0.3,qd[12,7]=-0.6,qd[12,8]=-0.2,qd[12,9]=-0.8,qd[12,10]=-0.7,qd[12,11]=-0.4,qd[12,12]=0.1 qd[13,1]=0.2,qd[13,2]=1.0,qd[13,3]=-0.3,qd[13,4]=0.9,qd[13,5]=0.6,qd[13,6]=-0.5,qd[13,7]=0.6,qd[13,8]=1.0,qd[13,9]=-1.0,qd[13,10]=-0.1,qd[13,11]=-1.2,qd[13,12]=0.8 qd[14,1]=-0.6,qd[14,2]=-0.5,qd[14,3]=0.7,qd[14,4]=0.4,qd[14,5]=-0.7,qd[14,6]=-0.1,qd[14,7]=0.7,qd[14,8]=0.4,qd[14,9]=-0.7,qd[14,10]=1.0,qd[14,11]=0.1,qd[14,12]=-0.1 qd[15,1]=0.6,qd[15,2]=-0.3,qd[15,3]=-0.1,qd[15,4]=-1.1,qd[15,5]=-1.1,qd[15,6]=0.5,qd[15,7]=-0.1,qd[15,8]=0.1,qd[15,9]=0.7,qd[15,10]=0.9,qd[15,11]=-0.8,qd[15,12]=1.0 qd[16,1]=-0.4,qd[16,2]=-1.0,qd[16,3]=-0.7,qd[16,4]=-0.7,qd[16,5]=-1.1,qd[16,6]=-0.1,qd[16,7]=1.2,qd[16,8]=-0.5,qd[16,9]=-0.7,qd[16,10]=0.3,qd[16,11]=0.5,qd[16,12]=-0.6 qd[17,1]=-0.7,qd[17,2]=0.7,qd[17,3]=1.0,qd[17,4]=-0.5,qd[17,5]=0.7,qd[17,6]=0.3,qd[17,7]=0.8,qd[17,8]=-0.9,qd[17,9]=-0.8,qd[17,10]=-1.0,qd[17,11]=-0.6,qd[17,12]=-1.1 qd[18,1]=0.8,qd[18,2]=0.3,qd[18,3]=0.0,qd[18,4]=0.2,qd[18,5]=0.3,qd[18,6]=-0.8,qd[18,7]=-0.4,qd[18,8]=-1.2,qd[18,9]=-0.9,qd[18,10]=-1.1,qd[18,11]=-0.2,qd[18,12]=0.2 qd[19,1]=0.3,qd[19,2]=1.0,qd[19,3]=-0.4,qd[19,4]=0.9,qd[19,5]=0.3,qd[19,6]=-0.5,qd[19,7]=0.0,qd[19,8]=-1.0,qd[19,9]=-1.2,qd[19,10]=0.1,qd[19,11]=-0.9,qd[19,12]=0.0 qd[20,1]=1.2,qd[20,2]=-0.2,qd[20,3]=-0.9,qd[20,4]=1.1,qd[20,5]=0.5,qd[20,6]=-0.5,qd[20,7]=0.3,qd[20,8]=-0.5,qd[20,9]=-1.2,qd[20,10]=0.6,qd[20,11]=-0.1,qd[20,12]=-0.4 qd[21,1]=0.2,qd[21,2]=0.3,qd[21,3]=0.4,qd[21,4]=-0.1,qd[21,5]=1.2,qd[21,6]=-0.5,qd[21,7]=-0.4,qd[21,8]=-1.1,qd[21,9]=0.5,qd[21,10]=-1.2,qd[21,11]=1.2,qd[21,12]=0.3 qd[22,1]=1.1,qd[22,2]=0.4,qd[22,3]=-0.3,qd[22,4]=-0.2,qd[22,5]=0.4,qd[22,6]=-1.0,qd[22,7]=0.6,qd[22,8]=-0.4,qd[22,9]=-0.5,qd[22,10]=1.2,qd[22,11]=-0.9,qd[22,12]=1.0 qd[23,1]=-1.1,qd[23,2]=0.9,qd[23,3]=1.1,qd[23,4]=0.4,qd[23,5]=-1.2,qd[23,6]=1.0,qd[23,7]=0.3,qd[23,8]=0.3,qd[23,9]=0.3,qd[23,10]=-0.7,qd[23,11]=0.6,qd[23,12]=-0.9 qd[24,1]=-0.1,qd[24,2]=-0.4,qd[24,3]=-0.8,qd[24,4]=-0.8,qd[24,5]=0.9,qd[24,6]=-0.2,qd[24,7]=0.9,qd[24,8]=-0.2,qd[24,9]=-0.9,qd[24,10]=-0.9,qd[24,11]=-0.4,qd[24,12]=-1.2 qd[25,1]=-0.7,qd[25,2]=-0.2,qd[25,3]=-0.4,qd[25,4]=0.4,qd[25,5]=-0.9,qd[25,6]=0.9,qd[25,7]=0.3,qd[25,8]=-0.3,qd[25,9]=-1.1,qd[25,10]=-0.2,qd[25,11]=0.0,qd[25,12]=-0.4 qd[26,1]=-0.6,qd[26,2]=1.1,qd[26,3]=-0.2,qd[26,4]=0.7,qd[26,5]=-0.1,qd[26,6]=1.1,qd[26,7]=-1.2,qd[26,8]=0.0,qd[26,9]=1.1,qd[26,10]=0.3,qd[26,11]=0.7,qd[26,12]=0.8 qd[27,1]=0.1,qd[27,2]=-0.7,qd[27,3]=0.2,qd[27,4]=-0.2,qd[27,5]=0.1,qd[27,6]=1.2,qd[27,7]=-0.5,qd[27,8]=-0.9,qd[27,9]=0.5,qd[27,10]=0.4,qd[27,11]=-1.0,qd[27,12]=0.2 qd[28,1]=0.7,qd[28,2]=-0.6,qd[28,3]=-0.2,qd[28,4]=0.1,qd[28,5]=0.2,qd[28,6]=-0.2,qd[28,7]=-0.8,qd[28,8]=-0.7,qd[28,9]=0.6,qd[28,10]=1.2,qd[28,11]=0.4,qd[28,12]=1.2 qd[29,1]=-0.4,qd[29,2]=-0.1,qd[29,3]=-0.2,qd[29,4]=-0.4,qd[29,5]=-1.2,qd[29,6]=0.8,qd[29,7]=-0.7,qd[29,8]=-0.1,qd[29,9]=0.6,qd[29,10]=0.5,qd[29,11]=-0.9,qd[29,12]=0.7 qd[30,1]=-0.9,qd[30,2]=0.4,qd[30,3]=-0.6,qd[30,4]=-0.7,qd[30,5]=1.1,qd[30,6]=0.9,qd[30,7]=0.2,qd[30,8]=-1.0,qd[30,9]=0.3,qd[30,10]=1.1,qd[30,11]=0.3,qd[30,12]=0.0 qd[31,1]=-0.6,qd[31,2]=-0.4,qd[31,3]=1.1,qd[31,4]=-1.0,qd[31,5]=-0.6,qd[31,6]=1.2,qd[31,7]=0.4,qd[31,8]=0.3,qd[31,9]=-0.1,qd[31,10]=-0.8,qd[31,11]=0.9,qd[31,12]=0.1, qd[32,1]=0.2,qd[32,2]=-0.2,qd[32,3]=-0.3,qd[32,4]=-1.1,qd[32,5]=-0.3,qd[32,6]=-0.9,qd[32,7]=0.4,qd[32,8]=1.0,qd[32,9]=0.5,qd[32,10]=1.1,qd[32,11]=-0.7,qd[32,12]=-1.2 qd[33,1]=1.0,qd[33,2]=-0.8,qd[33,3]=-0.9,qd[33,4]=-0.3,qd[33,5]=-0.8,qd[33,6]=-0.1,qd[33,7]=0.3,qd[33,8]=-0.3,qd[33,9]=0.1,qd[33,10]=-0.1,qd[33,11]=0.1,qd[33,12]=-1.1 qd[34,1]=0.0,qd[34,2]=-0.9,qd[34,3]=0.0,qd[34,4]=-0.8,qd[34,5]=0.6,qd[34,6]=0.9,qd[34,7]=0.2,qd[34,8]=-0.9,qd[34,9]=-1.0,qd[34,10]=-1.2,qd[34,11]=-0.8,qd[34,12]=-1.2 qd[35,1]=0.2,qd[35,2]=0.4,qd[35,3]=-1.2,qd[35,4]=-0.6,qd[35,5]=-1.2,qd[35,6]=0.6,qd[35,7]=0.4,qd[35,8]=-1.1,qd[35,9]=1.2,qd[35,10]=-0.9,qd[35,11]=-0.4,qd[35,12]=-0.1 qd[36,1]=0.7,qd[36,2]=0.5,qd[36,3]=-1.2,qd[36,4]=-0.6,qd[36,5]=0.3,qd[36,6]=0.2,qd[36,7]=-1.2,qd[36,8]=-0.6,qd[36,9]=0.2,qd[36,10]=-0.7,qd[36,11]=-0.1,qd[36,12]=0.8 qd[37,1]=0.3,qd[37,2]=-0.3,qd[37,3]=-1.1,qd[37,4]=-1.0,qd[37,5]=0.5,qd[37,6]=-0.8,qd[37,7]=0.8,qd[37,8]=1.1,qd[37,9]=0.8,qd[37,10]=0.1,qd[37,11]=-0.9,qd[37,12]=0.1 qd[38,1]=-0.8,qd[38,2]=-1.1,qd[38,3]=-0.1,qd[38,4]=-0.5,qd[38,5]=-0.2,qd[38,6]=0.6,qd[38,7]=0.0,qd[38,8]=-0.8,qd[38,9]=-0.3,qd[38,10]=1.2,qd[38,11]=-1.0,qd[38,12]=1.1 qd[39,1]=0.5,qd[39,2]=0.3,qd[39,3]=-0.7,qd[39,4]=-0.2,qd[39,5]=-0.3,qd[39,6]=1.1,qd[39,7]=0.8,qd[39,8]=1.1,qd[39,9]=-1.0,qd[39,10]=-0.1,qd[39,11]=0.4,qd[39,12]=-0.6 qd[40,1]=-0.5,qd[40,2]=0.4,qd[40,3]=0.6,qd[40,4]=0.8,qd[40,5]=-0.3,qd[40,6]=-1.2,qd[40,7]=0.7,qd[40,8]=-0.5,qd[40,9]=-0.7,qd[40,10]=-1.0,qd[40,11]=0.1,qd[40,12]=-0.5 qd[41,1]=1.1,qd[41,2]=0.3,qd[41,3]=-1.2,qd[41,4]=1.0,qd[41,5]=0.7,qd[41,6]=-1.2,qd[41,7]=0.8,qd[41,8]=-0.7,qd[41,9]=0.1,qd[41,10]=-0.2,qd[41,11]=-1.0,qd[41,12]=1.0 qd[42,1]=-0.6,qd[42,2]=-0.2,qd[42,3]=1.0,qd[42,4]=0.9,qd[42,5]=-1.1,qd[42,6]=-0.6,qd[42,7]=0.3,qd[42,8]=0.7,qd[42,9]=-0.7,qd[42,10]=0.0,qd[42,11]=0.1,qd[42,12]=-0.6 qd[43,1]=0.6,qd[43,2]=-0.6,qd[43,3]=-0.5,qd[43,4]=0.2,qd[43,5]=-0.7,qd[43,6]=0.3,qd[43,7]=-0.5,qd[43,8]=0.8,qd[43,9]=-0.5,qd[43,10]=-1.1,qd[43,11]=-0.2,qd[43,12]=1.2 qd[44,1]=0.0,qd[44,2]=0.2,qd[44,3]=0.1,qd[44,4]=-0.9,qd[44,5]=-0.9,qd[44,6]=-1.2,qd[44,7]=-0.8,qd[44,8]=-1.0,qd[44,9]=0.4,qd[44,10]=0.1,qd[44,11]=0.6,qd[44,12]=0.4 qd[45,1]=-1.2,qd[45,2]=1.0,qd[45,3]=1.2,qd[45,4]=-0.8,qd[45,5]=-1.1,qd[45,6]=0.4,qd[45,7]=-0.2,qd[45,8]=0.6,qd[45,9]=-0.2,qd[45,10]=0.5,qd[45,11]=-1.0,qd[45,12]=-0.2 qd[46,1]=-0.2,qd[46,2]=-1.1,qd[46,3]=-0.5,qd[46,4]=0.1,qd[46,5]=0.9,qd[46,6]=0.3,qd[46,7]=0.5,qd[46,8]=-0.6,qd[46,9]=-1.0,qd[46,10]=0.8,qd[46,11]=-0.7,qd[46,12]=-0.7 qd[47,1]=-0.3,qd[47,2]=-0.3,qd[47,3]=0.7,qd[47,4]=-0.9,qd[47,5]=1.0,qd[47,6]=0.8,qd[47,7]=-0.7,qd[47,8]=-0.9,qd[47,9]=0.5,qd[47,10]=0.8,qd[47,11]=0.1,qd[47,12]=0.2 qd[48,1]=-0.8,qd[48,2]=-0.8,qd[48,3]=1.2,qd[48,4]=0.7,qd[48,5]=-0.7,qd[48,6]=0.1,qd[48,7]=1.0,qd[48,8]=-0.8,qd[48,9]=-0.6,qd[48,10]=0.5,qd[48,11]=1.0,qd[48,12]=-0.5 qd[49,1]=-0.3,qd[49,2]=-0.9,qd[49,3]=0.6,qd[49,4]=-0.2,qd[49,5]=-0.1,qd[49,6]=0.4,qd[49,7]=0.5,qd[49,8]=-1.1,qd[49,9]=1.0,qd[49,10]=-1.2,qd[49,11]=0.0,qd[49,12]=-1.0 qd[50,1]=-0.9,qd[50,2]=-0.2,qd[50,3]=1.1,qd[50,4]=0.5,qd[50,5]=0.5,qd[50,6]=-0.8,qd[50,7]=0.3,qd[50,8]=0.2,qd[50,9]=0.0,qd[50,10]=0.3,qd[50,11]=-0.6,qd[50,12]=-1.1 qd[51,1]=-1.1,qd[51,2]=0.0,qd[51,3]=1.0,qd[51,4]=0.0,qd[51,5]=0.4,qd[51,6]=0.1,qd[51,7]=-0.3,qd[51,8]=-0.7,qd[51,9]=-0.6,qd[51,10]=0.7,qd[51,11]=-0.8,qd[51,12]=0.9 qd[52,1]=0.0,qd[52,2]=-0.5,qd[52,3]=-0.2,qd[52,4]=-1.0,qd[52,5]=-1.2,qd[52,6]=-1.0,qd[52,7]=0.7,qd[52,8]=-0.3,qd[52,9]=-0.8,qd[52,10]=0.4,qd[52,11]=0.0,qd[52,12]=-0.5 qd[53,1]=-0.1,qd[53,2]=0.5,qd[53,3]=-0.1,qd[53,4]=-1.0,qd[53,5]=-0.6,qd[53,6]=-0.5,qd[53,7]=-0.6,qd[53,8]=-0.4,qd[53,9]=0.4,qd[53,10]=-0.8,qd[53,11]=-1.2,qd[53,12]=0.5 qd[54,1]=0.1,qd[54,2]=-0.8,qd[54,3]=0.6,qd[54,4]=0.1,qd[54,5]=1.1,qd[54,6]=0.6,qd[54,7]=0.3,qd[54,8]=-0.8,qd[54,9]=-1.0,qd[54,10]=-0.5,qd[54,11]=-0.5,qd[54,12]=-1.1 qd[55,1]=-1.1,qd[55,2]=0.1,qd[55,3]=1.1,qd[55,4]=0.9,qd[55,5]=0.3,qd[55,6]=-0.3,qd[55,7]=0.9,qd[55,8]=-1.1,qd[55,9]=-0.5,qd[55,10]=0.7,qd[55,11]=0.6,qd[55,12]=-0.2 qd[56,1]=-0.9,qd[56,2]=0.4,qd[56,3]=1.2,qd[56,4]=-1.2,qd[56,5]=0.8,qd[56,6]=0.5,qd[56,7]=-0.5,qd[56,8]=0.5,qd[56,9]=0.8,qd[56,10]=-0.4,qd[56,11]=-1.0,qd[56,12]=-1.1 qd[57,1]=0.8,qd[57,2]=-0.3,qd[57,3]=0.4,qd[57,4]=-1.0,qd[57,5]=-0.5,qd[57,6]=0.3,qd[57,7]=-1.1,qd[57,8]=0.0,qd[57,9]=0.3,qd[57,10]=0.1,qd[57,11]=-0.8,qd[57,12]=0.7 qd[58,1]=-0.2,qd[58,2]=-1.2,qd[58,3]=1.2,qd[58,4]=1.1,qd[58,5]=-1.0,qd[58,6]=0.9,qd[58,7]=0.1,qd[58,8]=-0.5,qd[58,9]=0.7,qd[58,10]=-1.2,qd[58,11]=-0.6,qd[58,12]=1.2 qd[59,1]=-0.1,qd[59,2]=-1.0,qd[59,3]=-0.7,qd[59,4]=0.9,qd[59,5]=0.4,qd[59,6]=-0.1,qd[59,7]=-0.6,qd[59,8]=0.4,qd[59,9]=0.6,qd[59,10]=1.0,qd[59,11]=-0.7,qd[59,12]=1.1 qd[60,1]=-0.4,qd[60,2]=-0.3,qd[60,3]=0.1,qd[60,4]=0.7,qd[60,5]=1.0,qd[60,6]=0.6,qd[60,7]=-0.3,qd[60,8]=1.0,qd[60,9]=-0.8,qd[60,10]=-0.5,qd[60,11]=0.5,qd[60,12]=0.8 qd[61,1]=0.4,qd[61,2]=-0.7,qd[61,3]=0.7,qd[61,4]=0.0,qd[61,5]=1.1,qd[61,6]=0.9,qd[61,7]=0.2,qd[61,8]=-0.9,qd[61,9]=-1.1,qd[61,10]=-0.4,qd[61,11]=-0.1,qd[61,12]=0.1 qd[62,1]=0.7,qd[62,2]=-0.2,qd[62,3]=-0.6,qd[62,4]=0.9,qd[62,5]=0.0,qd[62,6]=0.3,qd[62,7]=1.2,qd[62,8]=0.3,qd[62,9]=-0.6,qd[62,10]=-0.6,qd[62,11]=0.3,qd[62,12]=-1.0 qd[63,1]=1.0,qd[63,2]=0.7,qd[63,3]=-0.7,qd[63,4]=-0.2,qd[63,5]=0.9,qd[63,6]=0.1,qd[63,7]=0.9,qd[63,8]=1.0,qd[63,9]=-0.9,qd[63,10]=1.0,qd[63,11]=-0.2,qd[63,12]=-0.3 qd[64,1]=-0.7,qd[64,2]=1.1,qd[64,3]=0.9,qd[64,4]=1.1,qd[64,5]=0.3,qd[64,6]=-0.2,qd[64,7]=0.3,qd[64,8]=-1.1,qd[64,9]=-1.0,qd[64,10]=0.4,qd[64,11]=-0.6,qd[64,12]=-0.5 qd[65,1]=0.5,qd[65,2]=-0.2,qd[65,3]=-0.1,qd[65,4]=-0.6,qd[65,5]=0.3,qd[65,6]=0.7,qd[65,7]=1.0,qd[65,8]=0.6,qd[65,9]=-0.2,qd[65,10]=-1.2,qd[65,11]=0.3,qd[65,12]=-0.6 qd[66,1]=1.0,qd[66,2]=-0.8,qd[66,3]=-0.5,qd[66,4]=0.2,qd[66,5]=0.1,qd[66,6]=-0.4,qd[66,7]=-0.7,qd[66,8]=-0.4,qd[66,9]=1.1,qd[66,10]=-1.1,qd[66,11]=-0.5,qd[66,12]=-0.5 qd[67,1]=1.1,qd[67,2]=-0.4,qd[67,3]=-0.2,qd[67,4]=-0.6,qd[67,5]=0.4,qd[67,6]=-0.8,qd[67,7]=0.5,qd[67,8]=-0.9,qd[67,9]=-0.6,qd[67,10]=0.1,qd[67,11]=1.2,qd[67,12]=0.7 qd[68,1]=-0.2,qd[68,2]=-0.5,qd[68,3]=-0.1,qd[68,4]=-0.1,qd[68,5]=0.7,qd[68,6]=0.3,qd[68,7]=1.1,qd[68,8]=0.9,qd[68,9]=-0.8,qd[68,10]=0.2,qd[68,11]=0.2,qd[68,12]=-0.5 qd[69,1]=1.1,qd[69,2]=-0.9,qd[69,3]=0.4,qd[69,4]=-0.7,qd[69,5]=0.2,qd[69,6]=0.0,qd[69,7]=0.4,qd[69,8]=1.2,qd[69,9]=0.8,qd[69,10]=-0.7,qd[69,11]=-0.8,qd[69,12]=0.1 qd[70,1]=-0.8,qd[70,2]=0.3,qd[70,3]=0.4,qd[70,4]=-1.1,qd[70,5]=-0.1,qd[70,6]=1.2,qd[70,7]=-0.9,qd[70,8]=-0.7,qd[70,9]=1.2,qd[70,10]=-1.1,qd[70,11]=-0.2,qd[70,12]=0.3 qd[71,1]=-0.3,qd[71,2]=-1.2,qd[71,3]=0.5,qd[71,4]=-0.8,qd[71,5]=0.2,qd[71,6]=1.1,qd[71,7]=1.2,qd[71,8]=-0.8,qd[71,9]=0.9,qd[71,10]=-1.1,qd[71,11]=-1.1,qd[71,12]=1.2, qd[72,1]=-0.3,qd[72,2]=-1.2,qd[72,3]=0.7,qd[72,4]=0.3,qd[72,5]=0.4,qd[72,6]=0.6,qd[72,7]=0.1,qd[72,8]=0.7,qd[72,9]=-0.6,qd[72,10]=-0.6,qd[72,11]=0.7,qd[72,12]=0.8 qd[73,1]=-1.1,qd[73,2]=0.2,qd[73,3]=0.2,qd[73,4]=-1.1,qd[73,5]=-0.6,qd[73,6]=1.1,qd[73,7]=-0.1,qd[73,8]=0.5,qd[73,9]=1.2,qd[73,10]=0.9,qd[73,11]=0.8,qd[73,12]=-0.7 qd[74,1]=0.9,qd[74,2]=0.5,qd[74,3]=-1.1,qd[74,4]=-0.5,qd[74,5]=0.0,qd[74,6]=-1.2,qd[74,7]=0.2,qd[74,8]=1.2,qd[74,9]=-0.5,qd[74,10]=-0.3,qd[74,11]=-0.3,qd[74,12]=-0.8 qd[75,1]=0.8,qd[75,2]=0.7,qd[75,3]=-1.2,qd[75,4]=0.4,qd[75,5]=-0.1,qd[75,6]=-1.2,qd[75,7]=-0.7,qd[75,8]=-0.1,qd[75,9]=-1.0,qd[75,10]=0.0,qd[75,11]=-1.0,qd[75,12]=-0.3 qd[76,1]=-0.8,qd[76,2]=1.0,qd[76,3]=0.9,qd[76,4]=-1.1,qd[76,5]=-0.9,qd[76,6]=0.4,qd[76,7]=0.6,qd[76,8]=-0.1,qd[76,9]=0.8,qd[76,10]=-0.5,qd[76,11]=-0.2,qd[76,12]=-0.3 qd[77,1]=-0.7,qd[77,2]=-1.1,qd[77,3]=0.5,qd[77,4]=0.1,qd[77,5]=-0.6,qd[77,6]=0.6,qd[77,7]=-0.1,qd[77,8]=1.1,qd[77,9]=0.0,qd[77,10]=-1.2,qd[77,11]=-0.1,qd[77,12]=0.4 qd[78,1]=0.5,qd[78,2]=-1.1,qd[78,3]=-1.1,qd[78,4]=0.0,qd[78,5]=-0.5,qd[78,6]=0.0,qd[78,7]=0.7,qd[78,8]=1.2,qd[78,9]=-0.9,qd[78,10]=-0.2,qd[78,11]=0.5,qd[78,12]=-1.0 qd[79,1]=-0.4,qd[79,2]=-0.3,qd[79,3]=0.3,qd[79,4]=-0.1,qd[79,5]=-1.0,qd[79,6]=1.0,qd[79,7]=-0.7,qd[79,8]=-0.7,qd[79,9]=1.0,qd[79,10]=-1.2,qd[79,11]=0.5,qd[79,12]=0.8 qd[80,1]=0.6,qd[80,2]=-0.3,qd[80,3]=0.0,qd[80,4]=0.4,qd[80,5]=-0.8,qd[80,6]=-0.3,qd[80,7]=-0.7,qd[80,8]=-0.9,qd[80,9]=-0.3,qd[80,10]=0.2,qd[80,11]=1.1,qd[80,12]=1.1 qd[81,1]=-0.3,qd[81,2]=-0.7,qd[81,3]=0.2,qd[81,4]=-0.7,qd[81,5]=-0.3,qd[81,6]=0.5,qd[81,7]=1.2,qd[81,8]=-0.1,qd[81,9]=-0.8,qd[81,10]=-1.1,qd[81,11]=-0.1,qd[81,12]=-0.8 qd[82,1]=0.2,qd[82,2]=-0.4,qd[82,3]=-0.9,qd[82,4]=-0.2,qd[82,5]=1.2,qd[82,6]=1.2,qd[82,7]=0.3,qd[82,8]=-0.7,qd[82,9]=-1.1,qd[82,10]=-0.2,qd[82,11]=-0.2,qd[82,12]=-0.7 qd[83,1]=1.2,qd[83,2]=-0.7,qd[83,3]=-0.5,qd[83,4]=0.1,qd[83,5]=0.2,qd[83,6]=-1.1,qd[83,7]=0.3,qd[83,8]=-1.0,qd[83,9]=0.6,qd[83,10]=-0.3,qd[83,11]=0.2,qd[83,12]=-1.1 qd[84,1]=0.7,qd[84,2]=-1.2,qd[84,3]=0.9,qd[84,4]=0.0,qd[84,5]=-0.7,qd[84,6]=0.2,qd[84,7]=-0.7,qd[84,8]=1.2,qd[84,9]=0.5,qd[84,10]=1.0,qd[84,11]=-0.4,qd[84,12]=1.2 qd[85,1]=1.1,qd[85,2]=-0.4,qd[85,3]=-0.7,qd[85,4]=0.4,qd[85,5]=0.7,qd[85,6]=-0.4,qd[85,7]=-0.3,qd[85,8]=0.5,qd[85,9]=-0.2,qd[85,10]=0.6,qd[85,11]=0.0,qd[85,12]=0.8 qd[86,1]=1.2,qd[86,2]=-0.3,qd[86,3]=-0.1,qd[86,4]=-0.9,qd[86,5]=0.6,qd[86,6]=0.0,qd[86,7]=0.6,qd[86,8]=0.6,qd[86,9]=0.9,qd[86,10]=-0.6,qd[86,11]=-1.2,qd[86,12]=0.4 qd[87,1]=0.3,qd[87,2]=-1.0,qd[87,3]=0.3,qd[87,4]=-0.1,qd[87,5]=-1.0,qd[87,6]=1.1,qd[87,7]=-0.8,qd[87,8]=-0.4,qd[87,9]=0.6,qd[87,10]=0.0,qd[87,11]=0.6,qd[87,12]=1.0 qd[88,1]=-0.3,qd[88,2]=0.0,qd[88,3]=-0.3,qd[88,4]=0.8,qd[88,5]=-0.8,qd[88,6]=0.8,qd[88,7]=0.7,qd[88,8]=1.1,qd[88,9]=-0.5,qd[88,10]=0.0,qd[88,11]=0.6,qd[88,12]=-1.0 qd[89,1]=0.4,qd[89,2]=0.8,qd[89,3]=-0.3,qd[89,4]=-0.2,qd[89,5]=-1.2,qd[89,6]=-0.2,qd[89,7]=0.0,qd[89,8]=0.0,qd[89,9]=1.2,qd[89,10]=1.2,qd[89,11]=0.5,qd[89,12]=-1.1 qd[90,1]=0.5,qd[90,2]=-0.4,qd[90,3]=-0.8,qd[90,4]=-1.0,qd[90,5]=0.0,qd[90,6]=-0.7,qd[90,7]=0.0,qd[90,8]=-0.5,qd[90,9]=-1.1,qd[90,10]=1.0,qd[90,11]=0.8,qd[90,12]=0.1 qd[91,1]=-0.6,qd[91,2]=0.1,qd[91,3]=-0.3,qd[91,4]=-0.8,qd[91,5]=-0.5,qd[91,6]=0.2,qd[91,7]=-1.1,qd[91,8]=0.3,qd[91,9]=0.6,qd[91,10]=1.0,qd[91,11]=-0.2,qd[91,12]=0.9 qd[92,1]=1.0,qd[92,2]=0.3,qd[92,3]=-0.5,qd[92,4]=0.6,qd[92,5]=-1.2,qd[92,6]=-0.1,qd[92,7]=-1.0,qd[92,8]=-0.3,qd[92,9]=0.0,qd[92,10]=-1.2,qd[92,11]=0.4,qd[92,12]=0.1, qd[93,1]=-0.1,qd[93,2]=-1.2,qd[93,3]=-1.1,qd[93,4]=-0.3,qd[93,5]=0.9,qd[93,6]=-0.7,qd[93,7]=1.0,qd[93,8]=0.1,qd[93,9]=0.3,qd[93,10]=-0.6,qd[93,11]=0.4,qd[93,12]=-0.5 qd[94,1]=-1.2,qd[94,2]=0.8,qd[94,3]=0.1,qd[94,4]=1.1,qd[94,5]=-0.7,qd[94,6]=1.2,qd[94,7]=-0.5,qd[94,8]=0.7,qd[94,9]=-0.4,qd[94,10]=0.9,qd[94,11]=-1.2,qd[94,12]=-0.3 qd[95,1]=0.2,qd[95,2]=-0.4,qd[95,3]=-0.9,qd[95,4]=0.0,qd[95,5]=0.6,qd[95,6]=0.4,qd[95,7]=0.5,qd[95,8]=0.7,qd[95,9]=-1.1,qd[95,10]=0.4,qd[95,11]=-0.2,qd[95,12]=-1.1 qd[96,1]=0.8,qd[96,2]=0.2,qd[96,3]=-1.1,qd[96,4]=0.7,qd[96,5]=-1.2,qd[96,6]=-1.0,qd[96,7]=0.0,qd[96,8]=-0.3,qd[96,9]=1.1,qd[96,10]=-0.8,qd[96,11]=-0.5,qd[96,12]=0.9 qd[97,1]=0.7,qd[97,2]=-0.7,qd[97,3]=1.2,qd[97,4]=0.1,qd[97,5]=-1.0,qd[97,6]=0.1,qd[97,7]=0.5,qd[97,8]=1.1,qd[97,9]=-0.9,qd[97,10]=0.9,qd[97,11]=0.6,qd[97,12]=-1.2 qd[98,1]=1.0,qd[98,2]=-0.1,qd[98,3]=-0.8,qd[98,4]=0.0,qd[98,5]=0.7,qd[98,6]=-0.6,qd[98,7]=0.6,qd[98,8]=0.2,qd[98,9]=-0.2,qd[98,10]=0.8,qd[98,11]=1.0,qd[98,12]=-0.4 qd[99,1]=0.2,qd[99,2]=-0.9,qd[99,3]=0.1,qd[99,4]=0.5,qd[99,5]=0.0,qd[99,6]=0.8,qd[99,7]=-1.0,qd[99,8]=-0.4,qd[99,9]=0.9,qd[99,10]=-0.2,qd[99,11]=0.6,qd[99,12]=0.0 qd[100,1]=-1.0,qd[100,2]=-0.4,qd[100,3]=-0.3,qd[100,4]=0.9,qd[100,5]=0.8,qd[100,6]=1.0,qd[100,7]=-1.2,qd[100,8]=0.5,qd[100,9]=0.3,qd[100,10]=-0.4,qd[100,11]=0.1,qd[100,12]=0.1 sq1 = qd[@select,1] sq2 = qd[@select,2] sq3 = qd[@select,3] sq4 = qd[@select,4] sq5 = qd[@select,5] sq6 = qd[@select,6] sq7 = qd[@select,7] sq8 = qd[@select,8] sq9 = qd[@select,9] sq10 = qd[@select,10] sq11 = qd[@select,11] sq12 = qd[@select,12] endfunc complex func Iterate(complex pz) UserTransform.Iterate(pz) if @h2c == "0" h2c = 0 elseif @h2c == "1" h2c = 1 endif if @formula == 9 x = @fx y = @fy endif if @formula != 9 x = 0 y = 0 endif complex w = @fn1(pz - @offset) if @formula == 0 x = real(w) / @scale y = imag(w) / @scale elseif @formula == 1 x = real(w) / @mscale y = imag(w) / @mscale elseif @formula == 2 x = real(w) / @hscale y = imag(w) / @hscale elseif @formula == 9 x = real(w) / @h2scale y = imag(w) / @h2scale elseif @formula == 3 x = real(w) / @pscale y = imag(w) / @pscale elseif @formula == 4 x = real(w) / @qscale y = imag(w) / @qscale elseif @formula == 6 x = real(w) / @tscale y = imag(w) / @tscale elseif @formula == 7 x = real(w) / @lscale y = imag(w) / @lscale elseif @formula == 8 x = real(w) / @zscale y = imag(w) / @zscale elseif @formula == "Sprottquad" x = real(w) / @sqscale y = imag(w) / @sqscale endif float xx = 0 float zz = 0 int i = 0 float iterate = 0 if @formula == 3 iterate = @piters elseif @formula == 7 iterate = @liters elseif @formula == "Sprottquad" iterate = @sqiters else iterate = @iters endif while (i < iterate) xx = x if @formula == 6 ; Threeply if x != 0 x = y - x/abs(x)*(abs(sin(x)*cos(@tb) + @tc \ - x*sin(@ta + @tb + @tc))) else x = y - abs(sin(x)*cos(@tb) + @tc \ - x*sin(@ta + @tb + @tc)) endif y = @ta - xx elseif @formula == 2 ; Hopalong if x != 0 x = y - x/abs(x)*sqrt(abs(@hb*x-@hc)) else x = y - sqrt(abs(@hb*x-@hc)) endif y = @ha - xx elseif @formula == 9 ; New Hopalong if x != 0 x = y - x/abs(x)*sqrt(abs(@h2b*x-h2c)) else x = y - sqrt(abs(@h2b*x-h2c)) endif y = @h2a - xx elseif @formula == 0 ; Chip if x != 0 x = y - x/abs(x)*cos(sqr(log(abs(@cb*x-@cc)))) \ *atan(sqr(log(abs(@cc*x-@cb)))) else x = y - cos(sqr(log(abs(@cb*x-@cc)))) \ *atan(sqr(log(abs(@cc*x-@cb)))) endif y = @ca - xx elseif @formula == 4 ; Quadruptwo if x != 0 x = y - x/abs(x)*sin(log(abs(@qb*x-@qc))) \ *atan(sqr(log(abs(@qc*x-@qb)))) else x = y - sin(log(abs(@qb*x-@qc))) \ *atan(sqr(log(abs(@qc*x-@qb)))) endif y = @qa - xx elseif @formula == 3 ; Pickover x = real(@pfn1(@pa*y)) - zz*real(@pfn2(@pb*x)) y = zz*real(@pfn3(@pc*xx)) - real(@pfn4(@pd*y)) zz = real(@pfn5(xx)) elseif @formula == 1 ; CosMartin x = y - cos(x) y = @ma - xx elseif @formula == 7 ; Latoocarfian x = real(@lfn1(y*@lb)) + @lc*real(@lfn2(x*@lb)) y = real(@lfn3(xx*@la)) + @ld*real(@lfn4(y*@la)) elseif @formula == 8 ; Zito x = x*y +@za*x - y y = xx + y elseif @formula == "Sprottquad" ; Sprottquad x = sq1 + sq2*x + sq3*x*x + sq4*x*y + sq5*y + sq6*y*y y = sq7 + sq8*xx + sq9*xx*xx + sq10*xx*y + sq11*y + sq12*y*y endif i = i + 1 endwhile if @formula==3 if @plane == 1 y = zz elseif @plane == 2 x = zz endif endif if @formula == 0 if @mode == 0 w = @fn2(x * @scale + flip(y * @scale) + @offset) elseif @mode == 1 x = (@scale * x + real(@offset)) * @strength y = (@scale * y + imag(@offset)) * @strength w = @fn2(pz + x + flip(y)) endif elseif @formula == 1 if @mode == 0 w = @fn2(x * @mscale + flip(y * @mscale) + @offset) elseif @mode == 1 x = (@mscale * x + real(@offset)) * @strength y = (@mscale * y + imag(@offset)) * @strength w = @fn2(pz + x + flip(y)) endif elseif @formula == 2 if @mode == 0 w = @fn2(x * @hscale + flip(y * @hscale) + @offset) elseif @mode == 1 x = (@hscale * x + real(@offset)) * @strength y = (@hscale * y + imag(@offset)) * @strength w = @fn2(pz + x + flip(y)) endif elseif @formula == 9 if @mode == 0 w = @fn2(x * @h2scale + flip(y * @h2scale) + @offset) elseif @mode == 1 x = (@h2scale * x + real(@offset)) * @strength y = (@h2scale * y + imag(@offset)) * @strength w = @fn2(pz + x + flip(y)) endif elseif @formula == 3 if @mode == 0 w = @fn2(x * @pscale + flip(y * @pscale) + @offset) elseif @mode == 1 x = (@pscale * x + real(@offset)) * @strength y = (@pscale * y + imag(@offset)) * @strength w = @fn2(pz + x + flip(y)) endif elseif @formula == 4 if @mode == 0 w = @fn2(x * @qscale + flip(y * @qscale) + @offset) elseif @mode == 1 x = (@qscale * x + real(@offset)) * @strength y = (@qscale * y + imag(@offset)) * @strength w = @fn2(pz + x + flip(y)) endif elseif @formula == "Sprottquad" if @mode == 0 w = @fn2(x * @sqscale + flip(y * @sqscale) + @offset) elseif @mode == 1 x = (@sqscale * x + real(@offset)) * @strength y = (@sqscale * y + imag(@offset)) * @strength w = @fn2(pz + x + flip(y)) endif elseif @formula == 6 if @mode == 0 w = @fn2(x * @tscale + flip(y * @tscale) + @offset) elseif @mode == 1 x = (@tscale * x + real(@offset)) * @strength y = (@tscale * y + imag(@offset)) * @strength w = @fn2(pz + x + flip(y)) endif elseif @formula == 7 if @mode == 0 w = @fn2(x * @lscale + flip(y * @lscale) + @offset) elseif @mode == 1 x = (@lscale * x + real(@offset)) * @strength y = (@lscale * y + imag(@offset)) * @strength w = @fn2(pz + x + flip(y)) endif elseif @formula == 8 if @mode == 0 w = @fn2(x * @zscale + flip(y * @zscale) + @offset) elseif @mode == 1 x = (@zscale * x + real(@offset)) * @strength y = (@zscale * y + imag(@offset)) * @strength w = @fn2(pz + x + flip(y)) endif endif if @selection == 0 pz = w else float tested = 0 if @select_by == 0 tested = cabs(w) elseif @select_by == 1 tested = cabs(pz - w) elseif @select_by == 2 tested = cabs(@offset - w) elseif @select_by == 3 tested = cabs(x + flip(y)) endif bool test = false if @inverse test = tested <= @threshold else test = tested > @threshold endif if test if @selection == 1 pz = w endif else m_solid = true endif endif return pz endfunc protected: float qd[101,13] float sq1 float sq2 float sq3 float sq4 float sq5 float sq6 float sq7 float sq8 float sq9 float sq10 float sq11 float sq12 float h2a float h2b int h2c float x float y default: title = "Attractor Transformations" int param v_attractortransformations caption = "Version (Attractor Transformations)" default = 102 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_attractortransformations < 102 endparam heading caption = "New Martin Variant" visible = @formula == "Hopalong 2" endheading param formula caption = "Formula" enum = "Chip" "CosMartin" "Hopalong" "Pickover" "Quadruptwo" \ "Sprottquad" "Threeply" "Latoocarfian" "Zito" "Hopalong 2" default = 0 endparam param mode caption = "Mode" enum = "Transform" "Disturb" endparam param offset caption = "Offset" default = (0,0) endparam param selection caption = "Selection mode" enum = "None" "Normal" "Selection only" endparam param select_by caption = "Select by" enum = "Magnitude" "Pixel distance" "Offset distance" "Attractor Magnitude" default = 1 visible = @selection != 0 endparam param threshold caption = "Selection threshold" default = 1.0 visible = @selection != 0 endparam param inverse caption = "Inverse selection" default = false visible = @selection != 0 endparam func fn1 caption = "Pixel Modifier" default = ident() endfunc func fn2 caption = "Attractor Modifier" default = ident() endfunc heading caption = "Attr Parameters" endheading param ca caption = "Alpha" default = -15.0 visible=@formula==0 endparam param cb caption = "Beta" default = -19.0 visible=@formula==0 endparam param cc caption = "Gamma" default = 1.0 visible=@formula==0 endparam param ma caption = "Alpha" default = 0.67 visible=@formula==1 endparam param ha caption = "Alpha" default = 0.4 visible=@formula==2 endparam param hb caption = "Beta" default = 1.0 visible=@formula==2 endparam param hc caption = "Gamma" default = 0.0 visible=@formula==2 endparam param h2a caption = "Alpha" default = 0.4 visible=@formula==9 endparam param h2b caption = "Beta" default = 1.0 visible=@formula==9 endparam param h2c caption = "Delta" default = 1 enum = "0" "1" visible=@formula==9 endparam float param fx caption = "initial x" default = 0 visible=@formula==9 endparam float param fy caption = "initial y" default = 0 visible=@formula==9 endparam param pa caption = "Alpha" default = 2.34 visible=@formula==3 endparam param pb caption = "Beta" default = 0.43 visible=@formula==3 endparam param pc caption = "Gamma" default = -0.65 visible=@formula==3 endparam param pd caption = "Omega" default = -2.43 visible=@formula==3 endparam param qa caption = "Alpha" default = 34.0 visible=@formula==4 endparam param qb caption = "Beta" default = 1.0 visible=@formula==4 endparam param qc caption = "Gamma" default = 5.0 visible=@formula==4 endparam param ta caption = "Alpha" default = -55.0 visible=@formula==6 endparam param tb caption = "Beta" default = -1.0 visible=@formula==6 endparam param tc caption = "Gamma" default = -42.0 visible=@formula==6 endparam param la caption = "Alpha" default = -1.0 visible=@formula==7 endparam param lb caption = "Beta" default = 2.9 visible=@formula==7 endparam param lc caption = "Gamma" default = 0.8 visible=@formula==7 endparam param ld caption = "Omega" default = 0.7 visible=@formula==7 endparam param za caption = "Alpha" default = 0.357 visible=@formula==8 endparam func pfn1 caption = "Function 1" default = sin() visible=@formula==3 endfunc func pfn2 caption = "Function 2" default = cos() visible=@formula==3 endfunc func pfn3 caption = "Function 3" default = sin() visible=@formula==3 endfunc func pfn4 caption = "Function 4" default = cos() visible=@formula==3 endfunc func pfn5 caption = "Function 5" default = sin() visible=@formula==3 endfunc func lfn1 caption = "Function 1" default = sin() visible=@formula==7 endfunc func lfn2 caption = "Function 2" default = sin() visible=@formula==7 endfunc func lfn3 caption = "Function 3" default = sin() visible=@formula==7 endfunc func lfn4 caption = "Function 4" default = sin() visible=@formula==7 endfunc param plane caption = "Display Plane" default = 0 enum = "x-y" "x-z" "y-z" visible=@formula==3 endparam param iters caption = "Iterations" default = 10 visible= !((@formula==3)||(@formula==5) || (@formula==7)) endparam param piters caption = "Iterations" default = 2 visible=@formula==3 endparam param liters caption = "Iterations" default = 3 visible=@formula==7 endparam param scale caption = "Scale" default = 0.01 hint = "Changes the size of the shapes." visible=@formula==0 endparam param mscale caption = "Scale" default = 0.03 hint = "Changes the size of the shapes." visible=@formula==1 endparam param hscale caption = "Scale" default = 0.5 hint = "Changes the size of the shapes." visible=@formula==2 endparam param h2scale caption = "Scale" default = 0.5 hint = "Changes the size of the shapes." visible=@formula==9 endparam param pscale caption = "Scale" default = 1.0 hint = "Changes the size of the shapes." visible=@formula==3 endparam param qscale caption = "Scale" default = 0.03 hint = "Changes the size of the shapes." visible=@formula==4 endparam param tscale caption = "Scale" default = 0.003 hint = "Changes the size of the shapes." visible=@formula==6 endparam param lscale caption = "Scale" default = 0.5 hint = "Changes the size of the shapes." visible=@formula==7 endparam param zscale caption = "Scale" default = 0.5 hint = "Changes the size of the shapes." visible=@formula==8 endparam int param select caption = "Sprott selector" default = 0 enum = "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" \ "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" \ "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" \ "45" "46" "47" "48" "49" "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" \ "60" "61" "62" "63" "64" "65" "66" "67" "69" "69" "70" "71" "72" "73" "74" \ "75" "76" "77" "78" "79" "80" "81" "82" "83" "84" "85" "86" "87" "88" "89" \ "90" "91" "92" "93" "94" "95" "96" "97" "98" "99" "100" hint = "Each Sprott selector uses a different strange attractor." visible=@formula=="Sprottquad" endparam int param sqiters caption = "Iterations" default = 5 visible=@formula=="Sprottquad" endparam float param sqscale caption = "Scale" default = 1.5 visible=@formula=="Sprottquad" endparam param strength caption = "Strength" default = 0.5 hint = "This is used in only Disturb mode. \ In the Disturb mode it changes the amount by which a \ pixel is moved." visible=@mode==1 endparam } class REB_HyperbolicMapping(common.ulb:UserTransform) { ; Hyperbolic mapping onto a sphere.
public: ; constructor func REB_HyperbolicMapping(Generic pparent) UserTransform.UserTransform(pparent) endfunc ; initialize the objects func Init(complex pz) UserTransform.Init(pz) endfunc ; call for each iterated point complex func Iterate(complex pz) UserTransform.Iterate(pz) complex p = 0 if (|pz| <= @rad^2) if @view == "Bottom" p = (pz)/(sqrt(@rad^2 -|pz|)) else p = (pz)/(sqrt(@rad^2 +|pz|)) endif else m_solid = true endif if @scmag p = p*4/#magn/@scale else p = p*4/@scale endif return p endfunc default: title = "Hyperbolic Mapping" int param v_hyperbolicmapping caption = "Version (Hyperbolic Mapping)" default = 102 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_hyperbolicmapping < 102 endparam param view caption = "view" enum = "Bottom" "Top" default = 0 endparam param rad caption = "Radius" default = 1.0 endparam param scale caption = "Scale fractal" default = 1.0 endparam bool param scmag caption = "Scale to magn" default = true endparam } class REB_Inversions(common.ulb:UserTransform) { ; Circle Inversions transform.
public: import "common.ulb" ; constructor func REB_Inversions(Generic pparent) UserTransform.UserTransform(pparent) i = new @isph(0) i.recurse() cir = i.s max = i.fk endfunc ; initialize the object func Init(complex pz) UserTransform.Init(pz) if !@itertx iii = 0 c1 = 0 z3 = pz z4 = 0 pz = 0 width = 0 scale = 0 z2 = 0 x1 = 0 y1 = 0 beta = 0 theta1 = 0 x2 = 0 radius = 0 zrot = (0,1)^(#angle*2/#pi) while iii < max radius = cir.sph[iii].frad if ((@showbase || (radius < i.bradius ) &&(!i.circles || \ i.circles && ((!i.showc && radius != i.crad) || i.showc))) && radius > 0) c1 = cir.sph[iii].fcen*@scle/#magn*zrot width = radius*@scle/(#magn*@rad) scale = 2/(@scale*width) complex z2 = (z3-c1)*scale x1 = cabs(z2)/(width*scale) if x1 < 1 ; refraction calcs theta1 = acos(x1) y1=sin(theta1) beta = asin(x1/@n) x2 = -y1/real(tan(theta1+beta))+ x1 ; move pixel z4 = (z2/x1 * x2)*2/(@scale) pz = z4 endif endif iii = iii + 1 endwhile endif endfunc ; call for each iterated point complex func Iterate(complex pz) UserTransform.Iterate(pz) if @itertx iii = 0 c1 = 0 z3 = pz z4 = 0 pz = 0 width = 0 scale = 0 z2 = 0 x1 = 0 y1 = 0 beta = 0 theta1 = 0 x2 = 0 radius = 0 zrot = (0,1)^(#angle*2/#pi) while iii < max radius = cir.sph[iii].frad if ((@showbase || (radius < i.bradius ) &&(!i.circles || \ i.circles && ((!i.showc && radius != i.crad) || i.showc))) && radius > 0) c1 = cir.sph[iii].fcen*@scle/#magn*zrot width = radius*@scle/(#magn*@rad) scale = 2/(@scale*width) complex z2 = (z3-c1)*scale x1 = cabs(z2)/(width*scale) if x1 < 1 ; refraction calcs theta1 = acos(x1) y1=sin(theta1) beta = asin(x1/@n) x2 = -y1/real(tan(theta1+beta))+ x1 ; move pixel z4 = (z2/x1 * x2)*2/(@scale) pz = z4 endif endif iii = iii + 1 endwhile endif if pz != 0 pz = z4 else m_solid = true endif return pz endfunc protected: int iii complex c1 complex z2 complex z3 complex z4 float width float scale float x1 float y1 float beta float theta1 float x2 float radius complex zrot spherearray cir int max InvertSphere i default: title = "Circle Inversions" int param v_circleinversions caption = "Version (Circle Inversions)" default = 102 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_circleinversions < 102 endparam heading text = "Iterates the transform initialization for each iterated value of the \ pixel. May give very interesting effects but may dramatically slow \ the transform." visible = @itertx endheading param itertx caption = "Iterate transform" default = false endparam bool param showbase caption = "Show Base Set" default = false endparam InvertSphere param isph caption = "Invert Circles" default = InvertCircles selectable = false endparam heading caption = "Display Parameters" endheading param n caption = "Refractive index" default = 1.5 hint = "Refactive index of 'glass'" endparam float param scale caption = "Fractal zoom" default = 1.0 endparam float param scle caption = "Object magnification" default = 1.5 endparam float param rad caption = "radius adjustment" default = 1.0 endparam } class REB_Mobius(common.ulb:UserTransform) { ; Kleinian Inversions.
; public: import "common.ulb" ; constructor func REB_Mobius(Generic pparent) UserTransform.UserTransform(pparent) i = new @isph(0) i.recurse() cir = i.s max = i.fk endfunc ; initialize the object func Init(complex pz) UserTransform.Init(pz) if !@itertx iii = 0 c1 = 0 z3 = pz z4 = 0 pz = 0 width = 0 scale = 0 z2 = 0 x1 = 0 y1 = 0 beta = 0 theta1 = 0 x2 = 0 radius = 0 zrot = (0,1)^(#angle*2/#pi) while iii < max radius = cir.sph[iii].frad if ((@showbase || (radius < i.bradius ) &&(!i.circles || \ i.circles && ((!i.showc && radius != i.crad) || i.showc))) && radius > 0) c1 = cir.sph[iii].fcen*@scle/#magn*zrot width = radius*@scle/(#magn*@rad) scale = 2/(@scale*width) complex z2 = (z3-c1)*scale x1 = cabs(z2)/(width*scale) if x1 < 1 ; refraction calcs theta1 = acos(x1) y1=sin(theta1) beta = asin(x1/@n) x2 = -y1/real(tan(theta1+beta))+ x1 ; move pixel z4 = (z2/x1 * x2)*2/(@scale) pz = z4 endif endif iii = iii + 1 endwhile endif endfunc complex func Iterate(complex pz) UserTransform.Iterate(pz) if @itertx iii = 0 c1 = 0 z3 = pz z4 = 0 pz = 0 width = 0 scale = 0 z2 = 0 x1 = 0 y1 = 0 beta = 0 theta1 = 0 x2 = 0 radius = 0 zrot = (0,1)^(#angle*2/#pi) while iii < max radius = cir.sph[iii].frad if ((@showbase || (radius < i.bradius ) &&(!i.circles || \ i.circles && ((!i.showc && radius != i.crad) || i.showc))) && radius > 0) c1 = cir.sph[iii].fcen*@scle/#magn*zrot width = radius*@scle/(#magn*@rad) scale = 2/(@scale*width) complex z2 = (z3-c1)*scale x1 = cabs(z2)/(width*scale) if x1 < 1 ; refraction calcs theta1 = acos(x1) y1=sin(theta1) beta = asin(x1/@n) x2 = -y1/real(tan(theta1+beta))+ x1 ; move pixel z4 = (z2/x1 * x2)*2/(@scale) pz = z4 endif endif iii = iii + 1 endwhile endif if pz != 0 pz = z4 else m_solid = true endif return pz endfunc protected: int iii complex c1 complex z2 complex z3 complex z4 float width float scale float x1 float y1 float beta float theta1 float x2 float radius complex zrot spherearray cir int max InvertSphere i default: title = "Kleinian Inversions" int param v_kleinianinversions caption = "Version (Kleinian Inversions)" default = 102 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_kleinianinversions < 102 endparam heading text = "Iterates the transform initialization for each iterated value of the \ pixel. May give very interesting effects but may dramatically slow \ the transform." visible = @itertx endheading param itertx caption = "Iterate transform" default = false endparam bool param showbase caption = "Show Base Set" default = false visible = false endparam InvertSphere param isph caption = "Kleinian" default = InvertMobius selectable = false endparam heading caption = "Display Parameters" endheading param n caption = "Refractive index" default = 1.5 hint = "Refactive index of 'glass'" endparam float param scale caption = "Fractal zoom" default = 1.0 endparam float param scle caption = "Object magnification" default = 2.0 endparam float param rad caption = "radius adjustment" default = 1.0 endparam } class Seven_Klein_Group(common.ulb:UserTransform) { ; Modified from Morgan Owens' Fractint frm public: import "common.ulb" ; constructor func Seven_Klein_Group(Generic pparent) UserTransform.UserTransform(pparent) float ang=#pi/3 c1=0 c2=1 c3=exp((0,1)*ang) c4=exp((0,2)*ang) c5=exp((0,3)*ang) c6=exp((0,4)*ang) c7=exp((0,5)*ang) r=1/2 rr=r*r endfunc ; call for each iterated point complex func Iterate(complex pz) UserTransform.Iterate(pz) int i = 0 complex z=pz*@scale while i < @iter if(|z-c1|0 r=r1 else r=r2 endif float x=i-j*r float y=k-l*r ap=real(ax)+flip(ay) bp=real(bx)+flip(by) cp=real(cx)+flip(cy) p=real(x)+flip(y) arr=ar^2 brr=br^2 crr=cr^2 rr=r^2 endfunc ; call for each iterated point complex func Iterate(complex pz) UserTransform.Iterate(pz) int ii = 0 complex zz=pz*@scale while ii < @iter if(|zz-ap| public: import "common.ulb" ; constructor func REB_Hyperparaboloid(Generic pparent) UserTransform.UserTransform(pparent) endfunc ; call for each iterated point complex func Iterate(complex pz) UserTransform.Iterate(pz) float tt = 0 float lambda = 0 float u = 0 float v = 0 float x = 0 float y = 0 float z = 0 ; Construct a line from the current pixel on the screen through 3D space. ; The line is defined by (sx, sy, sz) + lambda * (dx, dy, dz) where ; lambda can be any real value > 0. So the line does not extend behind ; the screen. float sx = -@transx float sy = -@transy float sz = -@transz float dx = real(pz-#center+@hcen)*#magn*@hscale float dy = imag(pz-#center+@hcen)*#magn*@hscale+4 float dz = 4 ; Convert angles from degrees to radians. float angx = (@rotx * #pi) / 180 float angy = (@roty * #pi) / 180 float angz = (@rotz * #pi) / 180 ; Rotate the line according to the (rotx, roty, rotz) angle. ; Apply rotation around Z axis tt = cos(angz) * sy - sin(angz) * sx sx = cos(angz) * sx + sin(angz) * sy sy = tt tt = cos(angz) * dy - sin(angz) * dx dx = cos(angz) * dx + sin(angz) * dy dy = tt ; Apply rotation around Y axis tt = cos(angy) * sx - sin(angy) * sz sz = cos(angy) * sz + sin(angy) * sx sx = tt tt = cos(angy) * dx - sin(angy) * dz dz = cos(angy) * dz + sin(angy) * dx dx = tt ; Apply rotation around X axis tt = cos(angx) * sz - sin(angx) * sy sy = cos(angx) * sy + sin(angx) * sz sz = tt tt = cos(angx) * dz - sin(angx) * dy dy = cos(angx) * dy + sin(angx) * dz dz = tt ; Now compute the intersection of the line with the hyperparaboloid, and return ; the intersection point in #pixel (texture coordinates). ; This is the only shape-dependent part. ; Sphere shape (radius 0.5) ; ; This must be solved: ; [ sx ] [ dx ] [ x ] ; [ sy ] + lambda [ dy ] = [ y ] ; [ sz ] [ dz ] [ z ] ; and ; x^2 - y^2 = 10*z float a = sqr(dx) - sqr(dy) float b = 2 * sx * dx - 2 * sy * dy - 10*dz float c = sqr(sx) - sqr(sy) - 10*sz float d = sqr(b) - 4 * a * c if d < 0 ; No roots exist. m_solid = true else ; One or two roots: select smallest. if a >= 0 lambda = (-b - sqrt(d)) / (2 * a) else lambda = (-b + sqrt(d)) / (2 * a) endif if lambda < 0 ; Intersection point is behind the screen. m_solid = true else x = sx + lambda * dx y = sy + lambda * dy z = sz + lambda * dz if z == 0 if x > 0 u = 2 else u = -2 endif else u = (4 / #pi) * atan(x / abs(z)) endif v = (4 / #pi) * atan(y / sqrt(sqr(x) + sqr(z))) endif endif pz = u + flip(v) pz = @fraccenter + pz * exp(flip((@fracangle * #pi) / 180)) / @fracmagn return pz endfunc protected: default: title = "Hyperparaboloid" int param v_hyperparaboloid caption = "Version (Hyperparaboloid)" 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_hyperparaboloid < 100 endparam param rotx caption = "X rotation" default = 0.0 hint = "Rotation around the x-axis, in degrees. The x-axis points to \ the right. To determine the direction in which the rotation will \ take place, hold up your left hand with your thumb pointing to \ the right. Your (curled) fingers now indicate the direction of \ positive X rotation." endparam param roty caption = "Y rotation" default = 0.0 hint = "Rotation around the y-axis, in degrees. The y-axis points \ upwards. To determine the direction in which the rotation will \ take place, hold up your left hand with your thumb pointing \ upwards. Your (curled) fingers now indicate the direction of \ positive Y rotation." endparam param rotz caption = "Z rotation" default = 270.0 hint = "Rotation around the z-axis, in degrees. The z-axis points into \ the screen. To determine the direction in which the rotation will \ take place, hold up your left hand with your thumb pointing into \ the screen. Your (curled) fingers now indicate the direction of \ positive Z rotation." endparam param transx caption = "X Translation" default = 0.0 hint = "Translation along the x-axis. The x-axis points to the right, \ so increasing this value will move the fractal to the right, too." endparam param transy caption = "Y Translation" default = -0.5 hint = "Translation along the y-axis. The y-axis points upwards, \ so increasing this value will move the fractal upwards, too." endparam param transz caption = "Z Translation" default = 2.0 hint = "Translation along the z-axis. The z-axis points into the screen, \ so increasing this value will move the fractal away." endparam param fraccenter caption = "Fractal Center" default = (0,0) hint = "Center of the fractal image. Use here what you would \ normally enter in the Location tab." endparam param fracmagn caption = "Fractal Magnification" default = 1.0 hint = "Magnification of the fractal image. Use here what you would \ normally enter in the Location tab." endparam param fracangle caption = "Fractal Rotation" default = 0.0 hint = "Rotation angle (in degrees) of the fractal image. Use here \ what you would normally enter in the Location tab." endparam float param hscale caption = "Hyperbolic scale" default = 1.0 endparam complex param hcen caption = "Hyperbolic center" default = (0,0) endparam } class REB_IFSApollo(common.ulb:UserTransform) { ;
public: import "common.ulb" ; constructor func REB_IFSApollo(Generic pparent) UserTransform.UserTransform(pparent) endfunc ; call for each iterated point complex func Iterate(complex pz) UserTransform.Iterate(pz) float ra = sqrt(3) float x = real(pz+@cen) float y = imag(pz+@cen) float aa = 0 float a0 = 0 float b0 = 0 float a1 = -0.5 float b1 = 0.5*ra float a2 = -0.5 float b2 = -0.5*ra float x1 = 0 float y1 = 0 float f1x = 0 float f1y = 0 float s1 = @scale float s2 = s1 int seed = 123456789 int i = 0 while i < @iter seed = random(seed) float aa = abs(seed)/#randomrange a0 = 3*(1 + ra - x)/((1 + ra - x)^2 + y^2) - (1 + ra)/(2 + ra) b0 = 3*y/((1 + ra - x)^2 + y^2) f1x = a0/(a0^2 + b0^2) f1y = -b0/(a0^2 + b0^2) if aa >= 0 && aa < 1/3 x1 = 3*(1 + ra - x)/((1 + ra - x)^2 + y^2) - (1 + ra)/(2 + ra) y1 = 3*y/((1 + ra - x)^2 + y^2) elseif aa >= 1/3 && aa < 2/3 x1 = f1x*a1 - f1y*b1 y1 = f1x*b1 + f1y*a1 elseif aa >= 2/3 && aa <= 1 x1 = f1x*a2 - f1y*b2 y1 = f1x*b2 + f1y*a2 endif i = i+1 endwhile return s1*x1 + flip(s2*y1) endfunc protected: default: title = "IFS Apollo" int param v_ifsapollo caption = "Version (IFS Apollo)" 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_ifsapollo < 100 endparam float param scale caption = "scale" default = 1 endparam int param iter caption = "# of iterations" default = 1000 endparam complex param cen caption = "Transform center" default = (0,0) endparam } ;-------------------------------------------- ; 3D Mesh Classes ;-------------------------------------------- Class TriangleMesh(common.ulb:Generic) { ; Creates a triangle mesh array from an array of height values corresponding
; to points in the complex plane.
$define debug public: import "common.ulb" ; constructor func TriangleMesh(Generic pparent) initmesh() endfunc func initmesh() m_tarray = new @f_tarray(@ntriangles) m_mesh = new @f_mesh(this) m_dens = 1 m_mesh.initmesh() if @smoothmsh setlength(m_mesh.meshs,m_mesh.m_arrayx*m_mesh.m_arrayy) m_mesh.smoothmesh(@type) else setlength(m_mesh.meshs,0) endif m_dens = m_mesh.m_dens m_tymax = m_mesh.m_tymax m_txmax = m_mesh.m_txmax m_xang = m_mesh.m_xang m_yang = m_mesh.m_yang m_xrot = (0,1)^(m_xang/90) m_yrot = (0,1)^(m_yang/90) m_zrot = (0,1)^(#angle*2/#pi) float magn = #magn/2 ; fill the triangle array int i = 0 int j = 0 int k = 0 m_arrayx = m_mesh.m_arrayx m_arrayy = m_mesh.m_arrayy while j < m_arrayy*m_dens while i < m_arrayx*m_dens m_tarray.tr[k] = new Triangle(real(m_mesh.meshc[m_mesh.idx(i,j)])*magn, imag(m_mesh.meshc[m_mesh.idx(i,j)])*magn, m_mesh.meshz[m_mesh.idx(i,j)]*magn,\ real(m_mesh.meshc[m_mesh.idx(i+1,j+1)])*magn, imag(m_mesh.meshc[m_mesh.idx(i+1,j+1)])*magn, m_mesh.meshz[m_mesh.idx(i+1,j+1)]*magn,\ real(m_mesh.meshc[m_mesh.idx(i,j+1)])*magn, imag(m_mesh.meshc[m_mesh.idx(i,j+1)])*magn, m_mesh.meshz[m_mesh.idx(i,j+1)]*magn) k = k + 1 m_tarray.tr[k] = new Triangle(real(m_mesh.meshc[m_mesh.idx(i,j)])*magn, imag(m_mesh.meshc[m_mesh.idx(i,j)])*magn, m_mesh.meshz[m_mesh.idx(i,j)]*magn,\ real(m_mesh.meshc[m_mesh.idx(i+1,j)])*magn, imag(m_mesh.meshc[m_mesh.idx(i+1,j)])*magn, m_mesh.meshz[m_mesh.idx(i+1,j)]*magn,\ real(m_mesh.meshc[m_mesh.idx(i+1,j+1)])*magn, imag(m_mesh.meshc[m_mesh.idx(i+1,j+1)])*magn, m_mesh.meshz[m_mesh.idx(i+1,j+1)]*magn) k = k + 1 i = i + 1 endwhile m_trow = i*2 i = 0 j = j + 1 endwhile m_k = k-1 Rotate() endfunc func Rotate() int i = 0 while i < m_k complex z1 = 0 complex z2 = 0 complex z3 = 0 ; Z axis rotation (uses angle on location tab) z1 = m_zrot*(m_tarray.tr[i].fx1-flip(m_tarray.tr[i].fy1)) z2 = m_zrot*(m_tarray.tr[i].fx2-flip(m_tarray.tr[i].fy2)) z3 = m_zrot*(m_tarray.tr[i].fx3-flip(m_tarray.tr[i].fy3)) m_tarray.tr[i].Init(real(z1),imag(z1),m_tarray.tr[i].fz1,\ real(z2),imag(z2),m_tarray.tr[i].fz2,\ real(z3),imag(z3),m_tarray.tr[i].fz3) ; Y axis rotation z1 = m_yrot*(m_tarray.tr[i].fx1-flip(m_tarray.tr[i].fz1)) z2 = m_yrot*(m_tarray.tr[i].fx2-flip(m_tarray.tr[i].fz2)) z3 = m_yrot*(m_tarray.tr[i].fx3-flip(m_tarray.tr[i].fz3)) m_tarray.tr[i].Init(real(z1),m_tarray.tr[i].fy1,imag(z1),\ real(z2),m_tarray.tr[i].fy2,imag(z2),\ real(z3),m_tarray.tr[i].fy3,imag(z3)) ; X axis rotation z1 = m_xrot*(m_tarray.tr[i].fy1-flip(m_tarray.tr[i].fz1)) z2 = m_xrot*(m_tarray.tr[i].fy2-flip(m_tarray.tr[i].fz2)) z3 = m_xrot*(m_tarray.tr[i].fy3-flip(m_tarray.tr[i].fz3)) m_tarray.tr[i].fy3 = -m_tarray.tr[i].fy3 m_tarray.tr[i].Init(m_tarray.tr[i].fx1,real(z1),imag(z1),\ m_tarray.tr[i].fx2,real(z2),imag(z2),\ m_tarray.tr[i].fx3,real(z3),imag(z3)) i = i + 1 endwhile endfunc TriangleArray m_tarray CreateMesh m_mesh int m_k int m_trow float m_dens int m_arrayx int m_arrayy float m_txmax float m_tymax complex m_zrot complex m_yrot complex m_xrot float m_xang float m_yang default: title = "Triangle mesh" int param v_trianglemesh caption = "Version (Mesh)" 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_trianglemesh < 100 endparam TriangleArray param f_tarray caption = "Triangle array" default = TriangleArray selectable = false endparam int param ntriangles caption = "Number of triangles" default = 3000000 endparam CreateMesh param f_mesh caption = "Mesh type" default = MeshWrapper selectable = false endparam heading caption = "Mesh Smoothing" endheading heading text = "Mesh smoothing uses simple 3x3 convolution filters. The filters are \ applied as a pre-calculation to the entire mesh and have little effect \ on the overall rendering time." endheading heading text = " Average Blur: Averages the mesh point and its immedate neighbors." endheading heading text = " Gaussian: Uses Gaussian coefficients for averaging." endheading heading text = " Reduced Gaussian: Uses reduced Gaussian coefficients for averaging." endheading heading text = " Median: Picks the median value within the 3 x 3 matrix. Technically, \ it is not a convolution filter." endheading bool param smoothmsh caption = "Smooth mesh" default = false endparam param type caption = "Smoothing Type" default = 3 enum = "Average Blur" "Gaussian" "Reduced Gaussian" "Median" visible = @smoothmsh endparam } Class CreateMesh(common.ulb:Generic) { ; This is the mesh base class
; Modified 1/27/2011 to remove versioning, as changes too large for effectively ; version. $define debug public: import "common.ulb" ; constructor for a generic mesh array func CreateMesh(Generic pparent) m_xang = @xang m_yang = @yang m_c = @seed float dr2 = #pi/180 float angy = 1/cos(m_xang*dr2) float angx = 1/cos(m_yang*dr2) m_dens = @dens m_cx = real(#center) m_cy = imag(#center) m_xmin = (@xmin+@xshift)/#magn + m_cx m_xmax = (@xmax+@xshift)/#magn + m_cx m_ymin = (@ymin+@yshift)/#magn + m_cy m_ymax = (@ymax+@yshift)/#magn + m_cy m_xmax = m_xmax*angx m_ymax = m_ymax*angy m_xmin = m_xmin*angx m_ymin = m_ymin*angy m_txmax = m_xmax-m_xmin m_tymax = m_ymax-m_ymin m_arrayx = round(#width*m_txmax/6*#magn)+3 m_arrayy = round(#height*m_tymax/6*#magn)+3 setlength(meshc,m_arrayx*m_arrayy) setlength(meshz,m_arrayx*m_arrayy) pz = 0 initmesh() endfunc ; this function is customized for each mesh type func initmesh() endfunc ; this function is customized for each mesh type ; it provides smoothing of the mesh func smoothmesh(int type) endfunc ; This provides an index into a 2-dimensional dynamic array int func idx(int i, int j) int k = i*m_arrayy + j return k endfunc complex meshc[] float meshz[] float meshs[] float m_cx float m_cy float m_txmax float m_tymax float m_xmax float m_xmin float m_ymax float m_ymin complex pz complex m_c float m_dens bool m_solid float m_xang float m_yang float m_xangc float m_yangc int m_arrayx int m_arrayy default: int param v_mesh caption = "Version (Mesh)" 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_mesh < 100 endparam int param iter caption = "# of Iterations" default = 100 endparam heading text = "The 'Density' parameter sets the tightness of the triangle mesh. With \ a density of 1.0 every screen pixel is a trinagle vertex." endheading float param dens caption = "Density" default = 0.50 max = 1.0 endparam complex param seed caption = "Julia Seed" default = (-0.75, 0.25) endparam heading text = "'Max x' etc. are the x-y plane fractal parameter limits. These may \ need to be adjusted for zooms and panning. Try to keep the interval \ between the max and min values as small as possible." endheading float param xmax caption = "Max x" default = 3 endparam float param xmin caption = "Min x" default = -3 endparam float param ymax caption = "Max y" default = 5 endparam float param ymin caption = "Min y" default = -3 endparam float param xshift caption = "Shift x" default = 0 endparam float param yshift caption = "Shift y" default = 0 endparam heading caption = "Mesh Rotation" endheading heading text = "For rotation around the Z Axis, use the angle setting on the \ Location Tab. The Max X, Max Y, Min X and Min Y values are corrected \ depending upon the angle to aid in keeping the view window sized correctly. \ Similar rotation effects can be obtained by rotating the camera. Camera \ rotation makes no corrections to the view window." endheading float param xang caption = "X Axis Rotation" default = 45.0 endparam float param yang caption = "Y Axis Rotation" default = 0.0 endparam } Class MeshWrapper(CreateMesh) { ; This is wrapper to allow the use of object formula plugins.
; It creates the arrays of height values corresponding to points in the
; complex plane.
; Modified 1/27/2011 to remove versioning, as changes too large for effectively ; version. $define debug public: import "common.ulb" import "dmj5.ulb" ; constructor func MeshWrapper(Generic pparent) CreateMesh.CreateMesh(pparent) initmesh() endfunc func initmesh() m_f2 = new @formulaClass2(this) m_f2r = new @formulaClass2(this) m_f2i = new @formulaClass2(this) fTransform = new @transform(this) m_TrapShape = new @f_trapshape(this) m_TrapMode = new @f_trapmode(this) fTransfer = new @transfer(this) m_TrapTexture = new @f_traptexture(this) m_TrapShape.SetThreshold(@p_threshold) m_TrapMode.SetThreshold(@p_threshold) float magn = #magn int i = 0 int j = 0 int imax = 0 int jmax = 0 float zmax = -1e100 float iterexp = 0 float power = 0 float ptexture = 0 float cabsz = 0 float fx = m_xmin float fy = m_ymin float dr = 0 float d = 0 converge = false bail = m_f2.GetUpperBailout() if bail == -1 || bail == 256 converge = true endif repeat m_zold = 0 m_zold2 = 0 oldzd = 0 oldpz = 0 oldpzr = 0 oldpzi = 0 repeat zd = 1 pz = fx + flip(fy) fTransform.init(pz) m_TrapMode.Init(pz) m_TrapShape.Init(pz) fTransfer.Init(pz) m_TrapTexture.Init(pz) m_zold2 = m_zold = pz oldzd = zd meshc[idx(i,j)] = pz pzr = pz + @delta pzi = pz + flip(@delta) pz = m_f2.Init(pz) pzr = m_f2r.Init(pzr) pzi = m_f2i.Init(pzi) oldpz = pz oldpzr = pzr oldpzi = pzi k = 0 iterexp = 0 cabsz = 0 while k <= @iter && !m_f2.IsBailedOut(pz) ; this is equivalent to the iteration section if @deriv == "Analytical" oldzd = zd zd = m_f2.DrCalc(pz,zd) endif oldpz = pz pz = m_f2.iterate(pz) if @htype == "General Smoothing" iterexp = iterexp + exp(-cabs(pz)-0.5/(cabs(m_zold - pz))) elseif @htype == "Exponential Smoothing" if !converge iterexp = iterexp + exp(-cabs(pz)) else iterexp = iterexp + exp(-1/(cabs(m_zold - pz))) endif elseif @htype == "Potential" iterexp = iterexp + exp(-cabs(pz)-0.5/(cabs(m_zold - pz))) elseif @htype == "Distance Estimate" oldpzr = pzr oldpzi = pzi pzr = m_f2r.iterate(pzr) pzi = m_f2i.iterate(pzi) endif if @htype == "Vepstas/Härkönen Smoothing" || @htype == "Distance Estimate" if converge bail = m_f2.GetLowerBailout() endif power = log(|pz - m_zold|) / log(|m_zold - m_zold2|) f = (log(log(bail)) - log(log(1/(|(m_zold - pz)|))))/log(power) elseif @htype == "Cabs(z)" cabsz = cabs(pz) elseif @htype == "Orbit Traps" complex tx = 0 complex m_zr = fTransform.Iterate(pz) float pdistance = m_TrapShape.iterate(m_zr) pdistance = fTransfer.Iterate(pdistance) ptexture = abs(m_TrapTexture.Iterate(pz)*@p_texturestrength) pdistance = pdistance + ptexture m_TrapMode.Iterate(m_zr, tx, pdistance,ptexture) endif m_zold2 = m_zold m_zold = pz k = k + 1 endwhile ; this is the equivalent of the final section if @htype == "Iteration" meshz[idx(i,j)] = @hscale*k/@iter/magn elseif @htype == "General Smoothing" meshz[idx(i,j)] = 3.6*@hscale*iterexp/@iter/magn elseif @htype == "Exponential Smoothing" meshz[idx(i,j)] = 2*@hscale*iterexp/@iter/magn elseif @htype == "Potential" float pot = 2^(-iterexp)*@ddfact*magn if pot < 0 || isnan(pot) || isinf(pot) || isinf(-pot) pot = 0 endif if k < @iter meshz[idx(i,j)] = 4*@hscale*(1-tanh(pot))/magn else meshz[idx(i,j)] = 4*@hscale/magn endif elseif @htype == "Distance Estimate" if @deriv == "Slope" if !converge dr = cabs(pzr+pzi-2*pz)/@delta else dr = cabs(pzr+pzi-2*pz-(oldpzr+oldpzi-2*oldpz))/@delta endif else if !converge dr = cabs(zd) else dr = cabs(oldzd-zd) endif endif if !converge d = cabs(pz)*log(cabs(pz))/dr*@ddfact*magn else d = cabs(pz-oldpz)*log(cabs(1/(pz-oldpz)))/dr*@ddfact*magn endif ; distance range correction if d < 0 || isnan(d) || isinf(d) || isinf(-d) d = 0 endif if k < @iter meshz[idx(i,j)] = 4*@hscale*(1-tanh(d))/magn else meshz[idx(i,j)] = 4*@hscale/magn endif elseif @htype == "Vepstas/Härkönen Smoothing" if isnan(f) || isinf(f) || isinf(-f) f = 0 endif meshz[idx(i,j)] = @hscale*(k+f)/@iter/magn elseif @htype == "Cabs(z)" cabsz = tanh(1/cabsz) meshz[idx(i,j)] = @hscale*cabsz/magn elseif @htype == "Orbit Traps" m_TrapMode.Result() float final_distance = m_TrapMode.GetDistance(0) if @f_trapmode == TrapModeWithThreshold if @f_trapmode == DMJ_TrapModeExponentialAverage || \ @f_trapmode == DMJ_TrapModeInvertedSum || \ @f_trapmode == DMJ_TrapModeSum final_distance = tanh(1/final_distance)/@p_threshold else final_distance = 1-final_distance/@p_threshold endif elseif @f_trapmode == DMJ_TrapModeChangeAverage final_distance = tanh(1/final_distance) endif meshz[idx(i,j)] = 0.15*@hscale*final_distance/magn if m_TrapMode.IsSolid() if @f_trapmode != DMJ_TrapModeClosest && \ @f_trapmode != DMJ_TrapModeSecondClosest && \ @f_trapmode != DMJ_TrapModeTwoClosest meshz[idx(i,j)] = ptexture/magn endif if @usesolid meshz[idx(i,j)] = 1e10 endif endif endif if (@mflat || @htype == "Vepstas/Härkönen Smoothing") && k > @iter && \ @htype != "Cabs(z)" && @htype != "Orbit Traps" meshz[idx(i,j)] = @hscale*k/@iter/magn endif if @makezero && k > @iter && @htype != "Cabs(z)" && @htype != "Orbit Traps" meshz[idx(i,j)] = 0 endif if @atten && @htype != "Orbit Traps" meshz[idx(i,j)] = 2*@hscale*((meshz[idx(i,j)]/@hscale)^@smooth/(1+(meshz[idx(i,j)]/@hscale)^@smooth))/magn endif if meshz[idx(i,j)] > zmax zmax = meshz[idx(i,j)] endif j = j + 1 fy = fy + m_tymax/#height/m_dens until fy >= m_ymax jmax = j j = 0 i = i + 1 fy = m_ymin fx = fx + m_txmax/#width/m_dens until fx >= m_xmax imax = i i = 0 j = 0 if @corrz repeat repeat meshz[idx(i,j)] = meshz[idx(i,j)]-zmax j = j + 1 until j >= jmax j = 0 i = i + 1 until i >= imax endif endfunc ; call after initmesh() func smoothmesh(int type) int i = 0 int j = 0 while i < #width*m_dens*m_txmax/4*#magn+3 while j < #height*m_dens*m_tymax/4*#magn+3 if i-1 >= 0 && j-1 >= 0 && i+1 < #width*m_dens+1 && j+1 < #height*m_dens+1 if type == 1 ; Gaussian meshs[idx(i,j)] = (4*meshz[idx(i,j)]+ 2*meshz[idx(i-1,j)]+2*meshz[idx(i,j-1)]+\ 2*meshz[idx(i+1,j)]+2*meshz[idx(i,j+1)]+\ meshz[idx(i+1,j+1)]+meshz[idx(i-1,j-1)]+\ meshz[idx(i+1,j-1)]+meshz[idx(i-1,j+1)])/16 elseif type == 2 ; Reduced Gaussian meshs[idx(i,j)] = (1.5*meshz[idx(i,j)]+ 0.25*meshz[idx(i-1,j)]+0.25*meshz[idx(i,j-1)]+\ 0.25*meshz[idx(i+1,j)]+0.25*meshz[idx(i,j+1)]+\ 0.125*meshz[idx(i+1,j+1)]+0.125*meshz[idx(i-1,j-1)]+\ 0.125*meshz[idx(i+1,j-1)]+0.125*meshz[idx(i-1,j+1)])/3 elseif type == 0 ; Average blur meshs[idx(i,j)] = (meshz[idx(i,j)]+ meshz[idx(i-1,j)]+meshz[idx(i,j-1)]+\ meshz[idx(i+1,j)]+meshz[idx(i,j+1)]+\ meshz[idx(i+1,j+1)]+meshz[idx(i-1,j-1)]+\ meshz[idx(i+1,j-1)]+meshz[idx(i-1,j+1)])/9 elseif type == 3 ; Median float med[9] int k = 0 int l = 0 float tmp = 0 int si = 0 int sj = 0 bool continue = true med[0] = meshz[idx(i,j)] med[1] = meshz[idx(i-1,j)] med[2] = meshz[idx(i,j-1)] med[3] = meshz[idx(i+1,j)] med[4] = meshz[idx(i,j+1)] med[5] = meshz[idx(i+1,j+1)] med[6] = meshz[idx(i-1,j-1)] med[7] = meshz[idx(i+1,j-1)] med[8] = meshz[idx(i-1,j+1)] ;heapsort without recursion l = 5 k = 9 tmp = 0 repeat if l > 1 l = l-1 tmp = med[l-1] else tmp = med[k-1] med[k-1] = med[0] k = k-1 if k == 0 med[0] = tmp continue = false endif endif if continue == true si = l sj = 2*l endif while (sj <= k) && (continue == true) if sj < k if med[sj-1] < med[sj] sj = sj + 1 endif endif if tmp < med[sj-1] med[si-1] = med[sj-1] si = sj sj = sj + sj else sj = k + 1 endif endwhile if (continue == true) med[si-1] = tmp endif until continue == false ; end heapsort meshs[idx(i,j)] = med[4] endif endif j = j + 1 endwhile j = 0 i = i + 1 endwhile i = 0 j = 0 while i < #width*m_dens*m_txmax/4*#magn+3 while j < #height*m_dens*m_tymax/4*#magn+3 meshz[idx(i,j)] = meshs[idx(i,j)] j = j + 1 endwhile j = 0 i = i + 1 endwhile endfunc Switch m_f2 Switch m_f2r Switch m_f2i complex m_zold complex m_zold2 complex oldpz int k float f TrapShape m_TrapShape TrapMode m_TrapMode UserTransform fTransform Transfer fTransfer TrapShape m_TrapTexture float bail complex pzr complex pzi complex zd complex oldzd bool converge default: title = "Object Formula Wrapper" int param v_meshwrapper caption = "Version (Mesh Wrapper)" 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_meshwrapper < 100 endparam Switch param formulaClass2 caption = "Fractal Formula" default = REB_MandelbrotJulia_Switch endparam heading text = "Set 'Coloring bailout' to the value for the formula bialout." visible = @htype == "Vepstas/Härkönen Smoothing" && @v_meshwrapper == 100 endheading complex param seed caption = "Julia Seed" default = (-0.75, 0.25) visible = false endparam float param hscale caption = "Height scale" default = 0.25 endparam bool param corrz caption = "Correct Z by Zmax" default = true endparam bool param atten caption = "Peak attenuation" default = false visible = @htype != "Orbit Traps" endparam heading text = "If 'Attenuate value' < 1 sharp peaks will be attenuated. Values > 1 \ will accentuate sharpness." visible = @atten && @htype != "Orbit Traps" endheading float param smooth caption = "Attenuate value" default = 1 min = 0.01 max = 10 visible = @atten && @htype != "Orbit Traps" endparam bool param makezero caption = "Maxiter height = 0" default = false visible = @htype != "Cabs(z)" && @htype != "Orbit Traps" endparam bool param mflat caption = "Make flat at Max iter" default = false visible = (@htype != "Cabs(z)" && @htype != "Iteration" && @htype \ != "Vepstas/Härkönen Smoothing" && @htype != "Orbit Traps" \ && @htype != "Potential") && !@makezero endparam heading text = "The 'Orbit Traps' height type provides a simplified version of \ the options available in the Orbit Traps coloring formula, including \ a variety of plugins." visible = @htype == "Orbit Traps" endheading heading text = "The 'Cabs(z)' height type should only be used with divergent fractals." visible = @htype == "Cabs(z)" endheading param htype caption = "Height type" default = 1 enum = "Cabs(z)" "Distance Estimate" "Exponential Smoothing" \ "General Smoothing" "Iteration" \ "Orbit Traps" "Potential" "Vepstas/Härkönen Smoothing" endparam param deriv caption = "Derivative method" default = 0 enum = "Slope" "Analytical" visible = @htype == "Distance Estimate" endparam float param ddfact caption = "Distance factor" default = 1 visible = (@htype == "Potential" || @htype == "Distance Estimate") && @v_meshwrapper >= 102 endparam float param delta caption = "Delta DE" default = 1e-12 visible = @htype == "Distance Estimate" && @deriv != "Analytical" endparam heading caption = "Orbit Traps" visible = @htype == "Orbit Traps" endheading heading text = "All of the plugins in this section must be pre-calculated before \ anything will appear on the screen. Some sets of plugins may produce \ a substantial delay." visible = @htype == "Orbit Traps" endheading UserTransform param transform caption = "Trap Position" default = TrapTransform expanded = false hint = "Transforms the orbit values from the fractal formula before they \ are passed to the trap shape." visible = @htype == "Orbit Traps" endparam TrapShape param f_trapshape caption = "Trap Shape" default = REB_TrapShapeStirrupCurve visible = @htype == "Orbit Traps" endparam Transfer param transfer caption = "Trap Transfer" expanded = false default = TrapTransfer hint = "Provides additional options to scale and transform the distance \ that the trap shape returns." visible = @htype == "Orbit Traps" endparam TrapMode param f_trapmode caption = "Trap Mode" default = DMJ_TrapModeClosest visible = @htype == "Orbit Traps" endparam float param p_threshold caption = "Trap Threshold" default = 0.25 hint = "This is the overall size or thickness of the trap area. (Some trap modes may not use the threshold value.)" visible = (@f_trapmode == TrapModeWithThreshold) && @htype == "Orbit Traps" endparam bool param usesolid caption = "Use solid color" default = false visible = @htype == "Orbit Traps" endparam heading text = "The detail level of the texture depends upon the density setting." visible = (@f_traptexture != DMJ_TrapShapeFlat) && @htype == "Orbit Traps" endheading TrapShape param f_traptexture caption = "Trap Texture" default = DMJ_TrapShapeFlat expanded = false hint = "A trap shape that is used as a texture. Textures do not change the shape of the trap but may change its coloring." visible = @htype == "Orbit Traps" endparam float param p_texturestrength caption = "Texture Amount" default = 0.0 hint = "Sets the overall amount of texture to be used. Larger numbers will increase the effect of the texture. A value of 0 will remove the effects of the texture." visible = (@f_traptexture != DMJ_TrapShapeFlat) && @htype == "Orbit Traps" endparam } ;---------------------------------------- ; ; Raytrace Classes ; ;---------------------------------------- Class RaytraceGeneric(common.ulb:Generic) { ; The generic class sets up lights and the viewpoint. Objects are to be ; set up in the descendants. public: import "common.ulb" func RaytraceGeneric(Generic pparent) Init() endfunc ; Call Init() in the global section func Init() ; create the lights and light vectors ; create the objects, including surface and transparency characteristics ; 1. textures, patterns, images, refractive index ; 2. spheres, planes, 3D fractals lar = new VectorArray(@nlight) m_xangle = @xanglec m_yangle = @yanglec int i = 0 float vd = 0 float litex = 0 complex lite = 0 float litez = 0 while i < @nlight if i >= 0 litex = (@lightx-@pointx) litey = -(@lighty-@pointy) litez = @lightz+@pointz lite = litex + flip(litey) vd = sqrt(|lite|+litez^2) lite = lite/vd litez = litez/vd lar.m_elements[i] = new Vector(real(lite), imag(lite), litez, 0) spec[0] = @spec1 shiny[0] = @shiny1 sbright[0] = @sbright1 endif if i >= 1 litex = (@lightx2-@pointx2) litey = -(@lighty2-@pointy2) litez = @lightz2+@pointz2 lite = litex + flip(litey) vd = sqrt(|lite|+litez^2) lite = lite/vd litez = litez/vd lar.m_elements[i] = new Vector(real(lite), imag(lite), litez, 0) spec[1] = @spec2 shiny[1] = @shiny2 sbright[1] = @sbright2 endif if i >= 2 litex = (@lightx3-@pointx3) litey = -(@lighty3-@pointy3) litez = @lightz3+@pointz3 lite = litex + flip(litey) vd = sqrt(|lite|+litez^2) lite = lite/vd litez = litez/vd lar.m_elements[i] = new Vector(real(lite), imag(lite), litez, 0) spec[2] = @spec3 shiny[2] = @shiny3 sbright[2] = @sbright3 endif if i >= 3 litex = (@lightx4-@pointx4) litey = -(@lighty4-@pointy4) litez = @lightz4+@pointz4 lite = litex + flip(litey) vd = sqrt(|lite|+litez^2) lite = lite/vd litez = litez/vd lar.m_elements[i] = new Vector(real(lite), imag(lite), litez, 0) spec[3] = @spec4 shiny[3] = @shiny4 sbright[3] = @sbright4 endif if i >= 4 litex = (@lightx5-@pointx5) litey = -(@lighty5-@pointy5) litez = @lightz5+@pointz5 lite = litex + flip(litey) vd = sqrt(|lite|+litez^2) lite = lite/vd litez = litez/vd lar.m_elements[i] = new Vector(real(lite), imag(lite), litez, 0) spec[4] = @spec5 shiny[4] = @shiny5 sbright[4] = @sbright5 endif i = i + 1 endwhile i = 0 regress = 0 int j = 0 while i < 10 diffuse[i] = 0 while j < 5 specular[i,j] = 0 j = j + 1 endwhile si[i] = 0 i = i + 1 endwhile endfunc ; call ViewPoint() in the init section func ViewPoint() ; create camera, view screen and view vector ; initialize zero and infinite distances ; setup to allow transforms float asp = #height/#width float xcrd = real(#screenpixel) float ycrd = imag(#screenpixel) ; generate the x and y location in the image float dxx = (real(#pixel)-real(#center))*(#width)/4*#magn float dyy = (imag(#pixel)-imag(#center))*(#width)/4*#magn float transx = (#width)*0.5; float transy = (#height)*0.5; float cosan = cos(#angle); float sinan = sin(#angle); xcrd = transx + (dxx*cosan + dyy*sinan) ycrd = transy + (dxx*sinan - dyy*cosan) float camx0 = (xcrd/#width-0.5)*2 + real(#center)*#magn/2 float camy0 = (ycrd/#height-0.5)*asp*2 - imag(#center)*#magn/2 float camz0 = 0 float camx = 0 float camy = 0 float camz = -@cameraz float oldcamx = 0 float oldcamy = 0 float dr2 = #pi/180 ; camera rotation ; rotation around the x axis oldcamy = camy camy = camy*cos(-m_xangle*dr2) - camz*sin(-m_xangle*dr2) camz = oldcamy*sin(-m_xangle*dr2) + camz*cos(-m_xangle*dr2) ; rotation around the y axis oldcamx = camx camx = camx*cos(-m_yangle*dr2) + camz*sin(-m_yangle*dr2) camz = -oldcamx*sin(-m_yangle*dr2) + camz*cos(-m_yangle*dr2) ; screen rotation if @rotscreen ; rotation around the x axis oldcamy = camy0 camy0 = camy0*cos(-m_xangle*dr2) - camz0*sin(-m_xangle*dr2) camz0 = oldcamy*sin(-m_xangle*dr2) + camz0*cos(-m_xangle*dr2) ; rotation around the y axis oldcamx = camx0 camx0 = camx0*cos(-m_yangle*dr2) + camz0*sin(-m_yangle*dr2) camz0 = -oldcamx*sin(-m_yangle*dr2) + camz0*cos(-m_yangle*dr2) endif ; view = new Vector(camx0-camx,camy0-camy,camz0-camz,0) view.Normalize(view) origin = new Vector(camx,camy,camz,0) screen = new Vector(camx0, camy0, camz0,0) endfunc ;------------------------------------------------- ; Function to determine object intersections with rays ; The maximum recursion level is currently set to 10 ; @param origin = ray origin as a vector ; @param ray = ray as a vector ; @param regress = regression level ; @param rsi = object index - passed back from recursion ; @param dif = diffuse lighting parameter - passed back from recursion ; @param sbr = specular lighting paramer - passed back from recursion ; @param scolor = color of the intersected object ;------------------------------------------------ ; Call Intersect() after viewpoint bool func Intersect(Vector origin, Vector ray, int ®ress, int &rsi, \ float &dif, float &sbr, color &scolor) return false endfunc ; call result() in the final section color func Result() color return_color = rgba(0.5,0.5,0.5,1) return return_color endfunc Vector view Vector origin Vector screen float diffuse[10] float specular[10,5] int si[10] int regress color spec[5] color speccol[10,5] bool m_solid ; for floor reflections float flrdiffuse[10] float flrspecular[10,5] color flrspec[8] color flrspeccol[10,5] float m_xangle float m_yangle protected: VectorArray lar float shiny[5] float sbright[5] ; for floor reflections float flrsbright[5] default: int param v_raytracegeneric caption = "Version (Raytrace Generic)" 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_raytracegeneric < 100 endparam heading text = "This is the camera (viewpoint) distance from the view plane. The \ view plane is the computer screen. Positive distances are in the \ direction of the screen." endheading float param cameraz caption = "Camera Distance" default = -1e10 endparam heading caption = "Camera rotation" expanded = false endheading bool param rotscreen caption = "Also rotate view screen" default = true endparam float param xanglec caption = "X rotation" default = 0 endparam float param yanglec caption = "Y rotation" default = 0 endparam heading caption = "Light parameters" expanded = false endheading int param nlight caption = "Number of Lights" default = 1 min = 1 max = 5 endparam heading text = " Light Origin" endheading color param spec1 caption = "Specular color" default = rgba(1,1,1,1) endparam float param sbright1 caption = "Specular brightness" default = 0.7 min = 0 max = 1 endparam float param shiny1 caption = "Shininess" default = 100.0 endparam float param lightx caption = " X" default = 5 endparam float param lighty caption = " Y" default = 5 endparam float param lightz caption = " Z" default = 10 endparam heading text = " Light Point At" endheading float param pointx caption = " X" default = 0.0 endparam float param pointy caption = " Y" default = 0.0 endparam float param pointz caption = " Z" default = 0.0 endparam heading text = "Light #2" visible = @nlight > 1 endheading heading text = " Light Origin #2" visible = @nlight > 1 endheading color param spec2 caption = "Specular color" default = rgba(1,1,1,1) visible = @nlight > 1 endparam float param sbright2 caption = "Specular brightness" default = 0.7 min = 0 max = 1 visible = @nlight > 1 endparam float param shiny2 caption = "Shininess" default = 100.0 visible = @nlight > 1 endparam float param lightx2 caption = " X" default = 5.0 visible = @nlight > 1 endparam float param lighty2 caption = " Y" default = 0.0 visible = @nlight > 1 endparam float param lightz2 caption = " Z" default = 10 visible = @nlight > 1 endparam heading text = " Light Point At #2" visible = @nlight > 1 endheading float param pointx2 caption = " X" default = 0.0 visible = @nlight > 1 endparam float param pointy2 caption = " Y" default = 0.0 visible = @nlight > 1 endparam float param pointz2 caption = " Z" default = 0.0 visible = @nlight > 1 endparam heading text = "Light #3" visible = @nlight > 2 endheading heading text = " Light Origin #3" visible = @nlight > 2 endheading color param spec3 caption = "Specular color" default = rgba(1,1,1,1) visible = @nlight > 2 endparam float param sbright3 caption = "Specular brightness" default = 0.7 min = 0 max = 1 visible = @nlight > 2 endparam float param shiny3 caption = "Shininess" default = 100.0 visible = @nlight > 2 endparam float param lightx3 caption = " X" default = -2 visible = @nlight > 2 endparam float param lighty3 caption = " Y" default = 5 visible = @nlight > 2 endparam float param lightz3 caption = " Z" default = 10 visible = @nlight > 2 endparam heading text = " Light Point At #3" visible = @nlight > 2 endheading float param pointx3 caption = " X" default = 0.0 visible = @nlight > 2 endparam float param pointy3 caption = " Y" default = 0.0 visible = @nlight > 2 endparam float param pointz3 caption = " Z" default = 0.0 visible = @nlight > 2 endparam heading text = "Light #4" visible = @nlight > 3 endheading heading text = " Light Origin #4" visible = @nlight > 3 endheading color param spec4 caption = "Specular color" default = rgba(1,1,1,1) visible = @nlight > 3 endparam float param sbright4 caption = "Specular brightness" default = 0.7 min = 0 max = 1 visible = @nlight > 3 endparam float param shiny4 caption = "Shininess" default = 100.0 visible = @nlight > 3 endparam float param lightx4 caption = " X" default = -5 visible = @nlight > 3 endparam float param lighty4 caption = " Y" default = -5 visible = @nlight > 3 endparam float param lightz4 caption = " Z" default = 10 visible = @nlight > 3 endparam heading text = " Light Point At #4" visible = @nlight > 3 endheading float param pointx4 caption = " X" default = 0.0 visible = @nlight > 3 endparam float param pointy4 caption = " Y" default = 0.0 visible = @nlight > 3 endparam float param pointz4 caption = " Z" default = 0.0 visible = @nlight > 3 endparam heading text = "Light #5" visible = @nlight > 4 endheading heading text = " Light Origin #5" visible = @nlight > 4 endheading color param spec5 caption = "Specular color" default = rgba(1,1,1,1) visible = @nlight > 4 endparam float param sbright5 caption = "Specular brightness" default = 0.7 min = 0 max = 1 visible = @nlight > 4 endparam float param shiny5 caption = "Shininess" default = 100.0 visible = @nlight > 4 endparam float param lightx5 caption = " X" default = -2 visible = @nlight > 4 endparam float param lighty5 caption = " Y" default = -3 visible = @nlight > 4 endparam float param lightz5 caption = " Z" default = 10 visible = @nlight > 4 endparam heading text = " Light Point At #5" visible = @nlight > 4 endheading float param pointx5 caption = " X" default = 0.0 visible = @nlight > 4 endparam float param pointy5 caption = " Y" default = 0.0 visible = @nlight > 4 endparam float param pointz5 caption = " Z" default = 0.0 visible = @nlight > 4 endparam } Class RaytraceSphere(RaytraceGeneric) { public: $define debug import "common.ulb" import "dmj5.ulb" func RatytraceSphere(Generic pparent) Raytracegeneric.Raytracegeneric(0) init() endfunc func Init() Raytracegeneric.Init() ; create the sphere array is = new @isph(0) is.recurse() nsph = is.fk zsort = is.zsort rcen = is.crad bradius = is.bradius circles = is.circles showc = is.showc ;find the boundaries of sphere set is.findbound(is.s,is.fk,xmin, ymin, zmin, xmax, ymax, zmax) ; initialize origin, ray, normal, and half angle vectors norm = new Vector(0,0,0,0) pnorm = new Vector(0,0,0,0) hang = new Vector(0,0,0,0) rOrigin = new Vector(0,0,0,0) rRay = new Vector(0,0,0,0) rInternal = new Vector(0,0,0,0) rRefract = new Vector(0,0,0,0) rBackSph = new Vector(0,0,0,0) ; initial bool arrays int i = 0 while i < 10 inter[i] = false ispl[i] = false flrrfl[i] = false i = i + 1 endwhile isplane = false ; load the sphere arrays i = 0 setlength(cen,is.fk) setlength(z,is.fk) setlength(rad,is.fk) setlength(lev,is.fk) setlength(gen,is.fk) while i < nsph cen[i] = is.s.sph[i].fcen z[i] = is.s.sph[i].fz - @z rad[i] = is.s.sph[i].frad lev[i] = is.s.sph[i].flevel gen[i] = is.s.sph[i].fgen i = i + 1 endwhile ; create the plane array int j = 0 planes = 0 if @pset == "floor" || @pset == "back" || @pset == "left" || \ @pset == "right" || @pset == "top" planes = 1 elseif @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "left-right" \ || @pset == "left-top" || @pset == "right-top" planes = 2 elseif @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" planes = 3 elseif @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" planes = 4 elseif @pset == "open box" planes = 5 endif if planes > 0 pa = new @paar(planes) setlength(pfade,planes) setlength(pd,planes) setlength(pnx,planes) setlength(pny,planes) setlength(pnz,planes) setlength(planeno,planes) while j < planes pd[j] = 1e308 if j == 0 if @pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top" || @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box" pa.pl[j] = new Plane(@p1A,@p1B,@p1C,@p1D) pfade[j] = @p1F planeno[j] = 1 elseif @pset == "back" || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "back-left-right" \ || @pset == "back-left-top" || @pset == "back-right-top" \ || @pset == "back-left-right-top" pa.pl[j] = new Plane(@p2A,@p2B,@p2C,@p2D) pfade[j] = @p2F planeno[j] = 2 elseif @pset == "left" || @pset == "left-right" || @pset == "left-top" \ || @pset == "left-right-top" pa.pl[j] = new Plane(@p3A,@p3B,@p3C,@p3D) pfade[j] = @p3F planeno[j] = 3 elseif @pset == "right" || @pset == "right-top" pa.pl[j] = new Plane(@p4A,@p4B,@p4C,@p4D) pfade[j] = @p4F planeno[j] = 4 elseif @pset == "top" pa.pl[j] = new Plane(@p5A,@p5B,@p5C,@p5D) pfade[j] = @p5F planeno[j] = 5 endif pnx[j] = pa.pl[j].pnx pny[j] = pa.pl[j].pny pnz[j] = pa.pl[j].pnz elseif j == 1 if @pset == "floor-back" || @pset == "floor-back-left" \ || @pset == "floor-back-right" || @pset == "floor-back-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" || @pset == "open box" pa.pl[j] = new Plane(@p2A,@p2B,@p2C,@p2D) pfade[j] = @p2F planeno[j] = 2 elseif @pset == "floor-left" || @pset == "back-left" \ || @pset == "floor-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-right" || @pset == "back-left-top" \ ||@pset == "floor-left-right-top" || @pset == "back-left-right-top" pa.pl[j] = new Plane(@p3A,@p3B,@p3C,@p3D) pfade[j] = @p3F planeno[j] = 3 elseif @pset == "floor-right" || @pset == "back-right" \ || @pset == "left-right" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" pa.pl[j] = new Plane(@p4A,@p4B,@p4C,@p4D) pfade[j] = @p4F planeno[j] = 4 elseif @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" pa.pl[j] = new Plane(@p5A,@p5B,@p5C,@p5D) pfade[j] = @p5F planeno[j] = 5 endif pnx[j] = pa.pl[j].pnx pny[j] = pa.pl[j].pny pnz[j] = pa.pl[j].pnz elseif j == 2 if @pset == "floor-back-left" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "open box" pa.pl[j] = new Plane(@p3A,@p3B,@p3C,@p3D) pfade[j] = @p3F planeno[j] = 3 elseif @pset == "floor-back-right" || @pset == "floor-left-right" \ || @pset == "back-left-right"|| @pset == "floor-back-right-top" \ ||@pset == "floor-left-right-top" || @pset == "back-left-right-top" pa.pl[j] = new Plane(@p4A,@p4B,@p4C,@p4D) pfade[j] = @p4F planeno[j] = 4 elseif @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" pa.pl[j] = new Plane(@p5A,@p5B,@p5C,@p5D) pfade[j] = @p5F planeno[j] = 5 endif pnx[j] = pa.pl[j].pnx pny[j] = pa.pl[j].pny pnz[j] = pa.pl[j].pnz elseif j == 3 if @pset == "floor-back-left-right" || @pset == "open box" pa.pl[j] = new Plane(@p4A,@p4B,@p4C,@p4D) pfade[j] = @p4F planeno[j] = 4 elseif @pset == "floor-back-left-top" || @pset == "floor-back-right-top"\ ||@pset == "floor-left-right-top" || @pset == "back-left-right-top" pa.pl[j] = new Plane(@p5A,@p5B,@p5C,@p5D) pfade[j] = @p5F planeno[j] = 5 endif pnx[j] = pa.pl[j].pnx pny[j] = pa.pl[j].pny pnz[j] = pa.pl[j].pnz elseif j == 4 if @pset == "open box" pa.pl[j] = new Plane(@p5A,@p5B,@p5C,@p5D) pfade[j] = @p5F planeno[j] = 5 endif pnx[j] = pa.pl[j].pnx pny[j] = pa.pl[j].pny pnz[j] = pa.pl[j].pnz endif j = j + 1 endwhile endif ; initialize the plugins m_TrapTexture = new @f_traptexture(this) m_TrapTexture_plane1 = new @f_traptexture_plane1(this) m_TrapTexture_plane2 = new @f_traptexture_plane2(this) m_TrapTexture_plane3 = new @f_traptexture_plane3(this) m_TrapTexture_plane4 = new @f_traptexture_plane4(this) m_TrapTexture_plane5 = new @f_traptexture_plane5(this) m_TrapColor = new @f_trapcolor(this) m_TrapColor_plane1 = new @f_trapcolor_plane1(this) m_TrapColor_plane2 = new @f_trapcolor_plane2(this) m_TrapColor_plane3 = new @f_trapcolor_plane3(this) m_TrapColor_plane4 = new @f_trapcolor_plane4(this) m_TrapColor_plane5 = new @f_trapcolor_plane5(this) m_MergeColor = new @f_colormerge(this) m_MergeColor_plane1 = new @f_colormerge_plane1(this) m_MergeColor_plane2 = new @f_colormerge_plane2(this) m_MergeColor_plane3 = new @f_colormerge_plane3(this) m_MergeColor_plane4 = new @f_colormerge_plane4(this) m_MergeColor_plane5 = new @f_colormerge_plane5(this) m_MergeLight = new @f_lightmerge(this) endfunc ;------------------------------------------------- ; Function to determine object intersections with rays ; The maximum recursion level is currently set to 10 ; @param origin = ray origin as a vector ; @param ray = ray as a vector ; @param regress = regression level ; @param rsi = object index - passed back from recursion ; @param dif = diffuse lighting parameter - passed back from recursion ; @param sbr = specular lighting paramer - passed back from recursion ; @param scolor = color of the intersected object ;------------------------------------------------ ; Call Intersect() after viewpoint bool func Intersect(Vector origin, Vector ray, int ®ress, int &rsi, \ float &dif, float &sbr, color &scolor) int i = 0 float bi = 0 float ci = 0 float arg = 0 float ti1 = 0 float ti2 = 0 ; initialize distance to infinity float d = 1e308 float ti = 0 isplane = false floorrfl = false reg = regress inter[reg] = false shad[reg] = false float ctheta = 0 float ctheta2 = 0 float ortheta = 0 float dirtheta = 0 float comp = 0 int oldrsi = 0 passed = false ; determine the closest ray/sphere intersection ; check for bounding volume if !BoundXY(#pixel*#magn/2*@boundadj) || !@boundary while i < nsph if (i != rsi &&((@showbase || (rad[i] < bradius ) && (real(cen[i])*@sa+imag(cen[i])*\ @sb+z[i]*@sc <= @pd||!@slice))&&(!circles || \ circles && ((!showc && rad[i] != rcen) || showc))) && rad[i] > 0) bi = ray.m_x*(origin.m_x-real(cen[i]))+ray.m_y*(origin.m_y-imag(cen[i]))+\ ray.m_z*(origin.m_z-z[i]) ci = (origin.m_x-real(cen[i]))^2+(origin.m_y-imag(cen[i]))^2+\ (origin.m_z-z[i])^2-rad[i]^2 arg = bi*bi-ci if (arg > 0) ; ray intersects sphere ti1 = -bi - sqrt(arg) ti2 = -bi + sqrt(arg) if ti1 > ti2 ; find smallest ti ti = ti2 else ti = ti1 endif if ti > 0 && ti < d inter[reg] = true d = ti ; sphere parameters for the intersected sphere si[reg] = i rsi = si[reg] endif endif endif i = i + 1 if inter[reg] && zsort && reg == 0 i = nsph endif endwhile endif ; if planes are present, check for closest intersection and ; compare to sphere distance. Select closest i = 0 if @pset > 0 while i < planes ortheta = pnx[i]*origin.m_x+pny[i]*origin.m_y+pnz[i]*origin.m_z dirtheta = pnx[i]*ray.m_x+pny[i]*ray.m_y+pnz[i]*ray.m_z pd[i] = -(ortheta+pa.pl[i].pspot)/dirtheta if pd[i] > 0 && pd[i] < 1e308 && pd[i] < d && !isnan(pd[i]) && !isinf(pd[i]) isplane = true inter[reg] = true d = pd[i] pj = i endif i = i + 1 endwhile endif ; code for lighting and coloring if inter[reg] ; intersection point xi[reg] = ray.m_x*d + origin.m_x yi[reg] = ray.m_y*d + origin.m_y zi[reg] = ray.m_z*d + origin.m_z ; look for shadows - sphere on sphere if sphere the closest ; object if @shadow int j = 0 while j < @nlight d = 1e308 ti = 0 i = 0 while i < nsph if (i != rsi) && ((@showbase || (rad[i] < bradius ) \ && (real(cen[i])*@sa+imag(cen[i])*\ @sb+z[i]*@sc <= @pd||!@slice))&&(!circles || \ circles && ((!showc && rad[i] != rcen) || showc))) \ && rad[i] > 0 bi = lar.m_elements[j].m_x*(xi[reg]-real(cen[i]))+\ lar.m_elements[j].m_y*(yi[reg]-imag(cen[i]))+\ lar.m_elements[j].m_z*(zi[reg]-z[i]) ci = (xi[reg]-real(cen[i]))^2+\ (yi[reg]-imag(cen[i]))^2+\ (zi[reg]-z[i])^2-rad[i]^2 arg = bi*bi-ci if (arg > 0) ; ray intersects sphere ti1 = -bi - sqrt(arg) ti2 = -bi + sqrt(arg) if ti1 > ti2 ; find smallest ti ti = ti2 else ti = ti1 endif if ti > 0 && ti < d shad[reg] = true endif endif endif i = i + 1 if shad[reg] && zsort i = nsph endif endwhile j = j + 1 endwhile endif ; normal at intersection point on sphere if sphere the ; closest object if !isplane norm.init((xi[reg]-real(cen[si[reg]]))/rad[si[reg]],\ (yi[reg]-imag(cen[si[reg]]))/rad[si[reg]], \ (zi[reg]-z[si[reg]])/rad[si[reg]], 0) endif ; normal at intersection point on plane if plane the ; closest object if isplane norm.init(pnx[pj],pny[pj],pnz[pj],0) diffdotz = norm.m_z*ray.m_z endif ; ;--------------------------------------- ; textures ;--------------------------------------- ; ; sphere textures if @f_traptexture != DMJ_TrapShapeFlat && !isplane norm.Normalize(norm) ; perturb the normals with the textures pz = 0 if @cent pz = (xi[reg] + flip(yi[reg])-cen[si[reg]])/rad[si[reg]] else pz = (xi[reg] + flip(yi[reg]))/rad[si[reg]] endif if @sphmap pz = pz*(1+|pz|)*@sphsize *0.5 endif m_TrapTexture.Init(pz) ptexture = m_TrapTexture.Iterate(pz) complex tx = m_trapTexture.GetTransformedPoint() if @texflavor == 0 tx = tx*@p_texturestrength norm.init(norm.m_x+real(tx),norm.m_y+imag(tx),norm.m_z+cabs(tx),0) endif endif norm.Normalize(norm) ; plane textures if isplane if planeno[pj] == 1 if @f_traptexture_plane1 != DMJ_TrapShapeFlat ; perturb the normals with the textures pz = 0 float ang = atan2(pa.pl[pj].pb-flip(pa.pl[pj].pa)) complex pang = (0,1)^(ang*2/#pi) if !@pper1 pz = #pixel*pang else pz = xi[reg]+ flip(yi[reg])*pang pz = real(pz) + flip(imag(pz)+zi[reg]*(1-diffdotz)) endif m_TrapTexture_plane1.Init(pz) ptexture = m_TrapTexture_plane1.Iterate(pz) complex tx = m_trapTexture_plane1.GetTransformedPoint() if @texflavor_plane1 == 0 tx = tx*@p_texturestrength_plane1 norm.init(norm.m_x+real(tx),norm.m_y+imag(tx),norm.m_z+cabs(tx),0) endif endif elseif planeno[pj] == 2 if @f_traptexture_plane2 != DMJ_TrapShapeFlat ; perturb the normals with the textures pz = 0 float ang = atan2(pa.pl[pj].pb-flip(pa.pl[pj].pa)) complex pang = (0,1)^(ang*2/#pi) if !@pper2 pz = #pixel*pang else pz = xi[reg]+ flip(yi[reg])*pang pz = real(pz) + flip(imag(pz)+zi[reg]*(1-diffdotz)) endif m_TrapTexture_plane2.Init(pz) ptexture = m_TrapTexture_plane2.Iterate(pz) complex tx = m_trapTexture_plane2.GetTransformedPoint() if @texflavor_plane2 == 0 tx = tx*@p_texturestrength_plane2 norm.init(norm.m_x+real(tx),norm.m_y+imag(tx),norm.m_z+cabs(tx),0) endif endif elseif planeno[pj] == 3 if @f_traptexture_plane3 != DMJ_TrapShapeFlat ; perturb the normals with the textures pz = 0 float ang = atan2(pa.pl[pj].pb-flip(pa.pl[pj].pa)) complex pang = (0,1)^(ang*2/#pi) if !@pper3 pz = #pixel*pang else pz = xi[reg]+ flip(yi[reg])*pang pz = real(pz) + flip(imag(pz)+zi[reg]*(1-diffdotz)) endif m_TrapTexture_plane3.Init(pz) ptexture = m_TrapTexture_plane3.Iterate(pz) complex tx = m_trapTexture_plane3.GetTransformedPoint() if @texflavor_plane3 == 0 tx = tx*@p_texturestrength_plane3 norm.init(norm.m_x+real(tx),norm.m_y+imag(tx),norm.m_z+cabs(tx),0) endif endif elseif planeno[pj] == 4 if @f_traptexture_plane4 != DMJ_TrapShapeFlat ; perturb the normals with the textures pz = 0 float ang = atan2(pa.pl[pj].pb-flip(pa.pl[pj].pa)) complex pang = (0,1)^(ang*2/#pi) if !@pper4 pz = #pixel*pang else pz = xi[reg]+ flip(yi[reg])*pang pz = real(pz) + flip(imag(pz)+zi[reg]*(1-diffdotz)) endif m_TrapTexture_plane4.Init(pz) ptexture = m_TrapTexture_plane4.Iterate(pz) complex tx = m_trapTexture_plane4.GetTransformedPoint() if @texflavor_plane4 == 0 tx = tx*@p_texturestrength_plane4 norm.init(norm.m_x+real(tx),norm.m_y+imag(tx),norm.m_z+cabs(tx),0) endif endif elseif planeno[pj] == 5 if @f_traptexture_plane5 != DMJ_TrapShapeFlat ; perturb the normals with the textures pz = 0 float ang = atan2(pa.pl[pj].pb-flip(pa.pl[pj].pa)) complex pang = (0,1)^(ang*2/#pi) if !@pper5 pz = #pixel*pang else pz = xi[reg]+ flip(yi[reg])*pang pz = real(pz) + flip(imag(pz)+zi[reg]*(1-diffdotz)) endif m_TrapTexture_plane5.Init(pz) ptexture = m_TrapTexture_plane5.Iterate(pz) complex tx = m_trapTexture_plane5.GetTransformedPoint() if @texflavor_plane5 == 0 tx = tx*@p_texturestrength_plane5 norm.init(norm.m_x+real(tx),norm.m_y+imag(tx),norm.m_z+cabs(tx),0) endif endif endif norm.Normalize(norm) endif ; ;--------------------------------------- ; illumination parameters ;--------------------------------------- ; ; distance squared to light(s). Index is the light number. lds[0] = (@lightx-xi[reg])^2 + (@lighty-yi[reg])^2 + (@lightz-zi[reg])^2 lf = @lightx^2 + @lighty^2 + @lightz^2 if @nlight > 1 lds[1] = (@lightx2-xi[reg])^2 + (@lighty2-yi[reg])^2 + (@lightz2-zi[reg])^2 lf = lf + @lightx2^2 + @lighty2^2 + @lightz2^2 endif if @nlight > 2 lds[2] = (@lightx3-xi[reg])^2 + (@lighty3-yi[reg])^2 + (@lightz3-zi[reg])^2 lf = lf + @lightx3^2 + @lighty3^2 + @lightz3^2 endif if @nlight > 3 lds[3] = (@lightx4-xi[reg])^2 + (@lighty4-yi[reg])^2 + (@lightz4-zi[reg])^2 lf = lf + @lightx4^2 + @lighty4^2 + @lightz4^2 endif if @nlight > 4 lds[4] = (@lightx5-xi[reg])^2 + (@lighty5-yi[reg])^2 + (@lightz5-zi[reg])^2 lf = lf + @lightx5^2 + @lighty5^2 + @lightz5^2 endif lf = lf/@nlight ; diffuse value i = 0 diffuse[reg] = 0 while i < @nlight diffuse[reg] = diffuse[reg] + lar.m_elements[i].dot(norm)/lds[i] i = i + 1 endwhile diffuse[reg] = diffuse[reg]*lf*@bright/@nlight ; specular value if !isplane i = 0 while i < @nlight ray.sub(lar.m_elements[i],hang) hang.normalize(hang) specular[reg,i] = -hang.dot(norm) if specular[reg,i] < 0 specular[reg,i] = 0 endif specular[reg,i] = specular[reg,i]^shiny[i]*lf*sbright[i]/lds[i] if shad[0] specular[reg,i] = 0 endif if @texflavor == 1 specular[reg,i] = (specular[reg,i]+\ ptexture*@p_texturestrength) endif speccol[reg,i] = blend(@ambient,spec[i],specular[reg,i]) if i == 0 rspec[reg] = speccol[reg,i] rsbright[reg] = sbright[i] else rspec[reg] = rspec[reg] + speccol[reg,i] rsbright[reg] = rsbright[reg] + sbright[i] endif i = i + 1 endwhile rspec[reg] = rspec[reg]/@nlight scolor = rspec[reg] rsbright[reg] = rsbright[reg]/@nlight sbr = rsbright[reg] endif if @texflavor == 1 && !isplane diffuse[reg] = (diffuse[reg]+ptexture*@p_texturestrength)/\ (1+ptexture*@p_texturestrength) endif if isplane if planeno[pj] == 1 && @texflavor_plane1 == 1 diffuse[reg] = (diffuse[reg]+ptexture*@p_texturestrength_plane1)/\ (1+ptexture*@p_texturestrength_plane1) elseif planeno[pj] == 2 && @texflavor_plane2 == 1 diffuse[reg] = (diffuse[reg]+ptexture*@p_texturestrength_plane2)/\ (1+ptexture*@p_texturestrength_plane2) elseif planeno[pj] == 3 && @texflavor_plane3 == 1 diffuse[reg] = (diffuse[reg]+ptexture*@p_texturestrength_plane3)/\ (1+ptexture*@p_texturestrength_plane3) elseif planeno[pj] == 4 && @texflavor_plane4 == 1 diffuse[reg] = (diffuse[reg]+ptexture*@p_texturestrength_plane4)/\ (1+ptexture*@p_texturestrength_plane4) elseif planeno[pj] == 5 && @texflavor_plane5 == 1 diffuse[reg] = (diffuse[reg]+ptexture*@p_texturestrength_plane5)/\ (1+ptexture*@p_texturestrength_plane5) endif endif oldrsi = rsi ;----------------------------------------- ; ; Reflections onto floor ; ;------------------------------------------ ; sphere reflections off of a plane - one level only ; this may be overwriting the normal plane coloring creating a bug if (@reflect || @refract)&& reg == 0 && isplane && inter[0] ; calculate the reflected ray and the origin vector rorigin.init(xi[reg],yi[reg],zi[reg],0) ; create reflection vector from the plane ctheta = norm.dot(ray);-lxt*vx-lyt*vy-lzt*vz ; N.I ctheta = -ctheta rray.init(ray.m_x+2*norm.m_x*ctheta, ray.m_y+2*norm.m_y*ctheta, \ ray.m_z+2*norm.m_z*ctheta, 0) rray.normalize(rray) i = 0 d = 1e308 ti = 0 while i < nsph if (i != rsi &&((@showbase || (rad[i] < bradius ) && (real(cen[i])*@sa+imag(cen[i])*\ @sb+z[i]*@sc <= @pd||!@slice))&&(!circles || \ circles && ((!showc && rad[i] != rcen) || showc))) && rad[i] > 0) bi = rray.m_x*(rorigin.m_x-real(cen[i]))+rray.m_y*(rorigin.m_y-imag(cen[i]))+\ rray.m_z*(rorigin.m_z-z[i]) ci = (rorigin.m_x-real(cen[i]))^2+(rorigin.m_y-imag(cen[i]))^2+\ (rorigin.m_z-z[i])^2-rad[i]^2 arg = bi*bi-ci if (arg > 0) ; ray intersects sphere ti1 = -bi - sqrt(arg) ti2 = -bi + sqrt(arg) if ti1 > ti2 ; find smallest ti ti = ti2 else ti = ti1 endif if ti > 0 && ti < d inter[1] = true reg = 1 regress = 1 floorrfl = true d = ti ; sphere parameters for the intersected sphere si[reg] = i rsi = si[reg] endif endif endif i = i + 1 endwhile if floorrfl ; intersection point xi[reg] = rray.m_x*d + rorigin.m_x yi[reg] = rray.m_y*d + rorigin.m_y zi[reg] = rray.m_z*d + rorigin.m_z norm.init((xi[reg]-real(cen[si[reg]]))/rad[si[reg]],\ (yi[reg]-imag(cen[si[reg]]))/rad[si[reg]], \ (zi[reg]-z[si[reg]])/rad[si[reg]], 0) ; sphere textures if @f_traptexture != DMJ_TrapShapeFlat norm.Normalize(norm) ; perturb the normals with the textures pz = 0 if @cent pz = (xi[reg] + flip(yi[reg])-cen[si[reg]])/rad[si[reg]] else pz = (xi[reg] + flip(yi[reg]))/rad[si[reg]] endif if @sphmap pz = pz*(1+|pz|)*@sphsize *0.5 endif m_TrapTexture.Init(pz) ptexture = m_TrapTexture.Iterate(pz) complex tx = m_trapTexture.GetTransformedPoint() if @texflavor == 0 tx = tx*@p_texturestrength norm.init(norm.m_x+real(tx),norm.m_y+imag(tx),norm.m_z+cabs(tx),0) endif endif norm.Normalize(norm) ; illumination parameters ; distance squared to light(s). Index is the light number. lds[0] = (@lightx-xi[reg])^2 + (@lighty-yi[reg])^2 + (@lightz-zi[reg])^2 lf = @lightx^2 + @lighty^2 + @lightz^2 if @nlight > 1 lds[1] = (@lightx2-xi[reg])^2 + (@lighty2-yi[reg])^2 + (@lightz2-zi[reg])^2 lf = lf + @lightx2^2 + @lighty2^2 + @lightz2^2 endif if @nlight > 2 lds[2] = (@lightx3-xi[reg])^2 + (@lighty3-yi[reg])^2 + (@lightz3-zi[reg])^2 lf = lf + @lightx3^2 + @lighty3^2 + @lightz3^2 endif if @nlight > 3 lds[3] = (@lightx4-xi[reg])^2 + (@lighty4-yi[reg])^2 + (@lightz4-zi[reg])^2 lf = lf + @lightx4^2 + @lighty4^2 + @lightz4^2 endif if @nlight > 4 lds[4] = (@lightx5-xi[reg])^2 + (@lighty5-yi[reg])^2 + (@lightz5-zi[reg])^2 lf = lf + @lightx5^2 + @lighty5^2 + @lightz5^2 endif lf = lf/@nlight ; diffuse value i = 0 diffuse[reg] = 0 while i < @nlight diffuse[reg] = diffuse[reg] + lar.m_elements[i].dot(norm)/lds[i] i = i + 1 endwhile diffuse[reg] = diffuse[reg]*lf*@bright/@nlight ; specular value if isplane i = 0 while i < @nlight ray.sub(lar.m_elements[i],hang) hang.normalize(hang) specular[reg,i] = -hang.dot(norm) if specular[reg,i] < 0 specular[reg,i] = 0 endif specular[reg,i] = specular[reg,i]^shiny[i]*lf*sbright[i]/lds[i] if shad[0] specular[reg,i] = 0 endif if @texflavor == 1 specular[reg,i] = (specular[reg,i]+\ ptexture*@p_texturestrength) endif speccol[reg,i] = blend(@ambient,spec[i],specular[reg,i]) if i == 0 rspec[reg] = speccol[reg,i] rsbright[reg] = sbright[i] else rspec[reg] = rspec[reg] + speccol[reg,i] rsbright[reg] = rsbright[reg] + sbright[i] endif i = i + 1 endwhile rspec[reg] = rspec[reg]/@nlight scolor = rspec[reg] rsbright[reg] = rsbright[reg]/@nlight sbr = rsbright[reg] endif if @texflavor == 1 diffuse[reg] = (diffuse[reg]+ptexture*@p_texturestrength)/\ (1+ptexture*@p_texturestrength) endif endif endif ;--------------------------------------------------------------------- bool inreflect = false ; sphere reflections ; if (@reflect || @refract) && regress < 9 && @refval^(reg) > 0.005 && !isplane if (@reflect || @refract) && regress < @recurse && !isplane inreflect = true regress = regress + 1 reg = regress ; calculate the reflected ray and the origin vector rorigin.init(xi[reg-1],yi[reg-1],zi[reg-1],0) ; create reflection vector [R = I+2*N*(N.I)] ctheta = norm.dot(ray);-lxt*vx-lyt*vy-lzt*vz ; N.I ctheta = -ctheta rray.init(ray.m_x+2*norm.m_x*ctheta, ray.m_y+2*norm.m_y*ctheta, \ ray.m_z+2*norm.m_z*ctheta, 0) rray.normalize(rray) inter[reg] = intersect(rorigin, rray, regress, rsi, diffuse[reg], sbr, scolor) if inter[reg] si[reg] = rsi rspec[reg] = scolor diffuse[reg] = diffuse[reg-1] rsbright[reg] = sbr endif endif ; if @refract && regress < 9 && @refracval^(reg) > 0.005 && !isplane if @refract && regress < @trecurse && !isplane ; increment the regression counter if a reflection vector was sent ; if oldrsi != rsi || !inreflect if !inreflect regress = regress + 1 reg = regress endif rorigin.init(xi[reg-1],yi[reg-1],zi[reg-1],0) ctheta = norm.dot(ray) ; N.I ctheta = -ctheta ; calculate the internal refraction ray. ; T = [I/rfi-(ctheta2-ctheta/rfi)*N] ; Snell's law: sin(angle1)/sin(angle2) = rf2/rf1 = rfi ctheta2 = sqrt(1 - (1-ctheta^2)/@rfi^2) ; T.I comp = ctheta2 - ctheta/@rfi rinternal.init(ray.m_x/@rfi-norm.m_x*comp,ray.m_y/@rfi-norm.m_y*comp,\ ray.m_z/@rfi-norm.m_z*comp,0) rinternal.normalize(rinternal) ; calculate the intersection at the back of the sphere bi = rinternal.m_x*(rorigin.m_x-real(cen[oldrsi]))+\ rinternal.m_y*(rorigin.m_y-imag(cen[oldrsi]))+\ rinternal.m_z*(rorigin.m_z-z[oldrsi]) ci = (rorigin.m_x-real(cen[oldrsi]))^2+\ (rorigin.m_y-imag(cen[oldrsi]))^2+\ (rorigin.m_z-z[oldrsi])^2-rad[oldrsi]^2 arg = bi*bi-ci if (arg > 0) ; ray intersects sphere ti1 = -bi - sqrt(arg) ti2 = -bi + sqrt(arg) if ti1 < ti2 ; find largest ti ti = ti2 else ti = ti1 endif endif float xb = rorigin.m_x+rinternal.m_x*ti float yb = rorigin.m_y+rinternal.m_y*ti float zb = rorigin.m_z+rinternal.m_z*ti ; calculate the surface normal at the back of the sphere norm.init(-(xb-real(cen[oldrsi]))/rad[oldrsi],\ -(yb-imag(cen[oldrsi]))/rad[oldrsi], \ -(zb-z[oldrsi])/rad[oldrsi], 0) norm.Normalize(norm) ; calculate the refraction vector from the back of the sphere ctheta = norm.dot(rinternal) ; N.I ctheta = -ctheta ctheta2 = sqrt(1 - (1-ctheta^2)*@rfi^2) ; T.I comp = ctheta2 - ctheta*@rfi rrefract.init(rinternal.m_x*@rfi-norm.m_x*comp,rinternal.m_y*@rfi-norm.m_y*comp,\ rinternal.m_z*@rfi-norm.m_z*comp,0) rrefract.normalize(rrefract) rBackSph.init(xb,yb,zb,0) ; determine the next sphere intersection inter[reg] = intersect(rbacksph, rrefract, regress, oldrsi, diffuse[reg], sbr, scolor) if sin(real(acos(ctheta))) <= 1/@rfi passed = true endif if inter[reg] si[reg] = oldrsi rspec[reg] = scolor diffuse[reg] = diffuse[reg-1] rsbright[reg] = sbr endif endif endif return inter[reg] endfunc bool func BoundXY(complex grid) bool outside = false float dx = (xmax+xmin)/2 float dy = (ymax+ymin)/2 float x = (xmax-xmin)/2 float y = (ymax-ymin)/2 if ((real(grid)-dx)^2/x^2 + (imag(grid)-dy)^2/y^2 - 1 > 0.01) outside = true endif return outside endfunc color func Result() color return_color = rgba(0,0,0,1) color boundary_color = rgb(0.5,0.5,0.5) color flrclr = rgba(0,0,0,0) color tempflr[10] color base[10] color temp = rgba(0,0,0,1) color cpat = rgba(0,0,0,1) int i = 0 cp = false if @f_trapcolor != ColorTrapNoColor while i <= reg cp = true pz = 0 if @centp pz = (xi[i] + flip(yi[i])-cen[si[i]])/rad[si[i]] else pz = (xi[i] + flip(yi[i]))/rad[si[i]] endif if @sphmapp pz = pz*(1+|pz|)*@sphsizep *0.25 endif if @f_trapcolor == ColorTrapImageTiles && @override int inc = 0 if @selctype == "index" inc = si[0] % (@incment+1) elseif @selctype == "level" inc = lev[si[0]] % (@incment+1) elseif @selctype == "generator" inc = gen[si[0]] % (@incment+1) elseif @selctype == "position" inc = trunc(cabs(cen[si[0]])) % (@incment+1) elseif @selctype == "size" inc = trunc(@incment/rad[si[0]]) % (@incment+1) elseif @selctype == "size threshold" if rad[si[i]] < @rthresh inc = 0 else inc = 1 endif endif float range = imag(@ovrange) - real(@ovrange) if @selctype != "size threshold" pz = pz + real(@ovrange) + inc/range/@incment else pz = pz + real(@ovrange) + inc endif endif m_TrapColor.Init(pz) colpat[i] = m_TrapColor.Iterate(pz) ispl[i] = isplane flrrfl[i] = floorrfl i = i + 1 endwhile endif ; base coloring float ctype = 0 i = 0 while i <= reg if @selctype == "index" ctype = (si[i] % @mod)/@mod elseif @selctype == "level" ctype = (lev[si[i]] % @mod)/@mod elseif @selctype == "generator" ctype = (gen[si[i]] % @mod)/@mod elseif @selctype == "position" ctype = (cabs(cen[si[i]])%@mod)/@mod elseif @selctype == "size" ctype = ((@mod/rad[si[i]])%@mod)/@mod elseif @selctype == "size threshold" if rad[si[0]] < @rthresh ctype = 0 else ctype = 0.5 endif endif base[i] = gradient(ctype) i = i + 1 endwhile if inter[0] base[0] = compose(base[0],hsl(hue(base[0]),sat(base[0]),\ @lumfac*lum(base[0])), 1-diffuse[0]^2) if passed base[0] = blend(@backdrop,base[0],@blendval) endif return_color = m_MergeLight.FullMerge(base[0], rspec[0], \ rsbright[0]) tempflr[0] = return_color else color return_color = rgba(0,0,0,1) endif i = 1 while i <= reg if inter[i] base[i] = compose(base[i],hsl(hue(base[i]),sat(base[i]),\ @lumfac*lum(base[i])), 1-diffuse[i]^2) if passed && @refract base[i] = blend(@backdrop,base[i],@blendval) endif temp = m_MergeLight.FullMerge(base[i], rspec[i], \ rsbright[i]) if @refract float lm = (1-lum(base[i]))/@tradj lm = 1 - lm base[i] = hsla(hue(base[i]),sat(base[i])/@tradj,lm,1/@tradj) temp = m_MergeLight.FullMerge(base[i], rspec[i], 1) endif if (@reflect && !@refract) return_color = blend(return_color,temp,@refval^i) tempflr[i] = temp elseif @refract return_color = blend(return_color,temp,@refracval^i*@refval^i) tempflr[i] = temp if @pset != 0 return_color = blend(@backdrop,return_color,@blendval) tempflr[i] = blend(@backdrop,tempflr[i],@blendval) endif endif endif i = i + 1 endwhile if inter[0] && cp cpat = colpat[0] endif i = 1 while i <= reg if inter[i] temp = colpat[i] if (@reflect && !@refract) cpat = blend(cpat,temp,@refval^i) elseif @refract cpat = blend(cpat,temp,@refracval^i*@refval^i) endif endif i = i + 1 endwhile if cp if @nmerge == 1 temp = cpat cpat = return_color return_color = temp endif return_color = m_MergeColor.FullMerge(cpat, return_color, @opacity) i = 0 while i <= reg if @nmerge == 1 temp = colpat[i] colpat[i] = tempflr[i] tempflr[i] = temp endif tempflr[i] = m_MergeColor.FullMerge(colpat[i], tempflr[i], @opacity) i = i + 1 endwhile if shad[0] return_color = blend(return_color,@ambient,@shadval) endif if @displaybound && !BoundXY(#pixel*#magn/2*@boundadj) return_color = blend(boundary_color, return_color,0.5) endif endif i = 0 cp = false if pa != 0 if planeno[pj] == 1 if @f_trapcolor_plane1 != ColorTrapNoColor cp = true float ang = atan2(pa.pl[pj].pb-flip(pa.pl[pj].pa)) complex pang = (0,1)^(ang*2/#pi) if !@pper1 pz = #pixel*pang else if floorrfl pz = xi[0]+ flip(yi[0])*pang pz = real(pz) + flip(imag(pz)+zi[0]*(1-diffdotz)) else pz = xi[reg]+ flip(yi[reg])*pang pz = real(pz) + flip(imag(pz)+zi[reg]*(1-diffdotz)) endif endif m_TrapColor_plane1.Init(pz) colpat[reg] = m_TrapColor_plane1.Iterate(pz) endif if inter[reg] && cp cpat = colpat[reg] endif if @usepgrad1 flrclr = gradient(pj/planes) else flrclr = @plplaincolor1 endif if @f_traptexture_plane1 != DMJ_TrapShapeFlat && reg > 0 if @texflavor_plane1 == 0 flrclr = blend(flrclr,tempflr[reg],@adjdif1*(norm.m_x+norm.m_y+ norm.m_z)/3) else flrclr = blend(flrclr,tempflr[reg],\ @adjdif1*ptexture*@p_texturestrength_plane1/\ (1+ptexture*@p_texturestrength_plane1)) endif endif if cp if @nmerge_plane1 == 1 temp = cpat cpat = flrclr flrclr = temp endif flrclr = m_MergeColor_plane1.FullMerge(cpat, flrclr, @opacity_plane1) endif if reg ==0 flrclr = blend(@plambient1,flrclr,@adjdif1*diffuse[0]) elseif reg == 1 && floorrfl flrclr = blend(@plambient1,flrclr,@adjdif1*diffuse[0]) else float dcorr = 1-pd[pj]/sqrt(lf)*2 if dcorr < 0 dcorr = 0 elseif dcorr > 1 dcorr = 1 endif flrclr = blend(tempflr[reg],flrclr,dcorr) endif if @tpfade1 flrclr = rgba(red(flrclr),green(flrclr),blue(flrclr),@adjdif1*diffuse[reg]/pfade[pj]) endif if shad[0] flrclr = compose(flrclr,@ambient,@shadval) endif if @reflect && !@refract if reg >=0&& floorrfl flrclr = compose(flrclr,tempflr[reg],@sph2flr1*@refval) endif if reg >0&& !floorrfl if @refval > 0 flrclr = compose(flrclr,tempflr[reg-1],1-@flr2sph1) else flrclr = compose(flrclr,tempflr[0],1-@flr2sph1) endif endif endif if @refract if reg >=0&& floorrfl flrclr = compose(flrclr,tempflr[reg],@sph2flr1*@refracval) endif if reg >0&& !floorrfl if @refracval > 0 flrclr = compose(flrclr,tempflr[reg-1],1-@flr2sph1) else flrclr = compose(flrclr,tempflr[0],1-@flr2sph1) endif endif endif elseif planeno[pj] == 2 if @f_trapcolor_plane2 != ColorTrapNoColor cp = true float ang = atan2(pa.pl[pj].pb-flip(pa.pl[pj].pa)) complex pang = (0,1)^(ang*2/#pi) if !@pper2 pz = #pixel*pang else if floorrfl pz = xi[0]+ flip(yi[0])*pang pz = real(pz) + flip(imag(pz)+zi[0]*(1-diffdotz)) else pz = xi[reg]+ flip(yi[reg])*pang pz = real(pz) + flip(imag(pz)+zi[reg]*(1-diffdotz)) endif endif m_TrapColor_plane2.Init(pz) colpat[reg] = m_TrapColor_plane2.Iterate(pz) endif if inter[reg] && cp cpat = colpat[reg] endif if @usepgrad2 flrclr = gradient(pj/planes) else flrclr = @plplaincolor2 endif if @f_traptexture_plane2 != DMJ_TrapShapeFlat && reg > 0 if @texflavor_plane2 == 0 flrclr = blend(flrclr,tempflr[reg],@adjdif2*(norm.m_x+norm.m_y+ norm.m_z)/3) else flrclr = blend(flrclr,tempflr[reg],\ @adjdif2*ptexture*@p_texturestrength_plane2/\ (1+ptexture*@p_texturestrength_plane2)) endif endif if cp if @nmerge_plane2 == 1 temp = cpat cpat = flrclr flrclr = temp endif flrclr = m_MergeColor_plane2.FullMerge(cpat, flrclr, @opacity_plane2) endif if reg == 0 flrclr = blend(@plambient2,flrclr,@adjdif2*diffuse[0]) elseif reg == 1 && floorrfl flrclr = blend(@plambient2,flrclr,@adjdif2*diffuse[0]) else float dcorr = 1-pd[pj]/sqrt(lf)*2 if dcorr < 0 dcorr = 0 elseif dcorr > 1 dcorr = 1 endif flrclr = blend(tempflr[reg],flrclr,dcorr) endif if @tpfade2 flrclr = rgba(red(flrclr),green(flrclr),blue(flrclr),@adjdif2*diffuse[reg]/pfade[pj]) endif if shad[0] flrclr = compose(flrclr,@ambient,@shadval) endif if @reflect && !@refract if reg >=0&& floorrfl flrclr = compose(flrclr,tempflr[reg],@sph2flr2*@refval) endif if reg >0&& !floorrfl if @refval > 0 flrclr = compose(flrclr,tempflr[reg-1],1-@flr2sph2) else flrclr = compose(flrclr,tempflr[0],1-@flr2sph2) endif endif endif if @refract if reg >=0&& floorrfl flrclr = compose(flrclr,tempflr[reg],@sph2flr2*@refracval) endif if reg >0&& !floorrfl if @refracval > 0 flrclr = compose(flrclr,tempflr[reg-1],1-@flr2sph2) else flrclr = compose(flrclr,tempflr[0],1-@flr2sph2) endif endif endif elseif planeno[pj] == 3 if @f_trapcolor_plane3 != ColorTrapNoColor cp = true float ang = atan2(pa.pl[pj].pb-flip(pa.pl[pj].pa)) complex pang = (0,1)^(ang*2/#pi) if !@pper3 pz = #pixel*pang else if floorrfl pz = xi[0]+ flip(yi[0])*pang pz = real(pz) + flip(imag(pz)+zi[0]*(1-diffdotz)) else pz = xi[reg]+ flip(yi[reg])*pang pz = real(pz) + flip(imag(pz)+zi[reg]*(1-diffdotz)) endif endif m_TrapColor_plane3.Init(pz) colpat[reg] = m_TrapColor_plane3.Iterate(pz) endif if inter[reg] && cp cpat = colpat[reg] endif if @usepgrad3 flrclr = gradient(pj/planes) else flrclr = @plplaincolor3 endif if @f_traptexture_plane3 != DMJ_TrapShapeFlat && reg > 0 if @texflavor_plane3 == 0 flrclr = blend(flrclr,tempflr[reg],@adjdif3*(norm.m_x+norm.m_y+ norm.m_z)/3) else flrclr = blend(flrclr,tempflr[reg],\ @adjdif3*ptexture*@p_texturestrength_plane3/\ (1+ptexture*@p_texturestrength_plane3)) endif endif if cp if @nmerge_plane3 == 1 temp = cpat cpat = flrclr flrclr = temp endif flrclr = m_MergeColor_plane3.FullMerge(cpat, flrclr, @opacity_plane3) endif if reg ==0 flrclr = blend(@plambient3,flrclr,@adjdif3*diffuse[0]) elseif reg == 1 && floorrfl flrclr = blend(@plambient3,flrclr,@adjdif3*diffuse[0]) else float dcorr = 1-pd[pj]/sqrt(lf)*2 if dcorr < 0 dcorr = 0 elseif dcorr > 1 dcorr = 1 endif flrclr = blend(tempflr[reg],flrclr,dcorr) endif if @tpfade3 flrclr = rgba(red(flrclr),green(flrclr),blue(flrclr),@adjdif3*diffuse[reg]/pfade[pj]) endif if shad[0] flrclr = compose(flrclr,@ambient,@shadval) endif if @reflect && !@refract if reg >=0&& floorrfl flrclr = compose(flrclr,tempflr[reg],@sph2flr3*@refval) endif if reg >0&& !floorrfl if @refval > 0 flrclr = compose(flrclr,tempflr[reg-1],1-@flr2sph3) else flrclr = compose(flrclr,tempflr[0],1-@flr2sph3) endif endif endif if @refract if reg >=0&& floorrfl flrclr = compose(flrclr,tempflr[reg],@sph2flr3*@refracval) endif if reg >0&& !floorrfl if @refracval > 0 flrclr = compose(flrclr,tempflr[reg-1],1-@flr2sph3) else flrclr = compose(flrclr,tempflr[0],1-@flr2sph3) endif endif endif elseif planeno[pj] == 4 if @f_trapcolor_plane4 != ColorTrapNoColor cp = true float ang = atan2(pa.pl[pj].pb-flip(pa.pl[pj].pa)) complex pang = (0,1)^(ang*2/#pi) if !@pper4 pz = #pixel*pang else if floorrfl pz = xi[0]+ flip(yi[0])*pang pz = real(pz) + flip(imag(pz)+zi[0]*(1-diffdotz)) else pz = xi[reg]+ flip(yi[reg])*pang pz = real(pz) + flip(imag(pz)+zi[reg]*(1-diffdotz)) endif endif m_TrapColor_plane4.Init(pz) colpat[reg] = m_TrapColor_plane4.Iterate(pz) endif if inter[reg] && cp cpat = colpat[reg] endif if @usepgrad4 flrclr = gradient(pj/planes) else flrclr = @plplaincolor4 endif if @f_traptexture_plane4 != DMJ_TrapShapeFlat && reg > 0 if @texflavor_plane4 == 0 flrclr = blend(flrclr,tempflr[reg],@adjdif4*(norm.m_x+norm.m_y+ norm.m_z)/3) else flrclr = blend(flrclr,tempflr[reg],\ @adjdif4*ptexture*@p_texturestrength_plane4/\ (1+ptexture*@p_texturestrength_plane4)) endif endif if cp if @nmerge_plane4 == 1 temp = cpat cpat = flrclr flrclr = temp endif flrclr = m_MergeColor_plane4.FullMerge(cpat, flrclr, @opacity_plane4) endif if reg ==0 flrclr = blend(@plambient4,flrclr,@adjdif4*diffuse[0]) elseif reg == 1 && floorrfl flrclr = blend(@plambient4,flrclr,@adjdif4*diffuse[0]) else float dcorr = 1-pd[pj]/sqrt(lf)*2 if dcorr < 0 dcorr = 0 elseif dcorr > 1 dcorr = 1 endif flrclr = blend(tempflr[reg],flrclr,dcorr) endif if @tpfade1 flrclr = rgba(red(flrclr),green(flrclr),blue(flrclr),@adjdif4*diffuse[reg]/pfade[pj]) endif if shad[0] flrclr = compose(flrclr,@ambient,@shadval) endif if @reflect && !@refract if reg >=0&& floorrfl flrclr = compose(flrclr,tempflr[reg],@sph2flr4*@refval) endif if reg >0&& !floorrfl if @refval > 0 flrclr = compose(flrclr,tempflr[reg-1],1-@flr2sph4) else flrclr = compose(flrclr,tempflr[0],1-@flr2sph4) endif endif endif if @refract if reg >=0&& floorrfl flrclr = compose(flrclr,tempflr[reg],@sph2flr4*@refracval) endif if reg >0&& !floorrfl if @refracval > 0 flrclr = compose(flrclr,tempflr[reg-1],1-@flr2sph4) else flrclr = compose(flrclr,tempflr[0],1-@flr2sph4) endif endif endif elseif planeno[pj] == 5 if @f_trapcolor_plane5 != ColorTrapNoColor cp = true float ang = atan2(pa.pl[pj].pb-flip(pa.pl[pj].pa)) complex pang = (0,1)^(ang*2/#pi) if !@pper5 pz = #pixel*pang else if floorrfl pz = xi[0]+ flip(yi[0])*pang pz = real(pz) + flip(imag(pz)+zi[0]*(1-diffdotz)) else pz = xi[reg]+ flip(yi[reg])*pang pz = real(pz) + flip(imag(pz)+zi[reg]*(1-diffdotz)) endif endif m_TrapColor_plane5.Init(pz) colpat[reg] = m_TrapColor_plane5.Iterate(pz) endif if inter[reg] && cp cpat = colpat[reg] endif if @usepgrad5 flrclr = gradient(pj/planes) else flrclr = @plplaincolor5 endif if @f_traptexture_plane5 != DMJ_TrapShapeFlat && reg > 0 if @texflavor_plane5 == 0 flrclr = blend(flrclr,tempflr[reg],@adjdif5*(norm.m_x+norm.m_y+ norm.m_z)/3) else flrclr = blend(flrclr,tempflr[reg],\ @adjdif5*ptexture*@p_texturestrength_plane5/\ (1+ptexture*@p_texturestrength_plane5)) endif endif if cp if @nmerge_plane5 == 1 temp = cpat cpat = flrclr flrclr = temp endif flrclr = m_MergeColor_plane5.FullMerge(cpat, flrclr, @opacity_plane5) endif if reg ==0 flrclr = blend(@plambient5,flrclr,@adjdif5*diffuse[0]) elseif reg == 1 && floorrfl flrclr = blend(@plambient5,flrclr,@adjdif5*diffuse[0]) else float dcorr = 1-pd[pj]/sqrt(lf)*2 if dcorr < 0 dcorr = 0 elseif dcorr > 1 dcorr = 1 endif flrclr = blend(tempflr[reg],flrclr,dcorr) endif if @tpfade1 flrclr = rgba(red(flrclr),green(flrclr),blue(flrclr),@adjdif1*diffuse[reg]/pfade[pj]) endif if shad[0] flrclr = compose(flrclr,@ambient,@shadval) endif if @reflect && !@refract if reg >=0&& floorrfl flrclr = compose(flrclr,tempflr[reg],@sph2flr5*@refval) endif if reg >0&& !floorrfl if @refval > 0 flrclr = compose(flrclr,tempflr[reg-1],1-@flr2sph5) else flrclr = compose(flrclr,tempflr[0],1-@flr2sph5) endif endif endif if @refract if reg >=0&& floorrfl flrclr = compose(flrclr,tempflr[reg],@sph2flr5*@refracval) endif if reg >0&& !floorrfl if @refracval > 0 flrclr = compose(flrclr,tempflr[reg-1],1-@flr2sph5) else flrclr = compose(flrclr,tempflr[0],1-@flr2sph5) endif endif endif endif endif if !isplane return return_color else return flrclr endif endfunc bool inter[10] bool isplane bool ispl[10] int reg bool floorrfl bool flrrfl[10] protected: InvertSphere is PlaneArray pa TrapShape m_TrapTexture TrapShape m_TrapTexture_plane1 TrapShape m_TrapTexture_plane2 TrapShape m_TrapTexture_plane3 TrapShape m_TrapTexture_plane4 TrapShape m_TrapTexture_plane5 ColorTrap m_TrapColor ColorTrap m_TrapColor_plane1 ColorTrap m_TrapColor_plane2 ColorTrap m_TrapColor_plane3 ColorTrap m_TrapColor_plane4 ColorTrap m_TrapColor_plane5 DefaultColorMerge m_MergeColor DefaultColorMerge m_MergeColor_plane1 DefaultColorMerge m_MergeColor_plane2 DefaultColorMerge m_MergeColor_plane3 DefaultColorMerge m_MergeColor_plane4 DefaultColorMerge m_MergeColor_plane5 IllumColorMerge m_MergeLight Vector norm Vector pnorm Vector hang Vector rOrigin Vector rRay Vector rInternal Vector rRefract Vector rBackSph float rsbright[10] float xi[10] float yi[10] float zi[10] color colpat[10] color rspec[10] float sitrans[10] float lds[5] bool shad[10] complex cen[] float z[] float rad[] int lev[] int gen[] float rcen int nsph bool zsort float bradius bool circles bool showc bool cp float ptexture complex pz float xmin float ymin float zmin float xmax float ymax float zmax float refval bool passed float pfade[] float pnx[] float pny[] float pnz[] float pd[] float diffdotz int pj int planes int planeno[] float lf bool sphtoplane ; for floor reflections float flrrsbright[10] color flrrspec[10] default: title = "Raytrace Spheres" int param v_raytracespheres caption = "Version (Raytrace Spheres)" default = 101 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_raytracespheres < 101 endparam heading caption = "Illumination model" expanded = false endheading float param z caption = "Object Depth" default = 0 endparam param selctype caption = "Coloring mode" default = 1 enum = "index" "level" "generator" "position" "size" "size threshold" endparam heading text = "For the 'generator' option the modulus should equal the \ number of generator spheres. For this condition no two \ spheres of the same color will touch (except for Mobius)." visible = @selctype == "generator" endheading heading text = " Tetrahedron: 4; Cube: 7; Octahedron: 7; \ Dodecahedron: 13; Circle: circles + 1; Mobius: 4." visible = @selctype == "generator" endheading heading text = "Specular parameters are found under 'Light parameters'." endheading int param mod caption = "Color modulus" default = 8 visible = @selctype != "size threshold" endparam float param rthresh caption = "size threshold" default = 0.03 visible = @selctype == "size threshold" endparam float param bright caption = "Total brightness" default = 0.9 min = 0 endparam float param lumfac caption = "Luminosity factor" default = 0.2 min = 0 max = 1 endparam IllumColorMerge param f_lightmerge caption = "Light Merge" default = IllumColorMerge endparam color param ambient caption = "Ambient color" default = rgba(0.05,0.05,0.05,1) endparam int param trecurse caption = "Recurse level trans" default = 2 max = 9 visible = @refract endparam int param recurse caption = "Recurse level reflect" default = 2 max = 9 visible = @refract || @reflect endparam bool param shadow caption = "Shadows" default = false endparam float param shadval caption = "Shadow value" default = 0.5 visible = @shadow endparam bool param reflect caption = "Reflections" default = false visible = !@refract endparam float param refval caption = "Reflect value" default = 1.0 visible = @reflect || @refract endparam heading text = "Floor plane" visible = (@reflect || @refract) && (@pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box") endheading float param flr2sph1 caption = "Plane to sphere" default = 0.5 min = 0 max = 1 visible = (@reflect || @refract) && (@pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box") endparam float param sph2flr1 caption = "Sphere to plane" default = 0.5 min = 0 max = 1 visible = (@reflect || @refract) && (@pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box") endparam heading text = "Back plane" visible = (@reflect || @refract) && (@pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box") endheading float param flr2sph2 caption = "Plane to sphere" default = 0.5 min = 0 max = 1 visible = (@reflect || @refract) && (@pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box") endparam float param sph2flr2 caption = "Sphere to plane" default = 0.5 min = 0 max = 1 visible = (@reflect || @refract) && (@pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box") endparam heading text = "Left plane" visible = (@reflect || @refract) && (@pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box") endheading float param flr2sph3 caption = "Plane to sphere" default = 0.5 min = 0 max = 1 visible = (@reflect || @refract) && (@pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box") endparam float param sph2flr3 caption = "Sphere to plane" default = 0.5 min = 0 max = 1 visible = (@reflect || @refract) && (@pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box") endparam heading text = "Right plane" visible = (@reflect || @refract) && (@pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box") endheading float param flr2sph4 caption = "Plane to sphere" default = 0.5 min = 0 max = 1 visible = (@reflect || @refract) && (@pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box") endparam float param sph2flr4 caption = "Sphere to plane" default = 0.5 min = 0 max = 1 visible = (@reflect || @refract) && (@pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box") endparam heading text = "Top plane" visible = (@reflect || @refract) && (@pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box") endheading float param flr2sph5 caption = "Plane to sphere" default = 0.5 min = 0 max = 1 visible = (@reflect || @refract) && (@pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box") endparam float param sph2flr5 caption = "Sphere to plane" default = 0.5 min = 0 max = 1 visible = (@reflect || @refract) && (@pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box") endparam bool param refract caption = "Refractions" default = false endparam float param rfi caption = "Refractive index" default = 1.33 visible = @refract endparam float param refracval caption = "Refract value" default = 1.0 visible = @refract endparam color param backdrop caption = "Refract backdrop" default = rgba(0.5,0.5,0.5,1) visible = @refract hint = "Coloring for refraction rays that pass through all the \ spheres. Try setting to the background color in the \ outside tab." endparam float param blendval caption = "Backdrop blend" default = 0.5 max = 1.0 visible = @refract endparam float param tradj caption = "Refract color adj" default = 2 min = 1 visible = @refract hint = "Adjusts saturation and luminosity of refracted colors." endparam heading caption = "Sphere Textures" endheading TrapShape param f_traptexture caption = "Sphere Textures" default = DMJ_TrapShapeFlat expanded = false hint = "A trap shape that is used as a texture. Textures do not change \ the shape of the trap but may change its coloring." endparam float param p_texturestrength caption = "Texture Amount" default = 0.0 hint = "Sets the overall amount of texture to be used. Larger numbers \ will increase the effect of the texture. A value of 0 will remove \ the effects of the texture." visible = (@f_traptexture != DMJ_TrapShapeFlat) endparam heading text = "If 'Transformed' is selected the surface normals are purturbed, giving \ a bump map texture, which will also affect reflections and transparency." visible = @texflavor == "Transformed" && @f_traptexture != DMJ_TrapShapeFlat endheading param texflavor caption = "Texture type" default = 0 enum = "Transformed" "Standard" visible = (@f_traptexture != DMJ_TrapShapeFlat) endparam bool param cent caption = "Center on sphere" default = true visible = (@f_traptexture != DMJ_TrapShapeFlat) endparam bool param sphmap caption = "Spherical mapping" default = false visible = (@f_traptexture != DMJ_TrapShapeFlat) endparam float param sphsize caption = "Map size" default = 0.5 visible = @sphmap && (@f_traptexture != DMJ_TrapShapeFlat) endparam heading caption = "Plane Textures" endheading heading text = "Floor Plane" visible = @pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box" endheading TrapShape param f_traptexture_plane1 caption = "Plane Textures" default = DMJ_TrapShapeFlat expanded = false hint = "A trap shape that is used as a texture. Textures do not change \ the shape of the trap but may change its coloring." visible = @pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box" endparam float param p_texturestrength_plane1 caption = "Texture Amount" default = 0.0 hint = "Sets the overall amount of texture to be used. Larger numbers \ will increase the effect of the texture. A value of 0 will remove \ the effects of the texture." visible = (@f_traptexture_plane1 != DMJ_TrapShapeFlat) endparam param texflavor_plane1 caption = "Texture type" default = 0 enum = "Transformed" "Standard" visible = (@f_traptexture_plane1 != DMJ_TrapShapeFlat) endparam heading text = "Back Plane" visible = @pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endheading TrapShape param f_traptexture_plane2 caption = "Plane Textures" default = DMJ_TrapShapeFlat expanded = false hint = "A trap shape that is used as a texture. Textures do not change \ the shape of the trap but may change its coloring." visible = @pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam float param p_texturestrength_plane2 caption = "Texture Amount" default = 0.0 hint = "Sets the overall amount of texture to be used. Larger numbers \ will increase the effect of the texture. A value of 0 will remove \ the effects of the texture." visible = (@f_traptexture_plane2 != DMJ_TrapShapeFlat) endparam param texflavor_plane2 caption = "Texture type" default = 0 enum = "Transformed" "Standard" visible = (@f_traptexture_plane2 != DMJ_TrapShapeFlat) endparam heading text = "Left Plane" visible = @pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box" endheading TrapShape param f_traptexture_plane3 caption = "Plane Textures" default = DMJ_TrapShapeFlat expanded = false hint = "A trap shape that is used as a texture. Textures do not change \ the shape of the trap but may change its coloring." visible = @pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box" endparam float param p_texturestrength_plane3 caption = "Texture Amount" default = 0.0 hint = "Sets the overall amount of texture to be used. Larger numbers \ will increase the effect of the texture. A value of 0 will remove \ the effects of the texture." visible = (@f_traptexture_plane3 != DMJ_TrapShapeFlat) endparam param texflavor_plane3 caption = "Texture type" default = 0 enum = "Transformed" "Standard" visible = (@f_traptexture_plane3 != DMJ_TrapShapeFlat) endparam heading text = "Right Plane" visible = @pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endheading TrapShape param f_traptexture_plane4 caption = "Plane Textures" default = DMJ_TrapShapeFlat expanded = false hint = "A trap shape that is used as a texture. Textures do not change \ the shape of the trap but may change its coloring." visible = @pset == "right"|| @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam float param p_texturestrength_plane4 caption = "Texture Amount" default = 0.0 hint = "Sets the overall amount of texture to be used. Larger numbers \ will increase the effect of the texture. A value of 0 will remove \ the effects of the texture." visible = (@f_traptexture_plane4 != DMJ_TrapShapeFlat) endparam param texflavor_plane4 caption = "Texture type" default = 0 enum = "Transformed" "Standard" visible = (@f_traptexture_plane4 != DMJ_TrapShapeFlat) endparam heading text = "Top Plane" visible = @pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endheading TrapShape param f_traptexture_plane5 caption = "Plane Textures" default = DMJ_TrapShapeFlat expanded = false hint = "A trap shape that is used as a texture. Textures do not change \ the shape of the trap but may change its coloring." visible = @pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam float param p_texturestrength_plane5 caption = "Texture Amount" default = 0.0 hint = "Sets the overall amount of texture to be used. Larger numbers \ will increase the effect of the texture. A value of 0 will remove \ the effects of the texture." visible = (@f_traptexture_plane5 != DMJ_TrapShapeFlat) endparam param texflavor_plane5 caption = "Texture type" default = 0 enum = "Transformed" "Standard" visible = (@f_traptexture_plane5 != DMJ_TrapShapeFlat) endparam heading caption = "Patterns and Colors" endheading heading caption = "Spheres" endheading ColorTrap param f_trapcolor caption = "Sphere Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." endparam heading text = "The image offset override can alter the image position based upon \ the sphere coloring type (e.g., level, index, etc.). This \ functionality is intended for use with images for which the width is \ much greater than the height (e.g. 2:1), such as a mercator projection map. The \ tiling mode should NOT be active." visible = @f_trapcolor == ColorTrapImageTiles endheading bool param override caption = "Override Image Offset" default = false visible = @f_trapcolor == ColorTrapImageTiles endparam complex param ovrange caption = "Override range" default = (-0.5,0.5) visible = @f_trapcolor == ColorTrapImageTiles && @override endparam int param incment caption = "Override increments" default = 2 min = 1 visible = @f_trapcolor == ColorTrapImageTiles && @override endparam bool param centp caption = "Center on sphere" default = true visible = (@f_trapcolor != ColorTrapNoColor) endparam bool param sphmapp caption = "Spherical mapping" default = false visible = (@f_trapcolor != ColorTrapNoColor) endparam float param sphsizep caption = "Map size" default = 1.0 visible = @sphmapp && (@f_trapcolor != ColorTrapNoColor) endparam heading caption = "Sphere Color Merge" visible = @f_trapcolor != ColorTrapNoColor endheading DefaultColorMerge param f_colormerge caption = "Color Merge" default = DefaultColorMerge visible = @f_trapcolor != ColorTrapNoColor endparam param nmerge caption = "Merge order" default = 0 enum = "Base on Top" "Base on Bottom" visible = @f_trapcolor != ColorTrapNoColor endparam float param opacity caption = "Merge Opacity" default = 1.0 visible = @f_trapcolor != ColorTrapNoColor endparam heading caption = "Planes" endheading heading text = "Floor Plane" visible = @pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box" endheading bool param pper1 caption = "Use perspective" default = false visible = ((@f_traptexture_plane1 != DMJ_TrapShapeFlat) || \ (@f_trapcolor_plane1 != ColorTrapNoColor))&& \ (@pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box") endparam float param adjdif1 caption = "Diffuse adjustment" default = 1.0 visible = @pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box" endparam ColorTrap param f_trapcolor_plane1 caption = "Plane Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." visible = @pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box" endparam heading caption = "Plane Color Merge" visible = @f_trapcolor_plane1 != ColorTrapNoColor endheading DefaultColorMerge param f_colormerge_plane1 caption = "Color Merge" default = DefaultColorMerge visible = @f_trapcolor_plane1 != ColorTrapNoColor endparam param nmerge_plane1 caption = "Merge order" default = 0 enum = "Base on Top" "Base on Bottom" visible = @f_trapcolor_plane1 != ColorTrapNoColor endparam float param opacity_plane1 caption = "Merge Opacity" default = 0.5 visible = @f_trapcolor_plane1 != ColorTrapNoColor endparam bool param tpfade1 caption = "Use Distance Fade" default = false visible = @pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box" endparam bool param usepgrad1 caption = "Use gradient" default = true visible = @pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box" endparam color param plambient1 caption = "Distant color" default = rgba(0,0,0,1) visible = @pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box" endparam color param plplaincolor1 caption = "Base Color" default = rgba(0.9,0.9,0.9,1) visible = !@usepgrad1 && (@pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box") endparam heading text = "Back Plane" visible = @pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endheading bool param pper2 caption = "Use perspective" default = false visible = ((@f_traptexture_plane2 != DMJ_TrapShapeFlat) || \ (@f_trapcolor_plane2 != ColorTrapNoColor))&& \ (@pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box") endparam float param adjdif2 caption = "Diffuse adjustment" default = 1.0 visible = @pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam ColorTrap param f_trapcolor_plane2 caption = "Plane Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." visible = @pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam heading caption = "Plane Color Merge" visible = @f_trapcolor_plane2 != ColorTrapNoColor endheading DefaultColorMerge param f_colormerge_plane2 caption = "Color Merge" default = DefaultColorMerge visible = @f_trapcolor_plane2 != ColorTrapNoColor endparam param nmerge_plane2 caption = "Merge order" default = 0 enum = "Base on Top" "Base on Bottom" visible = @f_trapcolor_plane2 != ColorTrapNoColor endparam float param opacity_plane2 caption = "Merge Opacity" default = 0.5 visible = @f_trapcolor_plane2 != ColorTrapNoColor endparam bool param tpfade2 caption = "Use Distance Fade" default = false visible = @pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam bool param usepgrad2 caption = "Use gradient" default = true visible = @pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam color param plambient2 caption = "Distant color" default = rgba(0,0,0,1) visible = @pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam color param plplaincolor2 caption = "Base Color" default = rgba(0.9,0.9,0.9,1) visible = !@usepgrad2 && (@pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box") endparam heading text = "Left Plane" visible = @pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box" endheading bool param pper3 caption = "Use perspective" default = false visible = ((@f_traptexture_plane3 != DMJ_TrapShapeFlat) || \ (@f_trapcolor_plane3 != ColorTrapNoColor))&& \ (@pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box") endparam float param adjdif3 caption = "Diffuse adjustment" default = 1.0 visible = @pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box" endparam ColorTrap param f_trapcolor_plane3 caption = "Plane Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." visible = @pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box" endparam heading caption = "Plane Color Merge" visible = @f_trapcolor_plane3 != ColorTrapNoColor endheading DefaultColorMerge param f_colormerge_plane3 caption = "Color Merge" default = DefaultColorMerge visible = @f_trapcolor_plane3 != ColorTrapNoColor endparam param nmerge_plane3 caption = "Merge order" default = 0 enum = "Base on Top" "Base on Bottom" visible = @f_trapcolor_plane3 != ColorTrapNoColor endparam float param opacity_plane3 caption = "Merge Opacity" default = 0.5 visible = @f_trapcolor_plane3 != ColorTrapNoColor endparam bool param tpfade3 caption = "Use Distance Fade" default = false visible = @pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box" endparam bool param usepgrad3 caption = "Use gradient" default = true visible = @pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box" endparam color param plambient3 caption = "Distant color" default = rgba(0,0,0,1) visible = @pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box" endparam color param plplaincolor3 caption = "Base Color" default = rgba(0.9,0.9,0.9,1) visible = !@usepgrad3 && (@pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box") endparam heading text = "Right Plane" visible = @pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endheading bool param pper4 caption = "Use perspective" default = false visible = ((@f_traptexture_plane4 != DMJ_TrapShapeFlat) || \ (@f_trapcolor_plane4 != ColorTrapNoColor))&& \ (@pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box") endparam float param adjdif4 caption = "Diffuse adjustment" default = 1.0 visible = @pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam ColorTrap param f_trapcolor_plane4 caption = "Plane Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." visible = @pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam heading caption = "Plane Color Merge" visible = @f_trapcolor_plane4 != ColorTrapNoColor endheading DefaultColorMerge param f_colormerge_plane4 caption = "Color Merge" default = DefaultColorMerge visible = @f_trapcolor_plane4 != ColorTrapNoColor endparam param nmerge_plane4 caption = "Merge order" default = 0 enum = "Base on Top" "Base on Bottom" visible = @f_trapcolor_plane4 != ColorTrapNoColor endparam float param opacity_plane4 caption = "Merge Opacity" default = 0.5 visible = @f_trapcolor_plane4 != ColorTrapNoColor endparam bool param tpfade4 caption = "Use Distance Fade" default = false visible = @pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam bool param usepgrad4 caption = "Use gradient" default = true visible = @pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam color param plambient4 caption = "Distant color" default = rgba(0,0,0,1) visible = @pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam color param plplaincolor4 caption = "Base Color" default = rgba(0.9,0.9,0.9,1) visible = !@usepgrad4 && (@pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box") endparam heading text = "Top Plane" visible = @pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endheading bool param pper5 caption = "Use perspective" default = false visible = ((@f_traptexture_plane5 != DMJ_TrapShapeFlat) || \ (@f_trapcolor_plane5 != ColorTrapNoColor))&& \ (@pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box") endparam float param adjdif5 caption = "Diffuse adjustment" default = 1.0 visible = @pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam ColorTrap param f_trapcolor_plane5 caption = "Plane Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." visible = @pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam heading caption = "Plane Color Merge" visible = @f_trapcolor_plane5 != ColorTrapNoColor endheading DefaultColorMerge param f_colormerge_plane5 caption = "Color Merge" default = DefaultColorMerge visible = @f_trapcolor_plane5 != ColorTrapNoColor endparam param nmerge_plane5 caption = "Merge order" default = 0 enum = "Base on Top" "Base on Bottom" visible = @f_trapcolor_plane5 != ColorTrapNoColor endparam float param opacity_plane5 caption = "Merge Opacity" default = 0.5 visible = @f_trapcolor_plane5 != ColorTrapNoColor endparam bool param tpfade5 caption = "Use Distance Fade" default = false visible = @pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam bool param usepgrad5 caption = "Use gradient" default = true visible = @pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam color param plambient5 caption = "Distant color" default = rgba(0,0,0,1) visible = @pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam color param plplaincolor5 caption = "Base Color" default = rgba(0.9,0.9,0.9,1) visible = !@usepgrad5 && (@pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box") endparam heading caption = "Sphere inversion parameters" expanded = false endheading bool param boundary caption = "Use boundaries" default = false endparam float param boundadj caption = "Boundary adj" default = 1.0 visible = @boundary endparam bool param displaybound caption = "Display boundary" default = false visible = @boundary endparam InvertSphere param isph caption = "Inversion Type" default = InvertSphere endparam bool param showbase caption = "Show base spheres" default = true visible = @isph != InvertMobius endparam bool param slice caption = "Slice Gasket" default = false visible = @isph != InvertMobius endparam heading caption = "Slicing Plane" visible = @slice endheading float param sa caption = "X Direction" default = 0.0 visible = @slice endparam float param sb caption = "Y Direction" default = -1.0 visible = @slice endparam float param sc caption = "Z Direction" default = 0.5 visible = @slice endparam float param pd caption = "Position" default = 0.01 visible = @slice endparam heading caption = "Plane Parameters" expanded = false endheading PlaneArray param paar caption = "Plane array" default = PlaneArray endparam heading text = "Choose a set of plane objects" endheading heading text = "Ax + By + Cz + D = 0" endheading param pset caption = "Plane sets" default = 0 enum = "none" "floor" "back" "left" "right" "top" "floor-back" \ "floor-left" "floor-right" "floor-top" "back-left" "back-right" \ "back-top" "left-right" "left-top" "right-top" "floor-back-left" \ "floor-back-right" "floor-left-right" "back-left-right" \ "floor-back-top" "floor-left-top" "back-left-top" \ "floor-right-top" "back-right-top" "left-right-top" \ "floor-back-left-right" "floor-back-left-top" \ "floor-back-right-top" "floor-left-right-top" \ "back-left-right-top" "open box" endparam heading text = "Floor parameters" visible = @pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box" endheading float param p1A caption = "Floor A" default = 0 visible = @pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box" endparam float param p1B caption = "Floor B" default = -1 visible = @pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box" endparam float param p1C caption = "Floor C" default = 0 visible = @pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box" endparam float param p1D caption = "Floor D" default = 1 visible = @pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box" endparam float param p1F caption = "Fade" default = 1 visible = @pset == "floor" || @pset == "floor-back" || @pset == "floor-left" \ || @pset == "floor-right" || @pset == "floor-top" \ || @pset == "floor-back-left"|| @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "floor-back-top" \ || @pset == "floor-left-top"|| @pset == "floor-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "open box" endparam heading text = "Back parameters" visible = @pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endheading float param p2A caption = "Back A" default = 0 visible = @pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam float param p2B caption = "Back B" default = 1e-10 visible = @pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam float param p2C caption = "Back C" default = 1 visible = @pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam float param p2D caption = "Back D" default = 10 visible = @pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam float param p2F caption = "Fade" default = 1 visible = @pset == "back" || @pset == "floor-back"\ || @pset == "back-left" || @pset == "back-right" \ || @pset == "back-top" || @pset == "floor-back-left"\ || @pset == "floor-back-right" || @pset == "back-left-right" \ || @pset == "floor-back-top" || @pset == "back-left-top" \ || @pset == "back-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-left-top" || @pset == "floor-back-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam heading text = "Left parameters" visible = @pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box" endheading float param p3A caption = "Left A" default = 1 visible = @pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box" endparam float param p3B caption = "Left B" default = 0 visible = @pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box" endparam float param p3C caption = "Left C" default = 0 visible = @pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box" endparam float param p3D caption = "Left D" default = 1 visible = @pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box" endparam float param p3F caption = "Fade" default = 1 visible = @pset == "left" || @pset == "floor-left" || @pset == "back-left"\ || @pset == "left-right" || @pset == "left-top" \ || @pset == "floor-back-left" || @pset == "floor-left-right" \ || @pset == "back-left-right" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-right" || @pset == "floor-back-left-top" \ || @pset == "floor-left-right-top" || @pset == "back-left-right-top" \ || @pset == "open box" endparam heading text = "Right parameters" visible = @pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endheading float param p4A caption = "Right A" default = 1 visible = @pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam float param p4B caption = "Right B" default = 0 visible = @pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam float param p4C caption = "Right C" default = 0 visible = @pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam float param p4D caption = "Right D" default = -1 visible = @pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam float param p4F caption = "Fade" default = 1 visible = @pset == "right" || @pset == "floor-right" \ || @pset == "back-right" || @pset == "left-right" \ || @pset == "right-top" || @pset == "floor-back-right"\ || @pset == "floor-left-right" || @pset == "back-left-right" \ || @pset == "floor-right-top" || @pset == "back-right-top" \ || @pset == "left-right-top" || @pset == "floor-back-left-right" \ || @pset == "floor-back-right-top" || @pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam heading text = "Top parameters" visible = @pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endheading float param p5A caption = "Top A" default = 0 visible = @pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam float param p5B caption = "Top B" default = -1 visible = @pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam float param p5C caption = "Top C" default = 0 visible = @pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam float param p5D caption = "Top D" default = -1 visible = @pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam float param p5F caption = "Fade" default = 1 visible = @pset == "top" || @pset == "floor-top" || @pset == "back-top" \ || @pset == "left-top" || @pset == "right-top" \ || @pset == "floor-back-top" || @pset == "floor-left-top" \ || @pset == "back-left-top" || @pset == "floor-right-top" \ || @pset == "back-right-top" || @pset == "left-right-top" \ || @pset == "floor-back-left-top" \ || @pset == "floor-back-right-top" ||@pset == "floor-left-right-top" \ || @pset == "back-left-right-top" || @pset == "open box" endparam } Class Raytracemesh(reb.ulb:RaytraceGeneric) {; Raytracer for triangular meshes.
$define debug public: import "common.ulb" import "dmj5.ulb" ; constructor for mesh raytracing. func RatytraceMesh(Generic pparent) Raytracegeneric.Raytracegeneric(0) init() endfunc func Init() Raytracegeneric.Init() ; create the mesh containing the triangle array and initialize related ; parameters m_tr = new @f_tr(this) m_tr.initmesh() m_tarray = m_tr.m_tarray m_k = m_tr.m_k m_trow = m_tr.m_trow m_dens = m_tr.m_dens setlength(xi,m_k) setlength(yi,m_k) setlength(zi,m_k) m_norm = new VectorArray(m_k) m_MergeLight = new @f_lightmerge(this) t_norm = new Vector(0,0,0,0) V1 = new Vector(0,0,0,0) V2 = new Vector(0,0,0,0) V3 = new Vector(0,0,0,0) N1 = new Vector(0,0,0,0) N2 = new Vector(0,0,0,0) N3 = new Vector(0,0,0,0) test = new Triangle(0,0,0,0,0,0,0,0,0) hang = new Vector(0,0,0,0) close = @close/(2*m_tr.m_arrayx)/m_dens sclose = @sclose/(2*m_tr.m_arrayx)/m_dens m_TrapTexture = new @f_traptexture(this) m_TrapColor = new @f_trapcolor(this) m_MergeColor = new @f_colormerge(this) endfunc ;------------------------------------------------- ; Function to determine object intersections with rays ; @param origin = ray origin as a vector ; @param ray = ray as a vector ; @param regress = regression level - not used ; @param rsi = object index - not used ; @param dif = diffuse lighting parameter - not used ; @param sbr = specular lighting paramer - not used ; @param scolor = color of the intersected object - not used ;------------------------------------------------ ; Call Intersect() after viewpoint bool func Intersect(Vector origin, Vector ray, int ®ress, int &rsi, \ float &dif, float &sbr, color &scolor) Vector norm1 = new Vector(0,0,0,0) Vector norm2 = new Vector(0,0,0,0) Vector norm3 = new Vector(0,0,0,0) int i = 0 float d1 = 0 float d21 = 0 float d22 = 0 float d23 = 0 float b1 = 0 float b2 = 0 float b3 = 0 float bd = 0 float dtemp = 0 shad = false d = 1e308 m_solid = false int ii = 0 int jj = 0 int k = 0 int l = 0 int start_cell_x1 = 0 int end_cell_x1 = 0 int start_cell_y1 = 0 int end_cell_y1 = 0 float arx = 2*m_tr.m_arrayx*m_dens/@cells float ary = 0.5*m_tr.m_arrayy*m_dens/@cells float boxsize = @thresh*sqrt(arx*ary)*sqrt(3)/m_dens bool hit = false while k < @cells && !hit start_cell_x1 = floor(arx*k) end_cell_x1 = ceil(arx*(k+1)) l = 0 while l < @cells && !hit start_cell_y1 = floor(ary*l) end_cell_y1 = ceil(ary*(l+1)) ii = start_cell_x1 while ii <= end_cell_x1 jj = start_cell_y1 while jj <= end_cell_y1 i = jj*m_trow + ii if i > m_k i = m_k-1 elseif i < 1 i = 0 endif ; ray is not in the cell goto the next cell if dist(i)> boxsize jj = end_cell_y1 ii = end_cell_x1 else if dist(i)< close ; distance to plane containing triangle dtemp = -(origin.dot(m_tarray.tr[i].t_norm) + \ m_tarray.tr[i].pspot)/ray.dot(m_tarray.tr[i].t_norm) ; is there an intersection? if dtemp > 0 && dtemp < d ;intersection point - test if inside triangle xi[i] = origin.m_x + dtemp*ray.m_x yi[i] = origin.m_y + dtemp*ray.m_y zi[i] = origin.m_z + dtemp*ray.m_z V1.Init(m_tarray.tr[i].fx1-xi[i], m_tarray.tr[i].fy1-yi[i], \ m_tarray.tr[i].fz1-zi[i],0) V2.Init(m_tarray.tr[i].fx2-xi[i], m_tarray.tr[i].fy2-yi[i], \ m_tarray.tr[i].fz2-zi[i],0) V3.Init(m_tarray.tr[i].fx3-xi[i], m_tarray.tr[i].fy3-yi[i], \ m_tarray.tr[i].fz3-zi[i],0) V2.Cross(V1,N3), N3.m_w = 0 d1 = origin.dot(N3) d23 = d1 + (xi[i]*N3.m_x+yi[i]*N3.m_y+zi[i]*N3.m_z) V3.Cross(V2,N1), N1.m_w = 0 d1 = origin.dot(N1) d21 = d1 + (xi[i]*N1.m_x+yi[i]*N1.m_y+zi[i]*N1.m_z) V1.Cross(V3,N2), N2.m_w = 0 d1 = origin.dot(N2) d22 = d1 + (xi[i]*N2.m_x+yi[i]*N2.m_y+zi[i]*N2.m_z) ; Test for closest intersection - both sides of the triangle if (d21 >= 0 && d22 >=0 && d23 >= 0) d = dtemp si = i ; unscaled barycentric coordinates b1 = N1.size() b2 = N2.size() b3 = N3.size() m_norm.m_elements[i] = m_tarray.tr[i].t_norm if @firsthit hit = true endif endif endif endif endif jj = jj + 1 endwhile ii = ii + 1 endwhile l = l + 1 endwhile k = k + 1 endwhile if d != 308 ; find the shadows if @shadow int j = 0 Vector sorigin = new Vector(xi[si],yi[si],zi[si],0) while j < @nlight distance = 1e308 i = 0 d1 = 0 d21 = 0 d22 = 0 d23 = 0 dtemp = 0 k = 0 hit = false while k < @cells && !hit start_cell_x1 = floor(arx*k)-3 end_cell_x1 = ceil(arx*(k+1))+3 l = 0 while l < @cells && !hit start_cell_y1 = floor(ary*l)-3 end_cell_y1 = ceil(ary*(l+1))+3 ii = start_cell_x1 while ii <= end_cell_x1 jj = start_cell_y1 while jj <= end_cell_y1 i = jj*m_trow + ii if i > m_k i = m_k-1 elseif i < 1 i = 0 endif ; ray is not in the cell goto the next cell if sdist(i,j,sorigin) > boxsize*@gridadj jj = end_cell_y1 ii = end_cell_x1 else if (i != si && i+1 != si && i-1 != si && i-2 != si && i+2 != si ) \ && sdist(i,j,sorigin) < sclose ; distance to plane containing triangle dtemp = -(sorigin.dot(m_tarray.tr[i].t_norm) + \ m_tarray.tr[i].pspot)/lar.m_elements[j].dot(m_tarray.tr[i].t_norm) ; is there an intersection? if dtemp > 0 && dtemp < distance ;intersection point - test if inside triangle float xs = xi[si] + dtemp*lar.m_elements[j].m_x float ys = yi[si] + dtemp*lar.m_elements[j].m_y float zs = zi[si] + dtemp*lar.m_elements[j].m_z V1.Init(m_tarray.tr[i].fx1-xs, m_tarray.tr[i].fy1-ys, \ m_tarray.tr[i].fz1-zs,0) V2.Init(m_tarray.tr[i].fx2-xs, m_tarray.tr[i].fy2-ys, \ m_tarray.tr[i].fz2-zs,0) V3.Init(m_tarray.tr[i].fx3-xs, m_tarray.tr[i].fy3-ys, \ m_tarray.tr[i].fz3-zs,0) V2.Cross(V1,N3), N3.m_w = 0 d1 = sorigin.dot(N3) d23 = d1 + (xs*N3.m_x+ys*N3.m_y+zs*N3.m_z) V3.Cross(V2,N1), N1.m_w = 0 d1 = sorigin.dot(N1) d21 = d1 + (xs*N1.m_x+ys*N1.m_y+zs*N1.m_z) V1.Cross(V3,N2), N2.m_w = 0 d1 = sorigin.dot(N2) d22 = d1 + (xs*N2.m_x+ys*N2.m_y+zs*N2.m_z) ; Test for closest intersection on both sides of triangle if (d21 <= 0 && d22 <= 0 && d23 <= 0) || (d21 >= 0 && \ d22 >= 0 && d23 >= 0) ; if (d21 <= 0 && d22 <= 0 && d23 <= 0) shad = true if @firsthit hit = true endif endif endif endif endif jj = jj + 1 endwhile ii = ii + 1 endwhile l = l + 1 endwhile k = k + 1 endwhile j = j + 1 endwhile endif ; calculate normal at the intersection point by determining the ; barycentric coodinates. ; if @colorby == "Diffuse Lighting" && !@raw if !@raw ; calculate the vertex normals, ignoring the border triangle vertex ; and using triangle normals instead for the border triangles if si >= m_trow && si < m_k-m_trow && (si % m_trow != 0 || si % m_trow != 1 \ || si % m_trow != m_trow-1 || si % m_trow != m_trow-2) norm1.init(0,0,0,0) norm2.init(0,0,0,0) norm3.init(0,0,0,0) if si % 2 == 0 ;vertex 1 norm1.add(m_tarray.tr[si].t_norm,norm1) norm1.add(m_tarray.tr[si-1].t_norm,norm1) norm1.add(m_tarray.tr[si-(m_trow+2)].t_norm,norm1) norm1.add(m_tarray.tr[si-(m_trow+1)].t_norm,norm1) norm1.add(m_tarray.tr[si-m_trow].t_norm,norm1) norm1.add(m_tarray.tr[si+1].t_norm,norm1) ;vertex 2 norm2.add(m_tarray.tr[si].t_norm,norm2) norm2.add(m_tarray.tr[si+1].t_norm,norm2) norm2.add(m_tarray.tr[si+2].t_norm,norm2) norm2.add(m_tarray.tr[si+m_trow+3].t_norm,norm2) norm2.add(m_tarray.tr[si+m_trow+2].t_norm,norm2) norm2.add(m_tarray.tr[si+m_trow+1].t_norm,norm2) ;vertex 3 norm3.add(m_tarray.tr[si].t_norm,norm3) norm3.add(m_tarray.tr[si+m_trow+1].t_norm,norm3) norm3.add(m_tarray.tr[si+m_trow].t_norm,norm3) norm3.add(m_tarray.tr[si+m_trow-1].t_norm,norm3) norm3.add(m_tarray.tr[si-2].t_norm,norm3) norm3.add(m_tarray.tr[si-1].t_norm,norm3) else ;vertex 1 norm1.add(m_tarray.tr[si].t_norm,norm1) norm1.add(m_tarray.tr[si-1].t_norm,norm1) norm1.add(m_tarray.tr[si-2].t_norm,norm1) norm1.add(m_tarray.tr[si-(m_trow+3)].t_norm,norm1) norm1.add(m_tarray.tr[si-(m_trow+2)].t_norm,norm1) norm1.add(m_tarray.tr[si-(m_trow+1)].t_norm,norm1) ;vertex 2 norm2.add(m_tarray.tr[si].t_norm,norm2) norm2.add(m_tarray.tr[si-(m_trow+1)].t_norm,norm2) norm2.add(m_tarray.tr[si-(m_trow)].t_norm,norm2) norm2.add(m_tarray.tr[si-(m_trow-1)].t_norm,norm2) norm2.add(m_tarray.tr[si+2].t_norm,norm2) norm2.add(m_tarray.tr[si+1].t_norm,norm2) ;vertex 3 norm3.add(m_tarray.tr[si].t_norm,norm3) norm3.add(m_tarray.tr[si+1].t_norm,norm3) norm3.add(m_tarray.tr[si+m_trow+2].t_norm,norm3) norm3.add(m_tarray.tr[si+m_trow+1].t_norm,norm3) norm3.add(m_tarray.tr[si+m_trow].t_norm,norm3) norm3.add(m_tarray.tr[si-1].t_norm,norm3) endif else ; used for the border triangles norm1.init(0,0,-1,0) norm2.init(0,0,-1,0) norm3.init(0,0,-1,0) endif ; calculate the average normal at the intersection point. ; normalize the barycentric coordinates bd = b1 + b2 + b3 b1 = b1/bd b2 = b2/bd b3 = b3/bd norm1.MConst(b1,norm1) norm2.MConst(b2,norm2) norm3.MConst(b3,norm3) norm1.Add(norm2,norm1) norm1.Add(norm3,norm1) norm1.Normalize(norm1) m_norm.m_elements[si] = norm1 endif ; calculate the unrotated z value at the intersection point by determining the ; barycentric coodinates. This is used for one of the coloring modes, and ; for textures and color trap colors float z1 = 0 float z2 = 0 float z3 = 0 float z1 = m_tarray.tr[si].r_fz1 float z2 = m_tarray.tr[si].r_fz2 float z3 = m_tarray.tr[si].r_fz3 ; calculate the average color at the intersection point. ; normalize the barycentric coordinates bd = b1 + b2 + b3 b1 = b1/bd b2 = b2/bd b3 = b3/bd z1 = z1*b1 z2 = z2*b2 z3 = z3*b3 pcindex = z1 + z2 + z3 ;--------------------------------------- ; textures ;--------------------------------------- ; if @f_traptexture != DMJ_TrapShapeFlat pz = (xi[si]+@zmix*pcindex+flip(yi[si]+@zmix*pcindex)) m_TrapTexture.Init(pz) ptexture = m_TrapTexture.Iterate(pz) endif ;--------------------------------------- ; illumination parameters ;--------------------------------------- ; ; distance squared to light(s). Index is the light number. float distlight = 1 if @dlight distlight = @distlight endif lds[0] = (@lightx*distlight-xi[si])^2 + (@lighty*distlight-yi[si])^2 + (@lightz*distlight-zi[si])^2 lf = (@lightx*distlight)^2 + (@lighty*distlight)^2 + (@lightz*distlight)^2 if @nlight > 1 lds[1] = (@lightx2*distlight-xi[si])^2 + (@lighty2*distlight-yi[si])^2 + (@lightz2*distlight-zi[si])^2 lf = lf + (@lightx2*distlight)^2 + (@lighty2*distlight)^2 + (@lightz2*distlight)^2 endif if @nlight > 2 lds[2] = (@lightx3*distlight-xi[si])^2 + (@lighty3*distlight-yi[si])^2 + (@lightz3*distlight-zi[si])^2 lf = lf + (@lightx3*distlight)^2 + (@lighty3*distlight)^2 + (@lightz3*distlight)^2 endif if @nlight > 3 lds[3] = (@lightx4*distlight-xi[si])^2 + (@lighty4*distlight-yi[si])^2 + (@lightz4*distlight-zi[si])^2 lf = lf + (@lightx4*distlight)^2 + (@lighty4*distlight)^2 + (@lightz4*distlight)^2 endif if @nlight > 4 lds[4] = (@lightx5*distlight-xi[si])^2 + (@lighty5*distlight-yi[si])^2 + (@lightz5*distlight-zi[si])^2 lf = lf + (@lightx5*distlight)^2 + (@lighty5*distlight)^2 + (@lightz5*distlight)^2 endif lf = lf/@nlight ; diffuse value i = 0 diffuse[0] = 0 while i < @nlight diffuse[0] = diffuse[0] + lar.m_elements[i].dot(m_norm.m_elements[si])/(lds[i]) i = i + 1 endwhile diffuse[0] = diffuse[0]*lf*@bright/@nlight ; specular value i = 0 while i < @nlight ray.sub(lar.m_elements[i],hang) hang.normalize(hang) specular[0,i] = -hang.dot(m_norm.m_elements[si]) if specular[0,i] < 0 specular[0,i] = 0 endif specular[0,i] = specular[0,i]^shiny[i]*lf*sbright[i]/(lds[i]) if shad specular[0,i] = 0 endif specular[0,i] = (specular[0,i]+\ ptexture*@p_texturestrength) speccol[0,i] = blend(@ambient,spec[i],specular[0,i]) if i == 0 rspec[0] = speccol[0,i] rsbright[0] = sbright[i] else rspec[0] = rspec[0] + speccol[0,i] rsbright[0] = rsbright[0] + sbright[i] endif i = i + 1 endwhile rspec[0] = rspec[0]/@nlight rsbright[0] = rsbright[0]/@nlight diffuse[0] = (diffuse[0]+ptexture*@p_texturestrength)/\ (1+ptexture*@p_texturestrength) else m_solid = true endif return false endfunc color func Result() color base = rgba(0,0,0,0) color return_color = rgba(0,0,0,0) color colpat = rgba(0,0,0,0) color temp = rgba(0,0,0,0) float hopacity = 0 bool cp = false if !m_solid if @f_trapcolor != ColorTrapNoColor cp = true pz = xi[si]+@zmix*pcindex + flip(yi[si]+@zmix*pcindex) m_TrapColor.Init(pz) colpat = m_TrapColor.Iterate(pz) endif if @colorby == "Distance" if @v_Raytracemesh == 100 base = gradient(d/origin.m_z) else base = gradient(abs(d-origin.m_z+1)) endif elseif @colorby == "Z value" base = gradient(abs(pcindex+@hoffset)) elseif @colorby == "Diffuse Lighting" base = gradient(0.5) base = compose(base,hsl(hue(base),sat(base),\ @lumfac*lum(base)), 1-diffuse[0]^2) endif if @usespec && @colorby == "Diffuse Lighting" return_color = m_MergeLight.FullMerge(base, rspec[0], \ rsbright[0]) else return_color = base endif else return_color = @ambient endif if cp if @nmerge == 1 temp = colpat colpat = return_color return_color = temp endif return_color = m_MergeColor.FullMerge(colpat, return_color, @opacity) endif if @tbyhite hopacity = @tbyvalue*(pcindex+@hoffset)*10 if hopacity >1 hopacity = 1 endif return_color = hsla(hue(return_color),sat(return_color),\ lum(return_color), hopacity) endif if shad return_color = blend(return_color,@ambient,@shadval) endif return return_color endfunc float func dist(int i) float x = real(m_tarray.tr[i].xy_ave) float y = imag(m_tarray.tr[i].xy_ave) float z = m_tarray.tr[i].z_ave float t0 = view.m_x*(x-origin.m_x) + view.m_y*(y-origin.m_y) + view.m_z*(z-origin.m_z) float dist = (x-origin.m_x-t0*view.m_x)^2 + (y-origin.m_y-t0*view.m_y)^2 + (z-origin.m_z-t0*view.m_z)^2 return dist endfunc float func sdist(int i,int j,Vector sorigin) float x = real(m_tarray.tr[i].xy_ave) float y = imag(m_tarray.tr[i].xy_ave) float z = m_tarray.tr[i].z_ave float t0 = lar.m_elements[j].m_x*(x-sorigin.m_x) + \ lar.m_elements[j].m_y*(y-sorigin.m_y) + \ lar.m_elements[j].m_z*(z-sorigin.m_z) float dist = (x-sorigin.m_x-t0*lar.m_elements[j].m_x)^2 + \ (y-sorigin.m_y-t0*lar.m_elements[j].m_y)^2 + \ (z-sorigin.m_z-t0*lar.m_elements[j].m_z)^2 return dist endfunc Trianglemesh m_tr TriangleArray m_tarray IllumColorMerge m_MergeLight TrapShape m_TrapTexture ColorTrap m_TrapColor DefaultColorMerge m_MergeColor int m_k int m_trow float d float num float denom int si float xi[] float yi[] float zi[] VectorArray m_norm float lds[5] float lf Vector t_norm Vector V1 Vector V2 Vector V3 Vector N1 Vector N2 Vector N3 Vector hang Triangle test float rsbright[10] color rspec[10] float m_dens float close complex pz float ptexture float pcindex bool shad float sclose float distance default: title = "Raytrace Mesh" int param v_Raytracemesh caption = "Version (Raytrace Mesh)" 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_Raytracemesh < 100 endparam heading caption = "Illumination model" expanded = false endheading param colorby caption = "Coloring mode" default = 2 enum = "Distance" "Z value" "Diffuse Lighting" endparam bool param raw caption = "Use raw triangles" default = false visible = @colorby == "Diffuse Lighting" endparam bool param usespec caption = "Use Specular" default = true visible = @colorby == "Diffuse Lighting" endparam heading text = "Specular parameters are found under 'Light parameters'." visible = @usespec && @colorby == "Diffuse Lighting" endheading float param bright caption = "Total brightness" default = 0.9 min = 0 visible = @colorby == "Diffuse Lighting" endparam float param lumfac caption = "Luminosity factor" default = 0.2 min = 0 max = 1 visible = @colorby == "Diffuse Lighting" endparam IllumColorMerge param f_lightmerge caption = "Light Merge" default = IllumColorMerge visible = @usespec && @colorby == "Diffuse Lighting" endparam color param ambient caption = "Ambient color" default = rgba(0.05,0.05,0.05,1) endparam bool param shadow caption = "Shadows" default = false endparam float param shadval caption = "Shadow value" default = 0.5 visible = @shadow endparam heading text = "The 'Shadow closeness' parameter determines how closely to check for \ triangles near the light ray. A smaller value will speedup rendering \ but some triangles may be missed and so some shadows will be missing. \ Adjust the default value to get the best performance and appearance." visible = @shadow endheading float param sclose caption = "Shadow closeness" default = 3.0 visible = @shadow endparam float param @gridadj caption = "Grid adjustment" default = 1.0 visible = @shadow endparam bool param tbyhite caption = "Transparent by Height" default = false endparam float param hoffset caption = "Height offset" default = 0 visible = @tbyhite || @colorby == "Z value" endparam float param tbyvalue caption = "Transparency filter" default = 1.0 visible = @tbyhite endparam bool param dlight caption = "Use distant light" default = true endparam float param distlight caption = "Distant light" default = 1e10 visible = @dlight endparam heading caption = "Mesh Object" endheading heading text = "The 'Use first intersection' setting usually gives good results. If \ hidden surface removal seems to be failing, uncheck the parameter. This \ will slow the rendering but guarantee hidden surface removal." endheading bool param firsthit caption = "Use first intersection" default = true endparam heading text = "The 'Grid density', 'Grid threshold', 'Closeness' parameters are \ for optimizing rendering performance. The view screen is divided up \ into a grid using the 'Grid density' value. For a given camera ray \ the grid is scanned to see which box in the grid the ray passes \ through using the grid threshold parameter which determines the sensitivity \ to the grid position. For rays that pass the box test they are checked \ against the 'Closeness parameter to determine if the ray intersects \ a given triangle." endheading int param cells caption = "Grid density" default = 25 endparam float param @thresh caption = "Grid threshold" default = 0.01 endparam float param close caption = "Closeness" default = 3 endparam TriangleMesh param f_tr caption = "Triangle mesh" selectable = false endparam heading text = "'Z component mix' is used for both Mesh Textures and Colors." visible = (@f_traptexture != DMJ_TrapShapeFlat || \ @f_trapcolor != ColorTrapNoColor) endheading float param zmix caption = "Z component mix" default = -1.0 visible = (@f_traptexture != DMJ_TrapShapeFlat || \ @f_trapcolor != ColorTrapNoColor) endparam heading caption = "Mesh Textures" visible = @colorby == "Diffuse Lighting" endheading TrapShape param f_traptexture caption = "Texture" default = DMJ_TrapShapeFlat expanded = false hint = "A trap shape that is used as a texture. Textures do not change \ the shape of the trap but may change its coloring." visible = @colorby == "Diffuse Lighting" endparam float param p_texturestrength caption = "Texture Amount" default = 0.0 hint = "Sets the overall amount of texture to be used. Larger numbers \ will increase the effect of the texture. A value of 0 will remove \ the effects of the texture." visible = (@f_traptexture != DMJ_TrapShapeFlat)&& @colorby == "Diffuse Lighting" endparam heading caption = "Mesh Colors" endheading ColorTrap param f_trapcolor caption = "Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." endparam heading caption = "Color Merge" visible = @f_trapcolor != ColorTrapNoColor endheading DefaultColorMerge param f_colormerge caption = "Color Merge" default = DefaultColorMerge visible = @f_trapcolor != ColorTrapNoColor endparam param nmerge caption = "Merge order" default = 0 enum = "Base on Top" "Base on Bottom" visible = @f_trapcolor != ColorTrapNoColor endparam float param opacity caption = "Merge Opacity" default = 0.8 visible = @f_trapcolor != ColorTrapNoColor endparam } class IllumColorMerge(common.ulb:DefaultColorMerge) { ; Sets a new default for DefaultColorMerge for use with Raytracing.
public: import "common.ulb" func IllumColorMerge(Generic pparent) DefaultColorMerge.DefaultColorMerge(pparent) endfunc ; color func Merge(color pbottom, color ptop) ; return @f_mergemode(pbottom, ptop) ; endfunc default: title = "Illumination Color Merge Modes" int param v_illumcolormerge caption = "Version (IllumColorMerge)" 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_illumcolormerge < 100 endparam color func f_mergemode caption = "Merge Mode" default = mergescreen() hint = "Sets the method used to merge input colors with." endfunc } class REB_3DFractalRayTraceProgressive(common.ulb:Formula) { ; Based upon an article by Hart, Sandin and Kauffman for estimating ; the distance from a point to a fractal surface. The potential and ; gradient functions are based upon the exponential ; smoothing potential function. $define debug public: import "common.ulb" import "dmj5.ulb" ; constructor func REB_3DFractalRayTraceProgressive(Generic pparent) Formula.Formula(pparent) m_q = new @QuatClass(0) m_q.getjp(cri,cjk) m_julia = m_q.jtype() m_mand = m_q.mtype() m_quat = m_q.qtype() m_hyper = m_q.htype() m_brot = m_q.btype() m_spider = m_q.stype() m_oldz = m_q.ztype() m_sphere = m_q.sptype() if m_spider spidercri = cri spidercjk = cjk endif fourth = m_q.get4() ck = m_q.getck() scrsize = sqrt(#width*#width+#height*#height) maxstep = @camj*@maxstep zri = 0 zjk = 0 zrid = 0 zjkd = 0 oldzri = 0 oldzjk = 0 pow = 0 oldzri2 = 0 oldzjk2 = 0 rtemp = 0 vpr = 0 vpi = 0 vpj = 0 ; ray normal vr = 0 vi = 0 vj = 0 vd = 0 if @setzoom camr = real(#center)+@camr cami = imag(#center)+@cami else camr = @camr cami = @cami endif camj = @camj ucamr = 0 ucami = 0 ucamj = 0 modH = 0 modHold = 0 modHd = 0 d = 0 dist = 0 i = 0 i = 0 fr = 0 fi = 0 infinity = true if @szoom dfactor = @dfactor/#magn/scrsize*820 else dfactor = @dfactor endif epsilon = @epsilon/scrsize epsilon = epsilon/#magn ci = imag(#center) cr = real(#center) trmax = 4.0/#magn timax = trmax*#height/#width rmin = cr - trmax/2 imax = ci + timax/2 ; light origin lpointx = @lpointx lpointy = @lpointy lpointz = @lplane ; light point at lightx = @lightx lighty = @lighty lightz = @lightz ; light vector if @ltype == "Infinite light" float d2r = #pi/180; degrees to radians conversion factor lx = -cos(@angle*d2r) * cos(-@elevation*d2r) ly = -sin(@angle*d2r) * cos(-@elevation*d2r) lz = sin(-@elevation*d2r) else lx = lightx-lpointx ly = lighty-lpointy lz = lightz-lpointz endif vd = sqrt(lx^2+ly^2+lz^2) lx = lx/vd ly = ly/vd lz = lz/vd xangle = -@xangle*#pi/180 yangle = @yangle*#pi/180 zrot = cos(#angle) + flip(sin(#angle)) temp = 0 im = (0,1) bailout = sqrt(@p_bailout) pot = 0 grad = 0 siter = 0 reduce = 0 mindist = 0 mindistr = @mindistrqj mindisti = @mindistiqj mindistj = @mindistqj maxdist = 0 maxdistr = @maxdistrqj maxdisti = @maxdistiqj maxdistj = @maxdistqj camd = @camj mindistr = mindistr*camd mindisti = mindisti*camd maxdistr = maxdistr*camd maxdisti = maxdisti*camd firstpass = true bepsilon = 10*epsilon ; camera position ;rotate around x axis temp = cami cami = cami*cos(xangle)-camj*sin(xangle) camj = camj*cos(xangle)+temp*sin(xangle) ;rotate around y axis temp = camr camr = camr*cos(yangle)-camj*sin(yangle) camj = camj*cos(yangle)+temp*sin(yangle) ;rotate around z axis rtemp = camr + flip(cami) rtemp = rtemp*zrot camr = real(rtemp) cami = imag(rtemp) ; minimum distance position ;rotate around x axis temp = mindisti mindisti = mindisti*cos(xangle)-mindistj*sin(xangle) mindistj = mindistj*cos(xangle)+temp*sin(xangle) ;rotate around y axis temp = mindistr mindistr = mindistr*cos(yangle)-mindistj*sin(yangle) mindistj = mindistj*cos(yangle)+temp*sin(yangle) ;rotate around z axis rtemp = mindistr + flip(mindisti) rtemp = rtemp*zrot mindistr = real(rtemp) mindisti = imag(rtemp) ; maximum distance position ;rotate around x axis temp = maxdisti maxdisti = maxdisti*cos(xangle)-maxdistj*sin(xangle) maxdistj = maxdistj*cos(xangle)+temp*sin(xangle) ;rotate around y axis temp = maxdistr maxdistr = maxdistr*cos(yangle)-maxdistj*sin(yangle) maxdistj = maxdistj*cos(yangle)+temp*sin(yangle) ;rotate around z axis rtemp = maxdistr + flip(maxdisti) rtemp = rtemp*zrot maxdistr = real(rtemp) maxdisti = imag(rtemp) itercolor = 0 endfunc ; initialize the formula complex func Init(complex pz) Formula.Init(pz) complex fzri = 0 complex fzjk = 0 complex fzrix = 0 complex fzriy = 0 complex fzjkx = 0 complex fzjky = 0 complex fzrixn = 0 complex fzriyn = 0 complex fzjkxn = 0 complex fzjkyn = 0 float fdst = 0 float icolor = 0 bool dlimit = true bool dlimitx = false bool dlimity = false bool dlimitxn = false bool dlimityn = false float ddist = 0 float dd = 0 infinity = true ; MAIN RAY ; calculate screen position vpr = rmin + (#x*trmax)/#width vpi = imax - (#y*timax)/#height vpj = 0 ; unrotated position used for calcs fvpr = vpr fvpi = vpi fvpj = vpj ; screen position ; rotate around x axis temp = vpi vpi = vpi*cos(xangle)-vpj*sin(xangle) vpj = vpj*cos(xangle)+temp*sin(xangle) ; rotate around y axis temp = vpr vpr = vpr*cos(yangle)-vpj*sin(yangle) vpj = vpj*cos(yangle)+temp*sin(yangle) ; rotate around z axis rtemp = vpr + flip(vpi) rtemp = rtemp*zrot vpr = real(rtemp) vpi = imag(rtemp) ; create camera vector vr = camr-vpr vi = cami-vpi vj = camj-vpj vd = sqrt(vr*vr+vi*vi+vj*vj) vr = vr/vd vi = vi/vd vj = vj/vd mindist = mindistr*vr+mindisti*vi+mindistj*vj maxdist = maxdistr*vr+maxdisti*vi+maxdistj*vj ; distance camera correction if vd > mindist ucamr = camr-(vd-mindist)*vr ucami = cami-(vd-mindist)*vi ucamj = camj-(vd-mindist)*vj reduce = vd-mindist else ucamr = camr ucami = cami ucamj = camj reduce = 0 endif if @view == "3D" ; calculate distance from camera to quaternion zrid = 1 zjkd = 0 if m_julia || m_brot if fourth == 3 zri = ucamr + flip(ucami) zjk = ucamj + flip(ck) elseif fourth == 2 zri = ucamr + flip(ucami) zjk = flip(ucamj) + ck elseif fourth == 1 zri = ucamj + flip(ck) zjk = ucamr + flip(ucami) elseif fourth == 0 zri = flip(ucamj) + ck zjk = ucamr + flip(ucami) endif if @potmeth == "Delta DE" zrix = zri+@delta zjkx = zjk zriy = zri+flip(@delta) zjky = zjk zriz = zri zjkz = zjk+@delta zriw = zri zjkw = zjk+flip(@delta) endif elseif m_mand if fourth == 3 cri = ucamr + flip(ucami) cjk = ucamj + flip(ck) elseif fourth == 2 cri = ucamr + flip(ucami) cjk = flip(ucamj) + ck elseif fourth == 1 cri = ucamj + flip(ck) cjk = ucamr + flip(ucami) elseif fourth == 0 cri = flip(ucamj) + ck cjk = ucamr + flip(ucami) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) if @potmeth == "Delta DE" zrix = zri zjkx = zjk zriy = zri zjky = zjk zriz = zri zjkz = zjk zriw = zri zjkw = zjk endif endif i = 0 dist = 0 infinity = true siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif if @potmeth == "Brute Force" firstpass = true bepsilon = epsilon*@velocity else firstpass = false endif itercolor = 0 repeat repeat if m_oldz m_q.setomp(oldzri,oldzjk) endif ; calculate derivative if @potmeth != "Brute Force" && @potmeth != "delta DE" && \ !@special m_q.drcalc(zri, zjk, zrid, zjkd) endif ; calculate fractal m_q.frcalc(zri, zjk) if @potmeth == "delta DE" if m_mand m_q.setjp(cri+@delta, cjk) endif m_q.frcalc(zrix, zjkx) if m_mand m_q.setjp(cri+flip(@delta), cjk) endif m_q.frcalc(zriy, zjky) if m_mand m_q.setjp(cri, cjk+@delta) endif m_q.frcalc(zriz, zjkz) if !m_sphere if m_mand m_q.setjp(cri, cjk+flip(@delta)) endif m_q.frcalc(zriw, zjkw) endif if m_mand m_q.setjp(cri,cjk) endif endif if m_spider m_q.getjp(cri,cjk) endif if m_oldz m_q.getomp(oldzri,oldzjk) endif if m_brot modh = cabs(zri) else modh = sqrt(|zri|+|zjk|) endif if @colortype == "Exponential smoothing" itercolor = itercolor + exp(-modh) endif i = i + 1 until i == #maxiter || modh > bailout if @colortype == "Vepstas" itercolor = (i +log(log(modh))/log(2)) endif if @potmeth == "Brute Force" endif if !@special if m_brot modhd = cabs(zrid) else modhd = sqrt(|zrid|+|zjkd|) endif if modh <= bailout if @potmeth == "Brute Force" if firstpass dist = dist - bepsilon bepsilon = epsilon firstpass = false else d = 0 endif else dist = dist - d d = 0 if dist < 0 dist = 0 endif endif else if @potmeth == "Iteration smoothing" d = modh*log(modh)/modhd*(dfactor/2) elseif @potmeth == "delta DE" float Rx = sqrt(|zrix|+|zjkx|) float Ry = sqrt(|zriy|+|zjky|) float Rz = sqrt(|zriz|+|zjkz|) float rw = 0 if !m_sphere Rw = sqrt(|zriw|+|zjkw|) endif float drx = (modh-rx)/@delta float dry = (modh-ry)/@delta float drz = (modh-rz)/@delta if !m_sphere float drw = (modh-rw)/@delta else float drw = 0 endif float dr = sqrt(drx^2+dry^2+drz^2+drw^2) d = modh*log(modh)/dr*(dfactor/2) else d = bepsilon*1.1 endif if d > maxstep d = maxstep endif dist = d + dist endif elseif @special ; @special: mandelbox, conformal mandelbox, hybridmandelbox if modh <= bailout dist = dist - d d = 0 else ; real(m_q.getspecial()) retrieves spec siter = i + log(log(real(m_q.getspecial())))/log(2) if @alt pot = exp(-siter*log(2)) grad = exp(-(siter-i)*log(2)) d = 10*dfactor*sinh(pot)/(2*exp(pot)*grad) else d = 100*dfactor*exp(-siter) endif dist = d + dist endif endif zrid = 1 zjkd = 0 float eadj = @eadj if @accel eadj = 1e10 endif if (dlimit && ((d-epsilon) < epsilon*eadj)) ddist = dist dd = d dlimit = false dlimitx = true dlimitxn = true dlimity = true dlimityn = true endif if @distcorr itercolor = 0.01*itercolor*dist else if vd > mindist itercolor = 0.01*itercolor*(vd-reduce) else itercolor = 0.01*itercolor*vd endif endif if m_julia || m_brot if fourth == 3 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 zri = ucamj-dist*vj + flip(ck) zjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 zri = flip(ucamj-dist*vj) + ck zjk = ucamr-dist*vr + flip(ucami-dist*vi) endif if @potmeth == "Delta DE" zrix = zri+@delta zjkx = zjk zriy = zri-flip(@delta) zjky = zjk zriz = zri zjkz = zjk+@delta zriw = zri zjkw = zjk+flip(@delta) endif elseif m_mand if fourth == 3 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 cri = ucamj-dist*vj + flip(ck) cjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 cri = flip(ucamj-dist*vj) + ck cjk = ucamr-dist*vr + flip(ucami-dist*vi) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) zrix = zri zjkx = zjk zriy = zri zjky = zjk zriz = zri zjkz = zjk zriw = zri zjkw = zjk endif i = 0 siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif until (d <= epsilon || dist > maxdist) && \ (firstpass == false || dist > maxdist) if (dist > 0 && dist <= maxdist) || d == 0 infinity = false endif if !infinity ; set the intersection point and distance fzri = camr-(dist+reduce)*vr + flip(cami-(dist+reduce)*vi) if dist != 0 fzjk = camj-(dist+reduce)*vj + flip((dist+reduce)) icolor = itercolor else fzjk = camj-(dist+reduce)*vj + flip((1)) fdst = dist+reduce icolor = itercolor endif endif endif ; DELTA X bool dlimitxinner = false infinity = true ; calculate screen position vpr = rmin + ((#x+@dn)*trmax)/#width vpi = imax - (#y*timax)/#height vpj = 0 ; unrotated position used for calcs fvpr = vpr fvpi = vpi fvpj = vpj ; screen position ; rotate around x axis temp = vpi vpi = vpi*cos(xangle)-vpj*sin(xangle) vpj = vpj*cos(xangle)+temp*sin(xangle) ; rotate around y axis temp = vpr vpr = vpr*cos(yangle)-vpj*sin(yangle) vpj = vpj*cos(yangle)+temp*sin(yangle) ; rotate around z axis rtemp = vpr + flip(vpi) rtemp = rtemp*zrot vpr = real(rtemp) vpi = imag(rtemp) ; create camera vector vr = camr-vpr vi = cami-vpi vj = camj-vpj vd = sqrt(vr*vr+vi*vi+vj*vj) vr = vr/vd vi = vi/vd vj = vj/vd mindist = mindistr*vr+mindisti*vi+mindistj*vj maxdist = maxdistr*vr+maxdisti*vi+maxdistj*vj ; distance camera correction if vd > mindist ucamr = camr-(vd-mindist)*vr ucami = cami-(vd-mindist)*vi ucamj = camj-(vd-mindist)*vj reduce = vd-mindist else ucamr = camr ucami = cami ucamj = camj reduce = 0 endif if @view == "3D" ; calculate distance from camera to quaternion zrid = 1 zjkd = 0 if m_julia || m_brot if fourth == 3 zri = ucamr + flip(ucami) zjk = ucamj + flip(ck) elseif fourth == 2 zri = ucamr + flip(ucami) zjk = flip(ucamj) + ck elseif fourth == 1 zri = ucamj + flip(ck) zjk = ucamr + flip(ucami) elseif fourth == 0 zri = flip(ucamj) + ck zjk = ucamr + flip(ucami) endif if @potmeth == "Delta DE" zrix = zri+@delta zjkx = zjk zriy = zri+flip(@delta) zjky = zjk zriz = zri zjkz = zjk+@delta zriw = zri zjkw = zjk+flip(@delta) endif elseif m_mand if fourth == 3 cri = ucamr + flip(ucami) cjk = ucamj + flip(ck) elseif fourth == 2 cri = ucamr + flip(ucami) cjk = flip(ucamj) + ck elseif fourth == 1 cri = ucamj + flip(ck) cjk = ucamr + flip(ucami) elseif fourth == 0 cri = flip(ucamj) + ck cjk = ucamr + flip(ucami) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) if @potmeth == "Delta DE" zrix = zri zjkx = zjk zriy = zri zjky = zjk zriz = zri zjkz = zjk zriw = zri zjkw = zjk endif endif i = 0 dist = 0 infinity = true siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif if @potmeth == "Brute Force" firstpass = true bepsilon = epsilon*@velocity else firstpass = false endif repeat if dlimitxinner repeat if m_oldz m_q.setomp(oldzri,oldzjk) endif ; calculate derivative if @potmeth != "Brute Force" && @potmeth != "delta DE" && \ !@special m_q.drcalc(zri, zjk, zrid, zjkd) endif ; calculate fractal m_q.frcalc(zri, zjk) if @potmeth == "delta DE" if m_mand m_q.setjp(cri+@delta, cjk) endif m_q.frcalc(zrix, zjkx) if m_mand m_q.setjp(cri+flip(@delta), cjk) endif m_q.frcalc(zriy, zjky) if m_mand m_q.setjp(cri, cjk+@delta) endif m_q.frcalc(zriz, zjkz) if !m_sphere if m_mand m_q.setjp(cri, cjk+flip(@delta)) endif m_q.frcalc(zriw, zjkw) endif if m_mand m_q.setjp(cri,cjk) endif endif if m_spider m_q.getjp(cri,cjk) endif if m_oldz m_q.getomp(oldzri,oldzjk) endif if m_brot modh = cabs(zri) else modh = sqrt(|zri|+|zjk|) endif i = i + 1 until i == #maxiter || (modh > bailout) endif if !dlimitx if @potmeth == "Brute Force" endif if !@special if m_brot modhd = cabs(zrid) else modhd = sqrt(|zrid|+|zjkd|) endif if modh <= bailout if @potmeth == "Brute Force" if firstpass dist = dist - bepsilon bepsilon = epsilon firstpass = false else d = 0 endif else dist = dist - d d = 0 if dist < 0 dist = 0 endif endif else if @potmeth == "Iteration smoothing" d = modh*log(modh)/modhd*(dfactor/2) elseif @potmeth == "delta DE" ; itercolor = i +log(log(modh))/log(2) float Rx = sqrt(|zrix|+|zjkx|) float Ry = sqrt(|zriy|+|zjky|) float Rz = sqrt(|zriz|+|zjkz|) float rw = 0 if !m_sphere Rw = sqrt(|zriw|+|zjkw|) endif float drx = (modh-rx)/@delta float dry = (modh-ry)/@delta float drz = (modh-rz)/@delta if !m_sphere float drw = (modh-rw)/@delta else float drw = 0 endif float dr = sqrt(drx^2+dry^2+drz^2+drw^2) d = modh*log(modh)/dr*(dfactor/2) else d = bepsilon*1.1 endif if d > maxstep d = maxstep endif dist = d + dist endif elseif @special ; @special: mandelbox, conformal mandelbox, hybridmandelbox if modh <= bailout dist = dist - d d = 0 else ; real(m_q.getspecial()) retrieves spec siter = i + log(log(real(m_q.getspecial())))/log(2) ; itercolor = siter if @alt pot = exp(-siter*log(2)) grad = exp(-(siter-i)*log(2)) d = 10*dfactor*sinh(pot)/(2*exp(pot)*grad) else d = 100*dfactor*exp(-siter) endif dist = d + dist endif endif zrid = 1 zjkd = 0 endif if dlimitx dist = ddist d = dd dlimitx = false dlimitxinner = true endif if !dlimitx if m_julia || m_brot if fourth == 3 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 zri = ucamj-dist*vj + flip(ck) zjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 zri = flip(ucamj-dist*vj) + ck zjk = ucamr-dist*vr + flip(ucami-dist*vi) endif if @potmeth == "Delta DE" zrix = zri+@delta zjkx = zjk zriy = zri-flip(@delta) zjky = zjk zriz = zri zjkz = zjk+@delta zriw = zri zjkw = zjk+flip(@delta) endif elseif m_mand if fourth == 3 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 cri = ucamj-dist*vj + flip(ck) cjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 cri = flip(ucamj-dist*vj) + ck cjk = ucamr-dist*vr + flip(ucami-dist*vi) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) if @potmeth == "Delta DE" zrix = zri zjkx = zjk zriy = zri zjky = zjk zriz = zri zjkz = zjk zriw = zri zjkw = zjk endif endif i = 0 siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif endif until (d <= epsilon || dist > maxdist) && \ (firstpass == false || dist > maxdist) if dist < epsilon dist = 1e10 endif if (dist > 0 && dist <= maxdist) || d == 0 infinity = false endif if !infinity ; set the intersection point and distance for normal calculation fzrix = camr-(dist+reduce)*vr + flip(cami-(dist+reduce)*vi) if dist != 0 fzjkx = camj-(dist+reduce)*vj + flip((dist+reduce)) else fzjkx = camj-(dist+reduce)*vj + flip((1)) endif endif endif ; DELTA Y bool dlimityinner = false infinity = true ; calculate screen position vpr = rmin + (#x*trmax)/#width vpi = imax - ((#y+@dn)*timax)/#height vpj = 0 ; unrotated position used for calcs fvpr = vpr fvpi = vpi fvpj = vpj ; screen position ; rotate around x axis temp = vpi vpi = vpi*cos(xangle)-vpj*sin(xangle) vpj = vpj*cos(xangle)+temp*sin(xangle) ; rotate around y axis temp = vpr vpr = vpr*cos(yangle)-vpj*sin(yangle) vpj = vpj*cos(yangle)+temp*sin(yangle) ; rotate around z axis rtemp = vpr + flip(vpi) rtemp = rtemp*zrot vpr = real(rtemp) vpi = imag(rtemp) ; create camera vector vr = camr-vpr vi = cami-vpi vj = camj-vpj vd = sqrt(vr*vr+vi*vi+vj*vj) vr = vr/vd vi = vi/vd vj = vj/vd mindist = mindistr*vr+mindisti*vi+mindistj*vj maxdist = maxdistr*vr+maxdisti*vi+maxdistj*vj ; distance camera correction if vd > mindist ucamr = camr-(vd-mindist)*vr ucami = cami-(vd-mindist)*vi ucamj = camj-(vd-mindist)*vj reduce = vd-mindist else ucamr = camr ucami = cami ucamj = camj reduce = 0 endif if @view == "3D" ; calculate distance from camera to quaternion zrid = 1 zjkd = 0 if m_julia || m_brot if fourth == 3 zri = ucamr + flip(ucami) zjk = ucamj + flip(ck) elseif fourth == 2 zri = ucamr + flip(ucami) zjk = flip(ucamj) + ck elseif fourth == 1 zri = ucamj + flip(ck) zjk = ucamr + flip(ucami) elseif fourth == 0 zri = flip(ucamj) + ck zjk = ucamr + flip(ucami) endif if @potmeth == "Delta DE" zrix = zri+@delta zjkx = zjk zriy = zri+flip(@delta) zjky = zjk zriz = zri zjkz = zjk+@delta zriw = zri zjkw = zjk+flip(@delta) endif elseif m_mand if fourth == 3 cri = ucamr + flip(ucami) cjk = ucamj + flip(ck) elseif fourth == 2 cri = ucamr + flip(ucami) cjk = flip(ucamj) + ck elseif fourth == 1 cri = ucamj + flip(ck) cjk = ucamr + flip(ucami) elseif fourth == 0 cri = flip(ucamj) + ck cjk = ucamr + flip(ucami) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) zrix = zri zjkx = zjk zriy = zri zjky = zjk zriz = zri zjkz = zjk zriw = zri zjkw = zjk endif i = 0 dist = 0 infinity = true siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif if @potmeth == "Brute Force" firstpass = true bepsilon = epsilon*@velocity else firstpass = false endif repeat if dlimityinner repeat if m_oldz m_q.setomp(oldzri,oldzjk) endif ; calculate derivative if @potmeth != "Brute Force" && @potmeth != "delta DE" && \ !@special m_q.drcalc(zri, zjk, zrid, zjkd) endif ; calculate fractal m_q.frcalc(zri, zjk) if @potmeth == "delta DE" if m_mand m_q.setjp(cri+@delta, cjk) endif m_q.frcalc(zrix, zjkx) if m_mand m_q.setjp(cri+flip(@delta), cjk) endif m_q.frcalc(zriy, zjky) if m_mand m_q.setjp(cri, cjk+@delta) endif m_q.frcalc(zriz, zjkz) if !m_sphere if m_mand m_q.setjp(cri, cjk+flip(@delta)) endif m_q.frcalc(zriw, zjkw) endif if m_mand m_q.setjp(cri,cjk) endif endif if m_spider m_q.getjp(cri,cjk) endif if m_oldz m_q.getomp(oldzri,oldzjk) endif if m_brot modh = cabs(zri) else modh = sqrt(|zri|+|zjk|) endif i = i + 1 until i == #maxiter || (modh > bailout) endif if !dlimity if @potmeth == "Brute Force" endif if !@special if m_brot modhd = cabs(zrid) else modhd = sqrt(|zrid|+|zjkd|) endif if modh <= bailout if @potmeth == "Brute Force" if firstpass dist = dist - bepsilon bepsilon = epsilon firstpass = false else d = 0 endif else dist = dist - d d = 0 if dist < 0 dist = 0 endif endif else if @potmeth == "Iteration smoothing" d = modh*log(modh)/modhd*(dfactor/2) elseif @potmeth == "delta DE" float Rx = sqrt(|zrix|+|zjkx|) float Ry = sqrt(|zriy|+|zjky|) float Rz = sqrt(|zriz|+|zjkz|) float rw = 0 if !m_sphere Rw = sqrt(|zriw|+|zjkw|) endif float drx = (modh-rx)/@delta float dry = (modh-ry)/@delta float drz = (modh-rz)/@delta if !m_sphere float drw = (modh-rw)/@delta else float drw = 0 endif float dr = sqrt(drx^2+dry^2+drz^2+drw^2) d = modh*log(modh)/dr*(dfactor/2) else d = bepsilon*1.1 endif if d > maxstep d = maxstep endif dist = d + dist endif elseif @special ; @special: mandelbox, conformal mandelbox, hybridmandelbox if modh <= bailout dist = dist - d d = 0 else ; real(m_q.getspecial()) retrieves spec siter = i + log(log(real(m_q.getspecial())))/log(2) if @alt pot = exp(-siter*log(2)) grad = exp(-(siter-i)*log(2)) d = 10*dfactor*sinh(pot)/(2*exp(pot)*grad) else d = 100*dfactor*exp(-siter) endif dist = d + dist endif endif zrid = 1 zjkd = 0 endif if dlimity dist = ddist d = dd dlimity = false dlimityinner = true endif if !dlimity if m_julia || m_brot if fourth == 3 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 zri = ucamj-dist*vj + flip(ck) zjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 zri = flip(ucamj-dist*vj) + ck zjk = ucamr-dist*vr + flip(ucami-dist*vi) endif if @potmeth == "Delta DE" zrix = zri+@delta zjkx = zjk zriy = zri-flip(@delta) zjky = zjk zriz = zri zjkz = zjk+@delta zriw = zri zjkw = zjk+flip(@delta) endif elseif m_mand if fourth == 3 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 cri = ucamj-dist*vj + flip(ck) cjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 cri = flip(ucamj-dist*vj) + ck cjk = ucamr-dist*vr + flip(ucami-dist*vi) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) if @potmeth == "Delta DE" zrix = zri zjkx = zjk zriy = zri zjky = zjk zriz = zri zjkz = zjk zriw = zri zjkw = zjk endif endif i = 0 siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif endif until (d <= epsilon || dist > maxdist) && \ (firstpass == false || dist > maxdist) if dist < epsilon dist = 1e10 endif if (dist > 0 && dist <= maxdist) || d == 0 infinity = false endif if !infinity ; set the intersection point and distance for normal calculation fzriy = camr-(dist+reduce)*vr + flip(cami-(dist+reduce)*vi) if dist != 0 fzjky = camj-(dist+reduce)*vj + flip((dist+reduce)) else fzjky = camj-(dist+reduce)*vj + flip((1)) endif endif endif ; DELTA XN if @numnorm == "5 point" bool dlimitxninner = false infinity = true ; calculate screen position vpr = rmin + ((#x-@dn)*trmax)/#width vpi = imax - (#y*timax)/#height vpj = 0 ; unrotated position used for calcs fvpr = vpr fvpi = vpi fvpj = vpj ; screen position ; rotate around x axis temp = vpi vpi = vpi*cos(xangle)-vpj*sin(xangle) vpj = vpj*cos(xangle)+temp*sin(xangle) ; rotate around y axis temp = vpr vpr = vpr*cos(yangle)-vpj*sin(yangle) vpj = vpj*cos(yangle)+temp*sin(yangle) ; rotate around z axis rtemp = vpr + flip(vpi) rtemp = rtemp*zrot vpr = real(rtemp) vpi = imag(rtemp) ; create camera vector vr = camr-vpr vi = cami-vpi vj = camj-vpj vd = sqrt(vr*vr+vi*vi+vj*vj) vr = vr/vd vi = vi/vd vj = vj/vd mindist = mindistr*vr+mindisti*vi+mindistj*vj maxdist = maxdistr*vr+maxdisti*vi+maxdistj*vj ; distance camera correction if vd > mindist ucamr = camr-(vd-mindist)*vr ucami = cami-(vd-mindist)*vi ucamj = camj-(vd-mindist)*vj reduce = vd-mindist else ucamr = camr ucami = cami ucamj = camj reduce = 0 endif if @view == "3D" ; calculate distance from camera to quaternion zrid = 1 zjkd = 0 if m_julia || m_brot if fourth == 3 zri = ucamr + flip(ucami) zjk = ucamj + flip(ck) elseif fourth == 2 zri = ucamr + flip(ucami) zjk = flip(ucamj) + ck elseif fourth == 1 zri = ucamj + flip(ck) zjk = ucamr + flip(ucami) elseif fourth == 0 zri = flip(ucamj) + ck zjk = ucamr + flip(ucami) endif if @potmeth == "Delta DE" zrix = zri+@delta zjkx = zjk zriy = zri+flip(@delta) zjky = zjk zriz = zri zjkz = zjk+@delta zriw = zri zjkw = zjk+flip(@delta) endif elseif m_mand if fourth == 3 cri = ucamr + flip(ucami) cjk = ucamj + flip(ck) elseif fourth == 2 cri = ucamr + flip(ucami) cjk = flip(ucamj) + ck elseif fourth == 1 cri = ucamj + flip(ck) cjk = ucamr + flip(ucami) elseif fourth == 0 cri = flip(ucamj) + ck cjk = ucamr + flip(ucami) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) if @potmeth == "Delta DE" zrix = zri zjkx = zjk zriy = zri zjky = zjk zriz = zri zjkz = zjk zriw = zri zjkw = zjk endif endif i = 0 dist = 0 infinity = true siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif if @potmeth == "Brute Force" firstpass = true bepsilon = epsilon*@velocity else firstpass = false endif repeat if dlimitxninner repeat if m_oldz m_q.setomp(oldzri,oldzjk) endif ; calculate derivative if @potmeth != "Brute Force" && @potmeth != "delta DE" && \ !@special m_q.drcalc(zri, zjk, zrid, zjkd) endif ; calculate fractal m_q.frcalc(zri, zjk) if @potmeth == "delta DE" if m_mand m_q.setjp(cri+@delta, cjk) endif m_q.frcalc(zrix, zjkx) if m_mand m_q.setjp(cri+flip(@delta), cjk) endif m_q.frcalc(zriy, zjky) if m_mand m_q.setjp(cri, cjk+@delta) endif m_q.frcalc(zriz, zjkz) if !m_sphere if m_mand m_q.setjp(cri, cjk+flip(@delta)) endif m_q.frcalc(zriw, zjkw) endif if m_mand m_q.setjp(cri,cjk) endif endif if m_spider m_q.getjp(cri,cjk) endif if m_oldz m_q.getomp(oldzri,oldzjk) endif if m_brot modh = cabs(zri) else modh = sqrt(|zri|+|zjk|) endif i = i + 1 until i == #maxiter || (modh > bailout) endif if !dlimitxn if @potmeth == "Brute Force" endif if !@special if m_brot modhd = cabs(zrid) else modhd = sqrt(|zrid|+|zjkd|) endif if modh <= bailout if @potmeth == "Brute Force" if firstpass dist = dist - bepsilon bepsilon = epsilon firstpass = false else d = 0 endif else dist = dist - d d = 0 if dist < 0 dist = 0 endif endif else if @potmeth == "Iteration smoothing" d = modh*log(modh)/modhd*(dfactor/2) elseif @potmeth == "delta DE" ; itercolor = i +log(log(modh))/log(2) float Rx = sqrt(|zrix|+|zjkx|) float Ry = sqrt(|zriy|+|zjky|) float Rz = sqrt(|zriz|+|zjkz|) float rw = 0 if !m_sphere Rw = sqrt(|zriw|+|zjkw|) endif float drx = (modh-rx)/@delta float dry = (modh-ry)/@delta float drz = (modh-rz)/@delta if !m_sphere float drw = (modh-rw)/@delta else float drw = 0 endif float dr = sqrt(drx^2+dry^2+drz^2+drw^2) d = modh*log(modh)/dr*(dfactor/2) else d = bepsilon*1.1 endif if d > maxstep d = maxstep endif dist = d + dist endif elseif @special ; @special: mandelbox, conformal mandelbox, hybridmandelbox if modh <= bailout dist = dist - d d = 0 else ; real(m_q.getspecial()) retrieves spec siter = i + log(log(real(m_q.getspecial())))/log(2) ; itercolor = siter if @alt pot = exp(-siter*log(2)) grad = exp(-(siter-i)*log(2)) d = 10*dfactor*sinh(pot)/(2*exp(pot)*grad) else d = 100*dfactor*exp(-siter) endif dist = d + dist endif endif zrid = 1 zjkd = 0 endif if dlimitxn dist = ddist d = dd dlimitxn = false dlimitxninner = true endif if !dlimitxn if m_julia || m_brot if fourth == 3 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 zri = ucamj-dist*vj + flip(ck) zjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 zri = flip(ucamj-dist*vj) + ck zjk = ucamr-dist*vr + flip(ucami-dist*vi) endif if @potmeth == "Delta DE" zrix = zri+@delta zjkx = zjk zriy = zri-flip(@delta) zjky = zjk zriz = zri zjkz = zjk+@delta zriw = zri zjkw = zjk+flip(@delta) endif elseif m_mand if fourth == 3 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 cri = ucamj-dist*vj + flip(ck) cjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 cri = flip(ucamj-dist*vj) + ck cjk = ucamr-dist*vr + flip(ucami-dist*vi) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) if @potmeth == "Delta DE" zrix = zri zjkx = zjk zriy = zri zjky = zjk zriz = zri zjkz = zjk zriw = zri zjkw = zjk endif endif i = 0 siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif endif until (d <= epsilon || dist > maxdist) && \ (firstpass == false || dist > maxdist) if dist < epsilon dist = 1e10 endif if (dist > 0 && dist <= maxdist) || d == 0 infinity = false endif if !infinity ; set the intersection point and distance for normal calculation fzrixn = camr-(dist+reduce)*vr + flip(cami-(dist+reduce)*vi) if dist != 0 fzjkxn = camj-(dist+reduce)*vj + flip((dist+reduce)) else fzjkxn = camj-(dist+reduce)*vj + flip((1)) endif endif endif ; DELTA YN if @numnorm == "5 point" bool dlimityninner = false infinity = true ; calculate screen position vpr = rmin + (#x*trmax)/#width vpi = imax - ((#y-@dn)*timax)/#height vpj = 0 ; unrotated position used for calcs fvpr = vpr fvpi = vpi fvpj = vpj ; screen position ; rotate around x axis temp = vpi vpi = vpi*cos(xangle)-vpj*sin(xangle) vpj = vpj*cos(xangle)+temp*sin(xangle) ; rotate around y axis temp = vpr vpr = vpr*cos(yangle)-vpj*sin(yangle) vpj = vpj*cos(yangle)+temp*sin(yangle) ; rotate around z axis rtemp = vpr + flip(vpi) rtemp = rtemp*zrot vpr = real(rtemp) vpi = imag(rtemp) ; create camera vector vr = camr-vpr vi = cami-vpi vj = camj-vpj vd = sqrt(vr*vr+vi*vi+vj*vj) vr = vr/vd vi = vi/vd vj = vj/vd mindist = mindistr*vr+mindisti*vi+mindistj*vj maxdist = maxdistr*vr+maxdisti*vi+maxdistj*vj ; distance camera correction if vd > mindist ucamr = camr-(vd-mindist)*vr ucami = cami-(vd-mindist)*vi ucamj = camj-(vd-mindist)*vj reduce = vd-mindist else ucamr = camr ucami = cami ucamj = camj reduce = 0 endif if @view == "3D" ; calculate distance from camera to quaternion zrid = 1 zjkd = 0 if m_julia || m_brot if fourth == 3 zri = ucamr + flip(ucami) zjk = ucamj + flip(ck) elseif fourth == 2 zri = ucamr + flip(ucami) zjk = flip(ucamj) + ck elseif fourth == 1 zri = ucamj + flip(ck) zjk = ucamr + flip(ucami) elseif fourth == 0 zri = flip(ucamj) + ck zjk = ucamr + flip(ucami) endif if @potmeth == "Delta DE" zrix = zri+@delta zjkx = zjk zriy = zri+flip(@delta) zjky = zjk zriz = zri zjkz = zjk+@delta zriw = zri zjkw = zjk+flip(@delta) endif elseif m_mand if fourth == 3 cri = ucamr + flip(ucami) cjk = ucamj + flip(ck) elseif fourth == 2 cri = ucamr + flip(ucami) cjk = flip(ucamj) + ck elseif fourth == 1 cri = ucamj + flip(ck) cjk = ucamr + flip(ucami) elseif fourth == 0 cri = flip(ucamj) + ck cjk = ucamr + flip(ucami) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) zrix = zri zjkx = zjk zriy = zri zjky = zjk zriz = zri zjkz = zjk zriw = zri zjkw = zjk endif i = 0 dist = 0 infinity = true siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif if @potmeth == "Brute Force" firstpass = true bepsilon = epsilon*@velocity else firstpass = false endif repeat if dlimityninner repeat if m_oldz m_q.setomp(oldzri,oldzjk) endif ; calculate derivative if @potmeth != "Brute Force" && @potmeth != "delta DE" && \ !@special m_q.drcalc(zri, zjk, zrid, zjkd) endif ; calculate fractal m_q.frcalc(zri, zjk) if @potmeth == "delta DE" if m_mand m_q.setjp(cri+@delta, cjk) endif m_q.frcalc(zrix, zjkx) if m_mand m_q.setjp(cri+flip(@delta), cjk) endif m_q.frcalc(zriy, zjky) if m_mand m_q.setjp(cri, cjk+@delta) endif m_q.frcalc(zriz, zjkz) if !m_sphere if m_mand m_q.setjp(cri, cjk+flip(@delta)) endif m_q.frcalc(zriw, zjkw) endif if m_mand m_q.setjp(cri,cjk) endif endif if m_spider m_q.getjp(cri,cjk) endif if m_oldz m_q.getomp(oldzri,oldzjk) endif if m_brot modh = cabs(zri) else modh = sqrt(|zri|+|zjk|) endif i = i + 1 until i == #maxiter || (modh > bailout) endif if !dlimityn if @potmeth == "Brute Force" endif if !@special if m_brot modhd = cabs(zrid) else modhd = sqrt(|zrid|+|zjkd|) endif if modh <= bailout if @potmeth == "Brute Force" if firstpass dist = dist - bepsilon bepsilon = epsilon firstpass = false else d = 0 endif else dist = dist - d d = 0 if dist < 0 dist = 0 endif endif else if @potmeth == "Iteration smoothing" d = modh*log(modh)/modhd*(dfactor/2) elseif @potmeth == "delta DE" float Rx = sqrt(|zrix|+|zjkx|) float Ry = sqrt(|zriy|+|zjky|) float Rz = sqrt(|zriz|+|zjkz|) float rw = 0 if !m_sphere Rw = sqrt(|zriw|+|zjkw|) endif float drx = (modh-rx)/@delta float dry = (modh-ry)/@delta float drz = (modh-rz)/@delta if !m_sphere float drw = (modh-rw)/@delta else float drw = 0 endif float dr = sqrt(drx^2+dry^2+drz^2+drw^2) d = modh*log(modh)/dr*(dfactor/2) else d = bepsilon*1.1 endif if d > maxstep d = maxstep endif dist = d + dist endif elseif @special ; @special: mandelbox, conformal mandelbox, hybridmandelbox if modh <= bailout dist = dist - d d = 0 else ; real(m_q.getspecial()) retrieves spec siter = i + log(log(real(m_q.getspecial())))/log(2) if @alt pot = exp(-siter*log(2)) grad = exp(-(siter-i)*log(2)) d = 10*dfactor*sinh(pot)/(2*exp(pot)*grad) else d = 100*dfactor*exp(-siter) endif dist = d + dist endif endif zrid = 1 zjkd = 0 endif if dlimityn dist = ddist d = dd dlimityn = false dlimityninner = true endif if !dlimityn if m_julia || m_brot if fourth == 3 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 zri = ucamj-dist*vj + flip(ck) zjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 zri = flip(ucamj-dist*vj) + ck zjk = ucamr-dist*vr + flip(ucami-dist*vi) endif if @potmeth == "Delta DE" zrix = zri+@delta zjkx = zjk zriy = zri+flip(@delta) zjky = zjk zriz = zri zjkz = zjk+@delta zriw = zri zjkw = zjk+flip(@delta) endif elseif m_mand if fourth == 3 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 cri = ucamj-dist*vj + flip(ck) cjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 cri = flip(ucamj-dist*vj) + ck cjk = ucamr-dist*vr + flip(ucami-dist*vi) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) if @potmeth == "Delta DE" zrix = zri zjkx = zjk zriy = zri zjky = zjk zriz = zri zjkz = zjk zriw = zri zjkw = zjk endif endif i = 0 siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif endif until (d <= epsilon || dist > maxdist) && \ (firstpass == false || dist > maxdist) if dist < epsilon dist = 1e10 endif if (dist > 0 && dist <= maxdist) || d == 0 infinity = false endif if !infinity ; set the intersection point and distance for normal calculation fzriyn = camr-(dist+reduce)*vr + flip(cami-(dist+reduce)*vi) if dist != 0 fzjkyn = camj-(dist+reduce)*vj + flip((dist+reduce)) else fzjkyn = camj-(dist+reduce)*vj + flip((1)) endif endif endif endif endif sdfactor = @dfactor float svpr = 0 float svpi = 0 float svpj = 0 float svr = 0 float svi = 0 float svj = 0 float svd = 0 float stemp = 0 iii = 0 mycolor = 0 bool shad = false int xcrd = #x int ycrd = #y complex srtemp = 0 szri = 0 szjk = 0 oldszri = 0 oldszjk = 0 oldszri2 = 0 oldszjk2 = 0 sztemp = 0 szrid = 0 szjkd = 0 smodH = 0 smodHold = 0 float smodHd = 0 float sdist = 0 ; float sgrad = 0 ; float spot = 0 float sreduce = 0 float smindist = 0 float smindistr = mindistr float smindisti = mindisti float smindistj = mindistj float sd = 0 float ssiter = 0 int sj = 0 int si = 0 ; light origin float lightr = 0 float lighti = 0 float lightj = 0 if @ltype == "Infinite Light" ; assumes light points at (0,0,0) lightr = -lx*camj lighti = -ly*camj lightj = -lz*camj else lightr = lpointx lighti = lpointy lightj = lpointz endif float ulightr = 0 float ulighti = 0 float ulightj = 0 float slr = 0 float sli = 0 float slj = 0 float sld = 0 float l = 0 float svr = 0 float svi = 0 float svj = 0 float svd = 0 float rr = 0 float ri = 0 float rj = 0 float ir = 0 float ii = 0 float ij = 0 float nr = 0 float ni = 0 float nj = 0 complex fri = 0 complex frj = 0 float n = 0 bool sfirstpass = false float sbepsilon = 0 ; generate the x and y location in the image float dxx = (real(#pixel)-real(#center))*(#width)/4*#magn float dyy = (imag(#pixel)-imag(#center))*(#width)/4*#magn float transx = (#width)*0.5; float transy = (#height)*0.5; float cosan = cos(#angle); float sinan = sin(#angle); xcrd = round((transx + (dxx*cosan + dyy*sinan))) ycrd = round((transy + (dxx*sinan - dyy*cosan))) if @view == "3D" && imag(fzjk) > -3 if xcrd <#width-1 && ycrd <#height-1 && xcrd > 0 && \ ycrd > 0 ; calculate the normals fri = fzri frj = real(fzjk) rr = real(fzrix-fri) ri = imag(fzrix-fri) rj = real(fzjkx-frj) n = sqrt(rr^2+ri^2+rj^2) rr = rr/n ri = ri/n rj = rj/n ir = real(fzriy-fri) ii = imag(fzriy-fri) ij = real(fzjky-frj) n = sqrt(ir^2+ii^2+ij^2) ir = ir/n ii = ii/n ij = ij/n nr = ri*ij - rj*ii ni = rj*ir - rr*ij nj = rr*ii - ri*ir if @numnorm == "5 point" rr = real(fzrixn-fri) ri = imag(fzrixn-fri) rj = real(fzjkxn-frj) n = sqrt(rr^2+ri^2+rj^2) rr = rr/n ri = ri/n rj = rj/n ir = real(fzriyn-fri) ii = imag(fzriyn-fri) ij = real(fzjkyn-frj) n = sqrt(ir^2+ii^2+ij^2) ir = ir/n ii = ii/n ij = ij/n nr = (nr+ri*ij - rj*ii)/2 ni = (ni+rj*ir - rr*ij)/2 nj = (nj+rr*ii - ri*ir)/2 endif n = sqrt(nr^2+ni^2+nj^2) nr = nr/n ni = ni/n nj = nj/n float ntemp = 0 ; rotate around z axis in opposite direction from other z axis ; rotations srtemp = nr + flip(ni) srtemp = srtemp*conj(zrot) nr = real(srtemp) ni = imag(srtemp) ; rotate around y axis ntemp = nr nr = nr*cos(yangle)+nj*sin(yangle) nj = nj*cos(yangle)-ntemp*sin(yangle) ; rotate around x axis ntemp = ni ni = ni*cos(xangle)+nj*sin(xangle) nj = nj*cos(xangle)-ntemp*sin(xangle) n = sqrt(nr^2+ni^2+nj^2) nr = nr/n ni = ni/n nj = nj/n l = lx*nr + ly*ni + lz*nj if isNAN(l) l = 0 endif endif ; shadows on the fractal object if @shadows &&((imag(fzjk) > 0 && imag(fzjk)-reduce\ <= maxdist)) shad = false ; calculate light vector ; rotate around x axis ntemp = lighti lighti = lighti*cos(xangle)-lightj*sin(xangle) lightj = lightj*cos(xangle)+ntemp*sin(xangle) ; rotate around y axis ntemp = lightr lightr = lightr*cos(yangle)-lightj*sin(yangle) lightj = lightj*cos(yangle)+ntemp*sin(yangle) ; rotate around z axis srtemp = lightr + flip(lighti) srtemp = srtemp*zrot lightr = real(srtemp) lighti = imag(srtemp) slr = lightr - real(fzri) sli = lighti - imag(fzri) slj = lightj - real(fzjk) sld = sqrt(slr^2+sli^2+slj^2) slr = slr/sld sli = sli/sld slj = slj/sld svr = camr-real(fzri) svi = cami-imag(fzri) svj = camj-real(fzjk) svd = sqrt(svr*svr+svi*svi+svj*svj) svr = svr/svd svi = svi/svd svj = svj/svd smindist = (smindistr*svr+smindisti*svi+smindistj*svj) if sld >= smindist ulightr = lightr - (sld-smindist)*slr ulighti = lighti - (sld-smindist)*sli ulightj = lightj - (sld-smindist)*slj sreduce = sld-smindist else ulightr = lightr ulighti = lighti ulightj = lightj sreduce = 0 endif szrid = 1 szjkd = 0 if m_julia || m_brot if fourth == 3 szri = ulightr + flip(ulighti) szjk = ulightj + flip(ck) elseif fourth == 2 szri = ulightr + flip(ulighti) szjk = flip(ulightj) + ck elseif fourth == 1 szri = ulightj + flip(ck) szjk = ulightr + flip(ulighti) elseif fourth == 0 szri = flip(ulightj) + ck szjk = ulightr + flip(ulighti) endif if @potmeth == "Delta DE" szrix = szri+@delta szjkx = szjk szriy = szri+flip(@delta) szjky = szjk szriz = szri szjkz = szjk+@delta szriw = szri szjkw = szjk+flip(@delta) endif elseif m_mand if fourth == 3 scri = ulightr + flip(ulighti) scjk = ulightj + flip(ck) elseif fourth == 2 scri = ulightr + flip(ulighti) scjk = flip(ulightj) + ck elseif fourth == 1 scri = ulightj + flip(ck) scjk = ulightr + flip(ulighti) elseif fourth == 0 scri = flip(ulightj) + ck scjk = ulightr + flip(ulighti) endif m_q.setjp(scri,scjk) m_q.getmp(szri,szjk) if @potmeth == "Delta DE" szrix = szri szjkx = szjk szriy = szri szjky = szjk szriz = szri szjkz = szjk szriw = szri szjkw = szjk endif endif si = 0 sj = 0 sdist = 0 ssiter = 0 oldszri2 = oldszri oldszjk2 = oldszjk oldszri = szri oldszjk = szjk if m_spider scri = spidercri scjk = spidercjk m_q.setjp(scri,scjk) endif if @potmeth == "Brute Force" sfirstpass = true sbepsilon = epsilon*@velocity else sfirstpass = false endif repeat repeat if m_oldz m_q.setomp(oldszri,oldszjk) endif ; calculate derivative if @potmeth != "Brute Force" && @potmeth != "delta DE" && \ !@special m_q.drcalc(szri, szjk, szrid, szjkd) endif ; calculate fractal m_q.frcalc(szri,szjk) if @potmeth == "delta DE" if m_mand m_q.setjp(scri+@delta, scjk) endif m_q.frcalc(szrix, szjkx) if m_mand m_q.setjp(scri+flip(@delta), scjk) endif m_q.frcalc(szriy, szjky) if m_mand m_q.setjp(scri, scjk+@delta) endif m_q.frcalc(szriz, szjkz) if !m_sphere if m_mand m_q.setjp(scri, scjk+flip(@delta)) endif m_q.frcalc(szriw, szjkw) endif if m_mand m_q.setjp(scri,scjk) endif endif if m_oldz m_q.getomp(oldszri,oldszjk) endif if m_spider m_q.getjp(scri,scjk) endif if m_brot smodh = cabs(szri) else smodh = sqrt(|szri|+|szjk|) endif si = si + 1 until si == #maxiter || smodh > bailout if !@special if m_brot smodhd = cabs(szrid) else smodhd = sqrt(|szrid|+|szjkd|) endif if smodh <= bailout if @potmeth == "Brute Force" if sfirstpass sdist = sdist - sbepsilon sbepsilon = epsilon sfirstpass = false else sd = 0 endif else sdist = sdist - sd sd = 0 endif else if @potmeth == "Iteration smoothing" sd = smodh*log(smodh)/smodhd*(sdfactor/2) elseif @potmeth == "delta DE" float Rx = sqrt(|szrix|+|szjkx|) float Ry = sqrt(|szriy|+|szjky|) float Rz = sqrt(|szriz|+|szjkz|) float rw = 0 if !m_sphere Rw = sqrt(|szriw|+|szjkw|) endif float drx = (smodh-rx)/@delta float dry = (smodh-ry)/@delta float drz = (smodh-rz)/@delta if !m_sphere float drw = (smodh-rw)/@delta else float drw = 0 endif float dr = sqrt(drx^2+dry^2+drz^2+drw^2)*8 sd = smodh*log(smodh)/dr*(sdfactor/2) else sd = sbepsilon*1.1 endif if sd > maxstep sd = maxstep endif sdist = sd + sdist endif elseif @special if smodh <= bailout sdist = sdist - sd sd = 0 else ssiter = si + log(log(real(m_q.getspecial())))/log(2) if @alt pot = exp(-ssiter*log(2)) grad = exp(-(ssiter-si)*log(2)) sd = 10*dfactor*sinh(pot)/(2*exp(pot)*grad) else sd = 100*dfactor*exp(-ssiter) endif sdist = sd + sdist endif endif szrid = 1 szjkd = 0 if m_julia || m_brot if fourth == 3 szri = ulightr-sdist*slr + flip(ulighti-sdist*sli) szjk = ulightj-sdist*slj + flip(ck) elseif fourth == 2 szri = ulightr-sdist*slr + flip(ulighti-sdist*sli) szjk = flip(ulightj-sdist*slj) + ck elseif fourth == 1 szri = ulightj-sdist*slj + flip(ck) szjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) elseif fourth == 0 szri = flip(ulightj-sdist*slj) + ck szjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) endif if @potmeth == "Delta DE" szrix = szri+@delta szjkx = szjk szriy = szri+flip(@delta) szjky = szjk szriz = szri szjkz = szjk+@delta szriw = szri szjkw = szjk+flip(@delta) endif elseif m_mand if fourth == 3 scri = ulightr-sdist*slr + flip(ulighti-sdist*sli) scjk = ulightj-sdist*slj + flip(ck) elseif fourth == 2 scri = ulightr-sdist*slr + flip(ulighti-sdist*sli) scjk = flip(ulightj-sdist*slj) + ck elseif fourth == 1 scri = ulightj-sdist*slj + flip(ck) scjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) elseif fourth == 0 scri = flip(ulightj-sdist*slj) + ck scjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) endif m_q.setjp(scri,scjk) m_q.getmp(szri,szjk) if @potmeth == "Delta DE" szrix = szri szjkx = szjk szriy = szri szjky = szjk szriz = szri szjkz = szjk szriw = szri szjkw = szjk endif endif sj = sj + 1 si = 0 oldszri2 = oldszri oldszjk2 = oldszjk oldszri = szri oldszjk = szjk if m_spider scri = spidercri scjk = spidercjk m_q.setjp(scri,scjk) endif ssiter = 0 until (sd <= @objshadsens*epsilon || sdist > maxdist) if sreduce != 0 sdist = sdist+sreduce endif if sdist < sld*@srough && sd <= @objshadsens*epsilon && imag(fzjk) != 1 shad = true endif endif mycolor = l*#maxiter/2 if (imag(fzjk) != 0) || (imag(fzjk)-reduce <= maxdist) \ || imag(fzjk) == 1 if @type == "Raytrace" pz = l + flip(imag(fzjk)) if imag(fzjk) == 1 pz = l + flip(fdst) endif elseif @type == "Distance" if imag(fzjk) == 1 if @ray pz = fdst+ l/2 else pz = fdst endif else if @ray pz = imag(fzjk)+ l/2 else pz = imag(fzjk) endif endif elseif @type == "Z value" float nx= fdst float ny = fdst float nz = 0 if @corzd && imag(fzjk) != 0 nz= (real(fzjk)-@zoff)/@zmax else nz= real(fzjk) endif float ntemp = nx nx= nx*cos(yangle)+nz*sin(yangle) nz = nz*cos(yangle)-ntemp*sin(yangle) ntemp = ny ny = ny*cos(xangle)+nz*sin(xangle) nz = nz*cos(xangle)-ntemp*sin(xangle) if imag(fzjk) == 1 if @ray pz = nx + flip(ny) + l/2 else pz = nx + flip(ny) endif else if @ray pz = abs(nz) + l/2 else pz = abs(nz) endif endif elseif @type == "Iteration" if imag(fzjk) == 1 if @ray pz = trunc(l*2^19) + icolor/2^20 else pz = icolor/2^20 endif else if @ray pz = trunc(l*2^19) + icolor/2^20 else pz = icolor/2^20 endif ; endif endif endif endif if cabs(pz) != 0 if @type == "Raytrace" pz = real(pz) + (0,-1) if shad pz = real(pz) + (0,-2) endif elseif @type == "Distance" || @type == "Z value" pz = real(pz) + (0,1) elseif @type == "Iteration" pz = real(pz) + (0,2) endif endif elseif @view == "2D"; initialize 2D parameters svpr = rmin + (xcrd*trmax)/#width svpi = imax - (ycrd*timax)/#height svpj = 0 ; rotate around x axis stemp = svpi svpi = svpi*cos(xangle)-svpj*sin(xangle) svpj = svpj*cos(xangle)+stemp*sin(xangle) ; rotate around y axis stemp = svpr svpr = svpr*cos(yangle)-svpj*sin(yangle) svpj = svpj*cos(yangle)+stemp*sin(yangle) ; rotate around z axis srtemp = svpr + flip(svpi) srtemp = srtemp*zrot svpr = real(srtemp) svpi = imag(srtemp) svr = camr-svpr svi = cami-svpi svj = camj-svpj svd = sqrt(svr*svr+svi*svi+svj*svj) svr = svr/svd svi = -svi/svd svj = -svj/svd smindist = svr*smindistr-svi*smindisti-svj*smindistj if m_julia || m_brot if fourth == 3 szri = camr - (svd-smindist)*svr + flip(cami +(svd-smindist)*svi) szjk = camj + (svd-smindist)*svj + flip(ck) elseif fourth == 2 szri = camr- (svd-smindist)*svr - flip(cami+ (svd-smindist)*svi) szjk = flip(camj+ (svd-smindist)*svj) + ck elseif fourth == 1 szri = camj+ (svd-smindist)*svj + flip(ck) szjk = camr- (svd-smindist)*svr + flip(cami- (svd-smindist)*svi) elseif fourth == 0 szri = flip(camj+ (svd-smindist)*svj) + ck szjk = camr- (svd-smindist)*svr + flip(cami- (svd-smindist)*svi) endif elseif m_mand if fourth == 3 scri = camr - (svd-smindist)*svr - flip(cami + (svd-smindist)*svi) scjk = camj + (svd-smindist)*svj + flip(ck) elseif fourth == 2 scri = camr - (svd-smindist)*svr - flip(cami + (svd-smindist)*svi) scjk = flip(camj + (svd-smindist)*svj) + ck elseif fourth == 1 scri = camj + (svd-smindist)*svj + flip(ck) scjk = camr - (svd-smindist)*svr - flip(cami + (svd-smindist)*svi) elseif fourth == 0 scri = flip(camj + (svd-smindist)*svj) + ck scjk = camr - (svd-smindist)*svr - flip(cami + (svd-smindist)*svi) endif m_q.setjp(scri,scjk) m_q.getmp(szri,szjk) endif oldszri2 = oldszri oldszjk2 = oldszjk oldszri = szri oldszjk = szjk if m_spider scri = spidercri scjk = spidercjk m_q.setjp(scri,scjk) endif endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Formula.Iterate(pz) iii = iii + 1 if @view == "2D" if m_oldz m_q.setomp(oldszri,oldszjk) endif m_q.frcalc(szri, szjk) if m_oldz m_q.getomp(oldszri,oldszjk) endif if m_spider m_q.getjp(scri,scjk) endif if m_brot smodh = cabs(szri) else smodh = sqrt(|szri|+|szjk|) endif pz = szri if @compat float m = abs(real(pz))/512.0 if m < 1e-200 m = 1e-200 endif m = m + (356)*2.0^floor(1.0+log(m)/log(2.0)) if real(pz)<0.0 m = -m endif pz = m + flip(imag(pz)) endif endif return pz endfunc ; This overrides formula bailout. bool func IsBailedOut(complex pz) if @view == "2D" m_BailedOut = smodh > bailout else m_BailedOut = iii > mycolor endif return m_BailedOut endfunc protected: float scrsize complex zri complex zjk complex zrix complex zriy complex zriz complex zriw complex zjkx complex zjky complex zjkz complex zjkw complex zrid complex zjkd complex rtemp complex cri complex cjk float vpr float vpi float vpj float fvpr float fvpi float fvpj ; ray normal float vr float vi float vj float vd float camr float cami float camj float ucamr float ucami float ucamj float modH float modHd float d float dist int fr int fi bool infinity float dfactor float sdfactor float olddfactor float oldsdfactor float epsilon float ci float cr float trmax float timax float rmin float imax ; light origin float lpointx float lpointy float lpointz ; light point at float lightx float lighty float lightz ; light vector float lx float ly float lz float xangle float yangle complex zrot float temp complex im float bailout float pot float grad float siter float reduce float mindist float mindistr float mindisti float mindistj float maxdist float maxdistr float maxdisti float maxdistj float camd int iii float smodh float mycolor complex sztemp complex szri complex szjk complex szrix complex szjkx complex szriy complex szjky complex szriz complex szjkz complex szriw complex szjkw complex scri complex scjk Quat m_q bool m_julia bool m_mand bool m_hyper bool m_quat bool m_brot bool m_sphere bool firstpass float bepsilon int fourth float ck complex oldzri complex oldzjk complex oldszri complex oldszjk float modHold float smodHold bool m_spider complex spidercri complex spidercjk bool m_oldz float inc float maxstep float pow complex oldzri2 complex oldzjk2 complex oldszri2 complex oldszjk2 float dold float itercolor int i default: title = "3D Fractal Raytrace Progressive (UF5)" int param v_3D_Fractal_RaytraceProgressive caption = "Version (3D Fractal Raytrace Progressive)" 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_3D_Fractal_RaytraceProgressive < 100 endparam complex param p_power caption = "Exponent" default = (2,0) visible = false endparam heading text = "Based upon an article by Hart, Sandin and Kauffman for estimating \ the distance from a point to a fractal surface." endheading heading text = "For optimal Raytracing results, use the coloring formula 3D Fractal \ Coloring Direct Progressive or 3D Fractal Coloring Gradient Progressive. \ Any coloring formula can be used when the Object view parameter is 2D." endheading heading caption = "Camera Settings" expanded = false endheading bool param setzoom caption = "Set to zoom center" default = false endparam heading text = "Camera Origin" visible = @view == "3D" endheading float param camr caption = " X" default = 0.0 visible = !@setzoom endparam float param cami caption = " Y" default = 0.0 visible = !@setzoom endparam float param camj caption = " Z" default = 10.0 endparam heading caption = "Illumination" expanded = false visible = @view == "3D" && @type == "raytrace" endheading param ltype caption = "Light type" enum = "Point source" "Infinite light" default = 0 visible = @view == "3D" && @type == "raytrace" endparam heading text = "Counter clockwise from the X axis." visible = @ltype == "Infinite light" && @view == "3D" && @type == "raytrace" endheading param angle caption = "Light Rotation" default = 60.0 min = -180 max = 180 hint = "Gives the rotation of the light source, in degrees." visible = @ltype == "Infinite light" && @view == "3D" && @type == "raytrace" endparam heading text = "Degrees of elevation above the complex plane." visible = @ltype == "Infinite light" && @view == "3D" && @type == "raytrace" endheading param elevation caption = "Light Elevation" default = 60.0 min = -90 max = 90 hint = "Gives the elevation of the light source, in degrees." visible = @ltype == "Infinite light" && @view == "3D" && @type == "raytrace" endparam heading text = "Light Origin" visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endheading float param lpointx caption = " X" default = 1.5 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam float param lpointy caption = " Y" default = 2 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam float param lplane caption = " Z" default = 5 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam heading text = "Light Point At" visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endheading float param lightx caption = " X" default = 0.0 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam float param lighty caption = " Y" default = 0.0 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam float param lightz caption = " Z" default = 0.0 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam heading caption = "Shadows" visible = @view == "3D" && @type == "raytrace" endheading bool param shadows caption = "Add Shadows" default = false visible = @view == "3D" && @type == "raytrace" endparam heading text = "Increasing 'shadow sensivity' will give shadows that show less fractal \ detail, but can also increase the number of false shadows from roughness \ on the fractal surface. Decreasing object roughness slightly may reduce \ the false shadows." visible = @view == "3D" && @shadows && @type == "raytrace" endheading float param objshadsens caption = "Object shadow sens" default = 0.1 visible = @view == "3D" && @shadows && @type == "raytrace" hint = "Determines shadow detail and sensitivity to surface roughness. Larger \ show less detail and more response to surface roughness" endparam float param srough caption = "Object roughness" default = 0.99 visible = @view == "3D" && @shadows && @type == "raytrace" hint = "Determines shadow sensitivity to surface roughness. Larger \ have more response to surface roughness" endparam heading caption = "Environment" visible = @view == "3D" endheading heading caption = "Fractal Parameters" endheading Quat param QuatClass caption = "Fractal Formula" default = Julia endparam float param p_bailout ; Overrides p_bailout caption = "Bailout value" default = 1024 endparam heading caption = "Rotations" endheading heading text = "For rotation around the Z axis use the Location tab setting." endheading float param xangle caption = "X Axis Rotation" default = 0.0 endparam float param yangle caption = "Y Axis Rotation" default = 0.0 endparam heading caption = "Raytrace parameters" endheading param view caption = "Object view" enum = "3D" "2D" default = 0 hint = "The 2D view is at the level of the viewing screen (Starting Distance)." endparam heading text = "The compatibility box must be checked for use with the 3D Fractal \ Coloring Direct Progressive or 3D Fractal Coloring Gradient Progressive coloring formulas. It should be unchecked for use \ with other coloring formulas." visible = @view == "2D" endheading bool param compat caption = "Compatibility" default = true visible = @view == "2D" endparam param type caption = "Display type" enum = "Raytrace" "Distance" "Z Value" "Iteration" default = 0 visible = @view == "3D" hint = "The distance option provides coloring according to the distance \ from the camera." endparam heading text = "'Distance corection' may give coloring artifacts for some object \ positions/rotations, but it eliminates most artifacts that result from zooms." visible = @type == "Iteration" endheading bool param distcorr caption = "Distance correction" default = true visible = @type == "Iteration" endparam param colortype caption = "Color type" enum = "Vepstas" "Exponential Smoothing" default = 0 visible = @type == "Iteration" endparam bool param corzd caption = "Scale Z value" default = false visible = @view == "3D" && @type == "Z Value" endparam float param zoff caption = "Z offset" default = -1 visible = @view == "3D" && @type == "Z Value" && @corzd endparam float param zmax caption = "Z max" default = 2 visible = @view == "3D" && @type == "Z Value" && @corzd endparam param ray caption = "Add Raytrace" default = false visible = @type == "Distance" || @type == "Z Value" || @type == "Iteration" endparam float param epsilon caption = "Closeness" default = 1.0 hint = "Determines closeness of approach to the fractal \ surface in pixels." visible = @view == "3D" endparam float param dfactor caption = "Distance factor" default = 1.0 hint = "Decrease to more accurately approach the fractal surface. This will \ slow generation of the image." visible = @view == "3D" && @potmeth != "Brute Force" endparam bool param szoom caption = "Scale to zoom" default = false visible = @view == "3D" && @potmeth != "Brute Force" endparam heading text = "The next two parameters are for optimizing image quality and speed \ of execution. These may be different depending upon the formula and \ the potential method. 'Norm delta value' sets the cluster position \ of the short path intersections used for calculating the normals. \ a value of 1.0 clusters the points about a pixel away from the main \ ray intersection point. Depending upon the fractal, changes in either \ direction may increase or decrease speed and quality. 'Norm epsilon \ adjust' sets the short path limit for the normal intersections. Decreasing \ the value will speed up the execution but degrade the quality. The reverse \ will happen on increasing the value." endheading float param maxstep caption = "Max step" default = 0.1 visible = false endparam float param dn caption = "Norm delta value" default = 2.0 visible = @view == "3D" endparam param numnorm caption = "Normal points" enum = "5 point" "3 point" default = 0 visible = @view == "3D" endparam float param eadj caption = "Norm epsilon adjust" default = 1 visible = !@accel && @view == "3D" endparam heading text = "'No normal acceleration' may improve the image quality but will also \ slow the rendering." visible = @view == "3D" endheading bool param accel caption = "No normal acceleration" default = false visible = @view == "3D" endparam heading text = "The 'Delta DE' and 'Brute Force' methods do not use the analytical derivative of the fractal function." visible = (@potmeth == "Delta DE" || @potmeth == "Brute Force") endheading heading text = "Currently 'Delta DE' is not configured to work with any of the Phoenix or Spider fractal functions." visible = @potmeth == "Delta DE" endheading param potmeth caption = "Potential method" enum = "Iteration smoothing" "Delta DE" "Brute Force" default = 0 visible = @view == "3D" && !@special endparam param special caption = "Special potential" default = false visible = @view == "3D" && (@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) endparam heading text = "'Special potential' is a distance estimate type method which doesn't \ use derivatives. It was presented on Fractal Forums by Buddhi. The 'Alternate \ method' is a variant which is somewhat slower but usually gives a more \ detailed rendering. Make sure 'Include final scaling' is checked." visible = @view == "3D" && (@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) && \ @special endheading bool param alt caption = "Alternate method" default = true visible = @view == "3D" && (@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) && \ @special endparam float param delta caption = "delta" default = 1e-10 visible = @potmeth == "delta DE" && !@special endparam heading text = "Higher velocity values speed up the rendering, but they will also decrease \ the quality." visible = @view == "3D" && @potmeth == "Brute Force" endheading float param velocity caption = "Velocity" default = 20 visible = @view == "3D" && @potmeth == "Brute Force" hint = "The rate of the initial approach to the surface." endparam heading caption = "Cutting Plane" endheading heading text = "The starting and ending planes are defined by the X, Y and Z \ values referenced to the camera position and the plane of the \ screen. The cutting planes are applied after any rotations." endheading heading text = " Starting Plane" endheading float param mindistrqj caption = "X value" default = 0.0 hint = "This defines the cutting plane." endparam float param mindistiqj caption = "Y value" default = 0.0 hint = "This defines the cutting plane." endparam float param mindistqj caption = "Z value" default = 2.0 hint = "This defines the cutting plane." endparam heading text = " Ending Plane" visible = @view == "3D" endheading float param maxdistrqj caption = "X value" default = 0.0 hint = "This is the maximum distance from the cutting plane." visible = @view == "3D" endparam float param maxdistiqj caption = "Y value" default = 0.0 hint = "This is the maximum distance from the cutting plane." visible = @view == "3D" endparam float param maxdistqj caption = "Z value" default = 4.0 hint = "This is the maximum distance from the cutting plane." visible = @view == "3D" endparam } class REB_3DFractalRayTrace(common.ulb:Formula) { ; Based upon an article by Hart, Sandin and Kauffman for estimating ; the distance from a point to a fractal surface. The potential and ; gradient functions are based upon the exponential ; smoothing potential function. $define debug public: import "common.ulb" import "dmj5.ulb" ; import "transform.ulb" ; constructor func REB_3DFractalRayTrace(Generic pparent) Formula.Formula(pparent) maxzd = -1e100 minzd = 1e100 m_q = new @QuatClass(0) txf = new @transform(0) ; txf3d = new @transform3d(0) m_q.getjp(cri,cjk) m_julia = m_q.jtype() m_mand = m_q.mtype() m_quat = m_q.qtype() m_hyper = m_q.htype() m_brot = m_q.btype() m_spider = m_q.stype() m_oldz = m_q.ztype() m_sphere = m_q.sptype() if m_spider spidercri = cri spidercjk = cjk endif fourth = m_q.get4() ck = m_q.getck() int arrlength = (#width+1) * (#height+1) setLength(fracri, arrlength) setLength(fracjdist, arrlength) setLength(fdist, arrlength) setLength(fiter,arrlength) setLength(flr, arrlength) scrsize = sqrt(#width*#width+#height*#height) checkscale = 2/@checkscale if @v_3D_Fractal_Raytrace < 102 if !@altgrad maxstep = @maxstep else maxstep = 1e10 endif else maxstep = 1e10 endif zri = 0 zjk = 0 zrid = 0 zjkd = 0 oldzri = 0 oldzjk = 0 pow = 0 oldzri2 = 0 oldzjk2 = 0 rtemp = 0 vpr = 0 vpi = 0 vpj = 0 ; ray normal vr = 0 vi = 0 vj = 0 vd = 0 if @v_3D_Fractal_Raytrace < 103 camr = 0 cami = 0 else if @setzoom camr = real(#center)+@camr cami = imag(#center)+@cami else camr = @camr cami = @cami endif endif camj = @camj ucamr = 0 ucami = 0 ucamj = 0 modH = 0 modHold = 0 modHd = 0 d = 0 dist = 0 int i = 0 int j = 0 ; initialize the arrays while i < arrlength fracri[i] = (0,0) fracjdist[i] = (0,0) fdist[i] = 0 fiter[i] = 0 flr[i] = false i = i + 1 endwhile i = 0 fr = 0 fi = 0 infinity = true if @v_3D_Fractal_Raytrace < 102 if !@altgrad dfactor = @dfactor else dfactor = @dfactor*10 endif else dfactor = @dfactor endif epsilon = @epsilon/scrsize if @v_3D_Fractal_Raytrace > 100 epsilon = epsilon/#magn endif ci = imag(#center) cr = real(#center) trmax = 4.0/#magn timax = trmax*#height/#width rmin = cr - trmax/2 imax = ci + timax/2 ; light origin lpointx = @lpointx lpointy = @lpointy lpointz = @lplane ; light point at lightx = @lightx lighty = @lighty lightz = @lightz ; light vector if @ltype == "Infinite light" float d2r = #pi/180; degrees to radians conversion factor lx = -cos(@angle*d2r) * cos(-@elevation*d2r) ly = -sin(@angle*d2r) * cos(-@elevation*d2r) lz = sin(-@elevation*d2r) else lx = lightx-lpointx ly = lighty-lpointy lz = lightz-lpointz endif vd = sqrt(lx^2+ly^2+lz^2) lx = lx/vd ly = ly/vd lz = lz/vd xangle = -@xangle*#pi/180 yangle = @yangle*#pi/180 zrot = cos(#angle) + flip(sin(#angle)) temp = 0 im = (0,1) bailout = sqrt(@p_bailout) pot = 0 grad = 0 siter = 0 reduce = 0 fa = @fa fb = @fb fc = @fc fd = @fd*scrsize mindist = 0 mindistr = @mindistrqj mindisti = @mindistiqj mindistj = @mindistqj maxdist = 0 maxdistr = @maxdistrqj maxdisti = @maxdistiqj maxdistj = @maxdistqj camd = @camj mindistr = mindistr*camd mindisti = mindisti*camd maxdistr = maxdistr*camd maxdisti = maxdisti*camd firstpass = true bepsilon = 10*epsilon ; camera position ;rotate around x axis temp = cami cami = cami*cos(xangle)-camj*sin(xangle) camj = camj*cos(xangle)+temp*sin(xangle) ;rotate around y axis temp = camr camr = camr*cos(yangle)-camj*sin(yangle) camj = camj*cos(yangle)+temp*sin(yangle) ;rotate around z axis rtemp = camr + flip(cami) rtemp = rtemp*zrot camr = real(rtemp) cami = imag(rtemp) ; minimum distance position ;rotate around x axis temp = mindisti mindisti = mindisti*cos(xangle)-mindistj*sin(xangle) mindistj = mindistj*cos(xangle)+temp*sin(xangle) ;rotate around y axis temp = mindistr mindistr = mindistr*cos(yangle)-mindistj*sin(yangle) mindistj = mindistj*cos(yangle)+temp*sin(yangle) ;rotate around z axis rtemp = mindistr + flip(mindisti) rtemp = rtemp*zrot mindistr = real(rtemp) mindisti = imag(rtemp) ; maximum distance position ;rotate around x axis temp = maxdisti maxdisti = maxdisti*cos(xangle)-maxdistj*sin(xangle) maxdistj = maxdistj*cos(xangle)+temp*sin(xangle) ;rotate around y axis temp = maxdistr maxdistr = maxdistr*cos(yangle)-maxdistj*sin(yangle) maxdistj = maxdistj*cos(yangle)+temp*sin(yangle) ;rotate around z axis rtemp = maxdistr + flip(maxdisti) rtemp = rtemp*zrot maxdistr = real(rtemp) maxdisti = imag(rtemp) itercolor = 0 repeat repeat ; calculate screen position vpr = rmin + (fr*trmax)/#width vpi = imax - (fi*timax)/#height vpj = 0 ; unrotated position used for calcs fvpr = vpr fvpi = vpi fvpj = vpj ; screen position ; rotate around x axis temp = vpi vpi = vpi*cos(xangle)-vpj*sin(xangle) vpj = vpj*cos(xangle)+temp*sin(xangle) ; rotate around y axis temp = vpr vpr = vpr*cos(yangle)-vpj*sin(yangle) vpj = vpj*cos(yangle)+temp*sin(yangle) ; rotate around z axis rtemp = vpr + flip(vpi) rtemp = rtemp*zrot vpr = real(rtemp) vpi = imag(rtemp) ; create camera vector vr = camr-vpr vi = cami-vpi vj = camj-vpj vd = sqrt(vr*vr+vi*vi+vj*vj) vr = vr/vd vi = vi/vd vj = vj/vd mindist = mindistr*vr+mindisti*vi+mindistj*vj maxdist = maxdistr*vr+maxdisti*vi+maxdistj*vj ; distance camera correction if vd > mindist ucamr = camr-(vd-mindist)*vr ucami = cami-(vd-mindist)*vi ucamj = camj-(vd-mindist)*vj reduce = vd-mindist else ucamr = camr ucami = cami ucamj = camj reduce = 0 endif if @view == "3D" ; calculate distance from camera to quaternion zrid = 1 zjkd = 0 if (m_julia || m_brot) if fourth == 3 zri = ucamr + flip(ucami) zjk = ucamj + flip(ck) elseif fourth == 2 zri = ucamr + flip(ucami) zjk = flip(ucamj) + ck elseif fourth == 1 zri = ucamj + flip(ck) zjk = ucamr + flip(ucami) elseif fourth == 0 zri = flip(ucamj) + ck zjk = ucamr + flip(ucami) endif zrix = zri+@delta zjkx = zjk zriy = zri+flip(@delta) zjky = zjk zriz = zri zjkz = zjk+@delta zriw = zri zjkw = zjk+flip(@delta) elseif m_mand if fourth == 3 cri = ucamr + flip(ucami) cjk = ucamj + flip(ck) elseif fourth == 2 cri = ucamr + flip(ucami) cjk = flip(ucamj) + ck elseif fourth == 1 cri = ucamj + flip(ck) cjk = ucamr + flip(ucami) elseif fourth == 0 cri = flip(ucamj) + ck cjk = ucamr + flip(ucami) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) zrix = zri zjkx = zjk zriy = zri zjky = zjk zriz = zri zjkz = zjk zriw = zri zjkw = zjk endif i = 0 j = 0 dist = 0 infinity = true siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif if @potmeth == "Brute Force" firstpass = true bepsilon = epsilon*@velocity else firstpass = false endif repeat if @transform != NullTransform txf.init(zri) if !@xy txf.init(zjk) endif endif repeat if (i >= @prestart && i < (@prestart+@preend))&& \ @transform != NullTransform zri = (zri + txf.Iterate(zri)*@strength)/(1+@strength) if !@xy zjk = (zjk + txf.Iterate(zjk)*@strength)/(1+@strength) endif endif if m_oldz m_q.setomp(oldzri,oldzjk) endif ; calculate derivative if @v_3D_Fractal_Raytrace < 102 if @potmeth != "Brute Force" && !@altgrad && @potmeth != "delta DE" m_q.drcalc(zri, zjk, zrid, zjkd) endif elseif @v_3D_Fractal_Raytrace < 104 if @potmeth != "Brute Force" && @potmeth != "delta DE" m_q.drcalc(zri, zjk, zrid, zjkd) endif elseif (@potmeth != "Brute Force" && @potmeth != "delta DE" && \ (!(@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia || \ @noderiv) || @potmeth == "No iteration smoothing"))||\ (@v_3D_Fractal_Raytrace > 105 && !@special) m_q.drcalc(zri, zjk, zrid, zjkd) endif ; calculate fractal ; if @transform3D != NullTransform && i == 1 ; txf3D.init(zri,zjk) ; txf3D.iterate(zri,zjk) ; endif m_q.frcalc(zri, zjk) if @potmeth == "delta DE" if m_mand m_q.setjp(cri+@delta, cjk) endif m_q.frcalc(zrix, zjkx) if m_mand m_q.setjp(cri+flip(@delta), cjk) endif m_q.frcalc(zriy, zjky) if m_mand m_q.setjp(cri, cjk+@delta) endif m_q.frcalc(zriz, zjkz) if !m_sphere if m_mand m_q.setjp(cri, cjk+flip(@delta)) endif m_q.frcalc(zriw, zjkw) endif if m_mand m_q.setjp(cri,cjk) endif endif if m_spider m_q.getjp(cri,cjk) endif if m_oldz m_q.getomp(oldzri,oldzjk) endif if m_brot modh = cabs(zri) else modh = sqrt(|zri|+|zjk|) endif if @potmeth == "general smoothing" if m_brot modhold = cabs(oldzri-zri) else modhold = sqrt(|oldzri-zri|+|oldzjk-zjk|) endif siter = siter + exp(-modh-0.5/modhold) itercolor = siter endif i = i + 1 until i == #maxiter || (modh > bailout) if @potmeth == "Brute Force" itercolor = (i +log(log(modh))/log(2)) endif if (!(@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) \ || @v_3d_fractal_raytrace < 104) || (@v_3D_Fractal_Raytrace > 105 \ && !@special) if m_brot modhd = cabs(zrid) else modhd = sqrt(|zrid|+|zjkd|) endif if @potmeth == "Vepstas" siter = i + log(log(modh))/log(2) itercolor = siter endif if @potmeth == "Vepstas/Härkönen" pow = log(|zri - oldzri| + |zjk-oldzjk|)/log(|oldzri - oldzri2| + |oldzjk-oldzjk2|) siter = i + (log(log(bailout^2)) - log(log(1/(|zri - oldzri| + |zjk-oldzjk|))))/log(pow) itercolor = siter endif if modh <= bailout if @potmeth == "Brute Force" if firstpass dist = dist - bepsilon bepsilon = epsilon firstpass = false else d = 0 endif else dist = dist - d if @v_3D_fractal_raytrace < 102 if !@altgrad if olddfactor/@dadj == dfactor || @dadj == 1 d = 0 else olddfactor = dfactor dfactor = dfactor/@dadj endif else d = 0 endif else if olddfactor/@dadj == dfactor || @dadj == 1 d = 0 else olddfactor = dfactor dfactor = dfactor/@dadj endif endif endif else if @potmeth != "Brute Force" && @potmeth != "delta DE" && \ @potmeth != "no iteration smoothing" pot = exp(-siter*log(2)) ; itercolor = siter if @v_3d_fractal_raytrace < 102 if !@altgrad grad = pot*modhd/(modh*log(modh)) else grad = @gradadj*exp(-(siter-i)*log(2)) endif else if !@noderiv grad = pot*modhd/(modh*log(modh)) else grad = exp(-(siter-i)*log(2)) endif endif if @v_3d_fractal_raytrace < 102 if @limitgrad && !@constgrad if grad < @limvallow grad = @limvallow endif if grad > @limvalhigh grad = @limvalhigh endif endif if !@limitgrad && @constgrad grad = @gradval endif endif if !@noderiv d = dfactor*sinh(pot)/(2*exp(pot)*grad) else d = 10*dfactor*sinh(pot)/(2*exp(pot)*grad) endif elseif @potmeth == "no iteration smoothing" itercolor = i +log(log(modh))/log(2) d = modh*log(modh)/modhd*(dfactor/2)/log(2) elseif @potmeth == "delta DE" itercolor = i +log(log(modh))/log(2) float Rx = sqrt(|zrix|+|zjkx|) float Ry = sqrt(|zriy|+|zjky|) float Rz = sqrt(|zriz|+|zjkz|) float rw = 0 if !m_sphere Rw = sqrt(|zriw|+|zjkw|) endif float drx = (modh-rx)/@delta float dry = (modh-ry)/@delta float drz = (modh-rz)/@delta if !m_sphere float drw = (modh-rw)/@delta else float drw = 0 endif float dr = sqrt(drx^2+dry^2+drz^2+drw^2) d = modh*log(modh)/dr*(dfactor/2) else d = bepsilon*1.1 endif if d > maxstep d = maxstep endif dist = d + dist endif elseif @special ; mandelbox, conformal mandelbox, hybridmandelbox if modh <= bailout dist = dist - d if olddfactor/@dadj == dfactor || @dadj == 1 d = 0 else olddfactor = dfactor dfactor = dfactor/@dadj endif else ; real(m_q.getspecial()) retrieves spec siter = i + log(log(real(m_q.getspecial())))/log(2) itercolor = siter if @alt pot = exp(-siter*log(2)) grad = exp(-(siter-i)*log(2)) d = 10*dfactor*sinh(pot)/(2*exp(pot)*grad) else d = 100*dfactor*exp(-siter) endif dist = d + dist endif endif zrid = 1 zjkd = 0 if m_julia || m_brot if fourth == 3 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 zri = ucamj-dist*vj + flip(ck) zjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 zri = flip(ucamj-dist*vj) + ck zjk = ucamr-dist*vr + flip(ucami-dist*vi) endif zrix = zri+@delta zjkx = zjk zriy = zri-flip(@delta) zjky = zjk zriz = zri zjkz = zjk+@delta zriw = zri zjkw = zjk+flip(@delta) elseif m_mand if fourth == 3 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 cri = ucamj-dist*vj + flip(ck) cjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 cri = flip(ucamj-dist*vj) + ck cjk = ucamr-dist*vr + flip(ucami-dist*vi) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) zrix = zri zjkx = zjk zriy = zri zjky = zjk zriz = zri zjkz = zjk zriw = zri zjkw = zjk endif j = j + 1 i = 0 siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif until (d <= epsilon || dist > maxdist) && \ (firstpass == false || dist > maxdist) if (dist > 0 && dist <= maxdist) || d == 0 infinity = false endif if !infinity ; set the intersection point and distance fracri[idx(fr,fi)] = camr-(dist+reduce)*vr + flip(cami-(dist+reduce)*vi) if dist != 0 fracjdist[idx(fr,fi)] = camj-(dist+reduce)*vj + flip((dist+reduce)) fiter[idx(fr,fi)] = itercolor else fracjdist[idx(fr,fi)] = camj-(dist+reduce)*vj + flip((1)) fdist[idx(fr,fi)] = dist+reduce fiter[idx(fr,fi)] = itercolor endif endif endif if real(fracjdist[idx(fr,fi)]) > maxzd maxzd = real(fracjdist[idx(fr,fi)]) endif if real(fracjdist[idx(fr,fi)]) < minzd minzd = real(fracjdist[idx(fr,fi)]) endif if @floor ; create unrotated camera vector vr = -fvpr vi = -fvpi vj = @camj-fvpj vd = sqrt(vr*vr+vi*vi+vj*vj) vr = vr/vd vi = vi/vd vj = vj/vd ; floor normal lxtf = fa lytf = fb lztf = fc vd = 1/sqrt(lxtf*lxtf+lytf*lytf+lztf*lztf) lxtf = lxtf*vd lytf = lytf*vd lztf = lztf*vd ; dot product with ray origin ortheta = lztf*@camj ; dot product with camera vector dirtheta = lxtf*vr+lytf*vi+lztf*vj ; distance from camera to intersection td = -(ortheta+fd)/dirtheta/scrsize ; intersection point with camera ray ld = 0 if td > 0 xf = vr*td yf = vi*td zf = @camj-vj*td if td < imag(fracjdist[idx(fr,fi)])|| cabs(fracri[idx(fr,fi)]) == 0 fracri[idx(fr,fi)] = xf + flip(yf) flr[idx(fr,fi)] = true fracjdist[idx(fr,fi)] = zf + flip(-4) fp = (lytf+lztf)*xf + lxtf*yf + \ flip((lxtf+lytf)*zf + lztf*yf)+ \ real(@poffset) + flip(imag(@poffset)) ; vector from light to point on floor xlf = lpointx - xf ylf = lpointy - yf zlf = lpointz - zf vd = 1/sqrt(xlf*xlf+ylf*ylf+zlf*zlf) xlf = xlf*vd ylf = ylf*vd zlf = -zlf*vd ld = vd^@fade*(xlf*lx+ylf*ly+zlf*lz)*@dis*scrsize*10*20^(@fade-3) ; have floor fade according to lighting model if @ltype == "Point source" if ld >= 1 ld = 0.99 endif if ld < 0 ld = 0 endif else ld = 0.99 endif if @flrtype == "Checkerboard" fp = floor(fp*checkscale) if ((real(fp) + imag(fp)) % 2 == 0) fracjdist[idx(fr,fi)] = zf + flip(-4-ld) else fracjdist[idx(fr,fi)] = zf + flip(-5-ld) endif else fracjdist[idx(fr,fi)] = zf + flip(-4-ld) endif endif endif endif fr = fr + 1 until fr == #width fr = 0 fi = fi + 1 until fi == #height zd = maxzd - minzd endfunc ; initialize the formula complex func Init(complex pz) Formula.Init(pz) if @v_3D_Fractal_Raytrace < 102 if !@altgrad sdfactor = @dfactor else sdfactor = @dfactor*10 endif else sdfactor = @dfactor endif float svpr = 0 float svpi = 0 float svpj = 0 float svr = 0 float svi = 0 float svj = 0 float svd = 0 float stemp = 0 iii = 0 mycolor = 0 bool shad = false int xcrd = #x int ycrd = #y complex srtemp = 0 szri = 0 szjk = 0 oldszri = 0 oldszjk = 0 oldszri2 = 0 oldszjk2 = 0 sztemp = 0 szrid = 0 szjkd = 0 smodH = 0 smodHold = 0 float smodHd = 0 float sdist = 0 float sgrad = 0 float spot = 0 float sreduce = 0 float smindist = 0 float smindistr = mindistr float smindisti = mindisti float smindistj = mindistj float sd = 0 float ssiter = 0 int sj = 0 int si = 0 ; light origin float lightr = 0 float lighti = 0 float lightj = 0 if @ltype == "Infinite Light" ; assumes light points at (0,0,0) lightr = -lx*camj lighti = -ly*camj lightj = -lz*camj else lightr = lpointx lighti = lpointy lightj = lpointz endif float ulightr = 0 float ulighti = 0 float ulightj = 0 float slr = 0 float sli = 0 float slj = 0 float sld = 0 float l = 0 float svr = 0 float svi = 0 float svj = 0 float svd = 0 float rr = 0 float ri = 0 float rj = 0 float ir = 0 float ii = 0 float ij = 0 float nr = 0 float ni = 0 float nj = 0 complex fri = 0 complex frj = 0 float n = 0 bool sfirstpass = false float sbepsilon = 0 ; generate the x and y location in the image float dxx = (real(#pixel)-real(#center))*(#width)/4*#magn float dyy = (imag(#pixel)-imag(#center))*(#width)/4*#magn float transx = (#width)*0.5; float transy = (#height)*0.5; float cosan = cos(#angle); float sinan = sin(#angle); xcrd = round((transx + (dxx*cosan + dyy*sinan))) ycrd = round((transy + (dxx*sinan - dyy*cosan))) if @view == "3D" && imag(fracjdist[idx(xcrd,ycrd)]) > -3 if xcrd <#width-1 && ycrd <#height-1 && xcrd > 0 && \ ycrd > 0 ; calculate the normals fri = fracri[idx(xcrd,ycrd)] frj = real(fracjdist[idx(xcrd,ycrd)]) rr = real(fracri[idx(xcrd+1,ycrd)]-fri) ri = imag(fracri[idx(xcrd+1,ycrd)]-fri) rj = real(fracjdist[idx(xcrd+1,ycrd)]-frj) n = sqrt(rr^2+ri^2+rj^2) rr = rr/n ri = ri/n rj = rj/n ir = real(fracri[idx(xcrd,ycrd+1)]-fri) ii = imag(fracri[idx(xcrd,ycrd+1)]-fri) ij = real(fracjdist[idx(xcrd,ycrd+1)]-frj) n = sqrt(ir^2+ii^2+ij^2) ir = ir/n ii = ii/n ij = ij/n nr = ri*ij - rj*ii ni = rj*ir - rr*ij nj = rr*ii - ri*ir rr = real(fracri[idx(xcrd-1,ycrd)]-fri) ri = imag(fracri[idx(xcrd-1,ycrd)]-fri) rj = real(fracjdist[idx(xcrd-1,ycrd)]-frj) n = sqrt(rr^2+ri^2+rj^2) rr = rr/n ri = ri/n rj = rj/n ir = real(fracri[idx(xcrd,ycrd-1)]-fri) ii = imag(fracri[idx(xcrd,ycrd-1)]-fri) ij = real(fracjdist[idx(xcrd,ycrd-1)]-frj) n = sqrt(ir^2+ii^2+ij^2) ir = ir/n ii = ii/n ij = ij/n nr = (nr+ri*ij - rj*ii)/2 ni = (ni+rj*ir - rr*ij)/2 nj = (nj+rr*ii - ri*ir)/2 float ntemp = 0 ; rotate around z axis in opposite direction from other z axis ; rotations srtemp = nr + flip(ni) srtemp = srtemp*conj(zrot) nr = real(srtemp) ni = imag(srtemp) ; rotate around y axis ntemp = nr nr = nr*cos(yangle)+nj*sin(yangle) nj = nj*cos(yangle)-ntemp*sin(yangle) ; rotate around x axis ntemp = ni ni = ni*cos(xangle)+nj*sin(xangle) nj = nj*cos(xangle)-ntemp*sin(xangle) n = sqrt(nr^2+ni^2+nj^2) nr = nr/n ni = ni/n nj = nj/n ; l = abs(lx*nr + ly*ni + lz*nj) l = lx*nr + ly*ni + lz*nj if isNAN(l) l = 0 endif ; if isInf(l) ; l = 1 ; endif ; if l < 0 ; this corrects for l being not a number (NAN) ; l = 0 ; endif endif ; shadows on the fractal object if @shadows &&((imag(fracjdist[idx(xcrd,ycrd)]) > 0 && imag(fracjdist[idx(xcrd,ycrd)])-reduce\ <= maxdist)) shad = false ; calculate light vector ; rotate around x axis ntemp = lighti lighti = lighti*cos(xangle)-lightj*sin(xangle) lightj = lightj*cos(xangle)+ntemp*sin(xangle) ; rotate around y axis ntemp = lightr lightr = lightr*cos(yangle)-lightj*sin(yangle) lightj = lightj*cos(yangle)+ntemp*sin(yangle) ; rotate around z axis srtemp = lightr + flip(lighti) srtemp = srtemp*zrot lightr = real(srtemp) lighti = imag(srtemp) slr = lightr - real(fracri[idx(xcrd,ycrd)]) sli = lighti - imag(fracri[idx(xcrd,ycrd)]) slj = lightj - real(fracjdist[idx(xcrd,ycrd)]) sld = sqrt(slr^2+sli^2+slj^2) slr = slr/sld sli = sli/sld slj = slj/sld svr = camr-real(fracri[idx(xcrd,ycrd)]) svi = cami-imag(fracri[idx(xcrd,ycrd)]) svj = camj-real(fracjdist[idx(xcrd,ycrd)]) svd = sqrt(svr*svr+svi*svi+svj*svj) svr = svr/svd svi = svi/svd svj = svj/svd smindist = (smindistr*svr+smindisti*svi+smindistj*svj) if sld >= smindist ulightr = lightr - (sld-smindist)*slr ulighti = lighti - (sld-smindist)*sli ulightj = lightj - (sld-smindist)*slj sreduce = sld-smindist else ulightr = lightr ulighti = lighti ulightj = lightj sreduce = 0 endif szrid = 1 szjkd = 0 if m_julia || m_brot if fourth == 3 szri = ulightr + flip(ulighti) szjk = ulightj + flip(ck) elseif fourth == 2 szri = ulightr + flip(ulighti) szjk = flip(ulightj) + ck elseif fourth == 1 szri = ulightj + flip(ck) szjk = ulightr + flip(ulighti) elseif fourth == 0 szri = flip(ulightj) + ck szjk = ulightr + flip(ulighti) endif szrix = szri+@delta szjkx = szjk szriy = szri+flip(@delta) szjky = szjk szriz = szri szjkz = szjk+@delta szriw = szri szjkw = szjk+flip(@delta) elseif m_mand if fourth == 3 scri = ulightr + flip(ulighti) scjk = ulightj + flip(ck) elseif fourth == 2 scri = ulightr + flip(ulighti) scjk = flip(ulightj) + ck elseif fourth == 1 scri = ulightj + flip(ck) scjk = ulightr + flip(ulighti) elseif fourth == 0 scri = flip(ulightj) + ck scjk = ulightr + flip(ulighti) endif m_q.setjp(scri,scjk) m_q.getmp(szri,szjk) szrix = szri szjkx = szjk szriy = szri szjky = szjk szriz = szri szjkz = szjk szriw = szri szjkw = szjk endif si = 0 sj = 0 sdist = 0 ssiter = 0 oldszri2 = oldszri oldszjk2 = oldszjk oldszri = szri oldszjk = szjk if m_spider scri = spidercri scjk = spidercjk m_q.setjp(scri,scjk) endif if @potmeth == "Brute Force" sfirstpass = true sbepsilon = epsilon*@velocity else sfirstpass = false endif repeat if @transform != NullTransform txf.init(szri) if !@xy txf.init(szjk) endif endif repeat if (si >= @prestart && si < (@prestart+@preend))&& \ @transform != NullTransform szri = (szri + txf.Iterate(szri)*@strength)/(1+@strength) if !@xy szjk = (szjk + txf.Iterate(szjk)*@strength)/(1+@strength) endif endif if m_oldz m_q.setomp(oldszri,oldszjk) endif ; calculate derivative if @v_3D_Fractal_Raytrace < 102 if @potmeth != "Brute Force" && !@altgrad && @potmeth != "delta DE" m_q.drcalc(szri, szjk, szrid, szjkd) endif elseif @v_3D_Fractal_Raytrace < 104 if @potmeth != "Brute Force" && @potmeth != "delta DE" m_q.drcalc(szri, szjk, szrid, szjkd) endif elseif (@potmeth != "Brute Force" && @potmeth != "delta DE" && \ (!(@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia || \ @noderiv) || @potmeth == "No iteration smoothing"))||\ (@v_3D_Fractal_Raytrace > 105 && !@special) m_q.drcalc(szri, szjk, szrid, szjkd) endif ; calculate fractal m_q.frcalc(szri,szjk) if @potmeth == "delta DE" if m_mand m_q.setjp(scri+@delta, scjk) endif m_q.frcalc(szrix, szjkx) if m_mand m_q.setjp(scri+flip(@delta), scjk) endif m_q.frcalc(szriy, szjky) if m_mand m_q.setjp(scri, scjk+@delta) endif m_q.frcalc(szriz, szjkz) if !m_sphere if m_mand m_q.setjp(scri, scjk+flip(@delta)) endif m_q.frcalc(szriw, szjkw) endif if m_mand m_q.setjp(scri,scjk) endif endif if m_oldz m_q.getomp(oldszri,oldszjk) endif if m_spider m_q.getjp(scri,scjk) endif if m_brot smodh = cabs(szri) else smodh = sqrt(|szri|+|szjk|) endif if @potmeth == "general smoothing" if m_brot smodhold = cabs(oldszri-szri) else smodhold = sqrt(|oldszri-szri|+|oldszjk-szjk|) endif ssiter = ssiter + exp(-smodh-0.5/smodhold) endif si = si + 1 until si == #maxiter || smodh > bailout if (!(@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) \ || @v_3d_fractal_raytrace < 104) || (@v_3D_Fractal_Raytrace > 105 \ && !@special) if m_brot smodhd = cabs(szrid) else smodhd = sqrt(|szrid|+|szjkd|) endif if @potmeth == "Vepstas" ssiter = si+log(log(smodh))/log(2) endif if @potmeth == "Vepstas/Härkönen" pow = log(|szri - oldszri| + |szjk-oldszjk|)/log(|oldszri - oldszri2| + |oldszjk-oldszjk2|) ssiter = si + (log(log(bailout^2)) - log(log(1/(|szri - oldszri| + |szjk-oldszjk|))))/log(pow) endif if smodh <= bailout if @potmeth == "Brute Force" if sfirstpass sdist = sdist - sbepsilon sbepsilon = epsilon sfirstpass = false else sd = 0 endif else sdist = sdist - sd if @v_3d_fractal_raytrace < 102 if !@altgrad if oldsdfactor/@dadj == sdfactor || @dadj == 1 sd = 0 else oldsdfactor = sdfactor sdfactor = sdfactor/@dadj endif else sd = 0 endif else if oldsdfactor/@dadj == sdfactor || @dadj == 1 sd = 0 else oldsdfactor = sdfactor sdfactor = sdfactor/@dadj endif endif endif else if @potmeth != "Brute Force" && @potmeth != "delta DE" && @potmeth != "no iteration smoothing" spot = exp(-ssiter*log(2)) if @v_3d_fractal_raytrace < 102 if !@altgrad sgrad = spot*smodhd/(smodh*log(smodh)) else sgrad = @gradadj*exp(-(ssiter-si)*log(2)) endif else if !@noderiv sgrad = spot*smodhd/(smodh*log(smodh)) else sgrad = exp(-(ssiter-si)*log(2)) endif endif if @v_3d_fractal_raytrace < 102 if @limitgrad && !@constgrad if sgrad < @limvallow sgrad = @limvallow endif if sgrad > @limvalhigh sgrad = @limvalhigh endif endif if !@limitgrad && @constgrad sgrad = @gradval endif endif if !@noderiv sd = sdfactor*sinh(spot)/(2*exp(spot)*sgrad) else sd = 10*sdfactor*sinh(spot)/(2*exp(spot)*sgrad) endif elseif @potmeth == "no iteration smoothing" sd = smodh*log(smodh)/smodhd*(sdfactor/2) elseif @potmeth == "delta DE" float Rx = sqrt(|szrix|+|szjkx|) float Ry = sqrt(|szriy|+|szjky|) float Rz = sqrt(|szriz|+|szjkz|) float rw = 0 if !m_sphere Rw = sqrt(|szriw|+|szjkw|) endif float drx = (smodh-rx)/@delta float dry = (smodh-ry)/@delta float drz = (smodh-rz)/@delta if !m_sphere float drw = (smodh-rw)/@delta else float drw = 0 endif float dr = sqrt(drx^2+dry^2+drz^2+drw^2) sd = smodh*log(smodh)/dr*(sdfactor/2) else sd = sbepsilon*1.1 endif if sd > maxstep sd = maxstep endif sdist = sd + sdist endif elseif @special if smodh <= bailout sdist = sdist - sd if oldsdfactor/@dadj == sdfactor || @dadj == 1 sd = 0 else oldsdfactor = sdfactor sdfactor = sdfactor/@dadj endif else ssiter = si + log(log(real(m_q.getspecial())))/log(2) if @alt pot = exp(-ssiter*log(2)) grad = exp(-(ssiter-si)*log(2)) sd = 10*dfactor*sinh(pot)/(2*exp(pot)*grad) else sd = 100*dfactor*exp(-ssiter) endif sdist = sd + sdist endif endif szrid = 1 szjkd = 0 if m_julia || m_brot if fourth == 3 szri = ulightr-sdist*slr + flip(ulighti-sdist*sli) szjk = ulightj-sdist*slj + flip(ck) elseif fourth == 2 szri = ulightr-sdist*slr + flip(ulighti-sdist*sli) szjk = flip(ulightj-sdist*slj) + ck elseif fourth == 1 szri = ulightj-sdist*slj + flip(ck) szjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) elseif fourth == 0 szri = flip(ulightj-sdist*slj) + ck szjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) endif szrix = szri+@delta szjkx = szjk szriy = szri+flip(@delta) szjky = szjk szriz = szri szjkz = szjk+@delta szriw = szri szjkw = szjk+flip(@delta) elseif m_mand if fourth == 3 scri = ulightr-sdist*slr + flip(ulighti-sdist*sli) scjk = ulightj-sdist*slj + flip(ck) elseif fourth == 2 scri = ulightr-sdist*slr + flip(ulighti-sdist*sli) scjk = flip(ulightj-sdist*slj) + ck elseif fourth == 1 scri = ulightj-sdist*slj + flip(ck) scjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) elseif fourth == 0 scri = flip(ulightj-sdist*slj) + ck scjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) endif m_q.setjp(scri,scjk) m_q.getmp(szri,szjk) szrix = szri szjkx = szjk szriy = szri szjky = szjk szriz = szri szjkz = szjk szriw = szri szjkw = szjk endif sj = sj + 1 si = 0 oldszri2 = oldszri oldszjk2 = oldszjk oldszri = szri oldszjk = szjk if m_spider scri = spidercri scjk = spidercjk m_q.setjp(scri,scjk) endif ssiter = 0 until (sd <= @objshadsens*epsilon || sdist > maxdist) if sreduce != 0 sdist = sdist+sreduce endif if sdist < sld*@srough && sd <= @objshadsens*epsilon && imag(fracjdist[idx(xcrd,ycrd)]) != 1 shad = true endif endif mycolor = l*#maxiter/2 if (imag(fracjdist[idx(xcrd,ycrd)]) != 0) || (imag(fracjdist[idx(xcrd,ycrd)])-reduce <= maxdist) \ || imag(fracjdist[idx(xcrd,ycrd)]) == 1 if @type == "Raytrace" pz = l + flip(imag(fracjdist[idx(xcrd,ycrd)])) if imag(fracjdist[idx(xcrd,ycrd)]) == 1 pz = l + flip(fdist[idx(xcrd,ycrd)]) endif elseif @type == "Distance" if imag(fracjdist[idx(xcrd,ycrd)]) == 1 if @ray pz = fdist[idx(xcrd,ycrd)]+ l/2 else pz = fdist[idx(xcrd,ycrd)] endif else if @ray pz = imag(fracjdist[idx(xcrd,ycrd)])+ l/2 else pz = imag(fracjdist[idx(xcrd,ycrd)]) endif endif elseif @type == "Z value" if @v_3D_Fractal_Raytrace >= 105 float nx= real(fdist[idx(xcrd,ycrd)]) float ny = imag(fdist[idx(xcrd,ycrd)]) float nz = 0 if @corzd && imag(fracjdist[idx(xcrd,ycrd)]) != 0 nz= (real(fracjdist[idx(xcrd,ycrd)])-minzd)/zd else nz= real(fracjdist[idx(xcrd,ycrd)]) endif float ntemp = nx nx= nx*cos(yangle)+nz*sin(yangle) nz = nz*cos(yangle)-ntemp*sin(yangle) ntemp = ny ny = ny*cos(xangle)+nz*sin(xangle) nz = nz*cos(xangle)-ntemp*sin(xangle) if imag(fracjdist[idx(xcrd,ycrd)]) == 1 if @ray pz = nx + flip(ny) + l/2 else pz = nx + flip(ny) endif else if @ray pz = abs(nz) + l/2 else pz = abs(nz) endif endif else if imag(fracjdist[idx(xcrd,ycrd)]) == 1 pz = fdist[idx(xcrd,ycrd)] + flip(l) else pz = abs(sqrt(camr^2+cami^2 + camj^2)- imag(fracjdist[idx(xcrd,ycrd)])) + flip(l) endif endif elseif @type == "Iteration" if imag(fracjdist[idx(xcrd,ycrd)]) == 1 if @v_3d_fractal_raytrace < 106 pz = (fdist[idx(xcrd,ycrd)]) + flip(l) else if @ray pz = trunc(l*1e6/2) + fiter[idx(xcrd,ycrd)]/1e6 else pz = fiter[idx(xcrd,ycrd)]/1e6 endif endif else if @v_3d_fractal_raytrace < 106 pz = (imag(fracjdist[idx(xcrd,ycrd)])) + flip(l) else if @ray pz = trunc(l*1e6/2) + fiter[idx(xcrd,ycrd)]/1e6 else pz = fiter[idx(xcrd,ycrd)]/1e6 endif endif endif endif endif if cabs(pz) != 0 if @type == "Raytrace" pz = real(pz) + (0,-1) if shad pz = real(pz) + (0,-2) endif elseif @type == "Distance" || @type == "Z value" pz = real(pz) + (0,1) elseif @type == "Iteration" pz = real(pz) + (0,2) endif endif ; shadows on the floor elseif @view == "3D" && imag(fracjdist[idx(xcrd,ycrd)]) <= -3 sdfactor = @dfactor if @shadows shad = false if @ltype == "Infinite Light" ; assumes light points at (0,0,0) lightr = -lx*camj lighti = -ly*camj lightj = -lz*camj else lightr = lpointx lighti = lpointy lightj = lpointz endif ; calculate light vector slr = lightr - (rmin + (xcrd*trmax)/#width) sli = lighti - (imax - (ycrd*timax)/#height) slj = lightj - real(fracjdist[idx(xcrd,ycrd)]) ; rotate around x axis ntemp = sli sli = sli*cos(xangle)-slj*sin(xangle) slj = slj*cos(xangle)+ntemp*sin(xangle) ; rotate around y axis ntemp = slr slr = slr*cos(yangle)-slj*sin(yangle) slj = slj*cos(yangle)+ntemp*sin(yangle) ; rotate around z axis srtemp = slr + flip(sli) srtemp = srtemp*zrot slr = real(srtemp) sli = imag(srtemp) sld = sqrt(slr^2+sli^2+slj^2) slr = slr/sld sli = sli/sld slj = slj/sld ; rotate around x axis ntemp = lighti lighti = lighti*cos(xangle)-lightj*sin(xangle) lightj = lightj*cos(xangle)+ntemp*sin(xangle) ; rotate around y axis ntemp = lightr lightr = lightr*cos(yangle)-lightj*sin(yangle) lightj = lightj*cos(yangle)+ntemp*sin(yangle) ; rotate around z axis srtemp = lightr + flip(lighti) srtemp = srtemp*zrot lightr = real(srtemp) lighti = imag(srtemp) ulightr = lightr ulighti = lighti ulightj = lightj szrid = 1 szjkd = 0 if m_julia || m_brot if fourth == 3 szri = ulightr + flip(ulighti) szjk = ulightj + flip(ck) elseif fourth == 2 szri = ulightr + flip(ulighti) szjk = flip(ulightj) + ck elseif fourth == 1 szri = ulightj + flip(ck) szjk = ulightr + flip(ulighti) elseif fourth == 0 szri = flip(ulightj) + ck szjk = ulightr + flip(ulighti) endif szrix = szri+@delta szjkx = szjk szriy = szri+flip(@delta) szjky = szjk szriz = szri szjkz = szjk+@delta szriw = szri szjkw = szjk+flip(@delta) elseif m_mand if fourth == 3 scri = ulightr + flip(ulighti) scjk = ulightj + flip(ck) elseif fourth == 2 scri = ulightr + flip(ulighti) scjk = flip(ulightj) + ck elseif fourth == 1 scri = ulightj + flip(ck) scjk = ulightr + flip(ulighti) elseif fourth == 0 scri = flip(ulightj) + ck scjk = ulightr + flip(ulighti) endif m_q.setjp(scri,scjk) m_q.getmp(szri,szjk) szrix = szri szjkx = szjk szriy = szri szjky = szjk szriz = szri szjkz = szjk szriw = szri szjkw = szjk endif si = 0 sj = 0 sdist = 0 ssiter = 0 oldszri2 = oldszri oldszjk2 = oldszjk oldszri = szri oldszjk = szjk if m_spider scri = spidercri scjk = spidercjk m_q.setjp(scri,scjk) endif if @potmeth == "Brute Force" sfirstpass = true sbepsilon = epsilon*@velocity else sfirstpass = false endif repeat if @transform != NullTransform txf.init(szri) if !@xy txf.init(szjk) endif endif repeat if (si >= @prestart && si < (@prestart+@preend))&& \ @transform != NullTransform szri = (szri + txf.Iterate(szri)*@strength)/(1+@strength) if !@xy szjk = (szjk + txf.Iterate(szjk)*@strength)/(1+@strength) endif endif if m_oldz m_q.setomp(oldszri,oldszjk) endif ; calculate derivative if @v_3D_Fractal_Raytrace < 102 if @potmeth != "Brute Force" && !@altgrad && @potmeth != "delta DE" m_q.drcalc(szri, szjk, szrid, szjkd) endif elseif @v_3D_Fractal_Raytrace < 104 if @potmeth != "Brute Force" && @potmeth != "delta DE" m_q.drcalc(szri, szjk, szrid, szjkd) endif elseif (@potmeth != "Brute Force" && @potmeth != "delta DE" && \ (!(@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia || \ @noderiv) || @potmeth == "No iteration smoothing"))||\ (@v_3D_Fractal_Raytrace > 105 && !@special) m_q.drcalc(szri, szjk, szrid, szjkd) endif ; calculate fractal m_q.frcalc(szri,szjk) if @potmeth == "delta DE" if m_mand m_q.setjp(scri+@delta, scjk) endif m_q.frcalc(szrix, szjkx) if m_mand m_q.setjp(scri+flip(@delta), scjk) endif m_q.frcalc(szriy, szjky) if m_mand m_q.setjp(scri, scjk+@delta) endif m_q.frcalc(szriz, szjkz) if !m_sphere if m_mand m_q.setjp(scri, scjk+flip(@delta)) endif m_q.frcalc(szriw, szjkw) endif if m_mand m_q.setjp(scri,scjk) endif endif if m_oldz m_q.getomp(oldszri,oldszjk) endif if m_spider m_q.getjp(scri,scjk) endif if m_brot smodh = cabs(szri) else smodh = sqrt(|szri|+|szjk|) endif if @potmeth == "general smoothing" if m_brot smodhold = cabs(oldszri-szri) else smodhold = sqrt(|oldszri-szri|+|oldszjk-szjk|) endif ssiter = ssiter + exp(-smodh-0.5/smodhold) endif si = si + 1 until si == #maxiter || smodh > bailout if (!(@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) \ || @v_3d_fractal_raytrace < 104) || (@v_3D_Fractal_Raytrace > 105 \ && !@special) if m_brot smodhd = cabs(szrid) else smodhd = sqrt(|szrid|+|szjkd|) endif if @potmeth == "Vepstas" ssiter = si+log(log(smodh))/log(2) endif if @potmeth == "Vepstas/Härkönen" pow = log(|szri - oldszri| + |szjk-oldszjk|)/log(|oldszri - oldszri2| + |oldszjk-oldszjk2|) ssiter = si + (log(log(bailout^2)) - log(log(1/(|szri - oldszri| + |szjk-oldszjk|))))/log(pow) endif if smodh <= bailout if @potmeth == "Brute Force" if sfirstpass sdist = sdist - sbepsilon sbepsilon = epsilon sfirstpass = false else sd = 0 endif else sdist = sdist - sd if @v_3d_fractal_raytrace < 102 if !@altgrad if oldsdfactor/@dadj == sdfactor || @dadj == 1 sd = 0 else oldsdfactor = sdfactor sdfactor = sdfactor/@dadj endif else sd = 0 endif else if oldsdfactor/@dadj == sdfactor || @dadj == 1 sd = 0 else oldsdfactor = sdfactor sdfactor = sdfactor/@dadj endif endif endif else if @potmeth != "Brute Force" && @potmeth != "delta DE" && @potmeth != "no iteration smoothing" spot = exp(-ssiter*log(2)) if @v_3d_fractal_raytrace < 102 if !@altgrad sgrad = spot*smodhd/(smodh*log(smodh)) else sgrad = @gradadj*exp(-(ssiter-si)*log(2)) endif else if !@noderiv sgrad = spot*smodhd/(smodh*log(smodh)) else sgrad = exp(-(ssiter-si)*log(2)) endif endif if @v_3d_fractal_raytrace < 102 if @limitgrad && !@constgrad if sgrad < @limvallow sgrad = @limvallow endif if sgrad > @limvalhigh sgrad = @limvalhigh endif endif if !@limitgrad && @constgrad sgrad = @gradval endif endif if !@noderiv sd = sdfactor*sinh(spot)/(2*exp(spot)*sgrad) else sd = 10*sdfactor*sinh(spot)/(2*exp(spot)*sgrad) endif elseif @potmeth == "no iteration smoothing" sd = smodh*log(smodh)/smodhd*(sdfactor/2) elseif @potmeth == "delta DE" float Rx = sqrt(|szrix|+|szjkx|) float Ry = sqrt(|szriy|+|szjky|) float Rz = sqrt(|szriz|+|szjkz|) float rw = 0 if !m_sphere Rw = sqrt(|szriw|+|szjkw|) endif float drx = (smodh-rx)/@delta float dry = (smodh-ry)/@delta float drz = (smodh-rz)/@delta if !m_sphere float drw = (smodh-rw)/@delta else float drw = 0 endif float dr = sqrt(drx^2+dry^2+drz^2+drw^2) sd = smodh*log(smodh)/dr*(sdfactor/2) else sd = sbepsilon*1.1 endif if sd > maxstep sd = maxstep endif sdist = sd + sdist endif elseif @special if smodh <= bailout sdist = sdist - sd if oldsdfactor/@dadj == sdfactor || @dadj == 1 sd = 0 else oldsdfactor = sdfactor sdfactor = sdfactor/@dadj endif else ssiter = si + log(log(real(m_q.getspecial())))/log(2) if @alt pot = exp(-ssiter*log(2)) grad = exp(-(ssiter-si)*log(2)) sd = 10*dfactor*sinh(pot)/(2*exp(pot)*grad) else sd = 100*dfactor*exp(-ssiter) endif sdist = sd + sdist endif endif szrid = 1 szjkd = 0 if m_julia || m_brot if fourth == 3 szri = ulightr-sdist*slr + flip(ulighti-sdist*sli) szjk = ulightj-sdist*slj + flip(ck) elseif fourth == 2 szri = ulightr-sdist*slr + flip(ulighti-sdist*sli) szjk = flip(ulightj-sdist*slj) + ck elseif fourth == 1 szri = ulightj-sdist*slj + flip(ck) szjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) elseif fourth == 0 szri = flip(ulightj-sdist*slj) + ck szjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) endif szrix = szri+@delta szjkx = szjk szriy = szri+flip(@delta) szjky = szjk szriz = szri szjkz = szjk+@delta szriw = szri szjkw = szjk+flip(@delta) elseif m_mand if fourth == 3 scri = ulightr-sdist*slr + flip(ulighti-sdist*sli) scjk = ulightj-sdist*slj + flip(ck) elseif fourth == 2 scri = ulightr-sdist*slr + flip(ulighti-sdist*sli) scjk = flip(ulightj-sdist*slj) + ck elseif fourth == 1 scri = ulightj-sdist*slj + flip(ck) scjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) elseif fourth == 0 scri = flip(ulightj-sdist*slj) + ck scjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) endif m_q.setjp(scri,scjk) m_q.getmp(szri,szjk) szrix = szri szjkx = szjk szriy = szri szjky = szjk szriz = szri szjkz = szjk szriw = szri szjkw = szjk endif sj = sj + 1 si = 0 oldszri2 = oldszri oldszjk2 = oldszjk oldszri = szri oldszjk = szjk ssiter = 0 if m_spider scri = spidercri scjk = spidercjk m_q.setjp(scri,scjk) endif until (sd <= @floorshadsens*epsilon || sdist > sld) && \ (sfirstpass == false || sdist > maxdist) if sdist < sld&& sd <= @floorshadsens*epsilon shad = true endif endif elseif @view == "2D"; initialize 2D parameters svpr = rmin + (xcrd*trmax)/#width svpi = imax - (ycrd*timax)/#height svpj = 0 ; rotate around x axis stemp = svpi svpi = svpi*cos(xangle)-svpj*sin(xangle) svpj = svpj*cos(xangle)+stemp*sin(xangle) ; rotate around y axis stemp = svpr svpr = svpr*cos(yangle)-svpj*sin(yangle) svpj = svpj*cos(yangle)+stemp*sin(yangle) ; rotate around z axis srtemp = svpr + flip(svpi) srtemp = srtemp*zrot svpr = real(srtemp) svpi = imag(srtemp) svr = camr-svpr svi = cami-svpi svj = camj-svpj svd = sqrt(svr*svr+svi*svi+svj*svj) svr = svr/svd svi = -svi/svd svj = -svj/svd smindist = svr*smindistr-svi*smindisti-svj*smindistj if m_julia || m_brot if fourth == 3 szri = camr - (svd-smindist)*svr + flip(cami +(svd-smindist)*svi) szjk = camj + (svd-smindist)*svj + flip(ck) elseif fourth == 2 szri = camr- (svd-smindist)*svr - flip(cami+ (svd-smindist)*svi) szjk = flip(camj+ (svd-smindist)*svj) + ck elseif fourth == 1 szri = camj+ (svd-smindist)*svj + flip(ck) szjk = camr- (svd-smindist)*svr + flip(cami- (svd-smindist)*svi) elseif fourth == 0 szri = flip(camj+ (svd-smindist)*svj) + ck szjk = camr- (svd-smindist)*svr + flip(cami- (svd-smindist)*svi) endif elseif m_mand if fourth == 3 scri = camr - (svd-smindist)*svr - flip(cami + (svd-smindist)*svi) scjk = camj + (svd-smindist)*svj + flip(ck) elseif fourth == 2 scri = camr - (svd-smindist)*svr - flip(cami + (svd-smindist)*svi) scjk = flip(camj + (svd-smindist)*svj) + ck elseif fourth == 1 scri = camj + (svd-smindist)*svj + flip(ck) scjk = camr - (svd-smindist)*svr - flip(cami + (svd-smindist)*svi) elseif fourth == 0 scri = flip(camj + (svd-smindist)*svj) + ck scjk = camr - (svd-smindist)*svr - flip(cami + (svd-smindist)*svi) endif m_q.setjp(scri,scjk) m_q.getmp(szri,szjk) endif oldszri2 = oldszri oldszjk2 = oldszjk oldszri = szri oldszjk = szjk if m_spider scri = spidercri scjk = spidercjk m_q.setjp(scri,scjk) endif endif ; floor values if @view == "3D" && imag(fracjdist[idx(xcrd,ycrd)]) < -3 && @floor l = real(fracri[idx(xcrd,ycrd)])*lx + imag(fracri[idx(xcrd,ycrd)])*ly + \ imag(fracjdist[idx(xcrd,ycrd)])*lz pz = l + flip(imag(fracjdist[idx(xcrd,ycrd)])) if shad pz = l + flip(imag(fracjdist[idx(xcrd,ycrd)])-2) endif endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Formula.Iterate(pz) iii = iii + 1 if @view == "2D" if m_oldz m_q.setomp(oldszri,oldszjk) endif m_q.frcalc(szri, szjk) if m_oldz m_q.getomp(oldszri,oldszjk) endif if m_spider m_q.getjp(scri,scjk) endif if m_brot smodh = cabs(szri) else smodh = sqrt(|szri|+|szjk|) endif pz = szri if @compat float m = abs(real(pz))/512.0 if m < 1e-200 m = 1e-200 endif m = m + (356)*2.0^floor(1.0+log(m)/log(2.0)) if real(pz)<0.0 m = -m endif pz = m + flip(imag(pz)) endif endif return pz endfunc ; This overrides formula bailout. bool func IsBailedOut(complex pz) if @view == "2D" m_BailedOut = smodh > bailout else m_BailedOut = iii > mycolor endif return m_BailedOut endfunc ; This provides an index into a 2-dimensional dynamic array int func idx(int i, int j) int k = i*#height + j return k endfunc protected: complex fracri[] complex fracjdist[] float fdist[] float fiter[] bool flr[] float scrsize complex zri complex zjk complex zrix complex zriy complex zriz complex zriw complex zjkx complex zjky complex zjkz complex zjkw complex zrid complex zjkd complex rtemp complex cri complex cjk float vpr float vpi float vpj float fvpr float fvpi float fvpj ; ray normal float vr float vi float vj float vd float camr float cami float camj float ucamr float ucami float ucamj float modH float modHd float d float dist int fr int fi bool infinity float dfactor float sdfactor float olddfactor float oldsdfactor float epsilon float ci float cr float trmax float timax float rmin float imax ; light origin float lpointx float lpointy float lpointz ; light point at float lightx float lighty float lightz ; light vector float lx float ly float lz float xangle float yangle complex zrot float temp complex im float bailout float pot float grad float siter float reduce float mindist float mindistr float mindisti float mindistj float maxdist float maxdistr float maxdisti float maxdistj float camd int iii float smodh float mycolor complex sztemp complex szri complex szjk complex szrix complex szjkx complex szriy complex szjky complex szriz complex szjkz complex szriw complex szjkw complex scri complex scjk Quat m_q bool m_julia bool m_mand bool m_hyper bool m_quat bool m_brot bool m_sphere bool firstpass float bepsilon float checkscale float fa float fb float fc float fd float xf float yf float zf float lxtf float lytf float lztf float dirtheta float ortheta float td complex fp float xlf float ylf float zlf float ld int fourth float ck complex oldzri complex oldzjk complex oldszri complex oldszjk float modHold float smodHold bool m_spider complex spidercri complex spidercjk bool m_oldz float inc float maxstep float pow complex oldzri2 complex oldzjk2 complex oldszri2 complex oldszjk2 float dold UserTransform txf ; UserTransform3D txf3D float itercolor float maxzd float minzd float zd default: title = "3D Fractal Raytrace (UF5)" int param v_3D_Fractal_Raytrace caption = "Version (3D Fractal Raytrace)" default = 106 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_3D_Fractal_Raytrace < 106 endparam complex param p_power caption = "Exponent" default = (2,0) visible = false endparam heading text = "Based upon an article by Hart, Sandin and Kauffman for estimating \ the distance from a point to a fractal surface." endheading heading text = "For optimal Raytracing results, use the coloring formula 3D Fractal Coloring \ Direct (UF5). This formula is required for the 'Distance' Display Type. \ Any coloring formula can be used when the Object view parameter is 2D." endheading heading text = "The Delta DE potential method should not be used with transforms." visible = @v_3D_Fractal_Raytrace >= 104 endheading UserTransform param transform caption = "Transform" default = NullTransform expanded = false visible = @v_3D_Fractal_Raytrace >= 104 endparam bool param xy caption = "Apply to XY only" default = false visible = @transform != NullTransform && @v_3D_Fractal_Raytrace >= 104 endparam int param prestart caption = "Start Iter" default = 0 visible = @transform != NullTransform && @v_3D_Fractal_Raytrace >= 104 endparam int param preend caption = "Iterations" default = 1 visible = @transform != NullTransform && @v_3D_Fractal_Raytrace >= 104 endparam float param strength caption = "Strength" default = 1 visible = @transform != NullTransform && @v_3D_Fractal_Raytrace >= 104 endparam heading caption = "Camera Settings" expanded = false endheading bool param setzoom caption = "Set to zoom center" default = false endparam heading text = "Camera Origin" visible = @view == "3D" endheading float param camr caption = " X" default = 0.0 visible = @v_3D_Fractal_Raytrace >= 103 && !@setzoom endparam float param cami caption = " Y" default = 0.0 visible = @v_3D_Fractal_Raytrace >= 103 && !@setzoom endparam float param camj caption = " Z" default = 10.0 endparam heading caption = "Illumination" expanded = false visible = @view == "3D" && @type == "raytrace" endheading param ltype caption = "Light type" enum = "Point source" "Infinite light" default = 0 visible = @view == "3D" && @type == "raytrace" endparam heading text = "Counter clockwise from the X axis." visible = @ltype == "Infinite light" && @view == "3D" && @type == "raytrace" endheading param angle caption = "Light Rotation" default = 60.0 min = -180 max = 180 hint = "Gives the rotation of the light source, in degrees." visible = @ltype == "Infinite light" && @view == "3D" && @type == "raytrace" endparam heading text = "Degrees of elevation above the complex plane." visible = @ltype == "Infinite light" && @view == "3D" && @type == "raytrace" endheading param elevation caption = "Light Elevation" default = 60.0 min = -90 max = 90 hint = "Gives the elevation of the light source, in degrees." visible = @ltype == "Infinite light" && @view == "3D" && @type == "raytrace" endparam heading text = "Light Origin" visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endheading float param lpointx caption = " X" default = 1.5 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam float param lpointy caption = " Y" default = 2 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam float param lplane caption = " Z" default = 5 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam heading text = "Light Point At" visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endheading float param lightx caption = " X" default = 0.0 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam float param lighty caption = " Y" default = 0.0 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam float param lightz caption = " Z" default = 0.0 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam heading caption = "Shadows" visible = @view == "3D" && @type == "raytrace" endheading bool param shadows caption = "Add Shadows" default = false visible = @view == "3D" && @type == "raytrace" endparam heading text = "Increasing 'shadow sensivity' will give shadows that show less fractal \ detail, but can also increase the number of false shadows from roughness \ on the fractal surface. Decreasing object roughness slightly may reduce \ the false shadows." visible = @view == "3D" && @shadows && @type == "raytrace" endheading float param objshadsens caption = "Object shadow sens" default = 0.1 visible = @view == "3D" && @shadows && @type == "raytrace" hint = "Determines shadow detail and sensitivity to surface roughness. Larger \ show less detail and more response to surface roughness" endparam float param srough caption = "Object roughness" default = 0.99 visible = @view == "3D" && @shadows && @type == "raytrace" hint = "Determines shadow sensitivity to surface roughness. Larger \ have more response to surface roughness" endparam float param floorshadsens caption = "Floor shadow sens" default = 1.0 visible = @view == "3D" && @shadows && @floor endparam heading caption = "Environment" visible = @view == "3D" endheading bool param floor caption = "Add floor" default = false visible = @view == "3D" endparam float param fa caption = "X direction" default = 0.0 visible=@floor==true && @view == "3D" endparam float param fb caption = "Y direction" default = 1.0 visible=@floor==true && @view == "3D" endparam float param fc caption = "Z direction" default = 0.2 visible=@floor==true && @view == "3D" endparam float param fd caption = "Position" default = -4.0 visible=@floor==true && @view == "3D" endparam float param dis caption = "Floor brightness" default = 1.0 visible=@floor==true && @view == "3D" endparam float param fade caption = "Fade factor" default = 3.0 ; min = 3.0 visible=@floor==true && @view == "3D" endparam heading caption = "Floor Patterns" visible=@floor==true && @view == "3D" endheading param flrtype caption = "Floor Type" default = 0 enum = "Checkerboard" "Plain" visible=@floor==true && @view == "3D" endparam float param checkscale caption = "Pattern scale" default = 1 visible=@floor==true && @flrtype != "Plain" && @view == "3D" endparam complex param poffset caption = "Pattern offset" default = (0,0) visible=@floor==true && @flrtype != "Plain" && @view == "3D" endparam heading caption = "Fractal Parameters" endheading Quat param QuatClass caption = "Fractal Formula" default = Julia endparam float param p_bailout ; Overrides p_bailout caption = "Bailout value" default = 1024 endparam heading caption = "Rotations" endheading heading text = "For rotation around the Z axis use the Location tab setting." endheading float param xangle caption = "X Axis Rotation" default = 0.0 endparam float param yangle caption = "Y Axis Rotation" default = 0.0 endparam heading caption = "Raytrace parameters" endheading param view caption = "Object view" enum = "3D" "2D" default = 0 hint = "The 2D view is at the level of the viewing screen (Starting Distance)." endparam heading text = "The compatibility box must be checked for use with the '3D Fractal \ Coloring Direct (UF5) coloring formula. It should be unchecked for use \ with other coloring formulas." visible = @view == "2D" endheading bool param compat caption = "Compatibility" default = true visible = @view == "2D" endparam heading text = "The 'Distance' display type will work only with the 3D Fractal Coloring \ Direct (UF5) ucl. It's in reb5.ucl." visible = @type == "Distance" && @view == "3D" endheading param type caption = "Display type" enum = "Raytrace" "Distance" "Z Value" "Iteration" default = 0 visible = @view == "3D" hint = "The distance option provides coloring according to the distance \ from the camera." endparam bool param corzd caption = "Normalize Z value" default = false visible = @view == "3D" && @type == "Z Value" endparam param ray caption = "Add Raytrace" default = false visible = @type == "Distance" || @type == "Z Value" || @type == "Iteration" endparam float param epsilon caption = "Closeness" default = 1.0 hint = "Determines closeness of approach to the fractal \ surface in pixels." visible = @view == "3D" endparam float param dfactor caption = "Distance factor" default = 1.0 hint = "Decrease to more accurately approach the fractal surface. This will \ slow generation of the image." visible = @view == "3D" && @potmeth != "Brute Force" endparam heading text = "'Distance adjustment' provides an adjustment to the 'Distance factor' \ when the camera ray approaches the surface. For values less than 1.0 \ it will usually provide a closer fit to the fractal surface." visible = @view == "3D" && @potmeth != "Brute Force" && !@altgrad endheading float param dadj caption = "Distance adjustment" default = 1.0 visible = @view == "3D" && @potmeth != "Brute Force" && !@altgrad endparam float param maxstep caption = "Maxiumum step" default = 1e10 visible = @view == "3D" && !@altgrad && @potmeth != "Brute Force" && @v_3d_fractal_raytrace < 102 hint = "Largest allowed step for approach to the object surface." endparam bool param altgrad caption = "Alternate gradient" default = false visible = @view == "3D" && @potmeth != "Brute Force" && @v_3d_fractal_raytrace < 102 endparam heading text = "The alternate gradient may render faster as it does not need \ to calculate the derivative of the fractal. Larger values for the \ 'Gradient adjustment' will give a smoother image with less detail." visible = @altgrad && @view == "3D" && @potmeth != "Brute Force" && @v_3d_fractal_raytrace < 102 endheading float param gradadj caption = "Grad adjustment" default = 1.0 visible = @altgrad && @view == "3D" && @potmeth != "Brute Force" && @v_3d_fractal_raytrace < 102 endparam heading text = "For the 'Vepstas/Härkönen' potential method the bailout should be at least \ 1e10 or surface artifacts will be seen." visible = @view == "3D" && @potmeth == "Vepstas/Härkönen" \ && (!(@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) || @v_3d_fractal_raytrace < 104) endheading heading text = "The 'Delta DE' and 'Brute Force' methods do not use the analytical derivative of the fractal function." visible = (@v_3d_fractal_raytrace >= 102 && (@potmeth == "Delta DE" || @potmeth == "Brute Force")) \ && (!(@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) || @v_3d_fractal_raytrace < 104) endheading heading text = "Currently 'Delta DE' is not configured to work with any of the Phoenix or Spider fractal functions." visible = @v_3d_fractal_raytrace >= 102 && (@potmeth == "Delta DE")\ && (!(@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) || @v_3d_fractal_raytrace < 104) endheading param potmeth caption = "Potential method" enum = "General smoothing" "Vepstas" "Vepstas/Härkönen" "No iteration Smoothing" \ "Delta DE" "Brute Force" default = 4 visible = @view == "3D" && (!(@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) || @v_3d_fractal_raytrace < 104) \ || (@v_3d_fractal_raytrace > 105 && !@special) endparam param special caption = "Special potential" default = true visible = @view == "3D" && (@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) \ && @v_3d_fractal_raytrace > 105 endparam heading text = "'Special potential' is a distance estimate type method which doesn't \ use derivatives. It was presented on Fractal Forums by Buddhi. The 'Alternate \ method' is a variant which is somewhat slower but usually gives a more \ detailed rendering. Make sure 'Include final scaling' is checked." visible = @view == "3D" && (@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) && \ @special endheading bool param alt caption = "Alternate method" default = true visible = @view == "3D" && (@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) && \ @special endparam bool param noderiv caption = "No derivative" default = false visible = @view == "3D" && (!(@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) || @v_3d_fractal_raytrace < 104) \ && !(@potmeth == "no iteration smoothing" || @potmeth == "delta de" || \ @potmeth == "brute force") \ || (@v_3d_fractal_raytrace > 105 && !(@potmeth == "no iteration smoothing" \ || @potmeth == "delta de" || @potmeth == "brute force") \ && !@special) endparam float param delta caption = "delta" default = 1e-10 visible = @potmeth == "delta DE" && !(@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) \ || (@v_3d_fractal_raytrace > 105 && @potmeth == "delta DE" \ && !@special) endparam heading text = "Higher velocity values speed up the rendering, but they will also decrease \ the quality." visible = @view == "3D" && @potmeth == "Brute Force" \ && !(@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) \ || (@v_3d_fractal_raytrace > 105 && @potmeth == "Brute Force") endheading float param velocity caption = "Velocity" default = 20 visible = @view == "3D" && @potmeth == "Brute Force" \ && !(@quatclass == ConformalMandelbrot ||@quatclass == ConformalJulia \ ||@quatclass == AmazingFractalMandelbrot ||@quatclass == AmazingFractalJulia\ || @quatclass == HybridMandelbrot ||@quatclass == HybridJulia ) \ || (@v_3d_fractal_raytrace > 105 && @potmeth == "Brute Force") hint = "The rate of the initial approach to the surface." endparam bool param limitgrad caption = "Limit gradient" default = false visible = @view == "3D" && !@constgrad && !(@potmeth == "Brute Force") && !@altgrad \ && @v_3d_fractal_raytrace < 102 endparam float param limvallow caption = "lower limit" default = 1.0 visible = @view == "3D" && @limitgrad && !@constgrad && !(@potmeth == "Brute Force") && !@altgrad\ && @v_3d_fractal_raytrace < 102 endparam float param limvalhigh caption = "upper limit" default = 10.0 visible = @view == "3D" && @limitgrad && !@constgrad && !(@potmeth == "Brute Force") && !@altgrad\ && @v_3d_fractal_raytrace < 102 endparam bool param constgrad caption = "Constant gradient" default = false visible = @view == "3D" && !@limitgrad && !(@potmeth == "Brute Force") && !@altgrad\ && @v_3d_fractal_raytrace < 102 endparam float param gradval caption = "Gradient value" default = 1.0 visible = @view == "3D" && @constgrad && !@limitgrad && !(@potmeth == "Brute Force") && !@altgrad\ && @v_3d_fractal_raytrace < 102 endparam heading caption = "Cutting Plane" endheading heading text = "The starting and ending planes are defined by the X, Y and Z \ values referenced to the camera position and the plane of the \ screen. The cutting planes are applied after any rotations." endheading heading text = " Starting Plane" endheading float param mindistrqj caption = "X value" default = 0.0 hint = "This defines the cutting plane." endparam float param mindistiqj caption = "Y value" default = 0.0 hint = "This defines the cutting plane." endparam float param mindistqj caption = "Z value" default = 2.0 hint = "This defines the cutting plane." endparam heading text = " Ending Plane" visible = @view == "3D" endheading float param maxdistrqj caption = "X value" default = 0.0 hint = "This is the maximum distance from the cutting plane." visible = @view == "3D" endparam float param maxdistiqj caption = "Y value" default = 0.0 hint = "This is the maximum distance from the cutting plane." visible = @view == "3D" endparam float param maxdistqj caption = "Z value" default = 4.0 hint = "This is the maximum distance from the cutting plane." visible = @view == "3D" endparam } class REB_3DFractalRayTraceProgressiveDual(common.ulb:Formula) { ; Progressive rendering of dual 3D fractals using the iteration count to ; switch between fractal types. A merging option that is synchronized with the ; iteration switch is also available. $define debug public: import "common.ulb" import "dmj5.ulb" ; constructor func REB_3DFractalRayTraceProgressiveDual(Generic pparent) Formula.Formula(pparent) if @dual iterval = @setiter else iterval = 0 endif use1 = true m_q = new @QuatClass(0) m_q2 = new @QuatClass2(0) if use1 m_q.getjp(cri,cjk) else m_q2.getjp(cri,cjk) endif m_julia = m_q.jtype() m_mand = m_q.mtype() m_quat = m_q.qtype() m_hyper = m_q.htype() m_brot = m_q.btype() m_spider = m_q.stype() m_oldz = m_q.ztype() m_sphere = m_q.sptype() if m_spider spidercri = cri spidercjk = cjk endif fourth = m_q.get4() ck = m_q.getck() if @dual m_julia2 = m_q2.jtype() m_mand2 = m_q2.mtype() m_quat2 = m_q2.qtype() m_hyper2 = m_q2.htype() m_brot2 = m_q2.btype() m_spider2 = m_q2.stype() m_oldz2 = m_q2.ztype() m_sphere2 = m_q2.sptype() if m_spider2 spidercri = cri spidercjk = cjk endif fourth2 = m_q2.get4() ck2 = m_q2.getck() endif scrsize = sqrt(#width*#width+#height*#height) maxstep = @camj*@maxstep zri = 0 zjk = 0 zrid = 0 zjkd = 0 oldzri = 0 oldzjk = 0 pow = 0 oldzri2 = 0 oldzjk2 = 0 rtemp = 0 vpr = 0 vpi = 0 vpj = 0 ; ray normal vr = 0 vi = 0 vj = 0 vd = 0 if @setzoom camr = real(#center)+@camr cami = imag(#center)+@cami else camr = @camr cami = @cami endif camj = @camj ucamr = 0 ucami = 0 ucamj = 0 modH = 0 modHold = 0 modHd = 0 d = 0 dist = 0 infinity = true if @szoom dfactor = @dfactor/#magn/scrsize*410 else dfactor = @dfactor endif epsilon = @epsilon/scrsize epsilon = epsilon/#magn ci = imag(#center) cr = real(#center) trmax = 4.0/#magn timax = trmax*#height/#width rmin = cr - trmax/2 imax = ci + timax/2 ; light origin lpointx = @lpointx lpointy = @lpointy lpointz = @lplane ; light point at lightx = @lightx lighty = @lighty lightz = @lightz ; light vector if @ltype == "Infinite light" float d2r = #pi/180; degrees to radians conversion factor lx = -cos(@angle*d2r) * cos(-@elevation*d2r) ly = -sin(@angle*d2r) * cos(-@elevation*d2r) lz = sin(-@elevation*d2r) else lx = lightx-lpointx ly = lighty-lpointy lz = lightz-lpointz endif vd = sqrt(lx^2+ly^2+lz^2) lx = lx/vd ly = ly/vd lz = lz/vd xangle = -@xangle*#pi/180 yangle = @yangle*#pi/180 zrot = cos(#angle) + flip(sin(#angle)) temp = 0 im = (0,1) bailout = sqrt(@p_bailout) pot = 0 grad = 0 siter = 0 reduce = 0 mindist = 0 mindistr = @mindistrqj mindisti = @mindistiqj mindistj = @mindistqj maxdist = 0 maxdistr = @maxdistrqj maxdisti = @maxdistiqj maxdistj = @maxdistqj camd = @camj mindistr = mindistr*camd mindisti = mindisti*camd maxdistr = maxdistr*camd maxdisti = maxdisti*camd firstpass = false bepsilon = 10*epsilon ; camera position ;rotate around x axis temp = cami cami = cami*cos(xangle)-camj*sin(xangle) camj = camj*cos(xangle)+temp*sin(xangle) ;rotate around y axis temp = camr camr = camr*cos(yangle)-camj*sin(yangle) camj = camj*cos(yangle)+temp*sin(yangle) ;rotate around z axis rtemp = camr + flip(cami) rtemp = rtemp*zrot camr = real(rtemp) cami = imag(rtemp) ; minimum distance position ;rotate around x axis temp = mindisti mindisti = mindisti*cos(xangle)-mindistj*sin(xangle) mindistj = mindistj*cos(xangle)+temp*sin(xangle) ;rotate around y axis temp = mindistr mindistr = mindistr*cos(yangle)-mindistj*sin(yangle) mindistj = mindistj*cos(yangle)+temp*sin(yangle) ;rotate around z axis rtemp = mindistr + flip(mindisti) rtemp = rtemp*zrot mindistr = real(rtemp) mindisti = imag(rtemp) ; maximum distance position ;rotate around x axis temp = maxdisti maxdisti = maxdisti*cos(xangle)-maxdistj*sin(xangle) maxdistj = maxdistj*cos(xangle)+temp*sin(xangle) ;rotate around y axis temp = maxdistr maxdistr = maxdistr*cos(yangle)-maxdistj*sin(yangle) maxdistj = maxdistj*cos(yangle)+temp*sin(yangle) ;rotate around z axis rtemp = maxdistr + flip(maxdisti) rtemp = rtemp*zrot maxdistr = real(rtemp) maxdisti = imag(rtemp) itercolor = 0 endfunc ; initialize the formula complex func Init(complex pz) Formula.Init(pz) complex fzri = 0 complex fzjk = 0 complex fzrix = 0 complex fzriy = 0 complex fzjkx = 0 complex fzjky = 0 complex fzrixn = 0 complex fzriyn = 0 complex fzjkxn = 0 complex fzjkyn = 0 float fdst = 0 float icolor = 0 infinity = true ; MAIN RAY ; calculate screen position vpr = rmin + (#x*trmax)/#width vpi = imax - (#y*timax)/#height vpj = 0 ; unrotated position used for calcs fvpr = vpr fvpi = vpi fvpj = vpj ; screen position ; rotate around x axis temp = vpi vpi = vpi*cos(xangle)-vpj*sin(xangle) vpj = vpj*cos(xangle)+temp*sin(xangle) ; rotate around y axis temp = vpr vpr = vpr*cos(yangle)-vpj*sin(yangle) vpj = vpj*cos(yangle)+temp*sin(yangle) ; rotate around z axis rtemp = vpr + flip(vpi) rtemp = rtemp*zrot vpr = real(rtemp) vpi = imag(rtemp) ; create camera vector vr = camr-vpr vi = cami-vpi vj = camj-vpj vd = sqrt(vr*vr+vi*vi+vj*vj) vr = vr/vd vi = vi/vd vj = vj/vd mindist = mindistr*vr+mindisti*vi+mindistj*vj maxdist = maxdistr*vr+maxdisti*vi+maxdistj*vj ; distance camera correction if vd > mindist ucamr = camr-(vd-mindist)*vr ucami = cami-(vd-mindist)*vi ucamj = camj-(vd-mindist)*vj reduce = vd-mindist else ucamr = camr ucami = cami ucamj = camj reduce = 0 endif if @useFirst use1 = true else use1 = false endif if @view == "3D" ; calculate distance from camera to quaternion zrid = 1 zjkd = 0 if (m_julia || m_brot) && use1 if fourth == 3 zri = ucamr + flip(ucami) zjk = ucamj + flip(ck) elseif fourth == 2 zri = ucamr + flip(ucami) zjk = flip(ucamj) + ck elseif fourth == 1 zri = ucamj + flip(ck) zjk = ucamr + flip(ucami) elseif fourth == 0 zri = flip(ucamj) + ck zjk = ucamr + flip(ucami) endif elseif m_mand && use1 if fourth == 3 cri = ucamr + flip(ucami) cjk = ucamj + flip(ck) elseif fourth == 2 cri = ucamr + flip(ucami) cjk = flip(ucamj) + ck elseif fourth == 1 cri = ucamj + flip(ck) cjk = ucamr + flip(ucami) elseif fourth == 0 cri = flip(ucamj) + ck cjk = ucamr + flip(ucami) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) endif if (m_julia2 || m_brot2) && !use1 if fourth2 == 3 zri = ucamr + flip(ucami) zjk = ucamj + flip(ck2) elseif fourth2 == 2 zri = ucamr + flip(ucami) zjk = flip(ucamj) + ck2 elseif fourth2 == 1 zri = ucamj + flip(ck2) zjk = ucamr + flip(ucami) elseif fourth2 == 0 zri = flip(ucamj) + ck2 zjk = ucamr + flip(ucami) endif elseif m_mand2 && !use1 if fourth2 == 3 cri = ucamr + flip(ucami) cjk = ucamj + flip(ck2) elseif fourth2 == 2 cri = ucamr + flip(ucami) cjk = flip(ucamj) + ck2 elseif fourth2 == 1 cri = ucamj + flip(ck2) cjk = ucamr + flip(ucami) elseif fourth2 == 0 cri = flip(ucamj) + ck2 cjk = ucamr + flip(ucami) endif m_q2.setjp(cri,cjk) m_q2.getmp(zri,zjk) endif i = 0 ; iter1 = false ; iter2 = false ; switch1 = false ; switch2 = false dist = 0 infinity = true siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif if m_spider2 cri = spidercri cjk = spidercjk m_q2.setjp(cri,cjk) endif itercolor = 0 repeat repeat oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if !@altuse1 olduse1 = use1 else olduse1 = !use1 endif if @itermeth == "flavor1" if i % iterval == 0 && @dual && i != 0 use1 = !use1 endif else if @dual if i % (@seqgap1) >= 0 && @seqgap2 != 0 switch1 = true switch2 = false endif if (i % (@seqgap1) >= (i % @seqgap2)+1) || @seqgap2 == 0 switch1 = false switch2 = true endif if @seqgap2 > @seqgap1 switch1 = true switch2 = false endif endif if @dual if switch1 iter1 = true iter2 = false elseif switch2 iter1 = false iter2 = true endif endif if @dual if iter1 if @usefirst use1 = true else use1 = false endif elseif iter2 if @usefirst use1 = false else use1 = true endif endif endif endif if m_oldz m_q.setomp(oldzri,oldzjk) endif if m_oldz2 m_q2.setomp(oldzri,oldzjk) endif ; calculate derivative if use1 m_q.drcalc(zri, zjk, zrid, zjkd) else m_q2.drcalc(zri, zjk, zrid, zjkd) endif ; calculate fractal if use1 m_q.frcalc(zri, zjk) else m_q2.frcalc(zri, zjk) endif if m_spider m_q.getjp(cri,cjk) endif if m_spider2 m_q2.getjp(cri,cjk) endif if m_oldz m_q.getomp(oldzri,oldzjk) endif if m_oldz2 m_q2.getomp(oldzri,oldzjk) endif if @itermeth == "flavor1" if (olduse1 != use1) && @merge != "None" && i != 0 if @merge == "Average" zri = (oldzri + zri)/2 zjk = (oldzjk + zjk)/2 elseif @merge == "A+B" zri = (oldzri + zri) zjk = (oldzjk + zjk) elseif @merge == "A-B" zri = (oldzri - zri) zjk = (oldzjk - zjk) elseif @merge == "B-A" zri = (-oldzri + zri) zjk = (-oldzjk + zjk) elseif @merge == "A*B" zri = 2*(oldzri * zri)/(oldzri + zri) zjk = 2*(oldzjk * zjk)/(oldzjk + zjk) elseif @merge == "A/B" zri = (oldzri / (zri+0.01))+0.01 zjk = (oldzjk / (zjk+0.01))+0.01 elseif @merge == "B/A" zri = (zri / (oldzri+0.01))+0.01 zjk = (zjk / (oldzjk+0.01))+0.01 elseif @merge == "Largest(A,B)" if |zri| < |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif elseif @merge == "Smallest(A,B)" if |zri| > |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif endif endif else if @merge != "None" && (@mergealt && switch1 || switch2) if @merge == "Average" zri = (oldzri + zri)/2 zjk = (oldzjk + zjk)/2 elseif @merge == "A+B" zri = (oldzri + zri) zjk = (oldzjk + zjk) elseif @merge == "A-B" zri = (oldzri - zri) zjk = (oldzjk - zjk) elseif @merge == "B-A" zri = (-oldzri + zri) zjk = (-oldzjk + zjk) elseif @merge == "A*B" zri = 2*(oldzri * zri)/(oldzri + zri) zjk = 2*(oldzjk * zjk)/(oldzjk + zjk) elseif @merge == "A/B" zri = (oldzri / (zri+0.01))+0.01 zjk = (oldzjk / (zjk+0.01))+0.01 elseif @merge == "B/A" zri = (zri / (oldzri+0.01))+0.01 zjk = (zjk / (oldzjk+0.01))+0.01 elseif @merge == "Largest(A,B)" if |zri| < |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif elseif @merge == "Smallest(A,B)" if |zri| > |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif endif endif endif if m_brot modh = cabs(zri) else modh = sqrt(|zri|+|zjk|) endif if @potmeth == "general smoothing" if m_brot modhold = cabs(oldzri-zri) else modhold = sqrt(|oldzri-zri|+|oldzjk-zjk|) endif siter = siter + exp(-modh-0.5/modhold) endif if @colortype == "Exponential smoothing" itercolor = itercolor + exp(-modh) endif i = i + 1 until i == #maxiter || modh > bailout if @colortype == "Vepstas" itercolor = (i +log(log(modh))/log(2)) endif if @potmeth == "Vepstas" siter = i + log(log(modh))/log(2) endif if m_brot modhd = cabs(zrid) else modhd = sqrt(|zrid|+|zjkd|) endif if modh <= bailout dist = dist - d d = 0 if dist < 0 dist = 0 endif else if @potmeth != "Iteration Smoothing" pot = exp(-siter*log(2)) if !@noderiv grad = pot*modhd/(modh*log(modh)) else grad = exp(-(siter-i)*log(2)) endif if !@noderiv d = dfactor*sinh(pot)/(2*exp(pot)*grad) else d = 10*dfactor*sinh(pot)/(2*exp(pot)*grad) endif else d = modh*log(modh)/modhd*(dfactor/2) endif if d > maxstep d = maxstep endif dist = d + dist endif zrid = 1 zjkd = 0 if @distcorr itercolor = 0.01*itercolor*dist else if vd > mindist itercolor = 0.01*itercolor*(vd-reduce) else itercolor = 0.01*itercolor*vd endif endif if (m_julia || m_brot) && use1 if fourth == 3 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 zri = ucamj-dist*vj + flip(ck) zjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 zri = flip(ucamj-dist*vj) + ck zjk = ucamr-dist*vr + flip(ucami-dist*vi) endif elseif m_mand && use1 if fourth == 3 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 cri = ucamj-dist*vj + flip(ck) cjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 cri = flip(ucamj-dist*vj) + ck cjk = ucamr-dist*vr + flip(ucami-dist*vi) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) endif if (m_julia2 || m_brot2) && !use1 if fourth2 == 3 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = ucamj-dist*vj + flip(ck2) elseif fourth2 == 2 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = flip(ucamj-dist*vj) + ck2 elseif fourth2 == 1 zri = ucamj-dist*vj + flip(ck2) zjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth2 == 0 zri = flip(ucamj-dist*vj) + ck2 zjk = ucamr-dist*vr + flip(ucami-dist*vi) endif elseif m_mand2 && !use1 if fourth2 == 3 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = ucamj-dist*vj + flip(ck2) elseif fourth2 == 2 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = flip(ucamj-dist*vj) + ck2 elseif fourth2 == 1 cri = ucamj-dist*vj + flip(ck2) cjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth2 == 0 cri = flip(ucamj-dist*vj) + ck2 cjk = ucamr-dist*vr + flip(ucami-dist*vi) endif m_q2.setjp(cri,cjk) m_q2.getmp(zri,zjk) endif i = 0 siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif if m_spider2 cri = spidercri cjk = spidercjk m_q2.setjp(cri,cjk) endif until (d <= epsilon || dist > maxdist) if (dist > 0 && dist <= maxdist) || d == 0 infinity = false endif if !infinity ; set the intersection point and distance fzri = camr-(dist+reduce)*vr + flip(cami-(dist+reduce)*vi) if dist != 0 fzjk = camj-(dist+reduce)*vj + flip((dist+reduce)) icolor = itercolor else fzjk = camj-(dist+reduce)*vj + flip((1)) fdst = dist+reduce icolor = itercolor endif endif endif ; DELTA X infinity = true ; calculate screen position vpr = rmin + ((#x+@dn)*trmax)/#width vpi = imax - (#y*timax)/#height vpj = 0 ; unrotated position used for calcs fvpr = vpr fvpi = vpi fvpj = vpj ; screen position ; rotate around x axis temp = vpi vpi = vpi*cos(xangle)-vpj*sin(xangle) vpj = vpj*cos(xangle)+temp*sin(xangle) ; rotate around y axis temp = vpr vpr = vpr*cos(yangle)-vpj*sin(yangle) vpj = vpj*cos(yangle)+temp*sin(yangle) ; rotate around z axis rtemp = vpr + flip(vpi) rtemp = rtemp*zrot vpr = real(rtemp) vpi = imag(rtemp) ; create camera vector vr = camr-vpr vi = cami-vpi vj = camj-vpj vd = sqrt(vr*vr+vi*vi+vj*vj) vr = vr/vd vi = vi/vd vj = vj/vd mindist = mindistr*vr+mindisti*vi+mindistj*vj maxdist = maxdistr*vr+maxdisti*vi+maxdistj*vj ; distance camera correction if vd > mindist ucamr = camr-(vd-mindist)*vr ucami = cami-(vd-mindist)*vi ucamj = camj-(vd-mindist)*vj reduce = vd-mindist else ucamr = camr ucami = cami ucamj = camj reduce = 0 endif if @useFirst use1 = true else use1 = false endif if @view == "3D" ; calculate distance from camera to quaternion zrid = 1 zjkd = 0 if (m_julia || m_brot) && use1 if fourth == 3 zri = ucamr + flip(ucami) zjk = ucamj + flip(ck) elseif fourth == 2 zri = ucamr + flip(ucami) zjk = flip(ucamj) + ck elseif fourth == 1 zri = ucamj + flip(ck) zjk = ucamr + flip(ucami) elseif fourth == 0 zri = flip(ucamj) + ck zjk = ucamr + flip(ucami) endif elseif m_mand && use1 if fourth == 3 cri = ucamr + flip(ucami) cjk = ucamj + flip(ck) elseif fourth == 2 cri = ucamr + flip(ucami) cjk = flip(ucamj) + ck elseif fourth == 1 cri = ucamj + flip(ck) cjk = ucamr + flip(ucami) elseif fourth == 0 cri = flip(ucamj) + ck cjk = ucamr + flip(ucami) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) endif if (m_julia2 || m_brot2) && !use1 if fourth2 == 3 zri = ucamr + flip(ucami) zjk = ucamj + flip(ck2) elseif fourth2 == 2 zri = ucamr + flip(ucami) zjk = flip(ucamj) + ck2 elseif fourth2 == 1 zri = ucamj + flip(ck2) zjk = ucamr + flip(ucami) elseif fourth2 == 0 zri = flip(ucamj) + ck2 zjk = ucamr + flip(ucami) endif elseif m_mand2 && !use1 if fourth2 == 3 cri = ucamr + flip(ucami) cjk = ucamj + flip(ck2) elseif fourth2 == 2 cri = ucamr + flip(ucami) cjk = flip(ucamj) + ck2 elseif fourth2 == 1 cri = ucamj + flip(ck2) cjk = ucamr + flip(ucami) elseif fourth2 == 0 cri = flip(ucamj) + ck2 cjk = ucamr + flip(ucami) endif m_q2.setjp(cri,cjk) m_q2.getmp(zri,zjk) endif i = 0 dist = 0 infinity = true siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif if m_spider2 cri = spidercri cjk = spidercjk m_q2.setjp(cri,cjk) endif repeat repeat oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if !@altuse1 olduse1 = use1 else olduse1 = !use1 endif if @itermeth == "flavor1" if i % iterval == 0 && @dual && i != 0 use1 = !use1 endif else if @dual if i % (@seqgap1) >= 0 && @seqgap2 != 0 switch1 = true switch2 = false endif if (i % (@seqgap1) >= (i % @seqgap2)+1) || @seqgap2 == 0 switch1 = false switch2 = true endif if @seqgap2 > @seqgap1 switch1 = true switch2 = false endif endif if @dual if switch1 iter1 = true iter2 = false elseif switch2 iter1 = false iter2 = true endif endif if @dual if iter1 if @usefirst use1 = true else use1 = false endif elseif iter2 if @usefirst use1 = false else use1 = true endif endif endif endif if m_oldz m_q.setomp(oldzri,oldzjk) endif if m_oldz2 m_q2.setomp(oldzri,oldzjk) endif ; calculate derivative if use1 m_q.drcalc(zri, zjk, zrid, zjkd) else m_q2.drcalc(zri, zjk, zrid, zjkd) endif ; calculate fractal if use1 m_q.frcalc(zri, zjk) else m_q2.frcalc(zri, zjk) endif if m_spider m_q.getjp(cri,cjk) endif if m_oldz m_q.getomp(oldzri,oldzjk) endif if m_spider2 m_q2.getjp(cri,cjk) endif if m_oldz2 m_q2.getomp(oldzri,oldzjk) endif if @itermeth == "flavor1" if (olduse1 != use1) && @merge != "None" && i != 0 if @merge == "Average" zri = (oldzri + zri)/2 zjk = (oldzjk + zjk)/2 elseif @merge == "A+B" zri = (oldzri + zri) zjk = (oldzjk + zjk) elseif @merge == "A-B" zri = (oldzri - zri) zjk = (oldzjk - zjk) elseif @merge == "B-A" zri = (-oldzri + zri) zjk = (-oldzjk + zjk) elseif @merge == "A*B" zri = 2*(oldzri * zri)/(oldzri + zri) zjk = 2*(oldzjk * zjk)/(oldzjk + zjk) elseif @merge == "A/B" zri = (oldzri / (zri+0.01))+0.01 zjk = (oldzjk / (zjk+0.01))+0.01 elseif @merge == "B/A" zri = (zri / (oldzri+0.01))+0.01 zjk = (zjk / (oldzjk+0.01))+0.01 elseif @merge == "Largest(A,B)" if |zri| < |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif elseif @merge == "Smallest(A,B)" if |zri| > |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif endif endif else if @merge != "None" && (@mergealt && switch1 || switch2) if @merge == "Average" zri = (oldzri + zri)/2 zjk = (oldzjk + zjk)/2 elseif @merge == "A+B" zri = (oldzri + zri) zjk = (oldzjk + zjk) elseif @merge == "A-B" zri = (oldzri - zri) zjk = (oldzjk - zjk) elseif @merge == "B-A" zri = (-oldzri + zri) zjk = (-oldzjk + zjk) elseif @merge == "A*B" zri = 2*(oldzri * zri)/(oldzri + zri) zjk = 2*(oldzjk * zjk)/(oldzjk + zjk) elseif @merge == "A/B" zri = (oldzri / (zri+0.01))+0.01 zjk = (oldzjk / (zjk+0.01))+0.01 elseif @merge == "B/A" zri = (zri / (oldzri+0.01))+0.01 zjk = (zjk / (oldzjk+0.01))+0.01 elseif @merge == "Largest(A,B)" if |zri| < |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif elseif @merge == "Smallest(A,B)" if |zri| > |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif endif endif endif if m_brot modh = cabs(zri) else modh = sqrt(|zri|+|zjk|) endif if @potmeth == "general smoothing" if m_brot modhold = cabs(oldzri-zri) else modhold = sqrt(|oldzri-zri|+|oldzjk-zjk|) endif siter = siter + exp(-modh-0.5/modhold) endif i = i + 1 until i == #maxiter || (modh > bailout) if @potmeth == "Vepstas" siter = i + log(log(modh))/log(2) endif if m_brot modhd = cabs(zrid) else modhd = sqrt(|zrid|+|zjkd|) endif if modh <= bailout dist = dist - d d = 0 if dist < 0 dist = 0 endif else if @potmeth != "Iteration Smoothing" pot = exp(-siter*log(2)) if !@noderiv grad = pot*modhd/(modh*log(modh)) else grad = exp(-(siter-i)*log(2)) endif if !@noderiv d = dfactor*sinh(pot)/(2*exp(pot)*grad) else d = 10*dfactor*sinh(pot)/(2*exp(pot)*grad) endif else d = modh*log(modh)/modhd*(dfactor/2) endif if d > maxstep d = maxstep endif dist = d + dist endif zrid = 1 zjkd = 0 if (m_julia || m_brot) && use1 if fourth == 3 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 zri = ucamj-dist*vj + flip(ck) zjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 zri = flip(ucamj-dist*vj) + ck zjk = ucamr-dist*vr + flip(ucami-dist*vi) endif elseif m_mand && use1 if fourth == 3 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 cri = ucamj-dist*vj + flip(ck) cjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 cri = flip(ucamj-dist*vj) + ck cjk = ucamr-dist*vr + flip(ucami-dist*vi) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) endif if (m_julia2 || m_brot2) && !use1 if fourth2 == 3 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = ucamj-dist*vj + flip(ck2) elseif fourth2 == 2 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = flip(ucamj-dist*vj) + ck2 elseif fourth2 == 1 zri = ucamj-dist*vj + flip(ck2) zjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth2 == 0 zri = flip(ucamj-dist*vj) + ck2 zjk = ucamr-dist*vr + flip(ucami-dist*vi) endif elseif m_mand2 && !use1 if fourth2 == 3 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = ucamj-dist*vj + flip(ck2) elseif fourth2 == 2 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = flip(ucamj-dist*vj) + ck2 elseif fourth2 == 1 cri = ucamj-dist*vj + flip(ck2) cjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth2 == 0 cri = flip(ucamj-dist*vj) + ck2 cjk = ucamr-dist*vr + flip(ucami-dist*vi) endif m_q2.setjp(cri,cjk) m_q2.getmp(zri,zjk) endif i = 0 siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif if m_spider2 cri = spidercri cjk = spidercjk m_q2.setjp(cri,cjk) endif until (d <= epsilon || dist > maxdist) if dist < epsilon dist = 1e10 endif if (dist > 0 && dist <= maxdist) || d == 0 infinity = false endif if !infinity ; set the intersection point and distance for normal calculation fzrix = camr-(dist+reduce)*vr + flip(cami-(dist+reduce)*vi) if dist != 0 fzjkx = camj-(dist+reduce)*vj + flip((dist+reduce)) else fzjkx = camj-(dist+reduce)*vj + flip((1)) endif endif endif ; DELTA XN if @numnorm == "5 point" infinity = true ; calculate screen position vpr = rmin + ((#x-@dn)*trmax)/#width vpi = imax - (#y*timax)/#height vpj = 0 ; unrotated position used for calcs fvpr = vpr fvpi = vpi fvpj = vpj ; screen position ; rotate around x axis temp = vpi vpi = vpi*cos(xangle)-vpj*sin(xangle) vpj = vpj*cos(xangle)+temp*sin(xangle) ; rotate around y axis temp = vpr vpr = vpr*cos(yangle)-vpj*sin(yangle) vpj = vpj*cos(yangle)+temp*sin(yangle) ; rotate around z axis rtemp = vpr + flip(vpi) rtemp = rtemp*zrot vpr = real(rtemp) vpi = imag(rtemp) ; create camera vector vr = camr-vpr vi = cami-vpi vj = camj-vpj vd = sqrt(vr*vr+vi*vi+vj*vj) vr = vr/vd vi = vi/vd vj = vj/vd mindist = mindistr*vr+mindisti*vi+mindistj*vj maxdist = maxdistr*vr+maxdisti*vi+maxdistj*vj ; distance camera correction if vd > mindist ucamr = camr-(vd-mindist)*vr ucami = cami-(vd-mindist)*vi ucamj = camj-(vd-mindist)*vj reduce = vd-mindist else ucamr = camr ucami = cami ucamj = camj reduce = 0 endif if @useFirst use1 = true else use1 = false endif if @view == "3D" ; calculate distance from camera to quaternion zrid = 1 zjkd = 0 if (m_julia || m_brot) && use1 if fourth == 3 zri = ucamr + flip(ucami) zjk = ucamj + flip(ck) elseif fourth == 2 zri = ucamr + flip(ucami) zjk = flip(ucamj) + ck elseif fourth == 1 zri = ucamj + flip(ck) zjk = ucamr + flip(ucami) elseif fourth == 0 zri = flip(ucamj) + ck zjk = ucamr + flip(ucami) endif elseif m_mand && use1 if fourth == 3 cri = ucamr + flip(ucami) cjk = ucamj + flip(ck) elseif fourth == 2 cri = ucamr + flip(ucami) cjk = flip(ucamj) + ck elseif fourth == 1 cri = ucamj + flip(ck) cjk = ucamr + flip(ucami) elseif fourth == 0 cri = flip(ucamj) + ck cjk = ucamr + flip(ucami) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) endif if (m_julia2 || m_brot2) && !use1 if fourth2 == 3 zri = ucamr + flip(ucami) zjk = ucamj + flip(ck2) elseif fourth2 == 2 zri = ucamr + flip(ucami) zjk = flip(ucamj) + ck2 elseif fourth2 == 1 zri = ucamj + flip(ck2) zjk = ucamr + flip(ucami) elseif fourth2 == 0 zri = flip(ucamj) + ck2 zjk = ucamr + flip(ucami) endif elseif m_mand2 && !use1 if fourth2 == 3 cri = ucamr + flip(ucami) cjk = ucamj + flip(ck2) elseif fourth2 == 2 cri = ucamr + flip(ucami) cjk = flip(ucamj) + ck2 elseif fourth2 == 1 cri = ucamj + flip(ck2) cjk = ucamr + flip(ucami) elseif fourth2 == 0 cri = flip(ucamj) + ck2 cjk = ucamr + flip(ucami) endif m_q2.setjp(cri,cjk) m_q2.getmp(zri,zjk) endif i = 0 dist = 0 infinity = true siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif if m_spider2 cri = spidercri cjk = spidercjk m_q2.setjp(cri,cjk) endif repeat repeat oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if !@altuse1 olduse1 = use1 else olduse1 = !use1 endif if @itermeth == "flavor1" if i % iterval == 0 && @dual && i != 0 use1 = !use1 endif else if @dual if i % (@seqgap1) >= 0 && @seqgap2 != 0 switch1 = true switch2 = false endif if (i % (@seqgap1) >= (i % @seqgap2)+1) || @seqgap2 == 0 switch1 = false switch2 = true endif if @seqgap2 > @seqgap1 switch1 = true switch2 = false endif endif if @dual if switch1 iter1 = true iter2 = false elseif switch2 iter1 = false iter2 = true endif endif if @dual if iter1 if @usefirst use1 = true else use1 = false endif elseif iter2 if @usefirst use1 = false else use1 = true endif endif endif endif if m_oldz m_q.setomp(oldzri,oldzjk) endif if m_oldz2 m_q2.setomp(oldzri,oldzjk) endif ; calculate derivative if use1 m_q.drcalc(zri, zjk, zrid, zjkd) else m_q2.drcalc(zri, zjk, zrid, zjkd) endif ; calculate fractal if use1 m_q.frcalc(zri, zjk) else m_q2.frcalc(zri, zjk) endif if m_spider m_q.getjp(cri,cjk) endif if m_oldz m_q.getomp(oldzri,oldzjk) endif if m_spider2 m_q2.getjp(cri,cjk) endif if m_oldz2 m_q2.getomp(oldzri,oldzjk) endif if @itermeth == "flavor1" if (olduse1 != use1) && @merge != "None" && i != 0 if @merge == "Average" zri = (oldzri + zri)/2 zjk = (oldzjk + zjk)/2 elseif @merge == "A+B" zri = (oldzri + zri) zjk = (oldzjk + zjk) elseif @merge == "A-B" zri = (oldzri - zri) zjk = (oldzjk - zjk) elseif @merge == "B-A" zri = (-oldzri + zri) zjk = (-oldzjk + zjk) elseif @merge == "A*B" zri = 2*(oldzri * zri)/(oldzri + zri) zjk = 2*(oldzjk * zjk)/(oldzjk + zjk) elseif @merge == "A/B" zri = (oldzri / (zri+0.01))+0.01 zjk = (oldzjk / (zjk+0.01))+0.01 elseif @merge == "B/A" zri = (zri / (oldzri+0.01))+0.01 zjk = (zjk / (oldzjk+0.01))+0.01 elseif @merge == "Largest(A,B)" if |zri| < |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif elseif @merge == "Smallest(A,B)" if |zri| > |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif endif endif else if @merge != "None" && (@mergealt && switch1 || switch2) if @merge == "Average" zri = (oldzri + zri)/2 zjk = (oldzjk + zjk)/2 elseif @merge == "A+B" zri = (oldzri + zri) zjk = (oldzjk + zjk) elseif @merge == "A-B" zri = (oldzri - zri) zjk = (oldzjk - zjk) elseif @merge == "B-A" zri = (-oldzri + zri) zjk = (-oldzjk + zjk) elseif @merge == "A*B" zri = 2*(oldzri * zri)/(oldzri + zri) zjk = 2*(oldzjk * zjk)/(oldzjk + zjk) elseif @merge == "A/B" zri = (oldzri / (zri+0.01))+0.01 zjk = (oldzjk / (zjk+0.01))+0.01 elseif @merge == "B/A" zri = (zri / (oldzri+0.01))+0.01 zjk = (zjk / (oldzjk+0.01))+0.01 elseif @merge == "Largest(A,B)" if |zri| < |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif elseif @merge == "Smallest(A,B)" if |zri| > |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif endif endif endif if m_brot modh = cabs(zri) else modh = sqrt(|zri|+|zjk|) endif if @potmeth == "general smoothing" if m_brot modhold = cabs(oldzri-zri) else modhold = sqrt(|oldzri-zri|+|oldzjk-zjk|) endif siter = siter + exp(-modh-0.5/modhold) endif i = i + 1 until i == #maxiter || (modh > bailout) if @potmeth == "Vepstas" siter = i + log(log(modh))/log(2) endif if m_brot modhd = cabs(zrid) else modhd = sqrt(|zrid|+|zjkd|) endif if modh <= bailout dist = dist - d d = 0 if dist < 0 dist = 0 endif else if @potmeth != "Iteration Smoothing" pot = exp(-siter*log(2)) if !@noderiv grad = pot*modhd/(modh*log(modh)) else grad = exp(-(siter-i)*log(2)) endif if !@noderiv d = dfactor*sinh(pot)/(2*exp(pot)*grad) else d = 10*dfactor*sinh(pot)/(2*exp(pot)*grad) endif else d = modh*log(modh)/modhd*(dfactor/2) endif if d > maxstep d = maxstep endif dist = d + dist endif zrid = 1 zjkd = 0 if (m_julia || m_brot) && use1 if fourth == 3 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 zri = ucamj-dist*vj + flip(ck) zjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 zri = flip(ucamj-dist*vj) + ck zjk = ucamr-dist*vr + flip(ucami-dist*vi) endif elseif m_mand && use1 if fourth == 3 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 cri = ucamj-dist*vj + flip(ck) cjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 cri = flip(ucamj-dist*vj) + ck cjk = ucamr-dist*vr + flip(ucami-dist*vi) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) endif if (m_julia2 || m_brot2) && !use1 if fourth2 == 3 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = ucamj-dist*vj + flip(ck2) elseif fourth2 == 2 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = flip(ucamj-dist*vj) + ck2 elseif fourth2 == 1 zri = ucamj-dist*vj + flip(ck2) zjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth2 == 0 zri = flip(ucamj-dist*vj) + ck2 zjk = ucamr-dist*vr + flip(ucami-dist*vi) endif elseif m_mand2 && !use1 if fourth2 == 3 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = ucamj-dist*vj + flip(ck2) elseif fourth2 == 2 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = flip(ucamj-dist*vj) + ck2 elseif fourth2 == 1 cri = ucamj-dist*vj + flip(ck2) cjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth2 == 0 cri = flip(ucamj-dist*vj) + ck2 cjk = ucamr-dist*vr + flip(ucami-dist*vi) endif m_q2.setjp(cri,cjk) m_q2.getmp(zri,zjk) endif i = 0 siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif if m_spider2 cri = spidercri cjk = spidercjk m_q2.setjp(cri,cjk) endif until (d <= epsilon || dist > maxdist) if dist < epsilon dist = 1e10 endif if (dist > 0 && dist <= maxdist) || d == 0 infinity = false endif if !infinity ; set the intersection point and distance for normal calculation fzrixn = camr-(dist+reduce)*vr + flip(cami-(dist+reduce)*vi) if dist != 0 fzjkxn = camj-(dist+reduce)*vj + flip((dist+reduce)) else fzjkxn = camj-(dist+reduce)*vj + flip((1)) endif endif endif endif ; DELTA Y infinity = true ; calculate screen position vpr = rmin + (#x*trmax)/#width vpi = imax - ((#y+@dn)*timax)/#height vpj = 0 ; unrotated position used for calcs fvpr = vpr fvpi = vpi fvpj = vpj ; screen position ; rotate around x axis temp = vpi vpi = vpi*cos(xangle)-vpj*sin(xangle) vpj = vpj*cos(xangle)+temp*sin(xangle) ; rotate around y axis temp = vpr vpr = vpr*cos(yangle)-vpj*sin(yangle) vpj = vpj*cos(yangle)+temp*sin(yangle) ; rotate around z axis rtemp = vpr + flip(vpi) rtemp = rtemp*zrot vpr = real(rtemp) vpi = imag(rtemp) ; create camera vector vr = camr-vpr vi = cami-vpi vj = camj-vpj vd = sqrt(vr*vr+vi*vi+vj*vj) vr = vr/vd vi = vi/vd vj = vj/vd mindist = mindistr*vr+mindisti*vi+mindistj*vj maxdist = maxdistr*vr+maxdisti*vi+maxdistj*vj ; distance camera correction if vd > mindist ucamr = camr-(vd-mindist)*vr ucami = cami-(vd-mindist)*vi ucamj = camj-(vd-mindist)*vj reduce = vd-mindist else ucamr = camr ucami = cami ucamj = camj reduce = 0 endif if @useFirst use1 = true else use1 = false endif if @view == "3D" ; calculate distance from camera to quaternion zrid = 1 zjkd = 0 if (m_julia || m_brot) && use1 if fourth == 3 zri = ucamr + flip(ucami) zjk = ucamj + flip(ck) elseif fourth == 2 zri = ucamr + flip(ucami) zjk = flip(ucamj) + ck elseif fourth == 1 zri = ucamj + flip(ck) zjk = ucamr + flip(ucami) elseif fourth == 0 zri = flip(ucamj) + ck zjk = ucamr + flip(ucami) endif elseif m_mand && use1 if fourth == 3 cri = ucamr + flip(ucami) cjk = ucamj + flip(ck) elseif fourth == 2 cri = ucamr + flip(ucami) cjk = flip(ucamj) + ck elseif fourth == 1 cri = ucamj + flip(ck) cjk = ucamr + flip(ucami) elseif fourth == 0 cri = flip(ucamj) + ck cjk = ucamr + flip(ucami) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) endif if (m_julia2 || m_brot2) && !use1 if fourth2 == 3 zri = ucamr + flip(ucami) zjk = ucamj + flip(ck2) elseif fourth2 == 2 zri = ucamr + flip(ucami) zjk = flip(ucamj) + ck2 elseif fourth2 == 1 zri = ucamj + flip(ck2) zjk = ucamr + flip(ucami) elseif fourth2 == 0 zri = flip(ucamj) + ck2 zjk = ucamr + flip(ucami) endif elseif m_mand2 && !use1 if fourth2 == 3 cri = ucamr + flip(ucami) cjk = ucamj + flip(ck2) elseif fourth2 == 2 cri = ucamr + flip(ucami) cjk = flip(ucamj) + ck2 elseif fourth2 == 1 cri = ucamj + flip(ck2) cjk = ucamr + flip(ucami) elseif fourth2 == 0 cri = flip(ucamj) + ck2 cjk = ucamr + flip(ucami) endif m_q2.setjp(cri,cjk) m_q2.getmp(zri,zjk) endif i = 0 dist = 0 infinity = true siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif if m_spider2 cri = spidercri cjk = spidercjk m_q2.setjp(cri,cjk) endif repeat repeat oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if !@altuse1 olduse1 = use1 else olduse1 = !use1 endif if @itermeth == "flavor1" if i % iterval == 0 && @dual && i != 0 use1 = !use1 endif else if @dual if i % (@seqgap1) >= 0 && @seqgap2 != 0 switch1 = true switch2 = false endif if (i % (@seqgap1) >= (i % @seqgap2)+1) || @seqgap2 == 0 switch1 = false switch2 = true endif if @seqgap2 > @seqgap1 switch1 = true switch2 = false endif endif if @dual if switch1 iter1 = true iter2 = false elseif switch2 iter1 = false iter2 = true endif endif if @dual if iter1 if @usefirst use1 = true else use1 = false endif elseif iter2 if @usefirst use1 = false else use1 = true endif endif endif endif if m_oldz m_q.setomp(oldzri,oldzjk) endif if m_oldz2 m_q2.setomp(oldzri,oldzjk) endif ; calculate derivative if use1 m_q.drcalc(zri, zjk, zrid, zjkd) else m_q2.drcalc(zri, zjk, zrid, zjkd) endif ; calculate fractal if use1 m_q.frcalc(zri, zjk) else m_q2.frcalc(zri, zjk) endif if m_spider m_q.getjp(cri,cjk) endif if m_oldz m_q.getomp(oldzri,oldzjk) endif if m_spider2 m_q2.getjp(cri,cjk) endif if m_oldz2 m_q2.getomp(oldzri,oldzjk) endif if @itermeth == "flavor1" if (olduse1 != use1) && @merge != "None" && i != 0 if @merge == "Average" zri = (oldzri + zri)/2 zjk = (oldzjk + zjk)/2 elseif @merge == "A+B" zri = (oldzri + zri) zjk = (oldzjk + zjk) elseif @merge == "A-B" zri = (oldzri - zri) zjk = (oldzjk - zjk) elseif @merge == "B-A" zri = (-oldzri + zri) zjk = (-oldzjk + zjk) elseif @merge == "A*B" zri = 2*(oldzri * zri)/(oldzri + zri) zjk = 2*(oldzjk * zjk)/(oldzjk + zjk) elseif @merge == "A/B" zri = (oldzri / (zri+0.01))+0.01 zjk = (oldzjk / (zjk+0.01))+0.01 elseif @merge == "B/A" zri = (zri / (oldzri+0.01))+0.01 zjk = (zjk / (oldzjk+0.01))+0.01 elseif @merge == "Largest(A,B)" if |zri| < |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif elseif @merge == "Smallest(A,B)" if |zri| > |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif endif endif else if @merge != "None" && (@mergealt && switch1 || switch2) if @merge == "Average" zri = (oldzri + zri)/2 zjk = (oldzjk + zjk)/2 elseif @merge == "A+B" zri = (oldzri + zri) zjk = (oldzjk + zjk) elseif @merge == "A-B" zri = (oldzri - zri) zjk = (oldzjk - zjk) elseif @merge == "B-A" zri = (-oldzri + zri) zjk = (-oldzjk + zjk) elseif @merge == "A*B" zri = 2*(oldzri * zri)/(oldzri + zri) zjk = 2*(oldzjk * zjk)/(oldzjk + zjk) elseif @merge == "A/B" zri = (oldzri / (zri+0.01))+0.01 zjk = (oldzjk / (zjk+0.01))+0.01 elseif @merge == "B/A" zri = (zri / (oldzri+0.01))+0.01 zjk = (zjk / (oldzjk+0.01))+0.01 elseif @merge == "Largest(A,B)" if |zri| < |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif elseif @merge == "Smallest(A,B)" if |zri| > |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif endif endif endif if m_brot modh = cabs(zri) else modh = sqrt(|zri|+|zjk|) endif if @potmeth == "general smoothing" if m_brot modhold = cabs(oldzri-zri) else modhold = sqrt(|oldzri-zri|+|oldzjk-zjk|) endif siter = siter + exp(-modh-0.5/modhold) endif i = i + 1 until i == #maxiter || (modh > bailout) if @potmeth == "Vepstas" siter = i + log(log(modh))/log(2) endif if m_brot modhd = cabs(zrid) else modhd = sqrt(|zrid|+|zjkd|) endif if modh <= bailout dist = dist - d d = 0 if dist < 0 dist = 0 endif else if @potmeth != "Iteration Smoothing" pot = exp(-siter*log(2)) if !@noderiv grad = pot*modhd/(modh*log(modh)) else grad = exp(-(siter-i)*log(2)) endif if !@noderiv d = dfactor*sinh(pot)/(2*exp(pot)*grad) else d = 10*dfactor*sinh(pot)/(2*exp(pot)*grad) endif else d = modh*log(modh)/modhd*(dfactor/2) endif if d > maxstep d = maxstep endif dist = d + dist endif zrid = 1 zjkd = 0 if (m_julia || m_brot) && use1 if fourth == 3 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 zri = ucamj-dist*vj + flip(ck) zjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 zri = flip(ucamj-dist*vj) + ck zjk = ucamr-dist*vr + flip(ucami-dist*vi) endif elseif m_mand && use1 if fourth == 3 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 cri = ucamj-dist*vj + flip(ck) cjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 cri = flip(ucamj-dist*vj) + ck cjk = ucamr-dist*vr + flip(ucami-dist*vi) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) endif if (m_julia2 || m_brot2) && !use1 if fourth2 == 3 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = ucamj-dist*vj + flip(ck2) elseif fourth2 == 2 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = flip(ucamj-dist*vj) + ck2 elseif fourth2 == 1 zri = ucamj-dist*vj + flip(ck2) zjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth2 == 0 zri = flip(ucamj-dist*vj) + ck2 zjk = ucamr-dist*vr + flip(ucami-dist*vi) endif elseif m_mand2 && !use1 if fourth2 == 3 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = ucamj-dist*vj + flip(ck2) elseif fourth2 == 2 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = flip(ucamj-dist*vj) + ck2 elseif fourth2 == 1 cri = ucamj-dist*vj + flip(ck2) cjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth2 == 0 cri = flip(ucamj-dist*vj) + ck2 cjk = ucamr-dist*vr + flip(ucami-dist*vi) endif m_q2.setjp(cri,cjk) m_q2.getmp(zri,zjk) endif i = 0 siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif until (d <= epsilon || dist > maxdist) if dist < epsilon dist = 1e10 endif if (dist > 0 && dist <= maxdist) || d == 0 infinity = false endif if !infinity ; set the intersection point and distance for normal calculation fzriy = camr-(dist+reduce)*vr + flip(cami-(dist+reduce)*vi) if dist != 0 fzjky = camj-(dist+reduce)*vj + flip((dist+reduce)) else fzjky = camj-(dist+reduce)*vj + flip((1)) endif endif endif ; DELTA YN if @numnorm == "5 point" infinity = true ; calculate screen position vpr = rmin + (#x*trmax)/#width vpi = imax - ((#y-@dn)*timax)/#height vpj = 0 ; unrotated position used for calcs fvpr = vpr fvpi = vpi fvpj = vpj ; screen position ; rotate around x axis temp = vpi vpi = vpi*cos(xangle)-vpj*sin(xangle) vpj = vpj*cos(xangle)+temp*sin(xangle) ; rotate around y axis temp = vpr vpr = vpr*cos(yangle)-vpj*sin(yangle) vpj = vpj*cos(yangle)+temp*sin(yangle) ; rotate around z axis rtemp = vpr + flip(vpi) rtemp = rtemp*zrot vpr = real(rtemp) vpi = imag(rtemp) ; create camera vector vr = camr-vpr vi = cami-vpi vj = camj-vpj vd = sqrt(vr*vr+vi*vi+vj*vj) vr = vr/vd vi = vi/vd vj = vj/vd mindist = mindistr*vr+mindisti*vi+mindistj*vj maxdist = maxdistr*vr+maxdisti*vi+maxdistj*vj ; distance camera correction if vd > mindist ucamr = camr-(vd-mindist)*vr ucami = cami-(vd-mindist)*vi ucamj = camj-(vd-mindist)*vj reduce = vd-mindist else ucamr = camr ucami = cami ucamj = camj reduce = 0 endif if @useFirst use1 = true else use1 = false endif if @view == "3D" ; calculate distance from camera to quaternion zrid = 1 zjkd = 0 if (m_julia || m_brot) && use1 if fourth == 3 zri = ucamr + flip(ucami) zjk = ucamj + flip(ck) elseif fourth == 2 zri = ucamr + flip(ucami) zjk = flip(ucamj) + ck elseif fourth == 1 zri = ucamj + flip(ck) zjk = ucamr + flip(ucami) elseif fourth == 0 zri = flip(ucamj) + ck zjk = ucamr + flip(ucami) endif elseif m_mand && use1 if fourth == 3 cri = ucamr + flip(ucami) cjk = ucamj + flip(ck) elseif fourth == 2 cri = ucamr + flip(ucami) cjk = flip(ucamj) + ck elseif fourth == 1 cri = ucamj + flip(ck) cjk = ucamr + flip(ucami) elseif fourth == 0 cri = flip(ucamj) + ck cjk = ucamr + flip(ucami) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) endif if (m_julia2 || m_brot2) && !use1 if fourth2 == 3 zri = ucamr + flip(ucami) zjk = ucamj + flip(ck2) elseif fourth2 == 2 zri = ucamr + flip(ucami) zjk = flip(ucamj) + ck2 elseif fourth2 == 1 zri = ucamj + flip(ck2) zjk = ucamr + flip(ucami) elseif fourth2 == 0 zri = flip(ucamj) + ck2 zjk = ucamr + flip(ucami) endif elseif m_mand2 && !use1 if fourth2 == 3 cri = ucamr + flip(ucami) cjk = ucamj + flip(ck2) elseif fourth2 == 2 cri = ucamr + flip(ucami) cjk = flip(ucamj) + ck2 elseif fourth2 == 1 cri = ucamj + flip(ck2) cjk = ucamr + flip(ucami) elseif fourth2 == 0 cri = flip(ucamj) + ck2 cjk = ucamr + flip(ucami) endif m_q2.setjp(cri,cjk) m_q2.getmp(zri,zjk) endif i = 0 dist = 0 infinity = true siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif if m_spider2 cri = spidercri cjk = spidercjk m_q2.setjp(cri,cjk) endif repeat repeat oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if !@altuse1 olduse1 = use1 else olduse1 = !use1 endif if @itermeth == "flavor1" if i % iterval == 0 && @dual && i != 0 use1 = !use1 endif else if @dual if i % (@seqgap1) >= 0 && @seqgap2 != 0 switch1 = true switch2 = false endif if (i % (@seqgap1) >= (i % @seqgap2)+1) || @seqgap2 == 0 switch1 = false switch2 = true endif if @seqgap2 > @seqgap1 switch1 = true switch2 = false endif endif if @dual if switch1 iter1 = true iter2 = false elseif switch2 iter1 = false iter2 = true endif endif if @dual if iter1 if @usefirst use1 = true else use1 = false endif elseif iter2 if @usefirst use1 = false else use1 = true endif endif endif endif if m_oldz m_q.setomp(oldzri,oldzjk) endif if m_oldz2 m_q2.setomp(oldzri,oldzjk) endif ; calculate derivative if use1 m_q.drcalc(zri, zjk, zrid, zjkd) else m_q2.drcalc(zri, zjk, zrid, zjkd) endif ; calculate fractal if use1 m_q.frcalc(zri, zjk) else m_q2.frcalc(zri, zjk) endif if m_spider m_q.getjp(cri,cjk) endif if m_oldz m_q.getomp(oldzri,oldzjk) endif if m_spider2 m_q2.getjp(cri,cjk) endif if m_oldz2 m_q2.getomp(oldzri,oldzjk) endif if @itermeth == "flavor1" if (olduse1 != use1) && @merge != "None" && i != 0 if @merge == "Average" zri = (oldzri + zri)/2 zjk = (oldzjk + zjk)/2 elseif @merge == "A+B" zri = (oldzri + zri) zjk = (oldzjk + zjk) elseif @merge == "A-B" zri = (oldzri - zri) zjk = (oldzjk - zjk) elseif @merge == "B-A" zri = (-oldzri + zri) zjk = (-oldzjk + zjk) elseif @merge == "A*B" zri = 2*(oldzri * zri)/(oldzri + zri) zjk = 2*(oldzjk * zjk)/(oldzjk + zjk) elseif @merge == "A/B" zri = (oldzri / (zri+0.01))+0.01 zjk = (oldzjk / (zjk+0.01))+0.01 elseif @merge == "B/A" zri = (zri / (oldzri+0.01))+0.01 zjk = (zjk / (oldzjk+0.01))+0.01 elseif @merge == "Largest(A,B)" if |zri| < |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif elseif @merge == "Smallest(A,B)" if |zri| > |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif endif endif else if @merge != "None" && (@mergealt && switch1 || switch2) if @merge == "Average" zri = (oldzri + zri)/2 zjk = (oldzjk + zjk)/2 elseif @merge == "A+B" zri = (oldzri + zri) zjk = (oldzjk + zjk) elseif @merge == "A-B" zri = (oldzri - zri) zjk = (oldzjk - zjk) elseif @merge == "B-A" zri = (-oldzri + zri) zjk = (-oldzjk + zjk) elseif @merge == "A*B" zri = 2*(oldzri * zri)/(oldzri + zri) zjk = 2*(oldzjk * zjk)/(oldzjk + zjk) elseif @merge == "A/B" zri = (oldzri / (zri+0.01))+0.01 zjk = (oldzjk / (zjk+0.01))+0.01 elseif @merge == "B/A" zri = (zri / (oldzri+0.01))+0.01 zjk = (zjk / (oldzjk+0.01))+0.01 elseif @merge == "Largest(A,B)" if |zri| < |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif elseif @merge == "Smallest(A,B)" if |zri| > |oldzri| zri = oldzri endif if |zjk| < |oldzjk| zjk = oldzjk endif endif endif endif if m_brot modh = cabs(zri) else modh = sqrt(|zri|+|zjk|) endif if @potmeth == "general smoothing" if m_brot modhold = cabs(oldzri-zri) else modhold = sqrt(|oldzri-zri|+|oldzjk-zjk|) endif siter = siter + exp(-modh-0.5/modhold) endif i = i + 1 until i == #maxiter || (modh > bailout) if @potmeth == "Vepstas" siter = i + log(log(modh))/log(2) endif if m_brot modhd = cabs(zrid) else modhd = sqrt(|zrid|+|zjkd|) endif if modh <= bailout dist = dist - d d = 0 if dist < 0 dist = 0 endif else if @potmeth != "Iteration Smoothing" pot = exp(-siter*log(2)) if !@noderiv grad = pot*modhd/(modh*log(modh)) else grad = exp(-(siter-i)*log(2)) endif if !@noderiv d = dfactor*sinh(pot)/(2*exp(pot)*grad) else d = 10*dfactor*sinh(pot)/(2*exp(pot)*grad) endif else d = modh*log(modh)/modhd*(dfactor/2) endif if d > maxstep d = maxstep endif dist = d + dist endif zrid = 1 zjkd = 0 if (m_julia || m_brot) && use1 if fourth == 3 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 zri = ucamj-dist*vj + flip(ck) zjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 zri = flip(ucamj-dist*vj) + ck zjk = ucamr-dist*vr + flip(ucami-dist*vi) endif elseif m_mand && use1 if fourth == 3 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = ucamj-dist*vj + flip(ck) elseif fourth == 2 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = flip(ucamj-dist*vj) + ck elseif fourth == 1 cri = ucamj-dist*vj + flip(ck) cjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth == 0 cri = flip(ucamj-dist*vj) + ck cjk = ucamr-dist*vr + flip(ucami-dist*vi) endif m_q.setjp(cri,cjk) m_q.getmp(zri,zjk) endif if (m_julia2 || m_brot2) && !use1 if fourth2 == 3 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = ucamj-dist*vj + flip(ck2) elseif fourth2 == 2 zri = ucamr-dist*vr + flip(ucami-dist*vi) zjk = flip(ucamj-dist*vj) + ck2 elseif fourth2 == 1 zri = ucamj-dist*vj + flip(ck2) zjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth2 == 0 zri = flip(ucamj-dist*vj) + ck2 zjk = ucamr-dist*vr + flip(ucami-dist*vi) endif elseif m_mand2 && !use1 if fourth2 == 3 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = ucamj-dist*vj + flip(ck2) elseif fourth2 == 2 cri = ucamr-dist*vr + flip(ucami-dist*vi) cjk = flip(ucamj-dist*vj) + ck2 elseif fourth2 == 1 cri = ucamj-dist*vj + flip(ck2) cjk = ucamr-dist*vr + flip(ucami-dist*vi) elseif fourth2 == 0 cri = flip(ucamj-dist*vj) + ck2 cjk = ucamr-dist*vr + flip(ucami-dist*vi) endif m_q2.setjp(cri,cjk) m_q2.getmp(zri,zjk) endif i = 0 siter = 0 oldzri2 = oldzri oldzjk2 = oldzjk oldzri = zri oldzjk = zjk if m_spider cri = spidercri cjk = spidercjk m_q.setjp(cri,cjk) endif until (d <= epsilon || dist > maxdist) if dist < epsilon dist = 1e10 endif if (dist > 0 && dist <= maxdist) || d == 0 infinity = false endif if !infinity ; set the intersection point and distance for normal calculation fzriyn = camr-(dist+reduce)*vr + flip(cami-(dist+reduce)*vi) if dist != 0 fzjkyn = camj-(dist+reduce)*vj + flip((dist+reduce)) else fzjkyn = camj-(dist+reduce)*vj + flip((1)) endif endif endif endif if @szoom sdfactor = @dfactor/#magn/scrsize*820 else sdfactor = @dfactor endif float svpr = 0 float svpi = 0 float svpj = 0 float svr = 0 float svi = 0 float svj = 0 float svd = 0 float stemp = 0 iii = 0 mycolor = 0 bool shad = false int xcrd = #x int ycrd = #y complex srtemp = 0 szri = 0 szjk = 0 oldszri = 0 oldszjk = 0 oldszri2 = 0 oldszjk2 = 0 sztemp = 0 szrid = 0 szjkd = 0 smodH = 0 smodHold = 0 float smodHd = 0 float sdist = 0 float sgrad = 0 float spot = 0 float sreduce = 0 float smindist = 0 float smindistr = mindistr float smindisti = mindisti float smindistj = mindistj float sd = 0 float ssiter = 0 ; light origin float lightr = 0 float lighti = 0 float lightj = 0 if @ltype == "Infinite Light" ; assumes light points at (0,0,0) lightr = -lx*camj lighti = -ly*camj lightj = -lz*camj else lightr = lpointx lighti = lpointy lightj = lpointz endif float ulightr = 0 float ulighti = 0 float ulightj = 0 float slr = 0 float sli = 0 float slj = 0 float sld = 0 float l = 0 float svr = 0 float svi = 0 float svj = 0 float svd = 0 float rr = 0 float ri = 0 float rj = 0 float ir = 0 float ii = 0 float ij = 0 float nr = 0 float ni = 0 float nj = 0 complex fri = 0 complex frj = 0 float n = 0 ; generate the x and y location in the image float dxx = (real(#pixel)-real(#center))*(#width)/4*#magn float dyy = (imag(#pixel)-imag(#center))*(#width)/4*#magn float transx = (#width)*0.5; float transy = (#height)*0.5; float cosan = cos(#angle); float sinan = sin(#angle); xcrd = round((transx + (dxx*cosan + dyy*sinan))) ycrd = round((transy + (dxx*sinan - dyy*cosan))) if @view == "3D" && imag(fzjk) > -3 if xcrd <#width-1 && ycrd <#height-1 && xcrd > 0 && \ ycrd > 0 ; calculate the normals fri = fzri frj = real(fzjk) rr = real(fzrix-fri) ri = imag(fzrix-fri) rj = real(fzjkx-frj) n = sqrt(rr^2+ri^2+rj^2) rr = rr/n ri = ri/n rj = rj/n ir = real(fzriy-fri) ii = imag(fzriy-fri) ij = real(fzjky-frj) n = sqrt(ir^2+ii^2+ij^2) ir = ir/n ii = ii/n ij = ij/n nr = ri*ij - rj*ii ni = rj*ir - rr*ij nj = rr*ii - ri*ir if @numnorm == "5 point" rr = real(fzrixn-fri) ri = imag(fzrixn-fri) rj = real(fzjkxn-frj) n = sqrt(rr^2+ri^2+rj^2) rr = rr/n ri = ri/n rj = rj/n ir = real(fzriyn-fri) ii = imag(fzriyn-fri) ij = real(fzjkyn-frj) n = sqrt(ir^2+ii^2+ij^2) ir = ir/n ii = ii/n ij = ij/n nr = (nr+ri*ij - rj*ii)/2 ni = (ni+rj*ir - rr*ij)/2 nj = (nj+rr*ii - ri*ir)/2 endif n = sqrt(nr^2+ni^2+nj^2) nr = nr/n ni = ni/n nj = nj/n float ntemp = 0 ; rotate around z axis in opposite direction from other z axis ; rotations srtemp = nr + flip(ni) srtemp = srtemp*conj(zrot) nr = real(srtemp) ni = imag(srtemp) ; rotate around y axis ntemp = nr nr = nr*cos(yangle)+nj*sin(yangle) nj = nj*cos(yangle)-ntemp*sin(yangle) ; rotate around x axis ntemp = ni ni = ni*cos(xangle)+nj*sin(xangle) nj = nj*cos(xangle)-ntemp*sin(xangle) n = sqrt(nr^2+ni^2+nj^2) nr = nr/n ni = ni/n nj = nj/n l = lx*nr + ly*ni + lz*nj if isNAN(l) l = 0 endif endif ; shadows on the fractal object if @shadows &&((imag(fzjk) > 0 && imag(fzjk)-reduce\ <= maxdist)) shad = false ; calculate light vector ; rotate around x axis ntemp = lighti lighti = lighti*cos(xangle)-lightj*sin(xangle) lightj = lightj*cos(xangle)+ntemp*sin(xangle) ; rotate around y axis ntemp = lightr lightr = lightr*cos(yangle)-lightj*sin(yangle) lightj = lightj*cos(yangle)+ntemp*sin(yangle) ; rotate around z axis srtemp = lightr + flip(lighti) srtemp = srtemp*zrot lightr = real(srtemp) lighti = imag(srtemp) slr = lightr - real(fzri) sli = lighti - imag(fzri) slj = lightj - real(fzjk) sld = sqrt(slr^2+sli^2+slj^2) slr = slr/sld sli = sli/sld slj = slj/sld svr = camr-real(fzri) svi = cami-imag(fzri) svj = camj-real(fzjk) svd = sqrt(svr*svr+svi*svi+svj*svj) svr = svr/svd svi = svi/svd svj = svj/svd smindist = (smindistr*svr+smindisti*svi+smindistj*svj) if sld >= smindist ulightr = lightr - (sld-smindist)*slr ulighti = lighti - (sld-smindist)*sli ulightj = lightj - (sld-smindist)*slj sreduce = sld-smindist else ulightr = lightr ulighti = lighti ulightj = lightj sreduce = 0 endif szrid = 1 szjkd = 0 if @useFirst use1 = true else use1 = false endif if (m_julia || m_brot) && use1 if fourth == 3 szri = ulightr + flip(ulighti) szjk = ulightj + flip(ck) elseif fourth == 2 szri = ulightr + flip(ulighti) szjk = flip(ulightj) + ck elseif fourth == 1 szri = ulightj + flip(ck) szjk = ulightr + flip(ulighti) elseif fourth == 0 szri = flip(ulightj) + ck szjk = ulightr + flip(ulighti) endif elseif m_mand && use1 if fourth == 3 scri = ulightr + flip(ulighti) scjk = ulightj + flip(ck) elseif fourth == 2 scri = ulightr + flip(ulighti) scjk = flip(ulightj) + ck elseif fourth == 1 scri = ulightj + flip(ck) scjk = ulightr + flip(ulighti) elseif fourth == 0 scri = flip(ulightj) + ck scjk = ulightr + flip(ulighti) endif m_q.setjp(scri,scjk) m_q.getmp(szri,szjk) endif if (m_julia2 || m_brot2) && !use1 if fourth2 == 3 szri = ulightr + flip(ulighti) szjk = ulightj + flip(ck) elseif fourth2 == 2 szri = ulightr + flip(ulighti) szjk = flip(ulightj) + ck2 elseif fourth2 == 1 szri = ulightj + flip(ck2) szjk = ulightr + flip(ulighti) elseif fourth2 == 0 szri = flip(ulightj) + ck2 szjk = ulightr + flip(ulighti) endif elseif m_mand && !use1 if fourth2 == 3 scri = ulightr + flip(ulighti) scjk = ulightj + flip(ck2) elseif fourth2 == 2 scri = ulightr + flip(ulighti) scjk = flip(ulightj) + ck2 elseif fourth2 == 1 scri = ulightj + flip(ck2) scjk = ulightr + flip(ulighti) elseif fourth2 == 0 scri = flip(ulightj) + ck2 scjk = ulightr + flip(ulighti) endif m_q2.setjp(scri,scjk) m_q2.getmp(szri,szjk) endif si = 0 sdist = 0 ssiter = 0 oldszri2 = oldszri oldszjk2 = oldszjk oldszri = szri oldszjk = szjk if m_spider scri = spidercri scjk = spidercjk m_q.setjp(scri,scjk) endif if m_spider2 scri = spidercri scjk = spidercjk m_q2.setjp(scri,scjk) endif repeat repeat oldszri2 = oldszri oldszjk2 = oldszjk oldszri = szri oldszjk = szjk if !@altuse1 olduse1 = use1 else olduse1 = !use1 endif if @itermeth == "flavor1" if si % iterval == 0 && @dual && si != 0 use1 = !use1 endif else if @dual if si % (@seqgap1) >= 0 && @seqgap2 != 0 switch1 = true switch2 = false endif if (si % (@seqgap1) >= (si % @seqgap2)+1) || @seqgap2 == 0 switch1 = false switch2 = true endif if @seqgap2 > @seqgap1 switch1 = true switch2 = false endif endif if @dual if switch1 iter1 = true iter2 = false elseif switch2 iter1 = false iter2 = true endif endif if @dual if iter1 if @usefirst use1 = true else use1 = false endif elseif iter2 if @usefirst use1 = false else use1 = true endif endif endif endif if m_oldz m_q.setomp(oldszri,oldszjk) endif if m_oldz2 m_q2.setomp(oldszri,oldszjk) endif ; calculate derivative if use1 m_q.drcalc(szri, szjk, szrid, szjkd) else m_q2.drcalc(szri, szjk, szrid, szjkd) endif ; calculate fractal if use1 m_q.frcalc(szri,szjk) else m_q2.frcalc(szri,szjk) endif if m_oldz m_q.getomp(oldszri,oldszjk) endif if m_spider m_q.getjp(scri,scjk) endif if m_oldz2 m_q2.getomp(oldszri,oldszjk) endif if m_spider2 m_q2.getjp(scri,scjk) endif if @itermeth == "flavor1" if (olduse1 != use1) && @merge != "None" && si != 0 if @merge == "Average" szri = (oldszri + szri)/2 szjk = (oldszjk + szjk)/2 elseif @merge == "A+B" szri = (oldszri + szri) szjk = (oldszjk + szjk) elseif @merge == "A-B" szri = (oldszri - szri) szjk = (oldszjk - szjk) elseif @merge == "B-A" szri = (-oldszri + szri) szjk = (-oldszjk + szjk) elseif @merge == "A*B" szri = 2*(oldszri * szri)/(oldszri + szri) szjk = 2*(oldszjk * szjk)/(oldszjk + szjk) elseif @merge == "A/B" szri = (oldszri / (szri+0.01))+0.01 szjk = (oldszjk / (szjk+0.01))+0.01 elseif @merge == "B/A" szri = (szri / (oldszri+0.01))+0.01 szjk = (szjk / (oldszjk+0.01))+0.01 elseif @merge == "Largest(A,B)" if |szri| < |oldszri| szri = oldszri endif if |szjk| < |oldszjk| szjk = oldszjk endif elseif @merge == "Smallest(A,B)" if |szri| > |oldszri| szri = oldszri endif if |szjk| < |oldszjk| szjk = oldszjk endif endif endif else if @merge != "None" && (@mergealt && switch1 || switch2) if @merge == "Average" szri = (oldszri + szri)/2 szjk = (oldszjk + szjk)/2 elseif @merge == "A+B" szri = (oldszri + szri) szjk = (oldszjk + szjk) elseif @merge == "A-B" szri = (oldszri - szri) szjk = (oldszjk - szjk) elseif @merge == "B-A" szri = (-oldszri + szri) szjk = (-oldszjk + szjk) elseif @merge == "A*B" szri = 2*(oldszri * szri)/(oldszri + szri) szjk = 2*(oldszjk * szjk)/(oldszjk + szjk) elseif @merge == "A/B" szri = (oldszri / (szri+0.01))+0.01 szjk = (oldszjk / (szjk+0.01))+0.01 elseif @merge == "B/A" szri = (szri / (oldszri+0.01))+0.01 szjk = (szjk / (oldszjk+0.01))+0.01 elseif @merge == "Largest(A,B)" if |szri| < |oldszri| szri = oldszri endif if |szjk| < |oldszjk| szjk = oldszjk endif elseif @merge == "Smallest(A,B)" if |szri| > |oldszri| szri = oldszri endif if |szjk| < |oldszjk| szjk = oldszjk endif endif endif endif if m_brot smodh = cabs(szri) else smodh = sqrt(|szri|+|szjk|) endif if @potmeth == "general smoothing" if m_brot smodhold = cabs(oldszri-szri) else smodhold = sqrt(|oldszri-szri|+|oldszjk-szjk|) endif ssiter = ssiter + exp(-smodh-0.5/smodhold) endif si = si + 1 until si == #maxiter || smodh > bailout if @potmeth == "Vepstas" ssiter = si + log(log(smodh))/log(2) endif if m_brot smodhd = cabs(szrid) else smodhd = sqrt(|szrid|+|szjkd|) endif if smodh <= bailout sdist = sdist - sd sd = 0 else if @potmeth != "Iteration Smoothing" spot = exp(-ssiter*log(2)) if !@noderiv sgrad = spot*smodhd/(smodh*log(smodh)) else sgrad = exp(-(ssiter-si)*log(2)) endif if !@noderiv sd = sdfactor*sinh(spot)/(2*exp(spot)*sgrad) else sd = 10*sdfactor*sinh(spot)/(2*exp(spot)*sgrad) endif else sd = smodh*log(smodh)/smodhd*(sdfactor/2) endif if sd > maxstep sd = maxstep endif sdist = sd + sdist endif szrid = 1 szjkd = 0 if (m_julia || m_brot) && use1 if fourth == 3 szri = ulightr-sdist*slr + flip(ulighti-sdist*sli) szjk = ulightj-sdist*slj + flip(ck) elseif fourth == 2 szri = ulightr-sdist*slr + flip(ulighti-sdist*sli) szjk = flip(ulightj-sdist*slj) + ck elseif fourth == 1 szri = ulightj-sdist*slj + flip(ck) szjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) elseif fourth == 0 szri = flip(ulightj-sdist*slj) + ck szjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) endif elseif m_mand && use1 if fourth == 3 scri = ulightr-sdist*slr + flip(ulighti-sdist*sli) scjk = ulightj-sdist*slj + flip(ck) elseif fourth == 2 scri = ulightr-sdist*slr + flip(ulighti-sdist*sli) scjk = flip(ulightj-sdist*slj) + ck elseif fourth == 1 scri = ulightj-sdist*slj + flip(ck) scjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) elseif fourth == 0 scri = flip(ulightj-sdist*slj) + ck scjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) endif m_q.setjp(scri,scjk) m_q.getmp(szri,szjk) endif if (m_julia2 || m_brot2) && !use1 if fourth2 == 3 szri = ulightr-sdist*slr + flip(ulighti-sdist*sli) szjk = ulightj-sdist*slj + flip(ck2) elseif fourth2 == 2 szri = ulightr-sdist*slr + flip(ulighti-sdist*sli) szjk = flip(ulightj-sdist*slj) + ck2 elseif fourth2 == 1 szri = ulightj-sdist*slj + flip(ck2) szjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) elseif fourth2 == 0 szri = flip(ulightj-sdist*slj) + ck2 szjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) endif elseif m_mand2 && !use1 if fourth2 == 3 scri = ulightr-sdist*slr + flip(ulighti-sdist*sli) scjk = ulightj-sdist*slj + flip(ck2) elseif fourth2 == 2 scri = ulightr-sdist*slr + flip(ulighti-sdist*sli) scjk = flip(ulightj-sdist*slj) + ck2 elseif fourth2 == 1 scri = ulightj-sdist*slj + flip(ck2) scjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) elseif fourth2 == 0 scri = flip(ulightj-sdist*slj) + ck2 scjk = ulightr-sdist*slr + flip(ulighti-sdist*sli) endif m_q2.setjp(scri,scjk) m_q2.getmp(szri,szjk) endif si = 0 oldszri2 = oldszri oldszjk2 = oldszjk oldszri = szri oldszjk = szjk if m_spider scri = spidercri scjk = spidercjk m_q.setjp(scri,scjk) endif if m_spider2 scri = spidercri scjk = spidercjk m_q2.setjp(scri,scjk) endif ssiter = 0 until (sd <= @objshadsens*epsilon || sdist > maxdist) if sreduce != 0 sdist = sdist+sreduce endif if sdist < sld*@srough && sd <= @objshadsens*epsilon && imag(fzjk) != 1 shad = true endif endif mycolor = l*#maxiter/2 if (imag(fzjk) != 0) || (imag(fzjk)-reduce <= maxdist) \ || imag(fzjk) == 1 if @type == "Raytrace" pz = l + flip(imag(fzjk)) if imag(fzjk) == 1 pz = l + flip(fdst) endif elseif @type == "Distance" if imag(fzjk) == 1 if @ray pz = fdst+ l/2 else pz = fdst endif else if @ray pz = imag(fzjk)+ l/2 else pz = imag(fzjk) endif endif elseif @type == "Z value" float nx= fdst float ny = fdst float nz = 0 if @corzd && imag(fzjk) != 0 nz= (real(fzjk)-@zoff)/@zmax else nz= real(fzjk) endif float ntemp = nx nx= nx*cos(yangle)+nz*sin(yangle) nz = nz*cos(yangle)-ntemp*sin(yangle) ntemp = ny ny = ny*cos(xangle)+nz*sin(xangle) nz = nz*cos(xangle)-ntemp*sin(xangle) if imag(fzjk) == 1 if @ray pz = nx + flip(ny) + l/2 else pz = nx + flip(ny) endif else if @ray pz = abs(nz) + l/2 else pz = abs(nz) endif endif elseif @type == "Iteration" if imag(fzjk) == 1 if @ray pz = trunc(l*2^19) + icolor/2^20 else pz = icolor/2^20 endif else if @ray pz = trunc(l*2^19) + icolor/2^20 else pz = icolor/2^20 endif ; endif endif endif endif if cabs(pz) != 0 if @type == "Raytrace" pz = real(pz) + (0,-1) if shad pz = real(pz) + (0,-2) endif elseif @type == "Distance" || @type == "Z value" pz = real(pz) + (0,1) elseif @type == "Iteration" pz = real(pz) + (0,2) endif endif elseif @view == "2D"; initialize 2D parameters svpr = rmin + (xcrd*trmax)/#width svpi = imax - (ycrd*timax)/#height svpj = 0 ; rotate around x axis stemp = svpi svpi = svpi*cos(xangle)-svpj*sin(xangle) svpj = svpj*cos(xangle)+stemp*sin(xangle) ; rotate around y axis stemp = svpr svpr = svpr*cos(yangle)-svpj*sin(yangle) svpj = svpj*cos(yangle)+stemp*sin(yangle) ; rotate around z axis srtemp = svpr + flip(svpi) srtemp = srtemp*zrot svpr = real(srtemp) svpi = imag(srtemp) svr = camr-svpr svi = cami-svpi svj = camj-svpj svd = sqrt(svr*svr+svi*svi+svj*svj) svr = svr/svd svi = -svi/svd svj = -svj/svd smindist = svr*smindistr-svi*smindisti-svj*smindistj if m_julia || m_brot if fourth == 3 szri = camr - (svd-smindist)*svr + flip(cami +(svd-smindist)*svi) szjk = camj + (svd-smindist)*svj + flip(ck) elseif fourth == 2 szri = camr- (svd-smindist)*svr - flip(cami+ (svd-smindist)*svi) szjk = flip(camj+ (svd-smindist)*svj) + ck elseif fourth == 1 szri = camj+ (svd-smindist)*svj + flip(ck) szjk = camr- (svd-smindist)*svr + flip(cami- (svd-smindist)*svi) elseif fourth == 0 szri = flip(camj+ (svd-smindist)*svj) + ck szjk = camr- (svd-smindist)*svr + flip(cami- (svd-smindist)*svi) endif elseif m_mand if fourth == 3 scri = camr - (svd-smindist)*svr - flip(cami + (svd-smindist)*svi) scjk = camj + (svd-smindist)*svj + flip(ck) elseif fourth == 2 scri = camr - (svd-smindist)*svr - flip(cami + (svd-smindist)*svi) scjk = flip(camj + (svd-smindist)*svj) + ck elseif fourth == 1 scri = camj + (svd-smindist)*svj + flip(ck) scjk = camr - (svd-smindist)*svr - flip(cami + (svd-smindist)*svi) elseif fourth == 0 scri = flip(camj + (svd-smindist)*svj) + ck scjk = camr - (svd-smindist)*svr - flip(cami + (svd-smindist)*svi) endif m_q.setjp(scri,scjk) m_q.getmp(szri,szjk) endif oldszri2 = oldszri oldszjk2 = oldszjk oldszri = szri oldszjk = szjk if m_spider scri = spidercri scjk = spidercjk m_q.setjp(scri,scjk) endif endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Formula.Iterate(pz) iii = iii + 1 if @view == "2D" if m_oldz m_q.setomp(oldszri,oldszjk) endif m_q.frcalc(szri, szjk) if m_oldz m_q.getomp(oldszri,oldszjk) endif if m_spider m_q.getjp(scri,scjk) endif if m_brot smodh = cabs(szri) else smodh = sqrt(|szri|+|szjk|) endif pz = szri if @compat float m = abs(real(pz))/512.0 if m < 1e-200 m = 1e-200 endif m = m + (356)*2.0^floor(1.0+log(m)/log(2.0)) if real(pz)<0.0 m = -m endif pz = m + flip(imag(pz)) endif endif return pz endfunc ; This overrides formula bailout. bool func IsBailedOut(complex pz) if @view == "2D" m_BailedOut = smodh > bailout else m_BailedOut = iii > mycolor endif return m_BailedOut endfunc protected: bool switch1 bool switch2 bool iter1 bool iter2 int iterval int si bool use1 bool olduse1 float scrsize complex zri complex zjk complex zrix complex zriy complex zriz complex zriw complex zjkx complex zjky complex zjkz complex zjkw complex zrid complex zjkd complex rtemp complex cri complex cjk float vpr float vpi float vpj float fvpr float fvpi float fvpj ; ray normal float vr float vi float vj float vd float camr float cami float camj float ucamr float ucami float ucamj float modH float modHd float d float dist bool infinity float dfactor float sdfactor float olddfactor float oldsdfactor float epsilon float ci float cr float trmax float timax float rmin float imax ; light origin float lpointx float lpointy float lpointz ; light point at float lightx float lighty float lightz ; light vector float lx float ly float lz float xangle float yangle complex zrot float temp complex im float bailout float pot float grad float siter float reduce float mindist float mindistr float mindisti float mindistj float maxdist float maxdistr float maxdisti float maxdistj float camd int iii float smodh float mycolor complex sztemp complex szri complex szjk complex szrix complex szjkx complex szriy complex szjky complex szriz complex szjkz complex szriw complex szjkw complex scri complex scjk Quat m_q Quat m_q2 bool m_julia bool m_mand bool m_hyper bool m_quat bool m_brot bool m_sphere bool m_julia2 bool m_mand2 bool m_hyper2 bool m_quat2 bool m_brot2 bool m_sphere2 bool firstpass float bepsilon int fourth float ck int fourth2 float ck2 complex oldzri complex oldzjk complex oldszri complex oldszjk float modHold float smodHold bool m_spider bool m_spider2 complex spidercri complex spidercjk bool m_oldz bool m_oldz2 float inc float maxstep float pow complex oldzri2 complex oldzjk2 complex oldszri2 complex oldszjk2 float dold float itercolor int i default: title = "3D Fractal Raytrace Progressive (UF5)" int param v_3D_Fractal_RaytraceProgressive caption = "Version (3D Fractal Raytrace Progressive)" 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_3D_Fractal_RaytraceProgressive < 100 endparam complex param p_power caption = "Exponent" default = (2,0) visible = false endparam heading text = "Based upon an article by Hart, Sandin and Kauffman for estimating \ the distance from a point to a fractal surface." endheading heading text = "For optimal Raytracing results, use the coloring formula 3D Fractal \ Coloring Direct (UF5). This formula is required for the 'Distance', \ 'Z Value' and 'Iteration' Display Types. Any coloring formula can \ be used when the Object view parameter is 2D." endheading heading caption = "Camera Settings" expanded = false endheading bool param setzoom caption = "Set to zoom center" default = false endparam heading text = "Camera Origin" visible = @view == "3D" endheading float param camr caption = " X" default = 0.0 visible = !@setzoom endparam float param cami caption = " Y" default = 0.0 visible = !@setzoom endparam float param camj caption = " Z" default = 100.0 endparam heading caption = "Illumination" expanded = false visible = @view == "3D" && @type == "raytrace" endheading param ltype caption = "Light type" enum = "Point source" "Infinite light" default = 0 visible = @view == "3D" && @type == "raytrace" endparam heading text = "Counter clockwise from the X axis." visible = @ltype == "Infinite light" && @view == "3D" && @type == "raytrace" endheading param angle caption = "Light Rotation" default = 60.0 min = -180 max = 180 hint = "Gives the rotation of the light source, in degrees." visible = @ltype == "Infinite light" && @view == "3D" && @type == "raytrace" endparam heading text = "Degrees of elevation above the complex plane." visible = @ltype == "Infinite light" && @view == "3D" && @type == "raytrace" endheading param elevation caption = "Light Elevation" default = 60.0 min = -90 max = 90 hint = "Gives the elevation of the light source, in degrees." visible = @ltype == "Infinite light" && @view == "3D" && @type == "raytrace" endparam heading text = "Light Origin" visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endheading float param lpointx caption = " X" default = 30 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam float param lpointy caption = " Y" default = 40 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam float param lplane caption = " Z" default = 100 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam heading text = "Light Point At" visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endheading float param lightx caption = " X" default = 0.0 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam float param lighty caption = " Y" default = 0.0 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam float param lightz caption = " Z" default = 0.0 visible=@ltype != "infinite light" && @view == "3D" && @type == "raytrace" endparam heading caption = "Shadows" visible = @view == "3D" && @type == "raytrace" endheading bool param shadows caption = "Add Shadows" default = false visible = @view == "3D" && @type == "raytrace" endparam heading text = "Increasing 'shadow sensivity' will give shadows that show less fractal \ detail, but can also increase the number of false shadows from roughness \ on the fractal surface. Decreasing object roughness slightly may reduce \ the false shadows." visible = @view == "3D" && @shadows && @type == "raytrace" endheading float param objshadsens caption = "Object shadow sens" default = 0.1 visible = @view == "3D" && @shadows && @type == "raytrace" hint = "Determines shadow detail and sensitivity to surface roughness. Larger \ show less detail and more response to surface roughness" endparam float param srough caption = "Object roughness" default = 0.99 visible = @view == "3D" && @shadows && @type == "raytrace" hint = "Determines shadow sensitivity to surface roughness. Larger \ have more response to surface roughness" endparam heading caption = "Environment" visible = @view == "3D" endheading heading caption = "Fractal Parameters" endheading bool param dual caption = "Dual formulas" default = true endparam param itermeth caption = "Iteration method" enum = "flavor1" "flavor2" visible = @dual endparam int param setiter caption = "Iter switch value" default = 2 visible = @dual && @itermeth == "flavor1" endparam bool param usefirst caption = "Start with 1st formula" default = true visible = @dual endparam int param seqgap1 caption = "Iteration cycle" default = 2 visible = @dual && @itermeth == "flavor2" endparam heading text = "'Formula 1 iters' must be less than or equal to the 'Iteration cycle' \ Out of range values will be truncated to the size of the 'Iteration \ cycle'." visible = @dual && @itermeth == "flavor2" endheading int param seqgap2 caption = "Formula 1 Iters" default = 1 visible = @dual && @itermeth == "flavor2" endparam param merge caption = "Merge type" default = 0 enum = "None" "Average" "A+B" "A-B" "B-A" "A*B" "Largest(A,B)"\ "Smallest(A,B)" "A/B" "B/A" visible = @dual endparam bool param mergealt caption = "Alternate merge" default = false visible = @dual && @itermeth == "flavor2" endparam bool param altuse1 caption = "Alternate switch" default = false visible = @dual && @merge != "none" && @itermeth == "flavor1" endparam Quat param QuatClass caption = "Fractal Formula" default = AmazingFractalMandelbrot endparam Quat param QuatClass2 caption = "Fractal Formula" default = juliasphere visible = @dual endparam float param p_bailout ; Overrides p_bailout caption = "Bailout value" default = 1024 endparam heading caption = "Rotations" endheading heading text = "For rotation around the Z axis use the Location tab setting." endheading float param xangle caption = "X Axis Rotation" default = 0.0 endparam float param yangle caption = "Y Axis Rotation" default = 0.0 endparam heading caption = "Raytrace parameters" endheading param view caption = "Object view" enum = "3D" "2D" default = 0 hint = "The 2D view is at the level of the viewing screen (Starting Distance)." endparam heading text = "The compatibility box must be checked for use with the '3D Fractal \ Coloring Direct (UF5) coloring formula. It should be unchecked for use \ with other coloring formulas." visible = @view == "2D" endheading bool param compat caption = "Compatibility" default = true visible = @view == "2D" endparam heading text = "The 'Distance' display type will work only with the 3D Fractal Coloring \ Direct (UF5) ucl. It's in reb5.ucl." visible = @type == "Distance" && @view == "3D" endheading param type caption = "Display type" enum = "Raytrace" "Distance" "Z Value" "Iteration" default = 0 visible = @view == "3D" hint = "The distance option provides coloring according to the distance \ from the camera." endparam heading text = "'Distance corection' may give coloring artifacts for some object \ positions/rotations, but it eliminates most artifacts that result from zooms." visible = @type == "Iteration" endheading bool param distcorr caption = "Distance correction" default = true visible = @type == "Iteration" endparam param colortype caption = "Color type" enum = "Vepstas" "Exponential Smoothing" default = 0 visible = @type == "Iteration" endparam bool param corzd caption = "Scale Z value" default = false visible = @view == "3D" && @type == "Z Value" endparam float param zoff caption = "Z offset" default = -1 visible = @view == "3D" && @type == "Z Value" && @corzd endparam float param zmax caption = "Z max" default = 2 visible = @view == "3D" && @type == "Z Value" && @corzd endparam param ray caption = "Add Raytrace" default = false visible = @type == "Distance" || @type == "Z Value" || @type == "Iteration" endparam float param epsilon caption = "Closeness" default = 1.0 hint = "Determines closeness of approach to the fractal \ surface in pixels." visible = @view == "3D" endparam float param dfactor caption = "Distance factor" default = 0.2 hint = "Decrease to more accurately approach the fractal surface. This will \ slow generation of the image." visible = @view == "3D" endparam bool param szoom caption = "Scale to zoom" default = false visible = @view == "3D" endparam param potmeth caption = "Potential method" enum = "General smoothing" "Vepstas" "Iteration Smoothing" default = 0 visible = @view == "3D" endparam bool param noderiv caption = "No derivative" default = false visible = @view == "3D" && @potmeth != "Iteration Smoothing" endparam float param maxstep caption = "Max step" default = 0.1 visible = false endparam float param dn caption = "Norm delta value" default = 1 endparam param numnorm caption = "Normal points" enum = "3 point" "5 point" default = 0 endparam heading caption = "Cutting Plane" endheading heading text = "The starting and ending planes are defined by the X, Y and Z \ values referenced to the camera position and the plane of the \ screen. The cutting planes are applied after any rotations." endheading heading text = " Starting Plane" endheading float param mindistrqj caption = "X value" default = 0.0 hint = "This defines the cutting plane." endparam float param mindistiqj caption = "Y value" default = 0.0 hint = "This defines the cutting plane." endparam float param mindistqj caption = "Z value" default = 10.0 hint = "This defines the cutting plane." endparam heading text = " Ending Plane" visible = @view == "3D" endheading float param maxdistrqj caption = "X value" default = 0.0 hint = "This is the maximum distance from the cutting plane." visible = @view == "3D" endparam float param maxdistiqj caption = "Y value" default = 0.0 hint = "This is the maximum distance from the cutting plane." visible = @view == "3D" endparam float param maxdistqj caption = "Z value" default = 20.0 hint = "This is the maximum distance from the cutting plane." visible = @view == "3D" endparam } class REB_3DFractalColoringDirect(common.ulb:DirectColoring) { $define debug public: import "common.ulb" import "dmj5.ulb" ;constructor func REB_3DFractalColoringDirect(Generic pparent) DirectColoring.DirectColoring(pparent) m_Texture = new @ftexture(this) m_MergeColor = new @f_colormerge(0) m_TrapColor = new @f_trapcolor(this) m_preset = new @f_preset(this) if (@colorPreset == "Preset") colorMap[0,1] = m_preset.getHI() colorMap[0,0] = m_preset.getLOW() elseif (@colorPreset == "Generate") ; Compute the color ranges using the gradient. color gradientColor = gradient(0.475) colorMap [0,1] = hsl(hue(gradientColor), sat(gradientColor), @luminanceUpper) colorMap [0,0] = hsl(hue(gradientColor), sat(gradientColor), @luminanceLower) endif endfunc ; Initialize the coloring formula func Init(complex pz, complex ppixel) DirectColoring.Init(pz,ppixel) m_Texture.Init(pz) m_TrapColor.Init(pz) extent = 1.0 - @extent hval = 0 colorPos = 0 colr = 0 luminance = 0 alpha1 = 0 alpha2 = 0 color1 = rgba(0,0,0,1) color2 = rgba(0,0,0,1) color3 = rgba(0,0,0,1) ltfac = 0 TwoDflag = false m_expiter = 0 m_oldz = 0 endfunc ; call for each iterated point func Iterate(complex pz) DirectColoring.Iterate(pz) if @colorpreset == "2D Smoothing" TwoDFlag = false float m = abs(real(pz)) float n = 2.0^ceil(log(m)/log(2.0)-9) int k = floor(m/n) m = 512.0*(m - n*k) if k-256 == 100 TwoDflag = true if real(pz)<0.0 m = -m endif pz = m + flip(imag(pz)) m_expiter = m_expiter + exp(-cabs(pz)-0.5/(cabs(m_oldz - pz))) if (@mtile == "Fixed Iteration" && m_iterations == @iternum) || \ (@mtile == "Cabs(z)" && cabs(pz) < @tcabs)|| @mtile == "none" ptexture = m_Texture.Iterate(pz) if @f_trapcolor == ColorTrapNoColor m_empty = true else m_color = m_TrapColor.Iterate(pz) m_empty = false endif endif m_oldz = pz endif endif endfunc ; call in the final section of the ucl to get final coloring results. color func Result(complex pz) complex pzflavor = 0 float pzf = 0 pzf = real(pz)^@fpower color fcolor = @fcolor fcolor = rgba(red(fcolor),green(fcolor),blue(fcolor),@falpha) color return_color = rgba(0,0,0,1) if @colorpreset != "2D Smoothing" if @flavor == 0 pzflavor = (pz+@wt)*#pixel/(1+@wt) elseif @flavor == 1 pzflavor = (real(pz)+@wt)*#pixel/(1+@wt) elseif @flavor == 2 pzflavor = real(pz) + flip(cabs(pz)) elseif @flavor == 3 pzflavor = real(pz) + flip(real(pz)) else pzflavor = pz endif ptexture = m_Texture.Iterate(pzflavor) if @f_trapcolor == ColorTrapNoColor m_empty = true else m_color = m_TrapColor.Iterate(pzflavor) m_empty = false endif float hparam = 0 float dparam = 0 if imag(pz) == 1 colorPos = @scale*(real(pz)) colr = @scale*real(pz) elseif imag(pz) == 2 float input = real(pz) float rt = trunc(input)/2^20 float iter = (input - trunc(input))*2^20 float smooth = 0 smooth = @scale*iter/sqrt(#magn) complex ez = cos(smooth)+flip(sin(smooth)) float angle = atan2(ez) while (angle < 0) angle = angle + #pi * 2 endwhile colr = angle/(2*#pi)+ rt elseif imag(pz) < 0 colorPos = @scale*(real(pz))/2 colr = @scale*real(pz)/2 endif if colorPos > 0.5 while colorPos > 0.5 colorPos = colorPos - 0.5 endwhile colorPos = colorPos/2 else colorPos = colorPos / 0.5 endif if @highlight_type == "none" hval = 0 elseif @highlight_type == "linear" if colorPos > extent hval = (5*@highlight*(colorPos-extent)/(1-extent)+1)/(5*@highlight + 1) else hval = 0 endif elseif @highlight_type == "log" if colorPos > extent hval = (5*@highlight*log(colorPos-extent+1)/log(2-extent)+1)/(5*@highlight + 1) else hval = 0 endif elseif @highlight_type == "exponential" if colorPos > extent hval = (5*@highlight*(exp(colorPos-extent)-1)/(exp(1-extent)-1)+1)/(5*@highlight + 1) else hval = 0 endif endif hparam = hval^@hblend dparam = colorPos^@cblend if imag(pz) == -2 ; apply shadow value if @colorpreset == "Gradient" color3 = gradient(colr) else color3 = blend(colorMap[0,0], blend(colorMap[0,1],@hcolor,0), \ colorPos^@cblend) endif luminance = lum(color3) luminance = luminance*(1-@shad) color3 = hsl(hue(color3),sat(color3),luminance) else if @colorpreset == "Gradient" color3 = gradient(colr+ptexture*@txamt) else color3 = blend(colorMap[0,0], blend(colorMap[0,1],@hcolor,hparam), dparam) endif endif if imag(pz) > -4 luminance = lum(color3) if luminance < @ambient color2 = hsl(hue(@ambcolor),sat(@ambcolor),@ambient) return_color = blend(color3,color2,0.5) else return_color = color3 endif endif if imag(pz) <= -4 ; floor ltfac = -4-imag(pz) if ltfac < 1 color1 = @floor1 luminance = lum(color1)*ltfac+@ambient alpha1 = alpha(color1) color1 = hsla(hue(color1),sat(color1),luminance,alpha1) color2 = hsla(hue(@ambcolor),sat(@ambcolor),@ambient,alpha1) return_color = blend(color1,color2,0.5) elseif ltfac < 2 ltfac = ltfac-1 color1 = @floor2 alpha2 = alpha(color1) luminance = lum(color1)*ltfac+@ambient color1 = hsla(hue(color1),sat(color1),luminance,alpha2) color2 = hsla(hue(@ambcolor),sat(@ambcolor),@ambient,alpha2) return_color = blend(color1,color2,0.5) elseif ltfac < 3 ltfac = ltfac-2 color1 = @floor1 alpha1 = alpha(color1) if alpha1 < 1 alpha1 = (1-alpha1)/2 + alpha1 endif luminance = lum(color1)*ltfac+@ambient color1 = hsla(hue(color1),sat(color1),luminance,alpha1) color2 = hsla(hue(@ambcolor),sat(@ambcolor),@ambient,alpha1) color3 = blend(color1,color2,0.5) luminance = lum(color3) luminance = luminance*(1-@shad) return_color = hsla(hue(color3),sat(color3),luminance,alpha1) elseif ltfac < 4 ltfac = ltfac-3 color1 = @floor2 alpha2 = alpha(color1) if alpha2 < 1 alpha2 = (1-alpha2)/2 + alpha2 endif luminance = lum(color1)*ltfac+@ambient color1 = hsla(hue(color1),sat(color1),luminance,alpha2) color2 = hsla(hue(@ambcolor),sat(@ambcolor),@ambient,alpha2) color3 = blend(color1,color2,0.5) luminance = lum(color3) luminance = luminance*(1-@shad) return_color = hsla(hue(color3),sat(color3),luminance,alpha2) endif endif else if TwoDflag return_color = gradient(0.05*m_expiter + ptexture*@txamt) ; color temp = rgba(0,0,0,0) ; if !m_empty && m_iterations >0 ; if @nmerge == 1 ; temp = return_color ; return_color = m_color ; m_color = temp ; endif ; return_color = m_MergeColor.FullMerge(return_color, m_color, @opacity) ; endif endif endif if @ahue m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ hue(m_color)/6*alpha(m_color)) endif if @alum m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ lum(m_color)*alpha(m_color)) endif if @asat m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ sat(m_color)*alpha(m_color)) endif color temp = rgba(0,0,0,0) if !m_empty && m_iterations >0 if @nmerge == 1 temp = m_color m_color = return_color return_color = temp endif return_color = m_MergeColor.FullMerge(return_color, m_color, @opacity) endif float br = (0.5-@p_bright)*2 int sign = 0 if br < 0 sign = -1 else sign = 1 endif br = br^2*sign float cr = (@p_contrast-0.5)*2 if cr < 0 sign = -1 else sign = 1 endif cr = cr^2*sign+1 float st = (0.5-@p_sat)*2 if st < 0 sign = -1 else sign = 1 endif st = st^2*sign*2 float hu = @p_hue*6 float rd = red(return_color)-br float gr = green(return_color)-br float bl = blue(return_color)-br if rd > 1 rd = 1 endif if gr > 1 gr = 1 endif if bl > 1 bl = 1 endif if rd < 0 rd = 0 endif if gr < 0 gr = 0 endif if bl < 0 bl = 0 endif return_color = rgba(rd,gr,bl,alpha(return_color)) rd = red(return_color)^cr gr = green(return_color)^cr bl = blue(return_color)^cr return_color = rgba(rd,gr,bl,alpha(return_color)) float satval = sat(return_color)-st if satval > 1 satval = 1 endif if satval < 0 satval = 0 endif return_color = hsla(hue(return_color), satval, lum(return_color), alpha(return_color)) float hueval = (hue(return_color)+hu) % 6 return_color = hsla(hueval, sat(return_color), lum(return_color), alpha(return_color)) if @p_poster float rd = floor(red(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float gr = floor(green(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float bl = floor(blue(return_color)*@p_chan)/@p_chan + 0.5/@p_chan return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_gray float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) return_color = rgba(gry,gry,gry,alpha(return_color)) endif if @p_solar float rd = red(return_color) float gr = green(return_color) float bl = blue(return_color) if rd > @p_thresh rd = 1-rd endif if gr > @p_thresh gr = 1-gr endif if bl > @p_thresh bl = 1-bl endif return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_bw float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) if gry < @p_bwt return_color = rgba(0,0,0,alpha(return_color)) else return_color = rgba(1,1,1,alpha(return_color)) endif endif if cabs(pz) == 0 m_Solid = true endif if @fog m_solid = false endif return_color = blend(return_color,colormap[0,0],ptexture*@txamt) if @fog return_color = compose(fcolor, blend(return_color, \ mergenormal(fcolor, return_color), alpha(fcolor)), (1-@fdepth)*pzf) endif return return_color endfunc ; Is the coloring solid? - used by the coloring ucl. bool func IsSolid() return m_Solid endfunc protected: color colormap[2,2] float extent float hval float colorPos float colr float luminance float alpha1 float alpha2 color color1 color color2 color color3 float ltfac float ptexture TrapShape m_Texture ImageImport m_img bool m_empty color m_color ColorTrap m_TrapColor DefaultColorMerge m_MergeColor bool TwoDFlag float m_expiter complex m_oldz REB_DirectColorPreset m_preset default: title = "3D Fractal Coloring Direct (UF5)" int param v_REB_3DFractalColoringDirect caption = "Version (3D Fractal Coloring Direct (UF5)" default = 101 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_REB_3DFractalColoringDirect < 101 endparam heading text = "This formula is intended for use with 3D Fractal Raytrace (UF5), and has \ plugin options for textures and colors." endheading heading caption = "Color Settings" endheading heading text = "If '3D Fractal Raytrace (UF5)' is in the Distance mode, the recommended \ 'Color Options' setting is 'Gradient'. If '3D Fractal Raytrace (UF5)' is \ in the 2D mode with compatibility for '3D Fractal Coloring Direct' checked, \ 'Color Options' must set to '2D Smoothing'. This will color the fractal \ using the gradient and the general smoothing algorithm." endheading param colorPreset caption = "Color Options" enum = "Gradient" "Generate" "Preset" "2D Smoothing" default = 2 hint = "Use 'Gradient' for colors from the gradient. \ Use 'Generate' to use the gradient to define the raytrace gradient." endparam float param luminanceUpper caption = "Lum. Upper Value" default = 0.6 min = 0.0 max = 1.0 hint = "The value of the Luminance component for the upper value \ when generating the ranges from the gradient. This value \ is used with the brighter end of the color range." visible = (@colorPreset == "Generate") endparam float param luminanceLower caption = "Lum. Lower Value" default = 0.2 min = 0.0 max = 1.0 hint = "The value of the Luminance component for the lower value \ when generating the ranges from the gradient. This value \ is used with the darker end of the color range." visible = (@colorPreset == "Generate") endparam REB_DirectColorPreset param f_preset caption = "Color Preset" default = TwoColorPresets visible = (@colorPreset == "Preset") endparam heading caption = "Color Parameters" visible = @colorPreset != "Gradient" && @colorpreset != "2D Smoothing" endheading color param hcolor caption = "Highlight color" default = rgba(255/255,255/255,255/255,1) visible = @colorPreset != "Gradient" && @highlight_type != "none" && \ @colorPreset != "2D Smoothing" endparam param highlight_type caption = "Color Highlight Type" default = 1 enum = "none" "linear" "log" "exponential" hint = "Use to generate a 'shiny' hightlight." visible = @colorPreset != "Gradient" && \ @colorPreset != "2D Smoothing" endparam param highlight caption = "Highlight Value" default = 5.0 hint = "Use to generate a 'shiny' hightlight." visible = @colorPreset != "Gradient" && @highlight_type != "none" && \ @colorPreset != "2D Smoothing" endparam param extent caption = "Highlight Extent" default = 0.05 min = 0.0 max = 0.5 hint = "Use to generate a 'shiny' hightlight." visible = @colorPreset != "Gradient" && @highlight_type != "none" && \ @colorPreset != "2D Smoothing" endparam float param hblend caption = "Highlight power" default = 2.0 visible = @colorPreset != "Gradient" && @highlight_type != "none" && \ @colorPreset != "2D Smoothing" endparam float param scale caption = "color scale adj" default = 1.0 visible = @colorPreset != "2D Smoothing" endparam float param cblend caption = "color blend power" default = 1.0 visible = @colorPreset != "Gradient" && \ @colorPreset != "2D Smoothing" endparam float param ambient caption = "Ambient light" default = 0.05 visible = @colorPreset != "2D Smoothing" endparam color param ambcolor caption = "Ambient color" default = rgba(192/255,192/255,192/255,1) visible = @colorPreset != "2D Smoothing" endparam heading text = "The fog option only works when the 'display type' is 'Z value'." endheading bool param fog caption = "Generate fog" default = false endparam color param fcolor caption = "Fog color" default = rgba(174/255,174/255,228/255,1) visible = @fog endparam float param fdepth caption = "Fog depth" default = 0.5 ; min = 0 max = 1 visible = @fog endparam float param fpower caption = "Fog power" default = 1 visible = @fog endparam float param falpha caption = "Fog opacity" default = 1 min = 0 max = 1 visible = @fog endparam heading caption = "Shadows" visible = @colorpreset != "2D Smoothing" endheading heading text = "'Add Shadows' must be selected in the ufm for this option to do \ anything." visible = @colorPreset != "2D Smoothing" endheading float param shad caption = "Shadow level" default = 0.4 min = 0.0 max = 1.0 visible = @colorPreset != "2D Smoothing" endparam heading caption = "Floor coloring" visible = @colorpreset != "2D Smoothing" endheading heading text = "'Add floor' must be selected in the ufm for this option to do \ anything." visible = @colorPreset != "2D Smoothing" endheading color param floor1 caption = "Floor color #1" default = rgba(64/255,64/255,64/255,1) visible = @colorPreset != "2D Smoothing" endparam color param floor2 caption = "Floor color #2" default = rgba(200/255,200/255,200/255,1) visible = @colorPreset != "2D Smoothing" endparam heading caption = "Textures and Colors" endheading float param txamt caption = "Texture amount" default = 0.0 visible = @fTexture != DMJ_TrapShapeFlat endparam heading text = "The 'Tile method' applies to both textures and images. Fixed Iteration \ will give a smoother tiling, while 'Cabs(z)' will more consistently \ follow the fractal shape." visible = (@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) \ && @colorpreset == "2D Smoothing" endheading param mtile caption = "Tile method" default = 1 enum = "None" "Fixed Iteration" "Cabs(z)" visible = (@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) \ && @colorpreset == "2D Smoothing" endparam int param iternum caption = "Iter number" default = 1 hint = "Changes the texture/image mapping." visible = ((@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) && \ @mtile == "Fixed iteration") \ && @colorpreset == "2D Smoothing" endparam float param tcabs caption = "Cabs limit" default = 1.0 visible = @mtile == "Cabs(z)" hint = "Changes the texture/image mapping." visible = (@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) \ && @colorpreset == "2D Smoothing" endparam param flavor caption = "Texture/color flavor" default = 0 enum = "flavor1" "flavor2" "flavor3" "flavor4" "flavor5" visible = (@fTexture != DMJ_TrapShapeFlat) || (@f_trapcolor != ColorTrapNoColor) \ && @colorpreset != "2D Smoothing" endparam float param wt caption = "Weight" default = 2.0 visible = (@flavor == "flavor1" || @flavor == "flavor2") && ( (@fTexture != \ DMJ_TrapShapeFlat) || (@f_trapcolor != ColorTrapNoColor) \ && @colorpreset != "2D Smoothing") endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam heading caption = "Images and Colorings" endheading ColorTrap param f_trapcolor caption = "Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." endparam DefaultColorMerge param f_colormerge caption = "Color Merge" default = DefaultColorMerge visible = @f_trapcolor != ColorTrapNoColor endparam param nmerge caption = "Merge order" default = 0 enum = "Image on Top" "Image on Bottom" visible = @f_trapcolor != ColorTrapNoColor endparam float param opacity caption = "Merge Opacity" default = 0.2 visible = @f_trapcolor != ColorTrapNoColor endparam heading text = "Make image transparent by: " visible = @f_trapcolor != ColorTrapNoColor endheading bool param ahue caption = "Hue value" default = false visible = !@alum && !@asat && \ @f_trapcolor != ColorTrapNoColor endparam bool param alum caption = "Luminance value" default = false visible = !@ahue && !@asat && \ @f_trapcolor != ColorTrapNoColor endparam bool param asat caption = "Saturation value" default = false visible = !@alum && !@ahue && \ @f_trapcolor != ColorTrapNoColor endparam heading caption = "Special Effects" endheading float param p_bright caption = "Brightness" default = 0.5 min = 0 max = 1 endparam float param p_contrast caption = "Contrast" default = 0.5 min = 0 max = 1 endparam float param p_sat caption = "Saturation" default = 0.5 min = 0 max = 1 endparam float param p_hue caption = "Hue" default = 0.0 min = 0 max = 1 endparam bool param p_gray caption = "Grayscale" default = false endparam bool param p_solar caption = "Solarize" default = false endparam float param p_thresh caption = "Threshold" default = 0.5 visible = @p_solar endparam bool param p_poster caption = "Posterize" default = false endparam int param p_chan caption = "Colors per channel" default = 4 min = 2 visible = @p_poster endparam bool param p_bw caption = "Black and White" default = false endparam float param p_bwt caption = "Threshold" default = 0.5 min = 0 max = 1 visible = @p_bw endparam } class REB_3DFractalColoringDirectProgressive(common.ulb:DirectColoring) { $define debug public: import "common.ulb" import "dmj5.ulb" ;constructor func REB_3DFractalColoringDirectProgressive(Generic pparent) DirectColoring.DirectColoring(pparent) m_Texture = new @ftexture(this) m_MergeColor = new @f_colormerge(0) m_TrapColor = new @f_trapcolor(this) m_preset = new @f_preset(this) if (@colorPreset == "Preset") colorMap[0,1] = m_preset.getHI() colorMap[0,0] = m_preset.getLOW() elseif (@colorPreset == "Generate") ; Compute the color ranges using the gradient. color gradientColor = gradient(0.475) colorMap [0,1] = hsl(hue(gradientColor), sat(gradientColor), @luminanceUpper) colorMap [0,0] = hsl(hue(gradientColor), sat(gradientColor), @luminanceLower) endif endfunc ; Initialize the coloring formula func Init(complex pz, complex ppixel) DirectColoring.Init(pz,ppixel) m_Texture.Init(pz) m_TrapColor.Init(pz) extent = 1.0 - @extent hval = 0 colorPos = 0 colr = 0 luminance = 0 alpha1 = 0 alpha2 = 0 color1 = rgba(0,0,0,1) color2 = rgba(0,0,0,1) color3 = rgba(0,0,0,1) ltfac = 0 TwoDflag = false m_expiter = 0 m_oldz = 0 endfunc ; call for each iterated point func Iterate(complex pz) DirectColoring.Iterate(pz) if @colorpreset == "2D Smoothing" TwoDFlag = false float m = abs(real(pz)) float n = 2.0^ceil(log(m)/log(2.0)-9) int k = floor(m/n) m = 512.0*(m - n*k) if k-256 == 100 TwoDflag = true if real(pz)<0.0 m = -m endif pz = m + flip(imag(pz)) m_expiter = m_expiter + exp(-cabs(pz)-0.5/(cabs(m_oldz - pz))) if (@mtile == "Fixed Iteration" && m_iterations == @iternum) || \ (@mtile == "Cabs(z)" && cabs(pz) < @tcabs)|| @mtile == "none" ptexture = m_Texture.Iterate(pz) if @f_trapcolor == ColorTrapNoColor m_empty = true else m_color = m_TrapColor.Iterate(pz) m_empty = false endif endif m_oldz = pz endif endif endfunc ; call in the final section of the ucl to get final coloring results. color func Result(complex pz) complex pzflavor = 0 float pzf = 0 pzf = real(pz)^@fpower color fcolor = @fcolor fcolor = rgba(red(fcolor),green(fcolor),blue(fcolor),@falpha) color return_color = rgba(0,0,0,1) if @colorpreset != "2D Smoothing" if @flavor == 0 pzflavor = (pz+@wt)*#pixel/(1+@wt) elseif @flavor == 1 pzflavor = (real(pz)+@wt)*#pixel/(1+@wt) elseif @flavor == 2 pzflavor = real(pz) + flip(cabs(pz)) elseif @flavor == 3 pzflavor = real(pz) + flip(real(pz)) else pzflavor = pz endif ptexture = m_Texture.Iterate(pzflavor) if @f_trapcolor == ColorTrapNoColor m_empty = true else m_color = m_TrapColor.Iterate(pzflavor) m_empty = false endif float hparam = 0 float dparam = 0 if imag(pz) == 1 colorPos = @scale*(real(pz)) colr = @scale*real(pz) elseif imag(pz) == 2 float input = real(pz) float rt = trunc(input)/2^20 float iter = (input - trunc(input))*2^20 ; colr = @scale*iter/sqrt(#magn) + rt colr = @scale*iter + rt elseif imag(pz) < 0 colorPos = @scale*(real(pz))/2 colr = @scale*real(pz)/2 endif if colorPos > 0.5 while colorPos > 0.5 colorPos = colorPos - 0.5 endwhile colorPos = colorPos/2 else colorPos = colorPos / 0.5 endif if @highlight_type == "none" hval = 0 elseif @highlight_type == "linear" if colorPos > extent hval = (5*@highlight*(colorPos-extent)/(1-extent)+1)/(5*@highlight + 1) else hval = 0 endif elseif @highlight_type == "log" if colorPos > extent hval = (5*@highlight*log(colorPos-extent+1)/log(2-extent)+1)/(5*@highlight + 1) else hval = 0 endif elseif @highlight_type == "exponential" if colorPos > extent hval = (5*@highlight*(exp(colorPos-extent)-1)/(exp(1-extent)-1)+1)/(5*@highlight + 1) else hval = 0 endif endif hparam = hval^@hblend dparam = colorPos^@cblend if imag(pz) == -2 ; apply shadow value if @colorpreset == "Gradient" color3 = gradient(colr) else color3 = blend(colorMap[0,0], blend(colorMap[0,1],@hcolor,0), \ colorPos^@cblend) endif luminance = lum(color3) luminance = luminance*(1-@shad) color3 = hsl(hue(color3),sat(color3),luminance) else if @colorpreset == "Gradient" color3 = gradient(colr+ptexture*@txamt) else color3 = blend(colorMap[0,0], blend(colorMap[0,1],@hcolor,hparam), dparam) endif endif if imag(pz) > -4 luminance = lum(color3) if luminance < @ambient color2 = hsl(hue(@ambcolor),sat(@ambcolor),@ambient) return_color = blend(color3,color2,0.5) else return_color = color3 endif endif else if TwoDflag return_color = gradient(0.05*m_expiter + ptexture*@txamt) endif endif if @ahue m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ hue(m_color)/6*alpha(m_color)) endif if @alum m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ lum(m_color)*alpha(m_color)) endif if @asat m_color = hsla(hue(m_color), sat(m_color), lum(m_color), \ sat(m_color)*alpha(m_color)) endif color temp = rgba(0,0,0,0) if !m_empty && m_iterations >0 if @nmerge == 1 temp = m_color m_color = return_color return_color = temp endif return_color = m_MergeColor.FullMerge(return_color, m_color, @opacity) endif float br = (0.5-@p_bright)*2 int sign = 0 if br < 0 sign = -1 else sign = 1 endif br = br^2*sign float cr = (@p_contrast-0.5)*2 if cr < 0 sign = -1 else sign = 1 endif cr = cr^2*sign+1 float st = (0.5-@p_sat)*2 if st < 0 sign = -1 else sign = 1 endif st = st^2*sign*2 float hu = @p_hue*6 float rd = red(return_color)-br float gr = green(return_color)-br float bl = blue(return_color)-br if rd > 1 rd = 1 endif if gr > 1 gr = 1 endif if bl > 1 bl = 1 endif if rd < 0 rd = 0 endif if gr < 0 gr = 0 endif if bl < 0 bl = 0 endif return_color = rgba(rd,gr,bl,alpha(return_color)) rd = red(return_color)^cr gr = green(return_color)^cr bl = blue(return_color)^cr return_color = rgba(rd,gr,bl,alpha(return_color)) float satval = sat(return_color)-st if satval > 1 satval = 1 endif if satval < 0 satval = 0 endif return_color = hsla(hue(return_color), satval, lum(return_color), alpha(return_color)) float hueval = (hue(return_color)+hu) % 6 return_color = hsla(hueval, sat(return_color), lum(return_color), alpha(return_color)) if @p_poster float rd = floor(red(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float gr = floor(green(return_color)*@p_chan)/@p_chan + 0.5/@p_chan float bl = floor(blue(return_color)*@p_chan)/@p_chan + 0.5/@p_chan return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_gray float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) return_color = rgba(gry,gry,gry,alpha(return_color)) endif if @p_solar float rd = red(return_color) float gr = green(return_color) float bl = blue(return_color) if rd > @p_thresh rd = 1-rd endif if gr > @p_thresh gr = 1-gr endif if bl > @p_thresh bl = 1-bl endif return_color = rgba(rd,gr,bl,alpha(return_color)) endif if @p_bw float gry = 0.3 * red(return_color)+ 0.59 * green(return_color) + 0.11 * blue(return_color) if gry < @p_bwt return_color = rgba(0,0,0,alpha(return_color)) else return_color = rgba(1,1,1,alpha(return_color)) endif endif if cabs(pz) == 0 m_Solid = true endif if @fog m_solid = false endif return_color = blend(return_color,colormap[0,0],ptexture*@txamt) if @fog return_color = compose(fcolor, blend(return_color, \ mergenormal(fcolor, return_color), alpha(fcolor)), (1-@fdepth)*pzf) endif return return_color endfunc ; Is the coloring solid? - used by the coloring ucl. bool func IsSolid() return m_Solid endfunc protected: color colormap[2,2] float extent float hval float colorPos float colr float luminance float alpha1 float alpha2 color color1 color color2 color color3 float ltfac float ptexture TrapShape m_Texture ImageImport m_img bool m_empty color m_color ColorTrap m_TrapColor DefaultColorMerge m_MergeColor bool TwoDFlag float m_expiter complex m_oldz REB_DirectColorPreset m_preset default: title = "3D Fractal Coloring Direct progressive" int param v_REB_3DFractalColoringDirectProgressive caption = "Version (3D Fractal Coloring Direct Proressive" default = 101 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_REB_3DFractalColoringDirectProgressive < 101 endparam heading text = "This formula is intended for use with 3D Fractal Raytrace \ Progressive, and has plugin options for textures and colors." endheading heading caption = "Color Settings" endheading heading text = "If '3D Fractal Raytrace Progressive' is in the Distance mode, the recommended \ 'Color Options' setting is 'Gradient'. If '3D Fractal Raytrace Progressive' is \ in the 2D mode with compatibility for '3D Fractal Coloring Direct' checked, \ 'Color Options' must set to '2D Smoothing'. This will color the fractal \ using the gradient and the general smoothing algorithm." endheading param colorPreset caption = "Color Options" enum = "Gradient" "Generate" "Preset" "2D Smoothing" default = 2 hint = "Use 'Gradient' for colors from the gradient. \ Use 'Generate' to use the gradient to define the raytrace gradient." endparam float param luminanceUpper caption = "Lum. Upper Value" default = 0.6 min = 0.0 max = 1.0 hint = "The value of the Luminance component for the upper value \ when generating the ranges from the gradient. This value \ is used with the brighter end of the color range." visible = (@colorPreset == "Generate") endparam float param luminanceLower caption = "Lum. Lower Value" default = 0.2 min = 0.0 max = 1.0 hint = "The value of the Luminance component for the lower value \ when generating the ranges from the gradient. This value \ is used with the darker end of the color range." visible = (@colorPreset == "Generate") endparam REB_DirectColorPreset param f_preset caption = "Color Preset" default = TwoColorPresets visible = (@colorPreset == "Preset") endparam heading caption = "Color Parameters" visible = @colorPreset != "Gradient" && @colorpreset != "2D Smoothing" endheading color param hcolor caption = "Highlight color" default = rgba(255/255,255/255,255/255,1) visible = @colorPreset != "Gradient" && @highlight_type != "none" && \ @colorPreset != "2D Smoothing" endparam param highlight_type caption = "Color Highlight Type" default = 1 enum = "none" "linear" "log" "exponential" hint = "Use to generate a 'shiny' hightlight." visible = @colorPreset != "Gradient" && \ @colorPreset != "2D Smoothing" endparam param highlight caption = "Highlight Value" default = 5.0 hint = "Use to generate a 'shiny' hightlight." visible = @colorPreset != "Gradient" && @highlight_type != "none" && \ @colorPreset != "2D Smoothing" endparam param extent caption = "Highlight Extent" default = 0.1 min = 0.0 max = 0.5 hint = "Use to generate a 'shiny' hightlight." visible = @colorPreset != "Gradient" && @highlight_type != "none" && \ @colorPreset != "2D Smoothing" endparam float param hblend caption = "Highlight power" default = 2.0 visible = @colorPreset != "Gradient" && @highlight_type != "none" && \ @colorPreset != "2D Smoothing" endparam float param scale caption = "color scale adj" default = 1.0 visible = @colorPreset != "2D Smoothing" endparam float param cblend caption = "color blend power" default = 3.0 visible = @colorPreset != "Gradient" && \ @colorPreset != "2D Smoothing" endparam float param ambient caption = "Ambient light" default = 0.05 visible = @colorPreset != "2D Smoothing" endparam color param ambcolor caption = "Ambient color" default = rgba(192/255,192/255,192/255,1) visible = @colorPreset != "2D Smoothing" endparam heading text = "The fog option only works when the 'display type' is 'Z value'." endheading bool param fog caption = "Generate fog" default = false endparam color param fcolor caption = "Fog color" default = rgba(174/255,174/255,228/255,1) visible = @fog endparam float param fdepth caption = "Fog depth" default = 0.5 ; min = 0 max = 1 visible = @fog endparam float param fpower caption = "Fog power" default = 1 visible = @fog endparam float param falpha caption = "Fog opacity" default = 1 min = 0 max = 1 visible = @fog endparam heading caption = "Shadows" visible = @colorpreset != "2D Smoothing" endheading heading text = "'Add Shadows' must be selected in the ufm for this option to do \ anything." visible = @colorPreset != "2D Smoothing" endheading float param shad caption = "Shadow level" default = 0.4 min = 0.0 max = 1.0 visible = @colorPreset != "2D Smoothing" endparam heading caption = "Textures and Colors" endheading float param txamt caption = "Texture amount" default = 0.0 visible = @fTexture != DMJ_TrapShapeFlat endparam heading text = "The 'Tile method' applies to both textures and images. Fixed Iteration \ will give a smoother tiling, while 'Cabs(z)' will more consistently \ follow the fractal shape." visible = (@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) \ && @colorpreset == "2D Smoothing" endheading param mtile caption = "Tile method" default = 1 enum = "None" "Fixed Iteration" "Cabs(z)" visible = (@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) \ && @colorpreset == "2D Smoothing" endparam int param iternum caption = "Iter number" default = 1 hint = "Changes the texture/image mapping." visible = ((@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) && \ @mtile == "Fixed iteration") \ && @colorpreset == "2D Smoothing" endparam float param tcabs caption = "Cabs limit" default = 1.0 visible = @mtile == "Cabs(z)" hint = "Changes the texture/image mapping." visible = (@fTexture != DMJ_TrapShapeFlat || @f_trapcolor != ColorTrapNoColor) \ && @colorpreset == "2D Smoothing" endparam param flavor caption = "Texture/color flavor" default = 0 enum = "flavor1" "flavor2" "flavor3" "flavor4" "flavor5" visible = (@fTexture != DMJ_TrapShapeFlat) || (@f_trapcolor != ColorTrapNoColor) \ && @colorpreset != "2D Smoothing" endparam float param wt caption = "Weight" default = 2.0 visible = (@flavor == "flavor1" || @flavor == "flavor2") && ( (@fTexture != \ DMJ_TrapShapeFlat) || (@f_trapcolor != ColorTrapNoColor) \ && @colorpreset != "2D Smoothing") endparam TrapShape param fTexture caption = "Texture" default = DMJ_TrapShapeFlat hint = "Use TrapShape plugins as textures." endparam heading caption = "Images and Colorings" endheading ColorTrap param f_trapcolor caption = "Colors" default = ColorTrapNoColor expanded = false hint = "A trap shape that is used as a color or pattern." endparam DefaultColorMerge param f_colormerge caption = "Color Merge" default = DefaultColorMerge visible = @f_trapcolor != ColorTrapNoColor endparam param nmerge caption = "Merge order" default = 0 enum = "Image on Top" "Image on Bottom" visible = @f_trapcolor != ColorTrapNoColor endparam float param opacity caption = "Merge Opacity" default = 0.2 visible = @f_trapcolor != ColorTrapNoColor endparam heading text = "Make image transparent by: " visible = @f_trapcolor != ColorTrapNoColor endheading bool param ahue caption = "Hue value" default = false visible = !@alum && !@asat && \ @f_trapcolor != ColorTrapNoColor endparam bool param alum caption = "Luminance value" default = false visible = !@ahue && !@asat && \ @f_trapcolor != ColorTrapNoColor endparam bool param asat caption = "Saturation value" default = false visible = !@alum && !@ahue && \ @f_trapcolor != ColorTrapNoColor endparam heading caption = "Special Effects" endheading float param p_bright caption = "Brightness" default = 0.5 min = 0 max = 1 endparam float param p_contrast caption = "Contrast" default = 0.5 min = 0 max = 1 endparam float param p_sat caption = "Saturation" default = 0.5 min = 0 max = 1 endparam float param p_hue caption = "Hue" default = 0.0 min = 0 max = 1 endparam bool param p_gray caption = "Grayscale" default = false endparam bool param p_solar caption = "Solarize" default = false endparam float param p_thresh caption = "Threshold" default = 0.5 visible = @p_solar endparam bool param p_poster caption = "Posterize" default = false endparam int param p_chan caption = "Colors per channel" default = 4 min = 2 visible = @p_poster endparam bool param p_bw caption = "Black and White" default = false endparam float param p_bwt caption = "Threshold" default = 0.5 min = 0 max = 1 visible = @p_bw endparam } class REB_DirectColorPreset(common.ulb:Generic) { public: import "common.ulb" ; constructor func REB_DirectColorPreset(Generic pparent) Generic.generic(pparent) endfunc color func GetHI() return colorMap[0,1] endfunc color func GetLOW() return colorMap[0,0] endfunc protected: color colormap[2,2] default: int param v_colorpreset caption = "Version (color preset)" 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_colorpreset < 100 endparam } class TwoColorPresets(REB_DirectColorPreset) { public: import "common.ulb" ; constructor func TwoColorPresets(Generic pparent) REB_DirectColorPreset.REB_DirectColorPreset(pparent) if @colorchoice == "Magenta" colorMap [0,1] = @colorMax1, colorMap [0,0] = @colorMin1 elseif @colorchoice == "Blueviolet" colorMap [0,1] = @colorMax2, colorMap [0,0] = @colorMin2 elseif @colorchoice == "AliceBlue" colorMap [0,1] = @colorMax3, colorMap [0,0] = @colorMin3 elseif @colorchoice == "AntiqueWhite" colorMap [0,1] = @colorMax4, colorMap [0,0] = @colorMin4 elseif @colorchoice == "Aquamarine" colorMap [0,1] = @colorMax5, colorMap [0,0] = @colorMin5 elseif @colorchoice == "Azure" colorMap [0,1] = @colorMax6, colorMap [0,0] = @colorMin6 elseif @colorchoice == "Beige" colorMap [0,1] = @colorMax7, colorMap [0,0] = @colorMin7 elseif @colorchoice == "Black" colorMap [0,1] = @colorMax8, colorMap [0,0] = @colorMin8 elseif @colorchoice == "BlanchedAlmond" colorMap [0,1] = @colorMax9, colorMap [0,0] = @colorMin9 elseif @colorchoice == "Blue" colorMap [0,1] = @colorMax10, colorMap [0,0] = @colorMin10 elseif @colorchoice == "Brown" colorMap [0,1] = @colorMax11, colorMap [0,0] = @colorMin11 elseif @colorchoice == "Burlywood" colorMap [0,1] = @colorMax12, colorMap [0,0] = @colorMin12 elseif @colorchoice == "CadetBlue" colorMap [0,1] = @colorMax13, colorMap [0,0] = @colorMin13 elseif @colorchoice == "Chocolate" colorMap [0,1] = @colorMax14, colorMap [0,0] = @colorMin14 elseif @colorchoice == "Coral" colorMap [0,1] = @colorMax15, colorMap [0,0] = @colorMin15 elseif @colorchoice == "CornflowerBlue" colorMap [0,1] = @colorMax16, colorMap [0,0] = @colorMin16 elseif @colorchoice == "Cornsilk" colorMap [0,1] = @colorMax17, colorMap [0,0] = @colorMin17 elseif @colorchoice == "Crimson" colorMap [0,1] = @colorMax18, colorMap [0,0] = @colorMin18 elseif @colorchoice == "Cyan" colorMap [0,1] = @colorMax19, colorMap [0,0] = @colorMin19 elseif @colorchoice == "DarkBlue" colorMap [0,1] = @colorMax20, colorMap [0,0] = @colorMin20 elseif @colorchoice == "DarkCyan" colorMap [0,1] = @colorMax21, colorMap [0,0] = @colorMin21 elseif @colorchoice == "DarkGoldenrod" colorMap [0,1] = @colorMax22, colorMap [0,0] = @colorMin22 elseif @colorchoice == "DarkGreen" colorMap [0,1] = @colorMax23, colorMap [0,0] = @colorMin23 elseif @colorchoice == "Silver" colorMap [0,1] = @colorMax24, colorMap [0,0] = @colorMin24 elseif @colorchoice == "DarkKhaki" colorMap [0,1] = @colorMax25, colorMap [0,0] = @colorMin25 elseif @colorchoice == "DarkMagenta" colorMap [0,1] = @colorMax26, colorMap [0,0] = @colorMin26 elseif @colorchoice == "DarkOliveGreen" colorMap [0,1] = @colorMax27, colorMap [0,0] = @colorMin27 elseif @colorchoice == "DarkOrchid" colorMap [0,1] = @colorMax28, colorMap [0,0] = @colorMin28 elseif @colorchoice == "DeepPink" colorMap [0,1] = @colorMax29, colorMap [0,0] = @colorMin29 elseif @colorchoice == "DarkRed" colorMap [0,1] = @colorMax30, colorMap [0,0] = @colorMin30 elseif @colorchoice == "DarkSalmon" colorMap [0,1] = @colorMax31, colorMap [0,0] = @colorMin31 elseif @colorchoice == "DarkSlateBlue" colorMap [0,1] = @colorMax32, colorMap [0,0] = @colorMin32 elseif @colorchoice == "DarkSlateGrey" colorMap [0,1] = @colorMax33, colorMap [0,0] = @colorMin33 elseif @colorchoice == "DarkTurquoise" colorMap [0,1] = @colorMax34, colorMap [0,0] = @colorMin34 elseif @colorchoice == "DarkViolet" colorMap [0,1] = @colorMax35, colorMap [0,0] = @colorMin35 elseif @colorchoice == "DeepSkyBlue" colorMap [0,1] = @colorMax36, colorMap [0,0] = @colorMin36 elseif @colorchoice == "DimGrey" colorMap [0,1] = @colorMax37, colorMap [0,0] = @colorMin37 elseif @colorchoice == "DodgerBlue" colorMap [0,1] = @colorMax38, colorMap [0,0] = @colorMin38 elseif @colorchoice == "FireBrick" colorMap [0,1] = @colorMax39, colorMap [0,0] = @colorMin39 elseif @colorchoice == "FloralWhite" colorMap [0,1] = @colorMax40, colorMap [0,0] = @colorMin40 elseif @colorchoice == "Chartreuse" colorMap [0,1] = @colorMax41, colorMap [0,0] = @colorMin41 elseif @colorchoice == "DarkSeaGreen" colorMap [0,1] = @colorMax42, colorMap [0,0] = @colorMin42 elseif @colorchoice == "ForestGreen" colorMap [0,1] = @colorMax43, colorMap [0,0] = @colorMin43 elseif @colorchoice == "Fuchia" colorMap [0,1] = @colorMax44, colorMap [0,0] = @colorMin44 elseif @colorchoice == "Gainsboro" colorMap [0,1] = @colorMax45, colorMap [0,0] = @colorMin45 elseif @colorchoice == "GhostWhite" colorMap [0,1] = @colorMax46, colorMap [0,0] = @colorMin46 elseif @colorchoice == "Gold" colorMap [0,1] = @colorMax47, colorMap [0,0] = @colorMin47 elseif @colorchoice == "Goldenrod" colorMap [0,1] = @colorMax48, colorMap [0,0] = @colorMin48 elseif @colorchoice == "Grey" colorMap [0,1] = @colorMax49, colorMap [0,0] = @colorMin49 elseif @colorchoice == "Green" colorMap [0,1] = @colorMax50, colorMap [0,0] = @colorMin50 elseif @colorchoice == "GreenYellow" colorMap [0,1] = @colorMax51, colorMap [0,0] = @colorMin51 elseif @colorchoice == "Honeydew" colorMap [0,1] = @colorMax52, colorMap [0,0] = @colorMin52 elseif @colorchoice == "HotPink" colorMap [0,1] = @colorMax53, colorMap [0,0] = @colorMin53 elseif @colorchoice == "IndianRed" colorMap [0,1] = @colorMax54, colorMap [0,0] = @colorMin54 elseif @colorchoice == "Indigo" colorMap [0,1] = @colorMax55, colorMap [0,0] = @colorMin55 elseif @colorchoice == "Ivory" colorMap [0,1] = @colorMax56, colorMap [0,0] = @colorMin56 elseif @colorchoice == "Khaki" colorMap [0,1] = @colorMax57, colorMap [0,0] = @colorMin57 elseif @colorchoice == "Lavender" colorMap [0,1] = @colorMax58, colorMap [0,0] = @colorMin58 elseif @colorchoice == "LavenderBlush" colorMap [0,1] = @colorMax59, colorMap [0,0] = @colorMin59 elseif @colorchoice == "LawnGreen" colorMap [0,1] = @colorMax60, colorMap [0,0] = @colorMin60 elseif @colorchoice == "LemonChiffon" colorMap [0,1] = @colorMax61, colorMap [0,0] = @colorMin61 elseif @colorchoice == "LightBlue" colorMap [0,1] = @colorMax62, colorMap [0,0] = @colorMin62 elseif @colorchoice == "LightCoral" colorMap [0,1] = @colorMax63, colorMap [0,0] = @colorMin63 elseif @colorchoice == "LightCyan" colorMap [0,1] = @colorMax64, colorMap [0,0] = @colorMin64 elseif @colorchoice == "LightGoldenrodYellow" colorMap [0,1] = @colorMax65, colorMap [0,0] = @colorMin65 elseif @colorchoice == "LightGreen" colorMap [0,1] = @colorMax66, colorMap [0,0] = @colorMin66 elseif @colorchoice == "LightGrey" colorMap [0,1] = @colorMax67, colorMap [0,0] = @colorMin67 elseif @colorchoice == "LightPink" colorMap [0,1] = @colorMax68, colorMap [0,0] = @colorMin68 elseif @colorchoice == "LightSalmon" colorMap [0,1] = @colorMax69, colorMap [0,0] = @colorMin69 elseif @colorchoice == "LightSeaGreen" colorMap [0,1] = @colorMax70, colorMap [0,0] = @colorMin70 elseif @colorchoice == "LightSkyBlue" colorMap [0,1] = @colorMax71, colorMap [0,0] = @colorMin71 elseif @colorchoice == "LightSlateGrey" colorMap [0,1] = @colorMax72, colorMap [0,0] = @colorMin72 elseif @colorchoice == "LightSteelBlue" colorMap [0,1] = @colorMax73, colorMap [0,0] = @colorMin73 elseif @colorchoice == "LightYellow" colorMap [0,1] = @colorMax74, colorMap [0,0] = @colorMin74 elseif @colorchoice == "Lime" colorMap [0,1] = @colorMax75, colorMap [0,0] = @colorMin75 elseif @colorchoice == "LimeGreen" colorMap [0,1] = @colorMax76, colorMap [0,0] = @colorMin76 elseif @colorchoice == "Linen" colorMap [0,1] = @colorMax77, colorMap [0,0] = @colorMin77 elseif @colorchoice == "Maroon" colorMap [0,1] = @colorMax78, colorMap [0,0] = @colorMin78 elseif @colorchoice == "MediumAquamarine" colorMap [0,1] = @colorMax79, colorMap [0,0] = @colorMin79 elseif @colorchoice == "MediumBlue" colorMap [0,1] = @colorMax80, colorMap [0,0] = @colorMin80 elseif @colorchoice == "MediumOrchid" colorMap [0,1] = @colorMax81, colorMap [0,0] = @colorMin81 elseif @colorchoice == "MediumPurple" colorMap [0,1] = @colorMax82, colorMap [0,0] = @colorMin82 elseif @colorchoice == "MediumSeaGreen" colorMap [0,1] = @colorMax83, colorMap [0,0] = @colorMin83 elseif @colorchoice == "MediumSlateBlue" colorMap [0,1] = @colorMax84, colorMap [0,0] = @colorMin84 elseif @colorchoice == "MediumSpringGreen" colorMap [0,1] = @colorMax85, colorMap [0,0] = @colorMin85 elseif @colorchoice == "MediumTurquoise" colorMap [0,1] = @colorMax86, colorMap [0,0] = @colorMin86 elseif @colorchoice == "MediumVioletRed" colorMap [0,1] = @colorMax87, colorMap [0,0] = @colorMin87 elseif @colorchoice == "MidnightBlue" colorMap [0,1] = @colorMax88, colorMap [0,0] = @colorMin88 elseif @colorchoice == "MintCream" colorMap [0,1] = @colorMax89, colorMap [0,0] = @colorMin89 elseif @colorchoice == "MistyRose" colorMap [0,1] = @colorMax90, colorMap [0,0] = @colorMin90 elseif @colorchoice == "Moccasin" colorMap [0,1] = @colorMax91, colorMap [0,0] = @colorMin91 elseif @colorchoice == "NavajoWhite" colorMap [0,1] = @colorMax92, colorMap [0,0] = @colorMin92 elseif @colorchoice == "OldLace" colorMap [0,1] = @colorMax93, colorMap [0,0] = @colorMin93 elseif @colorchoice == "Olive" colorMap [0,1] = @colorMax94, colorMap [0,0] = @colorMin94 elseif @colorchoice == "OliveDrab" colorMap [0,1] = @colorMax95, colorMap [0,0] = @colorMin95 elseif @colorchoice == "Orange" colorMap [0,1] = @colorMax96, colorMap [0,0] = @colorMin96 elseif @colorchoice == "OrangeRed" colorMap [0,1] = @colorMax97, colorMap [0,0] = @colorMin97 elseif @colorchoice == "Orchid" colorMap [0,1] = @colorMax98, colorMap [0,0] = @colorMin98 elseif @colorchoice == "PaleGoldenrod" colorMap [0,1] = @colorMax99, colorMap [0,0] = @colorMin99 elseif @colorchoice == "PaleGreen" colorMap [0,1] = @colorMax100, colorMap [0,0] = @colorMin100 elseif @colorchoice == "PaleTurquoise" colorMap [0,1] = @colorMax101, colorMap [0,0] = @colorMin101 elseif @colorchoice == "PaleVioletRed" colorMap [0,1] = @colorMax102, colorMap [0,0] = @colorMin102 elseif @colorchoice == "PapayaWhip" colorMap [0,1] = @colorMax103, colorMap [0,0] = @colorMin103 elseif @colorchoice == "PeachPuff" colorMap [0,1] = @colorMax104, colorMap [0,0] = @colorMin104 elseif @colorchoice == "Peru" colorMap [0,1] = @colorMax105, colorMap [0,0] = @colorMin105 elseif @colorchoice == "Pink" colorMap [0,1] = @colorMax106, colorMap [0,0] = @colorMin106 elseif @colorchoice == "Plum" colorMap [0,1] = @colorMax107, colorMap [0,0] = @colorMin107 elseif @colorchoice == "PowderBlue" colorMap [0,1] = @colorMax108, colorMap [0,0] = @colorMin108 elseif @colorchoice == "Purple" colorMap [0,1] = @colorMax109, colorMap [0,0] = @colorMin109 elseif @colorchoice == "Red" colorMap [0,1] = @colorMax110, colorMap [0,0] = @colorMin110 elseif @colorchoice == "RosyBrown" colorMap [0,1] = @colorMax111, colorMap [0,0] = @colorMin111 elseif @colorchoice == "RoyalBlue" colorMap [0,1] = @colorMax112, colorMap [0,0] = @colorMin112 elseif @colorchoice == "SaddleBrown" colorMap [0,1] = @colorMax113, colorMap [0,0] = @colorMin113 elseif @colorchoice == "Salmon" colorMap [0,1] = @colorMax114, colorMap [0,0] = @colorMin114 elseif @colorchoice == "SandyBrown" colorMap [0,1] = @colorMax115, colorMap [0,0] = @colorMin115 elseif @colorchoice == "SeaGreen" colorMap [0,1] = @colorMax116, colorMap [0,0] = @colorMin116 elseif @colorchoice == "SeaShell" colorMap [0,1] = @colorMax117, colorMap [0,0] = @colorMin117 elseif @colorchoice == "Sienna" colorMap [0,1] = @colorMax118, colorMap [0,0] = @colorMin118 elseif @colorchoice == "SkyBlue" colorMap [0,1] = @colorMax119, colorMap [0,0] = @colorMin119 elseif @colorchoice == "SlateBlue" colorMap [0,1] = @colorMax120, colorMap [0,0] = @colorMin120 elseif @colorchoice == "SlateGrey" colorMap [0,1] = @colorMax121, colorMap [0,0] = @colorMin121 elseif @colorchoice == "Snow" colorMap [0,1] = @colorMax122, colorMap [0,0] = @colorMin122 elseif @colorchoice == "SpringGreen" colorMap [0,1] = @colorMax123, colorMap [0,0] = @colorMin123 elseif @colorchoice == "SteelBlue" colorMap [0,1] = @colorMax124, colorMap [0,0] = @colorMin124 elseif @colorchoice == "Tan" colorMap [0,1] = @colorMax125, colorMap [0,0] = @colorMin125 elseif @colorchoice == "Teal" colorMap [0,1] = @colorMax126, colorMap [0,0] = @colorMin126 elseif @colorchoice == "Thistle" colorMap [0,1] = @colorMax127, colorMap [0,0] = @colorMin127 elseif @colorchoice == "Tomato" colorMap [0,1] = @colorMax128, colorMap [0,0] = @colorMin128 elseif @colorchoice == "Turquoise" colorMap [0,1] = @colorMax129, colorMap [0,0] = @colorMin129 elseif @colorchoice == "Violet" colorMap [0,1] = @colorMax130, colorMap [0,0] = @colorMin130 elseif @colorchoice == "Wheat" colorMap [0,1] = @colorMax131, colorMap [0,0] = @colorMin131 elseif @colorchoice == "White" colorMap [0,1] = @colorMax132, colorMap [0,0] = @colorMin132 elseif @colorchoice == "WhiteSmoke" colorMap [0,1] = @colorMax133, colorMap [0,0] = @colorMin133 elseif @colorchoice == "Yellow" colorMap [0,1] = @colorMax134, colorMap [0,0] = @colorMin134 elseif @colorchoice == "YellowGreen" colorMap [0,1] = @colorMax135, colorMap [0,0] = @colorMin135 endif endfunc color func GetHI() return colorMap[0,1] endfunc color func GetLOW() return colorMap[0,0] endfunc protected: color colormap[2,2] default: title = "Two Color Presets" int param v_2colorpreset caption = "Version (two color preset)" 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_2colorpreset < 100 endparam param colorchoice caption = "Preset choices" enum = "AliceBlue" "AntiqueWhite" "Aquamarine" "Azure" "Beige" "Black" \ "BlanchedAlmond" "Blue" "BlueViolet" "Brown" "Burlywood" \ "CadetBlue" "Chartreuse" "Chocolate" "Coral" "CornflowerBlue" "Cornsilk" \ "Crimson" "Cyan" "DarkBlue" "DarkCyan" "DarkGoldenrod" \ "DarkGreen" "DarkKhaki" "DarkMagenta" "DarkOliveGreen" \ "DarkOrchid" "DarkRed" "DarkSalmon" "DarkSeaGreen" "DarkSlateBlue" \ "DarkSlateGrey" "DarkTurquoise" "DarkViolet" "DeepPink" "DeepSkyBlue" \ "DimGrey" "DodgerBlue" "FireBrick" "FloralWhite" "ForestGreen" \ "Fuchia" "Gainsboro" "GhostWhite" "Gold" "Goldenrod" "Grey" "Green" \ "GreenYellow" "Honeydew" "HotPink" "IndianRed" "Indigo" "Ivory" \ "Khaki" "Lavender" "LavenderBlush" "LawnGreen" "LemonChiffon" \ "LightBlue" "LightCoral" "LightCyan" "LightGoldenrodYellow" \ "LightGreen" "LightGrey" "LightPink" "LightSalmon" "LightSeaGreen" \ "LightSkyBlue" "LightSlateGrey" "LightSteelBlue" "LightYellow" "Lime" \ "LimeGreen" "Linen" "Magenta" "Maroon" "MediumAquamarine" "MediumBlue" \ "MediumOrchid" "MediumPurple" "MediumSeaGreen" "MediumSlateBlue" \ "MediumSpringGreen" "MediumTurquoise" "MediumVioletRed" "MidnightBlue" \ "MintCream" "MistyRose" "Moccasin" "NavajoWhite" "OldLace" "Olive" \ "OliveDrab" "Orange" "OrangeRed" "Orchid" "PaleGoldenrod" "PaleGreen" \ "PaleTurquoise" "PaleVioletRed" "PapayaWhip" "PeachPuff" "Peru" \ "Pink" "Plum" "PowderBlue" "Purple" "Red" "RosyBrown" "RoyalBlue" \ "SaddleBrown" "Salmon" "SandyBrown" "SeaGreen" "SeaShell" "Sienna" \ "Silver" "SkyBlue" "SlateBlue" "SlateGrey" "Snow" "SpringGreen" \ "SteelBlue" "Tan" "Teal" "Thistle" "Tomato" "Turquoise" "Violet" \ "Wheat" "White" "WhiteSmoke" "Yellow" "YellowGreen" default = 64 endparam ;-------------------------------------------------------------------- ; Color Presets ;-------------------------------------------------------------------- heading caption = " Preset Color Settings" endheading color param colorMax1 caption = "Color Range 1 High" default = rgba(1,0,1,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Magenta" endparam color param colorMin1 caption = "Color Range 1 Low" default = rgba(100/255,0,100/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Magenta" endparam color param colorMax2 caption = "Color Range 1 High" default = rgba(138/255,43/255,226/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "BlueViolet" endparam color param colorMin2 caption = "Color Range 1 Low" default = rgba(52/255,13/255,87/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "BlueViolet" endparam color param colorMax3 caption = "Color Range 1 High" default = rgba(240/255,248/255,1,1) hint = "Specifies the color at the high end." visible = @colorchoice == "AliceBlue" endparam color param colorMin3 caption = "Color Range 1 Low" default = rgba(0,55/255,100/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "AliceBlue" endparam color param colorMax4 caption = "Color Range 1 High" default = rgba(250/255,235/255,215/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "AntiqueWhite" endparam color param colorMin4 caption = "Color Range 1 Low" default = rgba(88/255,56/255,12/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "AntiqueWhite" endparam color param colorMax5 caption = "Color Range 1 High" default = rgba(127/255,255/255,212/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Aquamarine" endparam color param colorMin5 caption = "Color Range 1 Low" default = rgba(0,100/255,66/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Aquamarine" endparam color param colorMax6 caption = "Color Range 1 High" default = rgba(240/255,255/255,255/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Azure" endparam color param colorMin6 caption = "Color Range 1 Low" default = rgba(0.0,100/255,100/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Azure" endparam color param colorMax7 caption = "Color Range 1 High" default = rgba(245/255,245/255,220/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Beige" endparam color param colorMin7 caption = "Color Range 1 Low" default = rgba(77/255,77/255,23/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Beige" endparam color param colorMax8 caption = "Color Range 1 High" default = rgba(0.1,0.1,0.1,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Black" endparam color param colorMin8 caption = "Color Range 1 Low" default = rgba(0.0,0.0,0.0,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Black" endparam color param colorMax9 caption = "Color Range 1 High" default = rgba(255/255,235/255,205/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "BlanchedAlmond" endparam color param colorMin9 caption = "Color Range 1 Low" default = rgba(100/255,60/255,0,1) hint = "Specifies the color at the low end" visible = @colorchoice == "BlanchedAlmond" endparam color param colorMax10 caption = "Color Range 1 High" default = rgba(0,0,1.0,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Blue" endparam color param colorMin10 caption = "Color Range 1 Low" default = rgba(0.0,0.0,100/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Blue" endparam color param colorMax11 caption = "Color Range 1 High" default = rgba(165/255,42/255,42/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Brown" endparam color param colorMin11 caption = "Color Range 1 Low" default = rgba(79/255,21/255,21/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Brown" endparam color param colorMax12 caption = "Color Range 1 High" default = rgba(222/255,184/255,135/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Burlywood" endparam color param colorMin12 caption = "Color Range 1 Low" default = rgba(78/255,53/255,22/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Burlywood" endparam color param colorMax13 caption = "Color Range 1 High" default = rgba(95/255,158/255,160/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "CadetBlue" endparam color param colorMin13 caption = "Color Range 1 Low" default = rgba(38/255,62/255,62/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "CadetBlue" endparam color param colorMax14 caption = "Color Range 1 High" default = rgba(210/255,105/255,30/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Chocolate" endparam color param colorMin14 caption = "Color Range 1 Low" default = rgba(87/255,43/255,13/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Chocolate" endparam color param colorMax15 caption = "Color Range 1 High" default = rgba(1,127/255,80/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Coral" endparam color param colorMin15 caption = "Color Range 1 Low" default = rgba(100/255,28/255,0,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Coral" endparam color param colorMax16 caption = "Color Range 1 High" default = rgba(100/255,147/255,237/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "CornflowerBlue" endparam color param colorMin16 caption = "Color Range 1 Low" default = rgba(11/255,40/255,89/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "CornflowerBlue" endparam color param colorMax17 caption = "Color Range 1 High" default = rgba(1.0,248/255,220/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Cornsilk" endparam color param colorMin17 caption = "Color Range 1 Low" default = rgba(100/255,80/255,0.0,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Cornsilk" endparam color param colorMax18 caption = "Color Range 1 High" default = rgba(220/255,20/255,60/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Crimson" endparam color param colorMin18 caption = "Color Range 1 Low" default = rgba(91/255,9/255,26/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Crimson" endparam color param colorMax19 caption = "Color Range 1 High" default = rgba(0,1.0,1.0,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Cyan" endparam color param colorMin19 caption = "Color Range 1 Low" default = rgba(0.0,100/255,100/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Cyan" endparam color param colorMax20 caption = "Color Range 1 High" default = rgba(0.0,0.0,139/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DarkBlue" endparam color param colorMin20 caption = "Color Range 1 Low" default = rgba(0.0,0.0,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DarkBlue" endparam color param colorMax21 caption = "Color Range 1 High" default = rgba(0.0,139/255,139/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DarkCyan" endparam color param colorMin21 caption = "Color Range 1 Low" default = rgba(0.0,50/255,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DarkCyan" endparam color param colorMax22 caption = "Color Range 1 High" default = rgba(184/255,134/255,11/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DarkGoldenrod" endparam color param colorMin22 caption = "Color Range 1 Low" default = rgba(47/255,34/255,3/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DarkGoldenrod" endparam color param colorMax23 caption = "Color Range 1 High" default = rgba(0.0,100/255,0.0,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DarkGreen" endparam color param colorMin23 caption = "Color Range 1 Low" default = rgba(0.0,50/255,0.0,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DarkGreen" endparam color param colorMax24 caption = "Color Range 1 High" default = rgba(169/255,169/255,169/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Silver" endparam color param colorMin24 caption = "Color Range 1 Low" default = rgba(50/255,50/255,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Silver" endparam color param colorMax25 caption = "Color Range 1 High" default = rgba(189/255,183/255,107/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DarkKhaki" endparam color param colorMin25 caption = "Color Range 1 Low" default = rgba(69/255,66/255,31/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DarkKhaki" endparam color param colorMax26 caption = "Color Range 1 High" default = rgba(139/255,0.0,139/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DarkMagenta" endparam color param colorMin26 caption = "Color Range 1 Low" default = rgba(50/255,0.0,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DarkMagenta" endparam color param colorMax27 caption = "Color Range 1 High" default = rgba(85/255,107/255,47/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DarkOliveGreen" endparam color param colorMin27 caption = "Color Range 1 Low" default = rgba(28/255,34/255,16/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DarkOliveGreen" endparam color param colorMax28 caption = "Color Range 1 High" default = rgba(153/255,50/255,204/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DarkOrchid" endparam color param colorMin28 caption = "Color Range 1 Low" default = rgba(30/255,10/255,40/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DarkOrchid" endparam color param colorMax29 caption = "Color Range 1 High" default = rgba(255/255,20/255,147/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DeepPink" endparam color param colorMin29 caption = "Color Range 1 Low" default = rgba(100/255,0,55/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DeepPink" endparam color param colorMax30 caption = "Color Range 1 High" default = rgba(139/255,0.0,0.0,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DarkRed" endparam color param colorMin30 caption = "Color Range 1 Low" default = rgba(50/255,0.0,0.0,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DarkRed" endparam color param colorMax31 caption = "Color Range 1 High" default = rgba(233/255,150/255,122/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DarkSalmon" endparam color param colorMin31 caption = "Color Range 1 Low" default = rgba(85/255,33/255,15/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DarkSalmon" endparam color param colorMax32 caption = "Color Range 1 High" default = rgba(71/255,61/255,139/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DarkSlateBlue" endparam color param colorMin32 caption = "Color Range 1 Low" default = rgba(18/255,16/255,34/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DarkSlateBlue" endparam color param colorMax33 caption = "Color Range 1 High" default = rgba(47/255,79/255,79/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DarkSlateGrey" endparam color param colorMin33 caption = "Color Range 1 Low" default = rgba(19/255,31/255,30/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DarkSlateGrey" endparam color param colorMax34 caption = "Color Range 1 High" default = rgba(0.0,206/255,209/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DarkTurquoise" endparam color param colorMin34 caption = "Color Range 1 Low" default = rgba(0.0,50/255,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DarkTurquoise" endparam color param colorMax35 caption = "Color Range 1 High" default = rgba(148/255,0.0,211/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DarkViolet" endparam color param colorMin35 caption = "Color Range 1 Low" default = rgba(35/255,0.0,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DarkViolet" endparam color param colorMax36 caption = "Color Range 1 High" default = rgba(0.0,191/255,255/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DeepSkyBlue" endparam color param colorMin36 caption = "Color Range 1 Low" default = rgba(0.0,75/255,100/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DeepSkyBlue" endparam color param colorMax37 caption = "Color Range 1 High" default = rgba(105/255,105/255,105/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DimGrey" endparam color param colorMin37 caption = "Color Range 1 Low" default = rgba(25/255,25/255,25/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DimGrey" endparam color param colorMax38 caption = "Color Range 1 High" default = rgba(30/255,144/255,255/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DodgerBlue" endparam color param colorMin38 caption = "Color Range 1 Low" default = rgba(0.0,52/255,100/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DodgerBlue" endparam color param colorMax39 caption = "Color Range 1 High" default = rgba(178/255,34/255,34/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "FireBrick" endparam color param colorMin39 caption = "Color Range 1 Low" default = rgba(41/255,9/255,9/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "FireBrick" endparam color param colorMax40 caption = "Color Range 1 High" default = rgba(255/255,250/255,240/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "FloralWhite" endparam color param colorMin40 caption = "Color Range 1 Low" default = rgba(100/255,70/255,0.0,1) hint = "Specifies the color at the low end" visible = @colorchoice == "FloralWhite" endparam color param colorMax41 caption = "Color Range 1 High" default = rgba(127/255,255/255,0,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Chartreuse" endparam color param colorMin41 caption = "Color Range 1 Low" default = rgba(50/255,100/255,0.0,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Chartreuse" endparam color param colorMax42 caption = "Color Range 1 High" default = rgba(143/255,188/255,143/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "DarkSeaGreen" endparam color param colorMin42 caption = "Color Range 1 Low" default = rgba(38/255,62/255,38/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "DarkSeaGreen" endparam color param colorMax43 caption = "Color Range 1 High" default = rgba(34/255,139/255,34/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "ForestGreen" endparam color param colorMin43 caption = "Color Range 1 Low" default = rgba(10/255,40/255,10/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "ForestGreen" endparam color param colorMax44 caption = "Color Range 1 High" default = rgba(255/255,0/255,255/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Fuchia" endparam color param colorMin44 caption = "Color Range 1 Low" default = rgba(100/255,0/255,100/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Fuchia" endparam color param colorMax45 caption = "Color Range 1 High" default = rgba(220/255,220/255,220/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Gainsboro" endparam color param colorMin45 caption = "Color Range 1 Low" default = rgba(50/255,50/255,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Gainsboro" endparam color param colorMax46 caption = "Color Range 1 High" default = rgba(248/255,248/255,255/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "GhostWhite" endparam color param colorMin46 caption = "Color Range 1 Low" default = rgba(0/255,0/255,100/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "GhostWhite" endparam color param colorMax47 caption = "Color Range 1 High" default = rgba(255/255,215/255,0/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Gold" endparam color param colorMin47 caption = "Color Range 1 Low" default = rgba(100/255,85/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Gold" endparam color param colorMax48 caption = "Color Range 1 High" default = rgba(218/255,165/255,32/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Goldenrod" endparam color param colorMin48 caption = "Color Range 1 Low" default = rgba(87/255,66/255,13/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Goldenrod" endparam color param colorMax49 caption = "Color Range 1 High" default = rgba(128/255,128/255,128/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Grey" endparam color param colorMin49 caption = "Color Range 1 Low" default = rgba(50/255,50/255,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Grey" endparam color param colorMax50 caption = "Color Range 1 High" default = rgba(0/255,128/255,0/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Green" endparam color param colorMin50 caption = "Color Range 1 Low" default = rgba(0/255,50/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Green" endparam color param colorMax51 caption = "Color Range 1 High" default = rgba(173/255,255/255,47/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "GreenYellow" endparam color param colorMin51 caption = "Color Range 1 Low" default = rgba(62/255,100/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "GreenYellow" endparam color param colorMax52 caption = "Color Range 1 High" default = rgba(240/255,255/255,240/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Honeydew" endparam color param colorMin52 caption = "Color Range 1 Low" default = rgba(0/255,100/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Honeydew" endparam color param colorMax53 caption = "Color Range 1 High" default = rgba(255/255,105/255,180/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "HotPink" endparam color param colorMin53 caption = "Color Range 1 Low" default = rgba(100/255,0/255,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "HotPink" endparam color param colorMax54 caption = "Color Range 1 High" default = rgba(205/255,92/255,92/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "IndianRed" endparam color param colorMin54 caption = "Color Range 1 Low" default = rgba(76/255,24/255,24/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "IndianRed" endparam color param colorMax55 caption = "Color Range 1 High" default = rgba(75/255,0/255,130/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Indigo" endparam color param colorMin55 caption = "Color Range 1 Low" default = rgba(29/255,0/255,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Indigo" endparam color param colorMax56 caption = "Color Range 1 High" default = rgba(255/255,255/255,240/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Ivory" endparam color param colorMin56 caption = "Color Range 1 Low" default = rgba(100/255,100/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Ivory" endparam color param colorMax57 caption = "Color Range 1 High" default = rgba(240/255,230/255,140/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Khaki" endparam color param colorMin57 caption = "Color Range 1 Low" default = rgba(88/255,80/255,12/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Khaki" endparam color param colorMax58 caption = "Color Range 1 High" default = rgba(230/255,230/255,250/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Lavender" endparam color param colorMin58 caption = "Color Range 1 Low" default = rgba(17/255,17/255,83/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Lavender" endparam color param colorMax59 caption = "Color Range 1 High" default = rgba(255/255,240/255,245/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LavenderBlush" endparam color param colorMin59 caption = "Color Range 1 Low" default = rgba(100/255,0/255,44/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LavenderBlush" endparam color param colorMax60 caption = "Color Range 1 High" default = rgba(124/255,252/255,0/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LawnGreen" endparam color param colorMin60 caption = "Color Range 1 Low" default = rgba(50/255,100/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LawnGreen" endparam color param colorMax61 caption = "Color Range 1 High" default = rgba(255/255,250/255,205/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LemonChiffon" endparam color param colorMin61 caption = "Color Range 1 Low" default = rgba(100/255,90/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LemonChiffon" endparam color param colorMax62 caption = "Color Range 1 High" default = rgba(173/255,216/255,230/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LightBlue" endparam color param colorMin62 caption = "Color Range 1 Low" default = rgba(24/255,64/255,76/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LightBlue" endparam color param colorMax63 caption = "Color Range 1 High" default = rgba(240/255,128/255,128/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LightCoral" endparam color param colorMin63 caption = "Color Range 1 Low" default = rgba(89/255,11/255,11/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LightCoral" endparam color param colorMax64 caption = "Color Range 1 High" default = rgba(224/255,255/255,255/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LightCyan" endparam color param colorMin64 caption = "Color Range 1 Low" default = rgba(0/255,100/255,100/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LightCyan" endparam color param colorMax65 caption = "Color Range 1 High" default = rgba(250/255,250/255,210/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LightGoldenrodYellow" endparam color param colorMin65 caption = "Color Range 1 Low" default = rgba(90/255,90/255,10/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LightGoldenrodYellow" endparam color param colorMax66 caption = "Color Range 1 High" default = rgba(144/255,238/255,144/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LightGreen" endparam color param colorMin66 caption = "Color Range 1 Low" default = rgba(14/255,86/255,14/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LightGreen" endparam color param colorMax67 caption = "Color Range 1 High" default = rgba(211/255,211/255,211/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LightGrey" endparam color param colorMin67 caption = "Color Range 1 Low" default = rgba(50/255,50/255,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LightGrey" endparam color param colorMax68 caption = "Color Range 1 High" default = rgba(255/255,182/255,193/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LightPink" endparam color param colorMin68 caption = "Color Range 1 Low" default = rgba(100/255,0/255,17/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LightPink" endparam color param colorMax69 caption = "Color Range 1 High" default = rgba(255/255,160/255,122/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LightSalmon" endparam color param colorMin69 caption = "Color Range 1 Low" default = rgba(100/255,30/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LightSalmon" endparam color param colorMax70 caption = "Color Range 1 High" default = rgba(32/255,178/255,170/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LightSeaGreen" endparam color param colorMin70 caption = "Color Range 1 Low" default = rgba(16/255,84/255,80/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LightSeaGreen" endparam color param colorMax71 caption = "Color Range 1 High" default = rgba(135/255,206/255,250/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LightSkyBlue" endparam color param colorMin71 caption = "Color Range 1 Low" default = rgba(5/255,62/255,95/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LightSkyBlue" endparam color param colorMax72 caption = "Color Range 1 High" default = rgba(119/255,136/255,153/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LightSlateGrey" endparam color param colorMin72 caption = "Color Range 1 Low" default = rgba(43/255,50/255,57/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LightSlateGrey" endparam color param colorMax73 caption = "Color Range 1 High" default = rgba(175/255,196/255,222/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LightSteelBlue" endparam color param colorMin73 caption = "Color Range 1 Low" default = rgba(30/255,48/255,70/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LightSteelBlue" endparam color param colorMax74 caption = "Color Range 1 High" default = rgba(255/255,255/255,224/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LightYellow" endparam color param colorMin74 caption = "Color Range 1 Low" default = rgba(100/255,100/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LightYellow" endparam color param colorMax75 caption = "Color Range 1 High" default = rgba(0/255,255/255,0/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Lime" endparam color param colorMin75 caption = "Color Range 1 Low" default = rgba(0/255,100/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Lime" endparam color param colorMax76 caption = "Color Range 1 High" default = rgba(50/255,205/255,50/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "LimeGreen" endparam color param colorMin76 caption = "Color Range 1 Low" default = rgba(20/255,80/255,20/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "LimeGreen" endparam color param colorMax77 caption = "Color Range 1 High" default = rgba(250/255,240/255,230/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Linen" endparam color param colorMin77 caption = "Color Range 1 Low" default = rgba(83/255,50/255,17/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Linen" endparam color param colorMax78 caption = "Color Range 1 High" default = rgba(128/255,0/255,0/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Maroon" endparam color param colorMin78 caption = "Color Range 1 Low" default = rgba(50/255,0/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Maroon" endparam color param colorMax79 caption = "Color Range 1 High" default = rgba(102/255,205/255,170/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "MediumAquamarine" endparam color param colorMin79 caption = "Color Range 1 Low" default = rgba(25/255,75/255,58/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "MediumAquamarine" endparam color param colorMax80 caption = "Color Range 1 High" default = rgba(0/255,0/255,205/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "MediumBlue" endparam color param colorMin80 caption = "Color Range 1 Low" default = rgba(0/255,0/255,100/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "MediumBlue" endparam color param colorMax81 caption = "Color Range 1 High" default = rgba(186/255,85/255,211/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "MediumOrchid" endparam color param colorMin81 caption = "Color Range 1 Low" default = rgba(68/255,21/255,79/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "MediumOrchid" endparam color param colorMax82 caption = "Color Range 1 High" default = rgba(147/255,112/255,219/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "MediumPurple" endparam color param colorMin82 caption = "Color Range 1 Low" default = rgba(40/255,21/255,79/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "MediumPurple" endparam color param colorMax83 caption = "Color Range 1 High" default = rgba(60/255,179/255,113/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "MediumSeaGreen" endparam color param colorMin83 caption = "Color Range 1 Low" default = rgba(26/255,74/255,47/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "MediumSeaGreen" endparam color param colorMax84 caption = "Color Range 1 High" default = rgba(123/255,104/255,238/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "MediumSlateBlue" endparam color param colorMin84 caption = "Color Range 1 Low" default = rgba(22/255,11/255,89/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "MediumSlateBlue" endparam color param colorMax85 caption = "Color Range 1 High" default = rgba(0/255,250/255,154/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "MediumSpringGreen" endparam color param colorMin85 caption = "Color Range 1 Low" default = rgba(0/255,100/255,61/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "MediumSpringGreen" endparam color param colorMax86 caption = "Color Range 1 High" default = rgba(72/255,209/255,204/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "MediumTurquoise" endparam color param colorMin86 caption = "Color Range 1 Low" default = rgba(21/255,79/255,77/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "MediumTurquoise" endparam color param colorMax87 caption = "Color Range 1 High" default = rgba(199/255,21/255,133/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "MediumVioletRed" endparam color param colorMin87 caption = "Color Range 1 Low" default = rgba(90/255,10/255,61/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "MediumVioletRed" endparam color param colorMax88 caption = "Color Range 1 High" default = rgba(25/255,25/255,112/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "MidnightBlue" endparam color param colorMin88 caption = "Color Range 1 Low" default = rgba(10/255,10/255,40/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "MidnightBlue" endparam color param colorMax89 caption = "Color Range 1 High" default = rgba(245/255,255/255,250/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "MintCream" endparam color param colorMin89 caption = "Color Range 1 Low" default = rgba(0/255,100/255,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "MintCream" endparam color param colorMax90 caption = "Color Range 1 High" default = rgba(255/255,228/255,225/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "MistyRose" endparam color param colorMin90 caption = "Color Range 1 Low" default = rgba(100/255,10/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "MistyRose" endparam color param colorMax91 caption = "Color Range 1 High" default = rgba(255/255,228/255,181/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Moccasin" endparam color param colorMin91 caption = "Color Range 1 Low" default = rgba(100/255,65/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Moccasin" endparam color param colorMax92 caption = "Color Range 1 High" default = rgba(255/255,222/255,173/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "NavajoWhite" endparam color param colorMin92 caption = "Color Range 1 Low" default = rgba(100/255,60/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "NavajoWhite" endparam color param colorMax93 caption = "Color Range 1 High" default = rgba(253/255,245/255,230/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "OldLace" endparam color param colorMin93 caption = "Color Range 1 Low" default = rgba(92/255,64/255,8/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "OldLace" endparam color param colorMax94 caption = "Color Range 1 High" default = rgba(128/255,128/255,0/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Olive" endparam color param colorMin94 caption = "Color Range 1 Low" default = rgba(50/255,50/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Olive" endparam color param colorMax95 caption = "Color Range 1 High" default = rgba(107/255,142/255,35/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "OliveDrab" endparam color param colorMin95 caption = "Color Range 1 Low" default = rgba(31/255,40/255,10/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "OliveDrab" endparam color param colorMax96 caption = "Color Range 1 High" default = rgba(255/255,165/255,0/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Orange" endparam color param colorMin96 caption = "Color Range 1 Low" default = rgba(100/255,65/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Orange" endparam color param colorMax97 caption = "Color Range 1 High" default = rgba(255/255,69/255,0/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "OrangeRed" endparam color param colorMin97 caption = "Color Range 1 Low" default = rgba(100/255,28/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "OrangeRed" endparam color param colorMax98 caption = "Color Range 1 High" default = rgba(218/255,112/255,214/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Orchid" endparam color param colorMin98 caption = "Color Range 1 Low" default = rgba(79/255,21/255,78/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Orchid" endparam color param colorMax99 caption = "Color Range 1 High" default = rgba(238/255,232/255,170/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "PaleGoldenrod" endparam color param colorMin99 caption = "Color Range 1 Low" default = rgba(81/255,74/255,19/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "PaleGoldenrod" endparam color param colorMax100 caption = "Color Range 1 High" default = rgba(152/255,251/255,152/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "PaleGreen" endparam color param colorMin100 caption = "Color Range 1 Low" default = rgba(4/255,96/255,4/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "PaleGreen" endparam color param colorMax101 caption = "Color Range 1 High" default = rgba(175/255,238/255,238/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "PaleTurquoise" endparam color param colorMin101 caption = "Color Range 1 Low" default = rgba(18/255,82/255,82/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "PaleTurquoise" endparam color param colorMax102 caption = "Color Range 1 High" default = rgba(219/255,112/255,147/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "PaleVioletRed" endparam color param colorMin102 caption = "Color Range 1 Low" default = rgba(79/255,21/255,41/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "PaleVioletRed" endparam color param colorMax103 caption = "Color Range 1 High" default = rgba(255/255,239/255,213/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "PapayaWhip" endparam color param colorMin103 caption = "Color Range 1 Low" default = rgba(100/255,63/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "PapayaWhip" endparam color param colorMax104 caption = "Color Range 1 High" default = rgba(255/255,218/255,185/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "PeachPuff" endparam color param colorMin104 caption = "Color Range 1 Low" default = rgba(100/255,48/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "PeachPuff" endparam color param colorMax105 caption = "Color Range 1 High" default = rgba(205/255,133/255,63/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Peru" endparam color param colorMin105 caption = "Color Range 1 Low" default = rgba(79/255,50/255,21/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Peru" endparam color param colorMax106 caption = "Color Range 1 High" default = rgba(255/255,192/255,203/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Pink" endparam color param colorMin106 caption = "Color Range 1 Low" default = rgba(100/255,0/255,19/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Pink" endparam color param colorMax107 caption = "Color Range 1 High" default = rgba(221/255,160/255,221/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Plum" endparam color param colorMin107 caption = "Color Range 1 Low" default = rgba(73/255,27/255,73/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Plum" endparam color param colorMax108 caption = "Color Range 1 High" default = rgba(176/255,224/255,230/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "PowderBlue" endparam color param colorMin108 caption = "Color Range 1 Low" default = rgba(25/255,70/255,75/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "PowderBlue" endparam color param colorMax109 caption = "Color Range 1 High" default = rgba(128/255,0/255,128/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Purple" endparam color param colorMin109 caption = "Color Range 1 Low" default = rgba(50/255,0/255,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Purple" endparam color param colorMax110 caption = "Color Range 1 High" default = rgba(255/255,0/255,0/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Red" endparam color param colorMin110 caption = "Color Range 1 Low" default = rgba(100/255,0/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Red" endparam color param colorMax111 caption = "Color Range 1 High" default = rgba(188/255,143/255,143/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "RosyBrown" endparam color param colorMin111 caption = "Color Range 1 Low" default = rgba(62/255,38/255,38/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "RosyBrown" endparam color param colorMax112 caption = "Color Range 1 High" default = rgba(65/255,105/255,225/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "RoyalBlue" endparam color param colorMin112 caption = "Color Range 1 Low" default = rgba(14/255,32/255,86/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "RoyalBlue" endparam color param colorMax113 caption = "Color Range 1 High" default = rgba(139/255,69/255,19/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "SaddleBrown" endparam color param colorMin113 caption = "Color Range 1 Low" default = rgba(43/255,22/255,7/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "SaddleBrown" endparam color param colorMax114 caption = "Color Range 1 High" default = rgba(250/255,128/255,114/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Salmon" endparam color param colorMin114 caption = "Color Range 1 Low" default = rgba(96/255,14/255,4/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Salmon" endparam color param colorMax115 caption = "Color Range 1 High" default = rgba(244/255,164/255,96/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "SandyBrown" endparam color param colorMin115 caption = "Color Range 1 Low" default = rgba(93/255,47/255,7/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "SandyBrown" endparam color param colorMax116 caption = "Color Range 1 High" default = rgba(46/255,139/255,87/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "SeaGreen" endparam color param colorMin116 caption = "Color Range 1 Low" default = rgba(13/255,37/255,23/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "SeaGreen" endparam color param colorMax117 caption = "Color Range 1 High" default = rgba(255/255,245/255,238/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "SeaShell" endparam color param colorMin117 caption = "Color Range 1 Low" default = rgba(100/255,41/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "SeaShell" endparam color param colorMax118 caption = "Color Range 1 High" default = rgba(160/255,82/255,45/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Sienna" endparam color param colorMin118 caption = "Color Range 1 Low" default = rgba(39/255,20/255,11/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Sienna" endparam color param colorMax119 caption = "Color Range 1 High" default = rgba(135/255,206/255,235/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "SkyBlue" endparam color param colorMin119 caption = "Color Range 1 Low" default = rgba(15/255,66/255,85/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "SkyBlue" endparam color param colorMax120 caption = "Color Range 1 High" default = rgba(106/255,90/255,205/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "SlateBlue" endparam color param colorMin120 caption = "Color Range 1 Low" default = rgba(21/255,34/255,76/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "SlateBlue" endparam color param colorMax121 caption = "Color Range 1 High" default = rgba(112/255,128/255,144/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "SlateGrey" endparam color param colorMin121 caption = "Color Range 1 Low" default = rgba(44/255,50/255,56/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "SlateGrey" endparam color param colorMax122 caption = "Color Range 1 High" default = rgba(255/255,250/255,250/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Snow" endparam color param colorMin122 caption = "Color Range 1 Low" default = rgba(100/255,0/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Snow" endparam color param colorMax123 caption = "Color Range 1 High" default = rgba(0/255,255/255,127/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "SpringGreen" endparam color param colorMin123 caption = "Color Range 1 Low" default = rgba(0/255,100/255,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "SpringGreen" endparam color param colorMax124 caption = "Color Range 1 High" default = rgba(70/255,130/255,180/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "SteelBlue" endparam color param colorMin124 caption = "Color Range 1 Low" default = rgba(29/255,53/255,79/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "SteelBlue" endparam color param colorMax125 caption = "Color Range 1 High" default = rgba(210/255,180/255,140/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Tan" endparam color param colorMin125 caption = "Color Range 1 Low" default = rgba(71/255,53/255,29/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Tan" endparam color param colorMax126 caption = "Color Range 1 High" default = rgba(0/255,128/255,128/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Teal" endparam color param colorMin126 caption = "Color Range 1 Low" default = rgba(0/255,50/255,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Teal" endparam color param colorMax127 caption = "Color Range 1 High" default = rgba(216/255,191/255,216/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Thistle" endparam color param colorMin127 caption = "Color Range 1 Low" default = rgba(61/255,39/255,61/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Thistle" endparam color param colorMax128 caption = "Color Range 1 High" default = rgba(255/255,99/255,71/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Tomato" endparam color param colorMin128 caption = "Color Range 1 Low" default = rgba(100/255,16/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Tomato" endparam color param colorMax129 caption = "Color Range 1 High" default = rgba(64/255,224/255,208/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Turquoise" endparam color param colorMin129 caption = "Color Range 1 Low" default = rgba(15/255,85/255,78/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Turquoise" endparam color param colorMax130 caption = "Color Range 1 High" default = rgba(238/255,130/255,238/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Violet" endparam color param colorMin130 caption = "Color Range 1 Low" default = rgba(87/255,13/255,87/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Violet" endparam color param colorMax131 caption = "Color Range 1 High" default = rgba(245/255,223/255,179/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Wheat" endparam color param colorMin131 caption = "Color Range 1 Low" default = rgba(88/255,62/255,12/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Wheat" endparam color param colorMax132 caption = "Color Range 1 High" default = rgba(255/255,255/255,255/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "White" endparam color param colorMin132 caption = "Color Range 1 Low" default = rgba(50/255,50/255,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "White" endparam color param colorMax133 caption = "Color Range 1 High" default = rgba(245/255,245/255,245/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "WhiteSmoke" endparam color param colorMin133 caption = "Color Range 1 Low" default = rgba(50/255,50/255,50/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "WhiteSmoke" endparam color param colorMax134 caption = "Color Range 1 High" default = rgba(255/255,255/255,0/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "Yellow" endparam color param colorMin134 caption = "Color Range 1 Low" default = rgba(100/255,100/255,0/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "Yellow" endparam color param colorMax135 caption = "Color Range 1 High" default = rgba(154/255,205/255,50/255,1) hint = "Specifies the color at the high end." visible = @colorchoice == "YellowGreen" endparam color param colorMin135 caption = "Color Range 1 Low" default = rgba(61/255,80/255,20/255,1) hint = "Specifies the color at the low end" visible = @colorchoice == "YellowGreen" endparam } class Quat(generic) { public: import "common.ulb" ; constructor func Quat(Generic pparent) Generic.Generic(pparent) im = (0,1) m_cri = 0 m_cjk = 0 m_zri = 0 m_zjk = 0 m_julia = false m_mand = false m_quat = false m_hyper = false m_brot = false m_spider = false m_oldz = false m_sphere = false m_converge = false m_fourth = 0 m_ck = 0 in = new Vector(0,0,0,0) out = new Vector(0,0,0,0) ind = new Vector(0,0,0,0) outd = new Vector(0,0,0,0) cin = new Vector(0,0,0,0) cout = new Vector(0,0,0,0) endfunc ; must be overridden func frcalc(complex &zri, complex &zjk) endfunc ; must be overridden func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) endfunc func CtoV(complex a, complex b, Vector &c) c.init(real(a), imag(a),real(b),imag(b)) endfunc func VtoC(complex &a, complex &b, Vector c) float a1 = c.get(0) float b1 = c.get(1) float c1 = c.get(2) float d1 = c.get(3) a = a1 + flip(b1) b = c1 + flip(d1) endfunc func Rotate(float &x, float &y, float &z, float angle, Vector a) ROT.Rotate(x, y, z, angle, a) endfunc func RotateX(float &x, float &y, float &z, float angle) ROT.RotateX(x, y, z, angle) endfunc func RotateY(float &x, float &y, float &z, float angle) ROT.RotateY(x, y, z, angle) endfunc func RotateZ(float &x, float &y, float &z, float angle) ROT.RotateZ(x, y, z, angle) endfunc func getjp(complex &cri, complex &cjk) cri = m_cri cjk = m_cjk endfunc func setjp(complex cri, complex cjk) m_cri = cri m_cjk = cjk endfunc func getmp(complex &zri, complex &zjk) zri = m_zri zjk = m_zjk endfunc func getomp(complex &zri, complex &zjk) zri = m_oldzri zjk = m_oldzjk endfunc func setomp(complex &zri, complex &zjk) m_oldzri = zri m_oldzjk = zjk endfunc int func get4() return m_fourth endfunc float func getck() return m_ck endfunc bool func jtype() return m_julia endfunc bool func mtype() return m_mand endfunc bool func qtype() return m_quat endfunc bool func htype() return m_hyper endfunc bool func btype() return m_brot endfunc bool func stype() return m_spider endfunc bool func ztype() return m_oldz endfunc bool func sptype() return m_sphere endfunc complex func getspecial() return spec endfunc bool func bailtype() return m_converge endfunc protected: complex im complex m_cri complex m_cjk complex m_zri complex m_zjk complex m_oldzri complex m_oldzjk complex temp bool m_julia bool m_mand bool m_quat bool m_hyper bool m_brot bool m_spider bool m_oldz bool m_sphere bool m_converge int m_fourth float m_ck Vector in Vector ind Vector out Vector cin Vector outd Vector cout complex spec default: int param v_quat caption = "Version (quat)" 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_quat < 100 endparam } class Julia(Quat) { ; This is the standard Quaternion public: import "common.ulb" ; constructor func Julia(Generic pparent) Quat.Quat(pparent) im = (0,1) hrotp = exp(im*@hangle*#pi/180) hrotn = exp(-im*@hangle*#pi/180) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) QH.QMul(in,in,out) VtoC(zri,zjk,out) zri = hrotn*zri + hrotp*m_cri zjk = hrotn*zjk + hrotp*m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.QMul(in,ind,out) VtoC(zrid,zjkd,out) zrid = hrotn*2*zrid zjkd = hrotn*2*zjkd endfunc protected: complex hrotp complex hrotn int rotcount default: title = "Julia Quaternion" int param v_juliaquat caption = "Version (Julia Quaternion)" 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_juliaquat < 100 endparam heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (-0.5,-0.5) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam heading text = "The 'Hart angle' rotates the fractal in the r-i plane. Because \ quaternian math is noncommutative, unusual shapes and forms are \ created." endheading float param hangle caption = "Hart angle" default = 0.0 hint = "The 'Hart angle' rotates the r-i plane. This is not the same \ as rotating the object." endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class ChebyshevJulia(Quat) { public: import "common.ulb" ; constructor func ChebyshevJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = true m_fourth = @fourth m_ck = @ck temp = new Vector(0,0,0,0) temp2 = new Vector(0,0,0,0) endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) if @n == 2 QH.Qmul(in,in,out) VtoC(a,b,out) a = 2*a - 1 b = 2*b CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 3 QH.QMul(in,in,out) QH.QMul(out,in,cin) VtoC(a,b,cin) a = 4*a - 3*zri b = 4*b - 3*zjk CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 4 QH.QMul(in,in,out) ; z^2 QH.QMul(out,out,cin) ; z^4 VtoC(a,b,out) VtoC(a1,b1,cin) a = 8*a1 - 8*a + 1 b = 8*b1 - 8*b CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 5 QH.QMul(in,in,out) ; z^2 QH.QMul(out,in,cin) ; z^3 QH.QMul(cin,out,temp) ; z^5 VtoC(a,b,cin) VtoC(a1,b1,temp) a = 16*a1 - 20*a + 5*zri b = 16*b1 - 20*b + 5*zjk CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 6 QH.QMul(in,in,out) ; z^2 QH.QMul(out,out,temp) ; z^4 QH.QMul(out,temp,in) ; z^6 VtoC(a,b,out) VtoC(a1,b1,temp) VtoC(a2,b2,in) a = 32*a2 - 48*a1 + 18*a - 1 b = 32*b2 - 48*b1 + 18*b CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) endif endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) CtoV(zrid,zjkd,ind) if @n == 2 QH.Qmul(cin,in,out) QH.Qmul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = 4*zrid + 1 zjkd = 4*zjkd elseif @n == 3 QH.QMul(in,in,out) VtoC(a,b,out) a = 12*a - 3 b = 12*b CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 4 QH.QMul(in,in,out) QH.Qmul(in,out,temp) VtoC(a,b,temp) a = 32*a - 16*zri b = 32*b - 16*zjk CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 5 QH.QMul(in,in,out) ; z^2 QH.QMul(out,out,temp) ; z^4 VtoC(a,b,out) VtoC(a1,b1,temp) a = 90*a1 - 60*a + 5 b = 90*b1 - 60*b CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 6 QH.QMul(in,in,out) ; z^2 QH.QMul(out,in,temp) ; z^3 QH.QMul(temp,out,temp2) ; z^5 VtoC(a,b,temp) VtoC(a1,b1,temp2) a = 192*a1 - 192*a + 36*zri b = 192*b1 - 192*b + 36*zjk CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 endif endfunc protected: complex a complex b complex a1 complex b1 complex a2 complex b2 vector temp vector temp2 default: title = "Chebyshev Julia Quaternion" int param v_Chebyshevjuliaquat caption = "Version (Chebyshev Julia Quaternion)" 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_Chebyshevjuliaquat < 100 endparam heading text = "Legendre polynomials are solutions to the Legendre differential equation \ which is frequently encountered in physics and other technical fields. \ These polynomials can also be used to define an \ interesting set of fractals." endheading heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.13125,0.45625) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam int param n caption = "Chebyschev number" default = 2 min = 2 max = 6 endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class LegendreJulia(Quat) { public: import "common.ulb" ; constructor func LegendreJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = true m_fourth = @fourth m_ck = @ck temp = new Vector(0,0,0,0) temp2 = new Vector(0,0,0,0) endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) if @n == 2 QH.Qmul(in,in,out) VtoC(a,b,out) a = (3*a - 1)/2 b = 3*b/2 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 3 QH.QMul(in,in,out) QH.QMul(out,in,cin) VtoC(a,b,cin) a = (5*a - 3*zri)/2 b = (5*b - 3*zjk)/2 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 4 QH.QMul(in,in,out) ; z^2 QH.QMul(out,out,cin) ; z^4 VtoC(a,b,out) VtoC(a1,b1,cin) a = (35*a1 - 30*a + 3)/8 b = (35*b1 - 30*b)/8 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 5 QH.QMul(in,in,out) ; z^2 QH.QMul(out,in,cin) ; z^3 QH.QMul(cin,out,temp) ; z^5 VtoC(a,b,cin) VtoC(a1,b1,temp) a = (63*a1 - 70*a + 15*zri)/8 b = (63*b1 - 70*b + 15*zjk)/8 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 6 QH.QMul(in,in,out) ; z^2 QH.QMul(out,out,temp) ; z^4 QH.QMul(out,temp,in) ; z^6 VtoC(a,b,out) VtoC(a1,b1,temp) VtoC(a2,b2,in) a = (231*a2 - 315*a1 + 105*a - 5)/16 b = (231*b2 - 315*b1 + 105*b)/16 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) endif endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) CtoV(zrid,zjkd,ind) if @n == 2 QH.Qmul(cin,in,out) QH.Qmul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = 3*zrid + 1 zjkd = 3*zjkd elseif @n == 3 QH.QMul(in,in,out) VtoC(a,b,out) a = (15*a - 3)/2 b = (15*b)/2 CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 4 QH.QMul(in,in,out) QH.Qmul(in,out,temp) VtoC(a,b,temp) a = (140*a - 60*zri)/8 b = (140*b - 60*zjk)/8 CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 5 QH.QMul(in,in,out) ; z^2 QH.QMul(out,out,temp) ; z^4 VtoC(a,b,out) VtoC(a1,b1,temp) a = (315*a1 - 210*a + 15)/8 b = (315*b1 - 210*b)/8 CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 6 QH.QMul(in,in,out) ; z^2 QH.QMul(out,in,temp) ; z^3 QH.QMul(temp,out,temp2) ; z^5 VtoC(a,b,temp) VtoC(a1,b1,temp2) a = (1386*a1 - 1260*a + 210*zri)/16 b = (1386*b1 - 1260*b + 210*zjk)/16 CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 endif endfunc protected: complex a complex b complex a1 complex b1 complex a2 complex b2 vector temp vector temp2 default: title = "Legendre Julia Quaternion" int param v_Legendrejuliaquat caption = "Version (Legendre Julia Quaternion)" 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_Legendrejuliaquat < 100 endparam heading text = "Legendre polynomials are solutions to the Legendre differential equation \ which is frequently encountered in physics and other technical fields. \ These polynomials can also be used to define an \ interesting set of fractals." endheading heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.93125,0.375) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam int param n caption = "Legendre number" default = 2 min = 2 max = 6 endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class LaguerreJulia(Quat) { public: import "common.ulb" ; constructor func LaguerreJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = true m_fourth = @fourth m_ck = @ck temp = new Vector(0,0,0,0) temp2 = new Vector(0,0,0,0) temp3 = new Vector(0,0,0,0) endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) if @n == 2 QH.Qmul(in,in,out) VtoC(a,b,out) a = (a - 4*zri + 2)/2 b = (b - 4*zjk)/2 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 3 QH.QMul(in,in,out) QH.QMul(out,in,cin) VtoC(a,b,cin) VtoC(a1,b1,out) a = (-a + 9*a1 - 18*zri + 6)/6 b = (-b + 9*b1 - 18*zjk)/6 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 4 QH.QMul(in,in,out) QH.QMul(in,out,temp) QH.QMul(out,out,cin) VtoC(a,b,out) VtoC(a1,b1,temp) VtoC(a2,b2,cin) a = (a2 -16*a1 + 72*a -96*zri +24)/24 b = (b2 -16*b1 + 72*b -96*zjk)/24 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 5 QH.QMul(in,in,out) ; z^2 QH.QMul(in,out,temp) ; z^3 QH.QMul(out,out,temp2) ;z^4 QH.QMul(temp2,in,cin) ; z^5 VtoC(a,b,cin) ;z^5 VtoC(a1,b1,temp2) ;z^4 VtoC(a2,b2,temp) ;z^3 VtoC(a3,b3,out) ;z^2 a = (-a + 25*a1 - 200*a2 + 600*a3 - 600*zri + 120)/120 b = (-b + 25*b1 - 200*b2 + 600*b3 - 600*zjk)/120 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 6 QH.QMul(in,in,out) ; z^2 QH.QMul(in,out,temp) ; z^3 QH.QMul(out,out,temp2) ;z^4 QH.QMul(temp2,in,temp3) ;z^5 QH.QMul(temp,temp,cin) ; z^6 VtoC(a,b,cin) ;z^6 VtoC(a1,b1,temp3) ;z^5 VtoC(a2,b2,temp2) ;z^4 VtoC(a3,b3,temp) ;z^3 VtoC(a4,b4,out) ;z^2 a = (a - 36*a1 + 450*a2 - 2400*a3 + 5400*a4 - 4320*zri + 720)/720 b = (b - 36*b1 + 450*b2 - 2400*b3 + 5400*b4 - 4320*zjk)/720 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) endif endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) CtoV(zrid,zjkd,ind) if @n == 2 zri = zri - 2 CtoV(zri,zjk,in) QH.Qmul(cin,in,out) QH.Qmul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 3 QH.QMul(in,in,out) VtoC(a,b,out) a = (-3*a + 18*zri - 18)/6 b = (-3*b + 18*zjk)/6 CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 4 QH.QMul(in,in,out) QH.Qmul(in,out,temp) VtoC(a,b,temp) VtoC(a1,b1,out) a = (4*a -48*a1 + 144*zri -96)/24 b = (4*b -48*b1 + 144*zjk)/24 CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 5 QH.QMul(in,in,out) ;z^2 QH.QMul(in,out,temp) ;z^3 QH.QMul(out,out,temp2) ;z^4 VtoC(a,b,temp2) ;z^4 VtoC(a1,b1,temp) ;z^3 VtoC(a2,b2,out) ;z^2 a = (-5*a + 100*a1 - 600*a2 + 1200*zri - 600)/120 b = (-5*b + 100*b1 - 600*b2 + 1200*zjk)/120 CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 6 QH.QMul(in,in,out) ;z^2 QH.QMul(in,out,temp) ;z^3 QH.QMul(out,out,temp2) ;z^4 QH.QMul(temp2,in,temp3) ;z^5 VtoC(a,b,temp3) ; z^5 VtoC(a1,b1,temp2) ; z^4 VtoC(a2,b2,temp) ;z^3 VtoC(a3,b3,out) ;z^2 a = (6*a - 180*a1 + 1800*a2 - 7200*a3 + 10800*zri - 4320)/720 b = (6*b - 180*b1 + 1800*b2 - 7200*b3 + 10800*zjk)/720 CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 endif endfunc protected: complex a complex b complex a1 complex b1 complex a2 complex b2 complex a3 complex b3 complex a4 complex b4 vector temp vector temp2 vector temp3 default: title = "Laguerre Julia Quaternion" int param v_Laguerrejuliaquat caption = "Version (Laguerre Julia Quaternion)" 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_Laguerrejuliaquat < 100 endparam heading text = "The Laguerre polynomials are solutions to Laguerre's differential equation. \ The Laguerre polynomials arise in quantum mechanics, in the radial part \ of the solution of the Schrödinger equation for a one-electron atom. \ These polynomials can also be used to define an \ interesting set of fractals." endheading heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (-0.4329942,0.0844477) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam int param n caption = "Laguerre number" default = 2 min = 2 max = 6 endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class LegendreHyperJulia(Quat) { public: import "common.ulb" ; constructor func LegendreHyperJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = true m_fourth = @fourth m_ck = @ck temp = new Vector(0,0,0,0) temp2 = new Vector(0,0,0,0) endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) if @n == 2 QH.HMul(in,in,out) VtoC(a,b,out) a = (3*a - 1)/2 b = 3*b/2 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.HMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 3 QH.HMul(in,in,out) QH.HMul(out,in,cin) VtoC(a,b,cin) a = (5*a - 3*zri)/2 b = (5*b - 3*zjk)/2 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.HMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 4 QH.HMul(in,in,out) ; z^2 QH.HMul(out,out,cin) ; z^4 VtoC(a,b,out) VtoC(a1,b1,cin) a = (35*a1 - 30*a + 3)/8 b = (35*b1 - 30*b)/8 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.HMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 5 QH.HMul(in,in,out) ; z^2 QH.HMul(out,in,cin) ; z^3 QH.HMul(cin,out,temp) ; z^5 VtoC(a,b,cin) VtoC(a1,b1,temp) a = (63*a1 - 70*a + 15*zri)/8 b = (63*b1 - 70*b + 15*zjk)/8 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.HMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 6 QH.HMul(in,in,out) ; z^2 QH.HMul(out,out,temp) ; z^4 QH.HMul(out,temp,in) ; z^6 VtoC(a,b,out) VtoC(a1,b1,temp) VtoC(a2,b2,in) a = (231*a2 - 315*a1 + 105*a - 5)/16 b = (231*b2 - 315*b1 + 105*b)/16 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.HMul(cin,in,out) VtoC(zri,zjk,out) endif endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) CtoV(zrid,zjkd,ind) if @n == 2 QH.HMul(cin,in,out) QH.HMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = 3*zrid + 1 zjkd = 3*zjkd elseif @n == 3 QH.HMul(in,in,out) VtoC(a,b,out) a = (15*a - 3)/2 b = (15*b)/2 CtoV(a,b,in) QH.HMul(cin,in,out) QH.HMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 4 QH.HMul(in,in,out) QH.HMul(in,out,temp) VtoC(a,b,temp) a = (140*a - 60*zri)/8 b = (140*b - 60*zjk)/8 CtoV(a,b,in) QH.HMul(cin,in,out) QH.HMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 5 QH.HMul(in,in,out) ; z^2 QH.HMul(out,out,temp) ; z^4 VtoC(a,b,out) VtoC(a1,b1,temp) a = (315*a1 - 210*a + 15)/8 b = (315*b1 - 210*b)/8 CtoV(a,b,in) QH.HMul(cin,in,out) QH.HMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 6 QH.HMul(in,in,out) ; z^2 QH.HMul(out,in,temp) ; z^3 QH.HMul(temp,out,temp2) ; z^5 VtoC(a,b,temp) VtoC(a1,b1,temp2) a = (1386*a1 - 1260*a + 210*zri)/16 b = (1386*b1 - 1260*b + 210*zjk)/16 CtoV(a,b,in) QH.HMul(cin,in,out) QH.HMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 endif endfunc protected: complex a complex b complex a1 complex b1 complex a2 complex b2 vector temp vector temp2 default: title = "Legendre Julia Hypercomplex" int param v_Legendrejuliahyper caption = "Version (Legendre Julia Hypercomplex)" 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_Legendrejuliahyper < 100 endparam heading text = "Legendre polynomials are solutions to the Legendre differential equation \ which is frequently encountered in physics and other technical fields. \ These polynomials can also be used to define an \ interesting set of fractals." endheading heading text = "Uses hypercomplex mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ commutative and the inverse is not always defined. This was first \ developed extensively by Clyde Davenport." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.93125,0.375) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam int param n caption = "Legendre number" default = 2 min = 2 max = 6 endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class LaguerreHyperJulia(Quat) { public: import "common.ulb" ; constructor func LaguerreHyperJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_hyper = true m_fourth = @fourth m_ck = @ck temp = new Vector(0,0,0,0) temp2 = new Vector(0,0,0,0) temp3 = new Vector(0,0,0,0) endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) if @n == 2 QH.Hmul(in,in,out) VtoC(a,b,out) a = (a - 4*zri + 2)/2 b = (b - 4*zjk)/2 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.HMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 3 QH.HMul(in,in,out) QH.HMul(out,in,cin) VtoC(a,b,cin) VtoC(a1,b1,out) a = (-a + 9*a1 - 18*zri + 6)/6 b = (-b + 9*b1 - 18*zjk)/6 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.HMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 4 QH.HMul(in,in,out) QH.HMul(in,out,temp) QH.HMul(out,out,cin) VtoC(a,b,out) VtoC(a1,b1,temp) VtoC(a2,b2,cin) a = (a2 -16*a1 + 72*a -96*zri +24)/24 b = (b2 -16*b1 + 72*b -96*zjk)/24 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.HMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 5 QH.HMul(in,in,out) ; z^2 QH.HMul(in,out,temp) ; z^3 QH.HMul(out,out,temp2) ;z^4 QH.HMul(temp2,in,cin) ; z^5 VtoC(a,b,cin) ;z^5 VtoC(a1,b1,temp2) ;z^4 VtoC(a2,b2,temp) ;z^3 VtoC(a3,b3,out) ;z^2 a = (-a + 25*a1 - 200*a2 + 600*a3 - 600*zri + 120)/120 b = (-b + 25*b1 - 200*b2 + 600*b3 - 600*zjk)/120 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.HMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 6 QH.HMul(in,in,out) ; z^2 QH.HMul(in,out,temp) ; z^3 QH.HMul(out,out,temp2) ;z^4 QH.HMul(temp2,in,temp3) ;z^5 QH.HMul(temp,temp,cin) ; z^6 VtoC(a,b,cin) ;z^6 VtoC(a1,b1,temp3) ;z^5 VtoC(a2,b2,temp2) ;z^4 VtoC(a3,b3,temp) ;z^3 VtoC(a4,b4,out) ;z^2 a = (a - 36*a1 + 450*a2 - 2400*a3 + 5400*a4 - 4320*zri + 720)/720 b = (b - 36*b1 + 450*b2 - 2400*b3 + 5400*b4 - 4320*zjk)/720 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.HMul(cin,in,out) VtoC(zri,zjk,out) endif endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) CtoV(zrid,zjkd,ind) if @n == 2 zri = zri - 2 CtoV(zri,zjk,in) QH.Hmul(cin,in,out) QH.Hmul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 3 QH.HMul(in,in,out) VtoC(a,b,out) a = (-3*a + 18*zri - 18)/6 b = (-3*b + 18*zjk)/6 CtoV(a,b,in) QH.HMul(cin,in,out) QH.HMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 4 QH.HMul(in,in,out) QH.Hmul(in,out,temp) VtoC(a,b,temp) VtoC(a1,b1,out) a = (4*a -48*a1 + 144*zri -96)/24 b = (4*b -48*b1 + 144*zjk)/24 CtoV(a,b,in) QH.HMul(cin,in,out) QH.HMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 5 QH.HMul(in,in,out) ;z^2 QH.HMul(in,out,temp) ;z^3 QH.HMul(out,out,temp2) ;z^4 VtoC(a,b,temp2) ;z^4 VtoC(a1,b1,temp) ;z^3 VtoC(a2,b2,out) ;z^2 a = (-5*a + 100*a1 - 600*a2 + 1200*zri - 600)/120 b = (-5*b + 100*b1 - 600*b2 + 1200*zjk)/120 CtoV(a,b,in) QH.HMul(cin,in,out) QH.HMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 6 QH.HMul(in,in,out) ;z^2 QH.HMul(in,out,temp) ;z^3 QH.HMul(out,out,temp2) ;z^4 QH.HMul(temp2,in,temp3) ;z^5 VtoC(a,b,temp3) ; z^5 VtoC(a1,b1,temp2) ; z^4 VtoC(a2,b2,temp) ;z^3 VtoC(a3,b3,out) ;z^2 a = (6*a - 180*a1 + 1800*a2 - 7200*a3 + 10800*zri - 4320)/720 b = (6*b - 180*b1 + 1800*b2 - 7200*b3 + 10800*zjk)/720 CtoV(a,b,in) QH.HMul(cin,in,out) QH.HMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 endif endfunc protected: complex a complex b complex a1 complex b1 complex a2 complex b2 complex a3 complex b3 complex a4 complex b4 vector temp vector temp2 vector temp3 default: title = "Laguerre Julia Hypercomplex" int param v_Laguerrejuliahyper caption = "Version (Laguerre Julia Hypercomplex)" 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_Laguerrejuliahyper < 100 endparam heading text = "The Laguerre polynomials are solutions to Laguerre's differential equation. \ The Laguerre polynomials arise in quantum mechanics, in the radial part \ of the solution of the Schrödinger equation for a one-electron atom. \ These polynomials can also be used to define an \ interesting set of fractals." endheading heading text = "Uses hypercomplex mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ commutative and the inverse is not always defined. This was first \ developed extensively by Clyde Davenport." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (-0.4329942,0.0844477) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam int param n caption = "Laguerre number" default = 2 min = 2 max = 6 endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class ChebyshevHyperJulia(Quat) { public: import "common.ulb" ; constructor func ChebyshevHyperJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_hyper = true m_fourth = @fourth m_ck = @ck temp = new Vector(0,0,0,0) temp2 = new Vector(0,0,0,0) endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) if @n == 2 QH.Hmul(in,in,out) VtoC(a,b,out) a = 2*a - 1 b = 2*b CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.HMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 3 QH.HMul(in,in,out) QH.HMul(out,in,cin) VtoC(a,b,cin) a = 4*a - 3*zri b = 4*b - 3*zjk CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.HMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 4 QH.HMul(in,in,out) ; z^2 QH.HMul(out,out,cin) ; z^4 VtoC(a,b,out) VtoC(a1,b1,cin) a = 8*a1 - 8*a + 1 b = 8*b1 - 8*b CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.HMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 5 QH.HMul(in,in,out) ; z^2 QH.HMul(out,in,cin) ; z^3 QH.HMul(cin,out,temp) ; z^5 VtoC(a,b,cin) VtoC(a1,b1,temp) a = 16*a1 - 20*a + 5*zri b = 16*b1 - 20*b + 5*zjk CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.HMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 6 QH.HMul(in,in,out) ; z^2 QH.HMul(out,out,temp) ; z^4 QH.HMul(out,temp,in) ; z^6 VtoC(a,b,out) VtoC(a1,b1,temp) VtoC(a2,b2,in) a = 32*a2 - 48*a1 + 18*a - 1 b = 32*b2 - 48*b1 + 18*b CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.HMul(cin,in,out) VtoC(zri,zjk,out) endif endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) CtoV(zrid,zjkd,ind) if @n == 2 QH.Hmul(cin,in,out) QH.Hmul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = 4*zrid + 1 zjkd = 4*zjkd elseif @n == 3 QH.HMul(in,in,out) VtoC(a,b,out) a = 12*a - 3 b = 12*b CtoV(a,b,in) QH.HMul(cin,in,out) QH.HMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 4 QH.HMul(in,in,out) QH.Hmul(in,out,temp) VtoC(a,b,temp) a = 32*a - 16*zri b = 32*b - 16*zjk CtoV(a,b,in) QH.HMul(cin,in,out) QH.HMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 5 QH.HMul(in,in,out) ; z^2 QH.HMul(out,out,temp) ; z^4 VtoC(a,b,out) VtoC(a1,b1,temp) a = 90*a1 - 60*a + 5 b = 90*b1 - 60*b CtoV(a,b,in) QH.HMul(cin,in,out) QH.HMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 6 QH.HMul(in,in,out) ; z^2 QH.HMul(out,in,temp) ; z^3 QH.HMul(temp,out,temp2) ; z^5 VtoC(a,b,temp) VtoC(a1,b1,temp2) a = 192*a1 - 192*a + 36*zri b = 192*b1 - 192*b + 36*zjk CtoV(a,b,in) QH.HMul(cin,in,out) QH.HMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 endif endfunc protected: complex a complex b complex a1 complex b1 complex a2 complex b2 vector temp vector temp2 default: title = "Chebyshev Julia Hypercomplex" int param v_Chebyshevjuliahyper caption = "Version (Chebyshev Julia Hypercomplex)" 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_Chebyshevjuliahyper < 100 endparam heading text = "The Chebyshev polynomials of the first kind are a set of orthogonal \ polynomials defined as the solutions to the Chebyshev differential \ equation. They are used as an approximation to a least squares fit \ to a set of points. These polynomials can also be used to define an \ interesting set of fractals." endheading heading text = "Uses hypercomplex mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ commutative and the inverse is not always defined. This was first \ developed extensively by Clyde Davenport." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.13125,0.45625) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam int param n caption = "Chebyschev number" default = 2 min = 2 max = 6 endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class CubicJulia(Quat) { ; This is the standard Quaternion public: import "common.ulb" ; constructor func CubicJulia(Generic pparent) Quat.Quat(pparent) im = (0,1) hrotp = exp(im*@hangle*#pi/180) hrotn = exp(-im*@hangle*#pi/180) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) zminus = zri-1 zplus = zri+1 CtoV(zminus,zjk,in) CtoV(zplus,zjk,cin) QH.QMul(in,in,ind) QH.QMul(ind,cin,out) VtoC(zri,zjk,out) zri = hrotn*zri - hrotp*m_cri + 1 zjk = hrotn*zjk - hrotp*m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) QH.QMul(in,in,out) VtoC(a,b,out) a1 = 3*a - 2*zri - 1 b1 = 3*b - 2*zjk CtoV(a1,b1,in) CtoV(zrid,zjkd,ind) QH.QMul(in,ind,out) VtoC(zrid,zjkd,out) zrid = hrotn*zrid + 1 zjkd = hrotn*zjkd endfunc protected: complex hrotp complex hrotn complex zminus complex zplus complex a complex b complex a1 complex b1 default: title = "Cubic Julia Quaternion" int param v_cubicjuliaquat caption = "Version (Cubic Julia Quaternion)" 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_cubicjuliaquat < 100 endparam heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.4,0.25) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam heading text = "The 'Hart angle' rotates the fractal in the r-i plane. Because \ quaternian math is noncommutative, unusual shapes and forms are \ created." endheading float param hangle caption = "Hart angle" default = 0.0 hint = "The 'Hart angle' rotates the r-i plane. This is not the same \ as rotating the object." endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class SpiderJulia(Quat) { public: import "common.ulb" ; constructor func SpiderJulia(Generic pparent) Quat.Quat(pparent) im = (0,1) hrotp = exp(im*@hangle*#pi/180) hrotn = exp(-im*@hangle*#pi/180) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = true m_spider = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) QH.QMul(in,in,out) VtoC(zri,zjk,out) zri = hrotn*zri + hrotp*m_cri zjk = hrotn*zjk + hrotp*m_cjk m_cri = m_cri/2 + zri m_cjk = m_cjk/2 + zjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.QMul(in,ind,out) VtoC(zrid,zjkd,out) zrid = hrotn*2*zrid zjkd = hrotn*2*zjkd endfunc protected: complex hrotp complex hrotn default: title = "Spider Julia Quaternion" int param v_spiderjuliaquat caption = "Version (Spider Julia Quaternion)" 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_spiderjuliaquat < 100 endparam heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.15,0.25) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam heading text = "The 'Hart angle' rotates the fractal in the r-i plane. Because \ quaternian math is noncommutative, unusual shapes and forms are \ created." endheading float param hangle caption = "Hart angle" default = 0.0 hint = "The 'Hart angle' rotates the r-i plane. This is not the same \ as rotating the object." endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class SineJulia(Quat) { public: import "common.ulb" ; constructor func SineJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) QH.Qsin(in, out) QH.Qmul(cin,out,in) VtoC(zri,zjk,in) endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) CtoV(zrid,zjkd,ind) QH.Qcos(in, out) QH.Qmul(cin,out,in) QH.Qmul(in,ind,out) VtoC(zrid,zjkd,out) endfunc protected: default: title = "Sine Julia Quaternion" int param v_sinejuliaquat caption = "Version (Sine Julia Quaternion)" 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_sinejuliaquat < 100 endparam heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.93,0.39) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class ExpJulia(Quat) { public: import "common.ulb" ; constructor func ExpJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) QH.Qexp(in, out) QH.Qmul(cin,out,in) VtoC(zri,zjk,in) endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) CtoV(zrid,zjkd,ind) QH.Qexp(in, out) QH.Qmul(cin,out,in) QH.Qmul(in,ind,out) VtoC(zrid,zjkd,out) endfunc protected: default: title = "Exponential Julia Quaternion" int param v_expjuliaquat caption = "Version (Exp Julia Quaternion)" 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_expjuliaquat < 100 endparam heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.0,2.0) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class ExpJuliaBulb(Quat) { public: import "common.ulb" ; constructor func ExpJuliaBulb(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) MD.Sexp(in, out) MD.Smult(@quadcor,@altel,cin,out,in,@pfactor,@flagtype) VtoC(zri,zjk,in) endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) CtoV(zrid,zjkd,ind) MD.Sexp(in, out) MD.Smult(@quadcor,@altel,cin,out,in,@pfactor,@flagtype) MD.Smult(@quadcor,@altel,in,ind,out,@pfactor,@flagtype) VtoC(zrid,zjkd,out) endfunc protected: default: title = "Exponential Juliabulb" int param v_expjuliaquat caption = "Version (Exponential Juliabulb)" 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_expjuliaquat < 100 endparam heading text = "Uses 3D spherical coordinates in analogy to 2D polar coordinates for \ complex numbers. Over 50 variants of triplex algebra are available, \ including the original White/Nylander version and many more described \ on Jason's Softology website \ (http://softology.com.au/gallery/ \ gallerymandelbulb.htm). Many are based upon the the formulas of Tad \ Boniecki." endheading heading text = "s = x + i*y + j*z expressed as complex spherical coordinates." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.0,2.0) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam param flagtype caption = "Bulb types" enum = "Original" "Positive Z" "Cosine" "Rucker" "Reversed" "Reversed +Z"\ "Msltoe" "IQ" "Negative IQ" "XpYp3" "XpZp2" "XpYn1" "XnYp1" "XpYn3"\ "XnYp3" "XnYn3" "YpXp3" "YpXn2" "YnXp2" "YpXn3" "YnXp3" "YnXn3"\ "ZpXp3" "ZpXn2" "ZnXp2" "ZpXn3" "ZnXp3" "ZnXn3" "XpZn1" "XnZp1"\ "XpZn2" "XnZp2" "XnZn2" "YpZp2" "YpZn1" "YnZp1" "YpZn2" "YnZp2"\ "YnZn2" "ZnYp1" "ZnYn1" "ZnYp3" "Tad 20" "Tad 28" "Tad 29" "Tad 34"\ "Tad 50" "Tad 61" "Tad 84" "Tad 85" "Tad 86" "Tad 87" "Tad 52"\ "Tad 53" "Tad 93" "Tad 95" "Tad 98" "Tad 114" "Tad 116" "Tad 117"\ "Tad 122" "Tad 123" "Tad 124" "Tad 125" "Tad 176" "Tad 177"\ "Tad 180" "Tad 185" "Tad 240" "Tad 241" "Tad 244" "Tad 245"\ "Tad 248" "Tad 249" "Tad 252" "Tad 253" "Tad 270" "Tad 272"\ "Tad 304" "Tad 305" "Tad 306" "Tad 322" "Tad 342" "Tad 345"\ "Tad 368" "Tad 369" "Tad 377" "Tad 378" "Tad 412" "Tad 413"\ "Tad 464" "Tad 465" "Tad 468" "Tad 469" "Tad 473" default = 0 endparam float param pfactor caption = "Azimuth Factor" default = 1.0 endparam heading caption = "Alternate settings" visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "The following two check boxes are alternatives to the standard \ Mandelbulb equations. They are included as they can give some \ interesting results." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "'alternate elevation' reverses the sign of the elevation." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param altel caption = "alternate elevation" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam heading text = "'Range correction' insures that the elevation is in the range -pi/2 to pi/2 \ after all applications of the power and multiply functions." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param quadcor caption = "range correction" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam } class CubicHyperJulia(Quat) { ; This is the standard Quaternion public: import "common.ulb" ; constructor func CubicHyperJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_hyper = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) zminus = zri-1 zplus = zri+1 CtoV(zminus,zjk,in) CtoV(zplus,zjk,cin) QH.HMul(in,in,ind) QH.HMul(ind,cin,out) VtoC(zri,zjk,out) zri = zri - m_cri + 1 zjk = zjk - m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) QH.HMul(in,in,out) VtoC(a,b,out) a1 = 3*a - 2*zri - 1 b1 = 3*b - 2*zjk CtoV(a1,b1,in) CtoV(zrid,zjkd,ind) QH.HMul(in,ind,out) VtoC(zrid,zjkd,out) zrid = zrid + 1 endfunc protected: complex zminus complex zplus complex a complex b complex a1 complex b1 default: title = "Cubic Julia Hypercomplex" int param v_cubicjuliahyper caption = "Version (Cubic Julia Hypercomplex)" 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_cubicjuliahyper < 100 endparam heading text = "Uses hypercomplex mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ commutative and the inverse is not always defined. This was first \ developed extensively by Clyde Davenport." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.4,0.25) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class SpiderHyperJulia(Quat) { public: import "common.ulb" ; constructor func SpiderHyperJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_hyper = true m_spider = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) QH.HMul(in,in,out) VtoC(zri,zjk,out) zri = zri + m_cri zjk = zjk + m_cjk m_cri = m_cri/2 + zri m_cjk = m_cjk/2 + zjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.HMul(in,ind,out) VtoC(zrid,zjkd,out) zrid = 2*zrid zjkd = 2*zjkd endfunc default: title = "Spider Julia Hypercomplex" int param v_spiderjuliahyper caption = "Version (Spider Julia Hypercomplex)" 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_spiderjuliahyper < 100 endparam heading text = "Uses hypercomplex mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ commutative and the inverse is not always defined. This was first \ developed extensively by Clyde Davenport." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.15,0.25) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class ExpHyperJulia(Quat) { public: import "common.ulb" ; constructor func ExpHyperJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_hyper = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) QH.Hexp(in, out) QH.Hmul(cin,out,in) VtoC(zri,zjk,in) endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) CtoV(zrid,zjkd,ind) QH.Hexp(in, out) QH.Hmul(cin,out,in) QH.Hmul(in,ind,out) VtoC(zrid,zjkd,out) endfunc protected: default: title = "Exponential Julia Hypercomplex" int param v_expjuliahyper caption = "Version (Exp Julia Hypercomplex)" 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_expjuliahyper < 100 endparam heading text = "Uses hypercomplex mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ commutative and the inverse is not always defined. This was first \ developed extensively by Clyde Davenport." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.0,2.0) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class SineHyperJulia(Quat) { public: import "common.ulb" ; constructor func SineHyperJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_hyper = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) QH.Hsin(in, out) QH.Hmul(cin,out,in) VtoC(zri,zjk,in) endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) CtoV(zrid,zjkd,ind) QH.Hcos(in, out) QH.Hmul(cin,out,in) QH.Hmul(in,ind,out) VtoC(zrid,zjkd,out) endfunc protected: default: title = "Sine Julia Hypercomplex" int param v_sinejuliahyper caption = "Version (Sine Julia Hypercomplex)" 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_sinejuliahyper < 100 endparam heading text = "Uses hypercomplex mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ commutative and the inverse is not always defined. This was first \ developed extensively by Clyde Davenport." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.93,0.39) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class PhoenixJulia(Quat) { public: import "common.ulb" ; constructor func PhoenixJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = true m_oldz = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) QH.QMul(in,in,out) VtoC(a1,b1,out) a2 = a1 + m_cri + @distort*(m_oldzri) b2 = b1 + m_cjk + @distort*(m_oldzjk) m_oldzri = zri m_oldzjk = zjk zri = a2 zjk = b2 endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zrid,zjkd,ind) a1 = 2*zri + @distort b1 = 2*zjk + @distort CtoV(a1,b1,in) QH.Qmul(in,ind,out) VtoC(zrid,zjkd,out) endfunc protected: complex a1 complex b1 complex a2 complex b2 default: title = "Phoenix Julia Quaternion" int param v_phoenixjuliaquat caption = "Version (Phoenix Julia Quaternion)" 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_phoenixjuliaquat < 100 endparam heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.56667,0.0) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam complex param distort caption = "Distortion value" default = (-0.5,0) endparam } class PhoenixJuliabulb(Quat) { public: import "common.ulb" ; constructor func PhoenixJuliabulb(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = false m_oldz = true m_sphere = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) MD.Spower(@quadcor,@altel,@power,in,out,@pfactor,@flagtype) VtoC(a1,b1,out) a2 = a1 + m_cri + @distort*(m_oldzri) b2 = b1 + m_cjk + @distort*(m_oldzjk) m_oldzri = zri m_oldzjk = zjk zri = a2 zjk = b2 endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) MD.Spower(@quadcor,@altel,@power-1,in,out,@pfactor,@flagtype) VtoC(a1,b1,out) a1 = @power*a1 +@distort b1 = @power*b1 + @distort CtoV(a1,b1,in) MD.Smult(@quadcor,@altel,in,ind,out,@pfactor,@flagtype) VtoC(zrid,zjkd,out) endfunc protected: complex a1 complex b1 complex a2 complex b2 default: title = "Phoenix Juliabulb" int param v_phoenixjuliabulb caption = "Version (Phoenix Juliabulb)" 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_phoenixjuliabulb < 100 endparam heading text = "Uses 3D spherical coordinates in analogy to 2D polar coordinates for \ complex numbers. Over 50 variants of triplex algebra are available, \ including the original White/Nylander version and many more described \ on Jason's Softology website \ (http://softology.com.au/gallery/ \ gallerymandelbulb.htm). Many are based upon the the formulas of Tad \ Boniecki." endheading heading text = "This version of the Phoenix Julia is based upon the old Fractint \ formula." endheading heading text = "s = x + i*y + j*z expressed as complex spherical coordinates." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.56667,0.0) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam complex param distort caption = "Distortion value" default = (-0.5,0) endparam float param power caption = "Phoenix Power" default = 2 endparam param flagtype caption = "Bulb types" enum = "Original" "Positive Z" "Cosine" "Rucker" "Reversed" "Reversed +Z"\ "Msltoe" "IQ" "Negative IQ" "XpYp3" "XpZp2" "XpYn1" "XnYp1" "XpYn3"\ "XnYp3" "XnYn3" "YpXp3" "YpXn2" "YnXp2" "YpXn3" "YnXp3" "YnXn3"\ "ZpXp3" "ZpXn2" "ZnXp2" "ZpXn3" "ZnXp3" "ZnXn3" "XpZn1" "XnZp1"\ "XpZn2" "XnZp2" "XnZn2" "YpZp2" "YpZn1" "YnZp1" "YpZn2" "YnZp2"\ "YnZn2" "ZnYp1" "ZnYn1" "ZnYp3" "Tad 20" "Tad 28" "Tad 29" "Tad 34"\ "Tad 50" "Tad 61" "Tad 84" "Tad 85" "Tad 86" "Tad 87" "Tad 52"\ "Tad 53" "Tad 93" "Tad 95" "Tad 98" "Tad 114" "Tad 116" "Tad 117"\ "Tad 122" "Tad 123" "Tad 124" "Tad 125" "Tad 176" "Tad 177"\ "Tad 180" "Tad 185" "Tad 240" "Tad 241" "Tad 244" "Tad 245"\ "Tad 248" "Tad 249" "Tad 252" "Tad 253" "Tad 270" "Tad 272"\ "Tad 304" "Tad 305" "Tad 306" "Tad 322" "Tad 342" "Tad 345"\ "Tad 368" "Tad 369" "Tad 377" "Tad 378" "Tad 412" "Tad 413"\ "Tad 464" "Tad 465" "Tad 468" "Tad 469" "Tad 473" default = 0 endparam float param pfactor caption = "Azimuth Factor" default = 1.0 endparam heading caption = "Alternate settings" visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "The following two check boxes are alternatives to the standard \ Mandelbulb equations. They are included as they can give some \ interesting results." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "'alternate elevation' reverses the sign of the elevation." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param altel caption = "alternate elevation" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam heading text = "'Range correction' insures that the elevation is in the range -pi/2 to pi/2 \ after all applications of the power and multiply functions." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param quadcor caption = "range correction" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam } class PhoenixMandelbulb(Quat) { public: import "common.ulb" ; constructor func PhoenixMandelbulb(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = false m_oldz = true m_sphere = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) MD.Spower(@quadcor,@altel,@power,in,out,@pfactor,@flagtype) VtoC(a1,b1,out) a2 = a1 + m_cri + @distort*(m_oldzri) b2 = b1 + m_cjk + @distort*(m_oldzjk) m_oldzri = zri m_oldzjk = zjk zri = a2 zjk = b2 endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) MD.Spower(@quadcor,@altel,@power-1,in,out,@pfactor,@flagtype) VtoC(a1,b1,out) a1 = @power*a1 + @distort b1 = @power*b1 + @distort CtoV(a1,b1,in) MD.Smult(@quadcor,@altel,in,ind,out,@pfactor,@flagtype) VtoC(zrid,zjkd,out) endfunc protected: complex a1 complex b1 complex a2 complex b2 default: title = "Phoenix Mandelbulb" int param v_phoenixMandelbulb caption = "Version (Phoenix Mandelbulb)" 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_phoenixMandelbulb < 100 endparam heading text = "Uses 3D spherical coordinates in analogy to 2D polar coordinates for \ complex numbers. Over 50 variants of triplex algebra are available, \ including the original White/Nylander version and many more described \ on Jason's Softology website \ (http://softology.com.au/gallery/ \ gallerymandelbulb.htm). Many are based upon the the formulas of Tad \ Boniecki." endheading heading text = "This version of the Phoenix Julia is based upon the old Fractint \ formula." endheading heading text = "s = x + i*y + j*z expressed as complex spherical coordinates." endheading heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." visible = false endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam complex param distort caption = "Distortion value" default = (-0.5,0) endparam float param power caption = "Phoenix Power" default = 2 endparam param flagtype caption = "Bulb types" enum = "Original" "Positive Z" "Cosine" "Rucker" "Reversed" "Reversed +Z"\ "Msltoe" "IQ" "Negative IQ" "XpYp3" "XpZp2" "XpYn1" "XnYp1" "XpYn3"\ "XnYp3" "XnYn3" "YpXp3" "YpXn2" "YnXp2" "YpXn3" "YnXp3" "YnXn3"\ "ZpXp3" "ZpXn2" "ZnXp2" "ZpXn3" "ZnXp3" "ZnXn3" "XpZn1" "XnZp1"\ "XpZn2" "XnZp2" "XnZn2" "YpZp2" "YpZn1" "YnZp1" "YpZn2" "YnZp2"\ "YnZn2" "ZnYp1" "ZnYn1" "ZnYp3" "Tad 20" "Tad 28" "Tad 29" "Tad 34"\ "Tad 50" "Tad 61" "Tad 84" "Tad 85" "Tad 86" "Tad 87" "Tad 52"\ "Tad 53" "Tad 93" "Tad 95" "Tad 98" "Tad 114" "Tad 116" "Tad 117"\ "Tad 122" "Tad 123" "Tad 124" "Tad 125" "Tad 176" "Tad 177"\ "Tad 180" "Tad 185" "Tad 240" "Tad 241" "Tad 244" "Tad 245"\ "Tad 248" "Tad 249" "Tad 252" "Tad 253" "Tad 270" "Tad 272"\ "Tad 304" "Tad 305" "Tad 306" "Tad 322" "Tad 342" "Tad 345"\ "Tad 368" "Tad 369" "Tad 377" "Tad 378" "Tad 412" "Tad 413"\ "Tad 464" "Tad 465" "Tad 468" "Tad 469" "Tad 473" default = 0 endparam float param pfactor caption = "Azimuth Factor" default = 1.0 endparam heading caption = "Alternate settings" visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "The following two check boxes are alternatives to the standard \ Mandelbulb equations. They are included as they can give some \ interesting results." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "'alternate elevation' reverses the sign of the elevation." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param altel caption = "alternate elevation" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam heading text = "'Range correction' insures that the elevation is in the range -pi/2 to pi/2 \ after all applications of the power and multiply functions." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param quadcor caption = "range correction" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam } class PowerJulia(Quat) { ; This is a Julia Quaternion to a Quaterion power public: import "common.ulb" ; constructor func PowerJulia(Generic pparent) Quat.Quat(pparent) im = (0,1) hrotp = exp(im*@hangle*#pi/180) hrotn = exp(-im*@hangle*#pi/180) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = true m_fourth = @fourth m_ck = @ck power = new Vector(real(@pri),imag(@pri),real(@pjk),imag(@pjk)) powerd = new Vector(real(@pri)-1,imag(@pri),real(@pjk),imag(@pjk)) endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) QH.QPower(in,power,out) VtoC(zri,zjk,out) zri = hrotn*zri + hrotp*m_cri zjk = hrotn*zjk + hrotp*m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.QPower(in,powerd,in) QH.QMul(in,ind,out) QH.QMul(power,out,ind) VtoC(zrid,zjkd,ind) zrid = hrotn*zrid zjkd = hrotn*zjkd endfunc protected: complex hrotp complex hrotn vector power vector powerd default: title = "Power Julia Quaternion" heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (-0.1,0.8) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam heading caption = "Quaternion Power" endheading complex param pri caption = "r-i plane" default = (3,0) endparam complex param pjk caption = "j-k plane" default = (0,0) endparam heading text = "The 'Hart angle' rotates the fractal in the r-i plane. Because \ quaternian math is noncommutative, unusual shapes and forms are \ created." endheading float param hangle caption = "Hart angle" default = 0.0 hint = "The 'Hart angle' rotates the r-i plane. This is not the same \ as rotating the object." endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class IkenagaJulia(Quat) { ; z*z*z + (c-1)*z - c public: import "common.ulb" ; constructor func IkenagaJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) QH.QMul(in,in,ind) ; z*z QH.QMul(in,ind,out) ; z*z*z VtoC(a,b,out) QH.QMul(cin,in,out) ; c*z VtoC(a1,b1,out) zri = a + a1 -zri - m_cri zjk = b + b1 - zjk - m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.QMul(in,in,out) ; z*z VtoC(a,b,out) a1 = 3*a + m_cri - 1 b1 = 3*b + m_cjk CtoV(a1,b1,in) QH.QMul(in,ind,out) VtoC(zrid,zjkd,out) endfunc protected: complex a complex b complex a1 complex b1 default: title = "Ikenaga Julia Quaternion" heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.1,0.3) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class FrameRobertJulia(Quat) { ; z*z*z/5 + z*z + c public: import "common.ulb" ; constructor func FrameRobertJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) QH.QMul(in,in,ind) ; z*z QH.QMul(in,ind,out) ; z*z*z VtoC(a,b,out) VtoC(a1,b1,ind) zri = a/5 + a1 + m_cri zjk = b/5 + b1 + m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.QMul(in,in,out) VtoC(a,b,out) a1 = 0.6*a + 2*zri b1 = 0.6*b + 2* zjk CtoV(a1,b1,in) QH.QMul(in,ind,out) VtoC(zrid,zjkd,out) endfunc protected: complex a complex b complex a1 complex b1 default: title = "FrameRobert Julia Quaternion" heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (-1,0.2) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class FrameRobertHyperJulia(Quat) { ; z*z*z/5 + z*z + c public: import "common.ulb" ; constructor func FrameRobertHyperJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_hyper = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) QH.HMul(in,in,ind) ; z*z QH.HMul(in,ind,out) ; z*z*z VtoC(a,b,out) VtoC(a1,b1,ind) zri = a/5 + a1 + m_cri zjk = b/5 + b1 + m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.HMul(in,in,out) VtoC(a,b,out) a1 = 0.6*a + 2*zri b1 = 0.6*b + 2* zjk CtoV(a1,b1,in) QH.HMul(in,ind,out) VtoC(zrid,zjkd,out) endfunc protected: complex a complex b complex a1 complex b1 default: title = "FrameRobert Julia Hypercomplex" heading text = "Uses hypercomplex mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ commutative and the inverse is not always defined. This was first \ developed extensively by Clyde Davenport." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (-1,0.2) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class PhoenixHyperJulia(Quat) { public: import "common.ulb" ; constructor func PhoenixHyperJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_hyper = true m_oldz = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) QH.HMul(in,in,out) VtoC(a1,b1,out) a2 = a1 + m_cri + @distort*(m_oldzri) b2 = b1 + m_cjk + @distort*(m_oldzjk) m_oldzri = zri m_oldzjk = zjk zri = a2 zjk = b2 endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zrid,zjkd,ind) a1 = 2*zri + @distort b1 = 2*zjk + @distort CtoV(a1,b1,in) QH.Hmul(in,ind,out) VtoC(zrid,zjkd,out) endfunc protected: complex a1 complex b1 complex a2 complex b2 default: title = "Phoenix Julia Hypercomplex" heading text = "Uses hypercomplex mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ commutative and the inverse is not always defined. This was first \ developed extensively by Clyde Davenport." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.56667,0.0) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam complex param distort caption = "Distortion value" default = (-0.5,0) endparam } class IkenagaHyperJulia(Quat) { ; z*z*z + (c-1)*z - c public: import "common.ulb" ; constructor func IkenagaHyperJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_hyper = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) QH.HMul(in,in,ind) QH.HMul(in,ind,out) VtoC(a,b,out) QH.HMul(cin,in,out) VtoC(a1,b1,out) zri = a + a1 -zri - m_cri zjk = b + b1 - zjk - m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.HMul(in,in,out) VtoC(a,b,out) a1 = 3*a + m_cri - 1 b1 = 3*b + m_cjk CtoV(a1,b1,in) QH.HMul(in,ind,out) VtoC(zrid,zjkd,out) endfunc protected: complex a complex b complex a1 complex b1 default: title = "Ikenaga Julia Hypercomplex" heading text = "Uses hypercomplex mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ commutative and the inverse is not always defined. This was first \ developed extensively by Clyde Davenport." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (0.1,0.3) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class PowerHyperJulia(Quat) { ; This is a Julia Quaternion to a Quaterion power public: import "common.ulb" ; constructor func PowerHyperJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_hyper = true m_fourth = @fourth m_ck = @ck power = new Vector(real(@pri),imag(@pri),real(@pjk),imag(@pjk)) powerd = new Vector(real(@pri)-1,imag(@pri),real(@pjk),imag(@pjk)) endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) QH.HPower(in,power,out) VtoC(zri,zjk,out) zri = zri + m_cri zjk = zjk + m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.HPower(in,powerd,in) QH.HMul(in,ind,out) QH.HMul(power,out,ind) VtoC(zrid,zjkd,ind) zrid = zrid zjkd = zjkd endfunc protected: vector power vector powerd default: title = "Power Julia Hypercomplex" heading text = "Uses hypercomplex mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ commutative and the inverse is not always defined. This was first \ developed extensively by Clyde Davenport." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (-0.1,0.8) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam heading caption = "Hypercomplex Power" endheading complex param pri caption = "r-i plane" default = (3,0) endparam complex param pjk caption = "j-k plane" default = (0,0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class HyperJulia(Quat) { ; This is the standard Quaternion public: import "common.ulb" ; constructor func HyperJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_hyper = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) QH.HMul(in,in,out) VtoC(zri,zjk,out) zri = zri + m_cri zjk = zjk + m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.HMul(in,ind,out) VtoC(zrid,zjkd,out) zrid = 2*zrid zjkd = 2*zjkd endfunc default: title = "Julia Hypercomplex" heading text = "Uses hypercomplex mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ commutative and the inverse is not always defined. This was first \ developed extensively by Clyde Davenport." endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param cri caption = "r-i plane" default = (-0.5,-0.5) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class FrameRobertMandel(Quat) { ; z*z*z/5 + z*z + c public: import "common.ulb" ; constructor func FrameRobertMandel(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) QH.QMul(in,in,ind) ; z*z QH.QMul(in,ind,out) ; z*z*z VtoC(a,b,out) VtoC(a1,b1,ind) zri = a/5 + a1 + m_cri zjk = b/5 + b1 + m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.QMul(in,in,out) ; z*z VtoC(a,b,out) a1 = 0.6*a + 2*zri ; 0.6*z*z + 2*z b1 = 0.6*b + 2*zjk CtoV(a1,b1,in) QH.QMul(in,ind,out) ; z*dz VtoC(zrid,zjkd,out) zrid = zrid + 1 endfunc protected: complex a complex b complex a1 complex b1 default: title = "FrameRobert Mandel Quaternion" heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class PowerMandel(Quat) { public: import "common.ulb" ; constructor func PowerMandel(Generic pparent) Quat.Quat(pparent) im = (0,1) hrotp = exp(im*@hangle*#pi/180) hrotn = exp(-im*@hangle*#pi/180) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = true m_fourth = @fourth m_ck = @ck power = new Vector(real(@pri),imag(@pri),real(@pjk),imag(@pjk)) powerd = new Vector(real(@pri)-1,imag(@pri),real(@pjk),imag(@pjk)) endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) QH.QPower(in,power,out) VtoC(zri,zjk,out) zri = hrotn*zri + hrotp*m_cri zjk = hrotn*zjk + hrotp*m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.QPower(in,powerd,in) QH.QMul(in,ind,out) QH.QMul(power,out,ind) VtoC(zrid,zjkd,ind) zrid = hrotn*zrid + 1 zjkd = hrotn*zjkd endfunc protected: complex hrotp complex hrotn vector power vector powerd default: title = "Power Mandel Quaternion" heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam heading caption = "Quaternion Power" endheading complex param pri caption = "r-i plane" default = (3,0) endparam complex param pjk caption = "j-k plane" default = (0,0) endparam heading text = "The 'Hart angle' rotates the fractal in the r-i plane. Because \ quaternian math is noncommutative, unusual shapes and forms are \ created." endheading float param hangle caption = "Hart angle" default = 0.0 hint = "The 'Hart angle' rotates the r-i plane. This is not the same \ as rotating the object." endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class CubicMandel(Quat) { public: import "common.ulb" ; constructor func CubicMandel(Generic pparent) Quat.Quat(pparent) im = (0,1) hrotp = exp(im*@hangle*#pi/180) hrotn = exp(-im*@hangle*#pi/180) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) zminus = zri-1 zplus = zri+1 CtoV(zminus,zjk,in) CtoV(zplus,zjk,cin) QH.QMul(in,in,ind) QH.QMul(ind,cin,out) VtoC(zri,zjk,out) zri = hrotn*zri - hrotp*m_cri + 1 zjk = hrotn*zjk - hrotp*m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) QH.QMul(in,in,out) VtoC(a,b,out) a1 = 3*a - 2*zri - 1 b1 = 3*b - 2*zjk CtoV(a1,b1,in) CtoV(zrid,zjkd,ind) QH.QMul(in,ind,out) VtoC(zrid,zjkd,out) zrid = hrotn*zrid zjkd = hrotn*zjkd endfunc protected: complex hrotp complex hrotn complex zminus complex zplus complex a complex b complex a1 complex b1 default: title = "Cubic Mandel Quaternion" int param v_cubicmandelquat caption = "Version (Cubic mandel Quaternion)" 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_cubicmandelquat < 100 endparam heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam heading text = "The 'Hart angle' rotates the fractal in the r-i plane. Because \ quaternian math is noncommutative, unusual shapes and forms are \ created." endheading float param hangle caption = "Hart angle" default = 0.0 hint = "The 'Hart angle' rotates the r-i plane. This is not the same \ as rotating the object." endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class LegendreMandel(Quat) { public: import "common.ulb" ; constructor func LegendreMandel(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = true m_fourth = @fourth m_ck = @ck temp = new Vector(0,0,0,0) temp2 = new Vector(0,0,0,0) endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) if @n == 2 QH.Qmul(in,in,out) VtoC(a,b,out) a = (3*a - 1)/2 b = 3*b/2 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 3 QH.QMul(in,in,out) QH.QMul(out,in,cin) VtoC(a,b,cin) a = (5*a - 3*zri)/2 b = (5*b - 3*zjk)/2 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 4 QH.QMul(in,in,out) ; z^2 QH.QMul(out,out,cin) ; z^4 VtoC(a,b,out) VtoC(a1,b1,cin) a = (35*a1 - 30*a + 3)/8 b = (35*b1 - 30*b)/8 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 5 QH.QMul(in,in,out) ; z^2 QH.QMul(out,in,cin) ; z^3 QH.QMul(cin,out,temp) ; z^5 VtoC(a,b,cin) VtoC(a1,b1,temp) a = (63*a1 - 70*a + 15*zri)/8 b = (63*b1 - 70*b + 15*zjk)/8 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 6 QH.QMul(in,in,out) ; z^2 QH.QMul(out,out,temp) ; z^4 QH.QMul(out,temp,in) ; z^6 VtoC(a,b,out) VtoC(a1,b1,temp) VtoC(a2,b2,in) a = (231*a2 - 315*a1 + 105*a - 5)/16 b = (231*b2 - 315*b1 + 105*b)/16 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) endif endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) CtoV(zrid,zjkd,ind) if @n == 2 QH.Qmul(cin,in,out) QH.Qmul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = 3*zrid + 1 zjkd = 3*zjkd elseif @n == 3 QH.QMul(in,in,out) VtoC(a,b,out) a = (15*a - 3)/2 b = (15*b)/2 CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 4 QH.QMul(in,in,out) QH.Qmul(in,out,temp) VtoC(a,b,temp) a = (140*a - 60*zri)/8 b = (140*b - 60*zjk)/8 CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 5 QH.QMul(in,in,out) ; z^2 QH.QMul(out,out,temp) ; z^4 VtoC(a,b,out) VtoC(a1,b1,temp) a = (315*a1 - 210*a + 15)/8 b = (315*b1 - 210*b)/8 CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 6 QH.QMul(in,in,out) ; z^2 QH.QMul(out,in,temp) ; z^3 QH.QMul(temp,out,temp2) ; z^5 VtoC(a,b,temp) VtoC(a1,b1,temp2) a = (1386*a1 - 1260*a + 210*zri)/16 b = (1386*b1 - 1260*b + 210*zjk)/16 CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 endif endfunc protected: complex a complex b complex a1 complex b1 complex a2 complex b2 vector temp vector temp2 default: title = "Legendre Mandel Quaternion" int param v_Legendremandquat caption = "Version (Legendre Mandel Quaternion)" 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_Legendremandquat < 100 endparam heading text = "Legendre polynomials are solutions to the Legendre differential equation \ which is frequently encountered in physics and other technical fields. \ These polynomials can also be used to define an \ interesting set of fractals." endheading heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions. For odd-numbered Chebyshev \ polynomials, initialize in the r-i plane with (1,0)." endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam int param n caption = "Legendre number" default = 2 min = 2 max = 6 endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class LaguerreMandel(Quat) { public: import "common.ulb" ; constructor func LaguerreMandel(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = true m_fourth = @fourth m_ck = @ck temp = new Vector(0,0,0,0) temp2 = new Vector(0,0,0,0) temp3 = new Vector(0,0,0,0) endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) if @n == 2 QH.Qmul(in,in,out) VtoC(a,b,out) a = (a - 4*zri + 2)/2 b = (b - 4*zjk)/2 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 3 QH.QMul(in,in,out) QH.QMul(out,in,cin) VtoC(a,b,cin) VtoC(a1,b1,out) a = (-a + 9*a1 - 18*zri + 6)/6 b = (-b + 9*b1 - 18*zjk)/6 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 4 QH.QMul(in,in,out) QH.QMul(in,out,temp) QH.QMul(out,out,cin) VtoC(a,b,out) VtoC(a1,b1,temp) VtoC(a2,b2,cin) a = (a2 -16*a1 + 72*a -96*zri +24)/24 b = (b2 -16*b1 + 72*b -96*zjk)/24 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 5 QH.QMul(in,in,out) ; z^2 QH.QMul(in,out,temp) ; z^3 QH.QMul(out,out,temp2) ;z^4 QH.QMul(temp2,in,cin) ; z^5 VtoC(a,b,cin) ;z^5 VtoC(a1,b1,temp2) ;z^4 VtoC(a2,b2,temp) ;z^3 VtoC(a3,b3,out) ;z^2 a = (-a + 25*a1 - 200*a2 + 600*a3 - 600*zri + 120)/120 b = (-b + 25*b1 - 200*b2 + 600*b3 - 600*zjk)/120 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 6 QH.QMul(in,in,out) ; z^2 QH.QMul(in,out,temp) ; z^3 QH.QMul(out,out,temp2) ;z^4 QH.QMul(temp2,in,temp3) ;z^5 QH.QMul(temp,temp,cin) ; z^6 VtoC(a,b,cin) ;z^6 VtoC(a1,b1,temp3) ;z^5 VtoC(a2,b2,temp2) ;z^4 VtoC(a3,b3,temp) ;z^3 VtoC(a4,b4,out) ;z^2 a = (a - 36*a1 + 450*a2 - 2400*a3 + 5400*a4 - 4320*zri + 720)/720 b = (b - 36*b1 + 450*b2 - 2400*b3 + 5400*b4 - 4320*zjk)/720 CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) endif endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) CtoV(zrid,zjkd,ind) if @n == 2 zri = zri - 2 CtoV(zri,zjk,in) QH.Qmul(cin,in,out) QH.Qmul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 3 QH.QMul(in,in,out) VtoC(a,b,out) a = (-3*a + 18*zri - 18)/6 b = (-3*b + 18*zjk)/6 CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 4 QH.QMul(in,in,out) QH.Qmul(in,out,temp) VtoC(a,b,temp) VtoC(a1,b1,out) a = (4*a -48*a1 + 144*zri -96)/24 b = (4*b -48*b1 + 144*zjk)/24 CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 5 QH.QMul(in,in,out) ;z^2 QH.QMul(in,out,temp) ;z^3 QH.QMul(out,out,temp2) ;z^4 VtoC(a,b,temp2) ;z^4 VtoC(a1,b1,temp) ;z^3 VtoC(a2,b2,out) ;z^2 a = (-5*a + 100*a1 - 600*a2 + 1200*zri - 600)/120 b = (-5*b + 100*b1 - 600*b2 + 1200*zjk)/120 CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 6 QH.QMul(in,in,out) ;z^2 QH.QMul(in,out,temp) ;z^3 QH.QMul(out,out,temp2) ;z^4 QH.QMul(temp2,in,temp3) ;z^5 VtoC(a,b,temp3) ; z^5 VtoC(a1,b1,temp2) ; z^4 VtoC(a2,b2,temp) ;z^3 VtoC(a3,b3,out) ;z^2 a = (6*a - 180*a1 + 1800*a2 - 7200*a3 + 10800*zri - 4320)/720 b = (6*b - 180*b1 + 1800*b2 - 7200*b3 + 10800*zjk)/720 CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 endif endfunc protected: complex a complex b complex a1 complex b1 complex a2 complex b2 complex a3 complex b3 complex a4 complex b4 vector temp vector temp2 vector temp3 default: title = "Laguerre Mandel Quaternion" int param v_Laguerrejuliamand caption = "Version (Laguerre Mandel Quaternion)" 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_Laguerrejuliamand < 100 endparam heading text = "The Laguerre polynomials are solutions to Laguerre's differential equation. \ The Laguerre polynomials arise in quantum mechanics, in the radial part \ of the solution of the Schrödinger equation for a one-electron atom. \ These polynomials can also be used to define an \ interesting set of fractals." endheading heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam int param n caption = "Laguerre number" default = 2 min = 2 max = 6 endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class ChebyshevMandel(Quat) { public: import "common.ulb" ; constructor func ChebyshevMandel(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = true m_fourth = @fourth m_ck = @ck temp = new Vector(0,0,0,0) temp2 = new Vector(0,0,0,0) endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) if @n == 2 QH.Qmul(in,in,out) VtoC(a,b,out) a = 2*a - 1 b = 2*b CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 3 QH.QMul(in,in,out) QH.QMul(out,in,cin) VtoC(a,b,cin) a = 4*a - 3*zri b = 4*b - 3*zjk CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 4 QH.QMul(in,in,out) ; z^2 QH.QMul(out,out,cin) ; z^4 VtoC(a,b,out) VtoC(a1,b1,cin) a = 8*a1 - 8*a + 1 b = 8*b1 - 8*b CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 5 QH.QMul(in,in,out) ; z^2 QH.QMul(out,in,cin) ; z^3 QH.QMul(cin,out,temp) ; z^5 VtoC(a,b,cin) VtoC(a1,b1,temp) a = 16*a1 - 20*a + 5*zri b = 16*b1 - 20*b + 5*zjk CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) elseif @n == 6 QH.QMul(in,in,out) ; z^2 QH.QMul(out,out,temp) ; z^4 QH.QMul(out,temp,in) ; z^6 VtoC(a,b,out) VtoC(a1,b1,temp) VtoC(a2,b2,in) a = 32*a2 - 48*a1 + 18*a - 1 b = 32*b2 - 48*b1 + 18*b CtoV(a,b,in) CtoV(m_cri,m_cjk,cin) QH.QMul(cin,in,out) VtoC(zri,zjk,out) endif endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) CtoV(zrid,zjkd,ind) if @n == 2 QH.Qmul(cin,in,out) QH.Qmul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = 4*zrid + 1 zjkd = 4*zjkd elseif @n == 3 QH.QMul(in,in,out) VtoC(a,b,out) a = 12*a - 3 b = 12*b CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 4 QH.QMul(in,in,out) QH.Qmul(in,out,temp) VtoC(a,b,temp) a = 32*a - 16*zri b = 32*b - 16*zjk CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 5 QH.QMul(in,in,out) ; z^2 QH.QMul(out,out,temp) ; z^4 VtoC(a,b,out) VtoC(a1,b1,temp) a = 90*a1 - 60*a + 5 b = 90*b1 - 60*b CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 elseif @n == 6 QH.QMul(in,in,out) ; z^2 QH.QMul(out,in,temp) ; z^3 QH.QMul(temp,out,temp2) ; z^5 VtoC(a,b,temp) VtoC(a1,b1,temp2) a = 192*a1 - 192*a + 36*zri b = 192*b1 - 192*b + 36*zjk CtoV(a,b,in) QH.QMul(cin,in,out) QH.QMul(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = zrid + 1 endif endfunc protected: complex a complex b complex a1 complex b1 complex a2 complex b2 vector temp vector temp2 default: title = "Chebyshev Mandel Quaternion" int param v_Chebyshevmandelquat caption = "Version (Chebyshev Mandel Quaternion)" 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_Chebyshevmandelquat < 100 endparam heading text = "The Chebyshev polynomials of the first kind are a set of orthogonal \ polynomials defined as the solutions to the Chebyshev differential \ equation. They are used as an approximation to a least squares fit \ to a set of points. These polynomials can also be used to define an \ interesting set of fractals." endheading heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions. For odd-numbered Chebyshev \ polynomials, initialize in the r-i plane with (1,0)." endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam int param n caption = "Chebyschev number" default = 2 min = 2 max = 6 endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class Mandel(Quat) { ; This is the standard Quaternion public: import "common.ulb" ; constructor func Mandel(Generic pparent) Quat.Quat(pparent) im = (0,1) hrotp = exp(im*@hangle*#pi/180) hrotn = exp(-im*@hangle*#pi/180) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) QH.QMul(in,in,out) ; z*z VtoC(zri,zjk,out) zri = hrotn*zri + hrotp*m_cri zjk = hrotn*zjk + hrotp*m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.QMul(in,ind,out) ; z*dz VtoC(zrid,zjkd,out) zrid = hrotn*2*zrid + 1 zjkd = hrotn*2*zjkd endfunc protected: complex hrotp complex hrotn default: title = "Mandel Quaternion" heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam heading text = "The 'Hart angle' rotates the fractal in the r-i plane. Because \ quaternian math is noncommutative, unusual shapes and forms are \ created." endheading float param hangle caption = "Hart angle" default = 0.0 hint = "The 'Hart angle' rotates the r-i plane. This is not the same \ as rotating the object." endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class Mandel3D(Quat) { public: import "common.ulb" ; import "reb.ulb ; constructor func Mandel3D(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = false m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) LKM.LKMsqr(in,out) VtoC(zri,zjk,out) zri = zri + m_cri zjk = zjk + m_cjk endfunc ; calculates the derivative of the fractal. Distance factor must be ; no greater than 0.1 for the derivative to work correctly. func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) LKM.LKMMult(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = 2*zrid + 1 zjkd = 2*zjkd endfunc default: title = "Mandelbrot 3D" heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." visible = false endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam } class Mandel3D_2(Quat) { public: import "common.ulb" ; import "reb.ulb ; constructor func Mandel3D_2(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = false m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) LKM.REBsqr(in,out) VtoC(zri,zjk,out) zri = zri + m_cri zjk = zjk + m_cjk endfunc ; calculates the derivative of the fractal. Distance factor must be ; no greater than 0.1 for the derivative to work correctly. func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) LKM.REBMult(out,ind,cin) VtoC(zrid,zjkd,cin) zrid = 2*zrid + 1 zjkd = 2*zjkd endfunc default: title = "Mandelbrot 3D #2" heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." visible = false endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam } class BarnsleyMandel1(Quat) { public: import "common.ulb" ; constructor func BarnsleyMandel1(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = true m_fourth = @fourth m_ck = @ck m_cri = m_zri m_cjk = m_zjk endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CToV(m_cri,m_cjk,cin) if real(zri) >= 0 CtoV(zri-1,zjk,in) QH.QMul(in,cin,out) VtoC(zri,zjk,out) else CtoV(zri+1,zjk,in) QH.QMul(in,cin,out) VtoC(zri,zjk,out) endif endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) endfunc protected: default: title = "BarnsleyMandel1 Quaternion" heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading text = "This formula must be used with one of the potential methods that \ does not require a derivative." endheading heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class HybridMandelbrot(Quat) { ; As presented by Tom Lowe on FractalForum and modified to include both Amzaing ; and Conformal algorithms. public: import "common.ulb" ; constructor func HybridMandelbrot(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = true m_fourth = @fourth m_ck = @ck scale = @scale rad = @rad minrad = @minrad foldx = @foldx foldy = @foldy foldz = @foldz diagonal = new Vector(@vx,@vy,@vz,0) diagonal.Normalize(diagonal) mx = diagonal.m_x my = diagonal.m_y mz = diagonal.m_z if (@v_hybridmandelbox < 103 || @arb) rvector = new Vector(-@ex+@ox,-@ey+@oy,-@ez+@oz,0) rvector.Normalize(rvector) endif if (@v_hybridmandelbox < 103 || @arb2) rvector2 = new Vector(-@ex2+@ox2,-@ey2+@oy2,-@ez2+@oz2,0) rvector2.Normalize(rvector2) endif endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) int i = 0 repeat defactor = scale*@conv if @order == "Box Rotate Invert" x = real(zri) y = imag(zri) z = real(zjk) ; fold box onto itself if @use if (@v_hybridmandelbox < 103 || @arb) cangle = cos(@ang*#pi/180) sangle = sin(@ang*#pi/180) rmatrix[0,0] = cangle+rvector.m_x^2*(1-cangle) rmatrix[1,0] = rvector.m_x*rvector.m_y*(1-cangle)-rvector.m_z*sangle rmatrix[2,0] = rvector.m_x*rvector.m_z*(1-cangle)+rvector.m_y*sangle rmatrix[0,1] = rvector.m_x*rvector.m_y*(1-cangle)+rvector.m_z*sangle rmatrix[1,1] = cangle+rvector.m_y^2*(1-cangle) rmatrix[2,1] = rvector.m_y*rvector.m_z*(1-cangle)-rvector.m_x*sangle rmatrix[0,2] = rvector.m_x*rvector.m_z*(1-cangle)-rvector.m_y*sangle rmatrix[1,2] = rvector.m_y*rvector.m_z*(1-cangle)+rvector.m_x*sangle rmatrix[2,2] = cangle+rvector.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_hybridmandelbox >= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_hybridmandelbox < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_hybridmandelbox < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_hybridmandelbox >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif ; vector folding dot = x*mx+y*my+z*mz x = x - 2*dot*mx y = y - 2*dot*my z = z - 2*dot*mz zri = x + flip(y) zjk = z ; fold sphere onto itself if @v_hybridmandelbox >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_hybridmandelbox < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_hybridmandelbox < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_hybridmandelbox >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif zri = x + flip(y) zjk = z ; fold sphere onto itself if @v_hybridmandelbox >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_hybridmandelbox < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_hybridmandelbox < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_hybridmandelbox >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif zri = x + flip(y) zjk = z elseif @order == "Rotate Box Invert" x = real(zri) y = imag(zri) z = real(zjk) ; composite with diagonal. This is a rotation ; vector folding dot = x*mx+y*my+z*mz x = x - 2*dot*mx y = y - 2*dot*my z = z - 2*dot*mz zri = x + flip(y) zjk = z ; fold box onto itself if @use if (@v_hybridmandelbox < 103 || @arb) cangle = cos(@ang*#pi/180) sangle = sin(@ang*#pi/180) rmatrix[0,0] = cangle+rvector.m_x^2*(1-cangle) rmatrix[1,0] = rvector.m_x*rvector.m_y*(1-cangle)-rvector.m_z*sangle rmatrix[2,0] = rvector.m_x*rvector.m_z*(1-cangle)+rvector.m_y*sangle rmatrix[0,1] = rvector.m_x*rvector.m_y*(1-cangle)+rvector.m_z*sangle rmatrix[1,1] = cangle+rvector.m_y^2*(1-cangle) rmatrix[2,1] = rvector.m_y*rvector.m_z*(1-cangle)-rvector.m_x*sangle rmatrix[0,2] = rvector.m_x*rvector.m_z*(1-cangle)-rvector.m_y*sangle rmatrix[1,2] = rvector.m_y*rvector.m_z*(1-cangle)+rvector.m_x*sangle rmatrix[2,2] = cangle+rvector.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_hybridmandelbox >= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_hybridmandelbox < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_hybridmandelbox < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_hybridmandelbox >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif zri = x + flip(y) zjk = z ; fold sphere onto itself if @v_hybridmandelbox >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_hybridmandelbox < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_hybridmandelbox < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_hybridmandelbox >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif zri = x + flip(y) zjk = z elseif @order == "Invert Box Rotate" ; fold sphere onto itself if @v_hybridmandelbox >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_hybridmandelbox < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_hybridmandelbox < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_hybridmandelbox >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif zri = x + flip(y) zjk = z ; composite with diagonal. This is a rotation ; vector folding dot = x*mx+y*my+z*mz x = x - 2*dot*mx y = y - 2*dot*my z = z - 2*dot*mz zri = x + flip(y) zjk = z endif i = i + 1 until i == @count zri = zri*scale + m_cri zjk = zjk*scale + m_cjk if @bscale defactor = defactor*scale endif spec = (cabs(zri) + cabs(zjk))/abs(defactor) endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) int i = 0 repeat if @order == "Box Rotate Invert" x = real(zri) y = imag(zri) z = real(zjk) derivx = 1 derivy = 1 derivz = 1 if @v_hybridmandelbox < 101 if x > 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif ; CtoV(zri,zjk,out) ; float dot = diagonal.dot(out) ; if dot > 1 derivx = 1 derivy = 1 derivz = 1 ; endif if @v_hybridmandelbox >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif if @v_hybridmandelbox >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length 1 derivx = 1 derivy = 1 derivz = 1 ; endif elseif @order == "Rotate Invert Box" x = real(zri) y = imag(zri) z = real(zjk) derivx = 1 derivy = 1 derivz = 1 CtoV(zri,zjk,out) ; CtoV(zri,zjk,out) ; float dot = diagonal.dot(out) ; if dot > 1 derivx = 1 derivy = 1 derivz = 1 ; endif if @v_hybridmandelbox >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif elseif @order == "Rotate Box Invert" x = real(zri) y = imag(zri) z = real(zjk) derivx = 1 derivy = 1 derivz = 1 ; CtoV(zri,zjk,out) ; float dot = diagonal.dot(out) ; if dot > 1 derivx = 1 derivy = 1 derivz = 1 ; endif if @v_hybridmandelbox < 101 if x > 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif if @v_hybridmandelbox >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length 1 derivx = 1 derivy = 1 derivz = 1 ; endif if @v_hybridmandelbox < 101 if x > 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif elseif @order == "Invert Box Rotate" x = real(zri) y = imag(zri) z = real(zjk) derivx = 1 derivy = 1 derivz = 1 if @v_hybridmandelbox >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif ; CtoV(zri,zjk,out) ; float dot = diagonal.dot(out) ; if dot > 1 derivx = 1 derivy = 1 derivz = 1 ; endif endif i = i + 1 until i == @count derivx=derivx*scale derivy=derivy*scale derivz=derivz*scale derivx=derivx*real(zrid)+1 derivy=derivy*imag(zrid)+1 derivz=derivz*real(zjkd)+1 zrid = derivz + flip(derivy) zjkd = derivz endfunc protected: float scale float rad float minrad float foldx float foldy float foldz Vector diagonal float x float y float z float derivx float derivy float derivz ; complex defactor float defactor Vector rvector Vector rvector2 float mx float my float mz float dot float rmatrix[3,3] float tempx float tempy float cangle float sangle default: title = "Hybrid Mandelbox" heading caption = "Mandel Initialization" visible = false endheading int param v_hybridmandelbox caption = "Version (Hybrid Mandelbox)" default = 103 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_hybridmandelbox < 103 endparam heading text = "Based upon the code of Tom Lowe presented on the FractalForum. A bailout \ value of 1024 is recomended along with a Starting \ Plane Z value of 10, an Ending Plane Z value of 20, and a Camera \ Origin Z value of 40." endheading param order caption = "Conformal Order" default = 0 enum = "Box Rotate Invert" "Box Invert Rotate" "Rotate Invert Box" \ "Rotate Box Invert" "Invert Rotate Box" "Invert Box Rotate" endparam int param count caption = "Fold count" default = 2 endparam float param scale caption = "Scale" default = 3 endparam float param rad caption = "Fixed Radius" default = 1 endparam float param minrad caption = "Minimum Radius" default = 0.5 endparam float param spower caption = "Spherical power" default = 2 visible = @v_hybridmandelbox >= 102 endparam float param foldx caption = "X fold value" default = 2 endparam float param foldxlim caption = "X fold limit" default = 1 visible = @v_hybridmandelbox >= 101 endparam float param foldy caption = "Y fold value" default = 2 endparam float param foldylim caption = "Y fold limit" default = 1 visible = @v_hybridmandelbox >= 101 endparam bool param noz caption = "No Z folding" default = false endparam float param foldz caption = "Z fold value" default = 2 visible = !@noz endparam float param foldzlim caption = "Z fold limit" default = 1 visible = @v_hybridmandelbox >= 101 && !@noz endparam heading text = "X, Y and Z are components of a diagonal vector. The dot product of \ the normalized vector is taken with the vector formed from zri and \ zjk. The dot product values are then used to fold zri and zjk." endheading float param vx caption = "X" default = 1 endparam float param vy caption = "Y" default = 1 endparam float param vz caption = "Z" default = 1 endparam float param conv caption = "Convergence factor" default = 1 endparam heading text = "This should be used with the special potential only" endheading bool param bscale caption = "Include final scaling" default = false endparam heading caption = "Pre-fold" endheading bool param use caption = "Rotate around axis" default = false endparam float param xang caption = "X Rotation angle" default = 0.0 visible = @use && @v_hybridmandelbox >= 103 endparam float param yang caption = "Y Rotation angle" default = 0.0 visible = @use && @v_hybridmandelbox >= 103 endparam float param zang caption = "Z Rotation angle" default = 0.0 visible = @use && @v_hybridmandelbox >= 103 endparam bool param arb caption = "Arbitrary axis rotation" default = false visible = @use endparam float param ang caption = "Rotation angle" default = 0.0 visible = @use && (@v_hybridmandelbox < 103 || @arb) endparam heading text = "Rotation vector origin" visible = @use && (@v_hybridmandelbox < 103 || @arb) endheading float param ox caption ="Origin X" default = 0 visible = @use && (@v_hybridmandelbox < 103 || @arb) endparam float param oy caption ="Origin Y" default = 0 visible = @use && (@v_hybridmandelbox < 103 || @arb) endparam float param oz caption ="Origin Z" default = 0 visible = @use && (@v_hybridmandelbox < 103 || @arb) endparam heading text = "Rotation vector end" visible = @use && (@v_hybridmandelbox < 103 || @arb) endheading float param ex caption ="End X" default = 1 visible = @use && (@v_hybridmandelbox < 103 || @arb) endparam float param ey caption ="End Y" default = 1 visible = @use && (@v_hybridmandelbox < 103 || @arb) endparam float param ez caption ="End Z" default = 1 visible = @use && (@v_hybridmandelbox < 103 || @arb) endparam heading caption = "Post-fold" endheading bool param use2 caption = "Rotate around axis" default = false endparam float param xang2 caption = "X Rotation angle" default = 0.0 visible = @use2 && @v_hybridmandelbox >= 103 endparam float param yang2 caption = "Y Rotation angle" default = 0.0 visible = @use2 && @v_hybridmandelbox >= 103 endparam float param zang2 caption = "Z Rotation angle" default = 0.0 visible = @use2 && @v_hybridmandelbox >= 103 endparam bool param arb2 caption = "Arbitrary axis rotation" default = false visible = @use2 endparam float param ang2 caption = "Rotation angle" default = 0.0 visible = @use2 && (@v_hybridmandelbox < 103 || @arb2) endparam heading text = "Rotation vector origin" visible = @use2 && (@v_hybridmandelbox < 103 || @arb2) endheading float param ox2 caption ="Origin X" default = 0 visible = @use2 && (@v_hybridmandelbox < 103 || @arb2) endparam float param oy2 caption ="Origin Y" default = 0 visible = @use2 && (@v_hybridmandelbox < 103 || @arb2) endparam float param oz2 caption ="Origin Z" default = 0 visible = @use2 && (@v_hybridmandelbox < 103 || @arb2) endparam heading text = "Rotation vector end" visible = @use2 && (@v_hybridmandelbox < 103 || @arb2) endheading float param ex2 caption ="End X" default = 1 visible = @use2 && (@v_hybridmandelbox < 103 || @arb2) endparam float param ey2 caption ="End Y" default = 1 visible = @use2 && (@v_hybridmandelbox < 103 || @arb2) endparam float param ez2 caption ="End Z" default = 1 visible = @use2 && (@v_hybridmandelbox < 103 || @arb2) endparam complex param zri caption = "r-i plane" default = (0.0,0.0) visible = false endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) visible = false endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam } class HybridJulia(Quat) { ; As presented by Tom Lowe on FractalForum and modified to include both Amzaing ; and Conformal algorithms. public: import "common.ulb" ; constructor func HybridJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = false m_sphere = false m_fourth = @fourth m_ck = @ck scale = @scale rad = @rad minrad = @minrad foldx = @foldx foldy = @foldy foldz = @foldz diagonal = new Vector(@vx,@vy,@vz,0) diagonal.Normalize(diagonal) mx = diagonal.m_x my = diagonal.m_y mz = diagonal.m_z if (@v_hybridjulia < 103 || @arb) rvector = new Vector(-@ex+@ox,-@ey+@oy,-@ez+@oz,0) rvector.Normalize(rvector) endif if (@v_hybridjulia < 103 || @arb2) rvector2 = new Vector(-@ex2+@ox2,-@ey2+@oy2,-@ez2+@oz2,0) rvector2.Normalize(rvector2) endif endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) int i = 0 repeat defactor = scale*@conv if @order == "Box Rotate Invert" x = real(zri) y = imag(zri) z = real(zjk) ; fold box onto itself if @use if (@v_hybridjulia < 103 || @arb) cangle = cos(@ang*#pi/180) sangle = sin(@ang*#pi/180) rmatrix[0,0] = cangle+rvector.m_x^2*(1-cangle) rmatrix[1,0] = rvector.m_x*rvector.m_y*(1-cangle)-rvector.m_z*sangle rmatrix[2,0] = rvector.m_x*rvector.m_z*(1-cangle)+rvector.m_y*sangle rmatrix[0,1] = rvector.m_x*rvector.m_y*(1-cangle)+rvector.m_z*sangle rmatrix[1,1] = cangle+rvector.m_y^2*(1-cangle) rmatrix[2,1] = rvector.m_y*rvector.m_z*(1-cangle)-rvector.m_x*sangle rmatrix[0,2] = rvector.m_x*rvector.m_z*(1-cangle)-rvector.m_y*sangle rmatrix[1,2] = rvector.m_y*rvector.m_z*(1-cangle)+rvector.m_x*sangle rmatrix[2,2] = cangle+rvector.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_hybridjulia >= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_hybridjulia < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_hybridjulia < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_hybridjulia >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif ; vector folding dot = x*mx+y*my+z*mz x = x - 2*dot*mx y = y - 2*dot*my z = z - 2*dot*mz zri = x + flip(y) zjk = z ; fold sphere onto itself if @v_hybridjulia >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_hybridjulia < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_hybridjulia < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_hybridjulia >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif zri = x + flip(y) zjk = z ; fold sphere onto itself if @v_hybridjulia >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_hybridjulia < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_hybridjulia < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_hybridjulia >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif zri = x + flip(y) zjk = z elseif @order == "Rotate Box Invert" x = real(zri) y = imag(zri) z = real(zjk) ; composite with diagonal. This is a rotation ; vector folding dot = x*mx+y*my+z*mz x = x - 2*dot*mx y = y - 2*dot*my z = z - 2*dot*mz zri = x + flip(y) zjk = z ; fold box onto itself if @use if (@v_hybridjulia < 103 || @arb) cangle = cos(@ang*#pi/180) sangle = sin(@ang*#pi/180) rmatrix[0,0] = cangle+rvector.m_x^2*(1-cangle) rmatrix[1,0] = rvector.m_x*rvector.m_y*(1-cangle)-rvector.m_z*sangle rmatrix[2,0] = rvector.m_x*rvector.m_z*(1-cangle)+rvector.m_y*sangle rmatrix[0,1] = rvector.m_x*rvector.m_y*(1-cangle)+rvector.m_z*sangle rmatrix[1,1] = cangle+rvector.m_y^2*(1-cangle) rmatrix[2,1] = rvector.m_y*rvector.m_z*(1-cangle)-rvector.m_x*sangle rmatrix[0,2] = rvector.m_x*rvector.m_z*(1-cangle)-rvector.m_y*sangle rmatrix[1,2] = rvector.m_y*rvector.m_z*(1-cangle)+rvector.m_x*sangle rmatrix[2,2] = cangle+rvector.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_hybridjulia >= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_hybridjulia < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_hybridjulia < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_hybridjulia >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif zri = x + flip(y) zjk = z ; fold sphere onto itself if @v_hybridjulia >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_hybridjulia < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_hybridjulia < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_hybridjulia >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif zri = x + flip(y) zjk = z elseif @order == "Invert Box Rotate" ; fold sphere onto itself if @v_hybridjulia >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_hybridjulia < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_hybridjulia < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_hybridjulia >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif zri = x + flip(y) zjk = z ; composite with diagonal. This is a rotation ; vector folding dot = x*mx+y*my+z*mz x = x - 2*dot*mx y = y - 2*dot*my z = z - 2*dot*mz zri = x + flip(y) zjk = z endif i = i + 1 until i == @count zri = zri*scale + m_cri zjk = zjk*scale + m_cjk if @bscale defactor = defactor*scale endif spec = (cabs(zri) + cabs(zjk))/abs(defactor) endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) int i = 0 repeat if @order == "Box Rotate Invert" x = real(zri) y = imag(zri) z = real(zjk) derivx = 1 derivy = 1 derivz = 1 if @v_hybridjulia < 101 if x > 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif ; CtoV(zri,zjk,out) ; float dot = diagonal.dot(out) ; if dot > 1 derivx = 1 derivy = 1 derivz = 1 ; endif if @v_hybridjulia >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif if @v_hybridjulia >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length 1 derivx = 1 derivy = 1 derivz = 1 ; endif elseif @order == "Rotate Invert Box" x = real(zri) y = imag(zri) z = real(zjk) derivx = 1 derivy = 1 derivz = 1 CtoV(zri,zjk,out) ; CtoV(zri,zjk,out) ; float dot = diagonal.dot(out) ; if dot > 1 derivx = 1 derivy = 1 derivz = 1 ; endif if @v_hybridjulia >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif elseif @order == "Rotate Box Invert" x = real(zri) y = imag(zri) z = real(zjk) derivx = 1 derivy = 1 derivz = 1 ; CtoV(zri,zjk,out) ; float dot = diagonal.dot(out) ; if dot > 1 derivx = 1 derivy = 1 derivz = 1 ; endif if @v_hybridjulia < 101 if x > 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif if @v_hybridjulia >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length 1 derivx = 1 derivy = 1 derivz = 1 ; endif if @v_hybridjulia < 101 if x > 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif elseif @order == "Invert Box Rotate" x = real(zri) y = imag(zri) z = real(zjk) derivx = 1 derivy = 1 derivz = 1 if @v_hybridjulia >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif ; CtoV(zri,zjk,out) ; float dot = diagonal.dot(out) ; if dot > 1 derivx = 1 derivy = 1 derivz = 1 ; endif endif i = i + 1 until i == @count derivx=derivx*scale derivy=derivy*scale derivz=derivz*scale derivx=derivx*real(zrid)+1 derivy=derivy*imag(zrid)+1 derivz=derivz*real(zjkd)+1 zrid = derivz + flip(derivy) zjkd = derivz endfunc protected: float scale float rad float minrad float foldx float foldy float foldz Vector diagonal float x float y float z float derivx float derivy float derivz ; complex defactor float defactor Vector rvector Vector rvector2 float mx float my float mz float dot float rmatrix[3,3] float tempx float tempy float cangle float sangle default: title = "Hybrid JuliaBox" int param v_hybridjulia caption = "Version (Hybrid JuliaBox)" default = 103 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_hybridjulia < 103 endparam heading text = "Based upon the code of Tom Lowe presented on the FractalForum. A bailout \ value of 1024 is recomended along with a Starting \ Plane Z value of 10, an Ending Plane Z value of 20, and a Camera \ Origin Z value of 40." endheading heading caption = "Julia Parameters" endheading complex param cri caption = "r-i plane" default = (1,1) endparam complex param cjk caption = "j-k plane" default = (1,0.0) endparam param order caption = "Conformal Order" default = 0 enum = "Box Rotate Invert" "Box Invert Rotate" "Rotate Invert Box" \ "Rotate Box Invert" "Invert Rotate Box" "Invert Box Rotate" endparam int param count caption = "Fold count" default = 2 endparam float param scale caption = "Scale" default = 3 endparam float param rad caption = "Fixed Radius" default = 1 endparam float param minrad caption = "Minimum Radius" default = 0.5 endparam float param spower caption = "Spherical power" default = 2 visible = @v_hybridjulia >= 102 endparam float param foldx caption = "X fold value" default = 2 endparam float param foldxlim caption = "X fold limit" default = 1 visible = @v_hybridjulia >= 101 endparam float param foldy caption = "Y fold value" default = 2 endparam float param foldylim caption = "Y fold limit" default = 1 visible = @v_hybridjulia >= 101 endparam bool param noz caption = "No Z folding" default = false endparam float param foldz caption = "Z fold value" default = 2 visible = !@noz endparam float param foldzlim caption = "Z fold limit" default = 1 visible = @v_hybridjulia >= 101 && !@noz endparam heading text = "X, Y and Z are components of a diagonal vector. The dot product of \ the normalized vector is taken with the vector formed from zri and \ zjk. The dot product values are then used to fold zri and zjk." endheading float param vx caption = "X" default = 1 endparam float param vy caption = "Y" default = 1 endparam float param vz caption = "Z" default = 1 endparam float param conv caption = "Convergence factor" default = 1 endparam heading text = "This should be used with the special potential only" endheading bool param bscale caption = "Include final scaling" default = false endparam heading caption = "Pre-fold" endheading bool param use caption = "Rotate around axis" default = false endparam float param xang caption = "X Rotation angle" default = 0.0 visible = @use && @v_hybridjulia >= 103 endparam float param yang caption = "Y Rotation angle" default = 0.0 visible = @use && @v_hybridjulia >= 103 endparam float param zang caption = "Z Rotation angle" default = 0.0 visible = @use && @v_hybridjulia >= 103 endparam bool param arb caption = "Arbitrary axis rotation" default = false visible = @use endparam float param ang caption = "Rotation angle" default = 0.0 visible = @use && (@v_hybridjulia < 103 || @arb) endparam heading text = "Rotation vector origin" visible = @use && (@v_hybridjulia < 103 || @arb) endheading float param ox caption ="Origin X" default = 0 visible = @use && (@v_hybridjulia < 103 || @arb) endparam float param oy caption ="Origin Y" default = 0 visible = @use && (@v_hybridjulia < 103 || @arb) endparam float param oz caption ="Origin Z" default = 0 visible = @use && (@v_hybridjulia < 103 || @arb) endparam heading text = "Rotation vector end" visible = @use && (@v_hybridjulia < 103 || @arb) endheading float param ex caption ="End X" default = 1 visible = @use && (@v_hybridjulia < 103 || @arb) endparam float param ey caption ="End Y" default = 1 visible = @use && (@v_hybridjulia < 103 || @arb) endparam float param ez caption ="End Z" default = 1 visible = @use && (@v_hybridjulia < 103 || @arb) endparam heading caption = "Post-fold" endheading bool param use2 caption = "Rotate around axis" default = false endparam float param xang2 caption = "X Rotation angle" default = 0.0 visible = @use2 && @v_hybridjulia >= 103 endparam float param yang2 caption = "Y Rotation angle" default = 0.0 visible = @use2 && @v_hybridjulia >= 103 endparam float param zang2 caption = "Z Rotation angle" default = 0.0 visible = @use2 && @v_hybridjulia >= 103 endparam bool param arb2 caption = "Arbitrary axis rotation" default = false visible = @use2 endparam float param ang2 caption = "Rotation angle" default = 0.0 visible = @use2 && (@v_hybridjulia < 103 || @arb2) endparam heading text = "Rotation vector origin" visible = @use2 && (@v_hybridjulia < 103 || @arb2) endheading float param ox2 caption ="Origin X" default = 0 visible = @use2 && (@v_hybridjulia < 103 || @arb2) endparam float param oy2 caption ="Origin Y" default = 0 visible = @use2 && (@v_hybridjulia < 103 || @arb2) endparam float param oz2 caption ="Origin Z" default = 0 visible = @use2 && (@v_hybridjulia < 103 || @arb2) endparam heading text = "Rotation vector end" visible = @use2 && (@v_hybridjulia < 103 || @arb2) endheading float param ex2 caption ="End X" default = 1 visible = @use2 && (@v_hybridjulia < 103 || @arb2) endparam float param ey2 caption ="End Y" default = 1 visible = @use2 && (@v_hybridjulia < 103 || @arb2) endparam float param ez2 caption ="End Z" default = 1 visible = @use2 && (@v_hybridjulia < 103 || @arb2) endparam complex param zri caption = "r-i plane" default = (0.0,0.0) visible = false endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) visible = false endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam } class AmazingFractalMandelbrot(Quat) { ; As presented by Tom Lowe on FractalForum public: import "common.ulb" ; constructor func AmazingFractalMandelbrot(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = false m_sphere = true m_fourth = @fourth m_ck = @ck scale = @scale rad = @rad minrad = @minrad foldx = @foldx foldy = @foldy foldz = @foldz if (@v_mandelbox < 103 || @arb) rvector = new Vector(-@ex+@ox,-@ey+@oy,-@ez+@oz,0) rvector.Normalize(rvector) endif if (@v_mandelbox < 103 || @arb2) rvector2 = new Vector(-@ex2+@ox2,-@ey2+@oy2,-@ez2+@oz2,0) rvector2.Normalize(rvector2) endif endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) int i = 0 defactor = scale*@conv float length = 0 repeat if !@fold float x = real(zri) float y = imag(zri) float z = real(zjk) if @use if (@v_mandelbox < 103 || @arb) cangle = cos(@ang*#pi/180) sangle = sin(@ang*#pi/180) rmatrix[0,0] = cangle+rvector.m_x^2*(1-cangle) rmatrix[1,0] = rvector.m_x*rvector.m_y*(1-cangle)-rvector.m_z*sangle rmatrix[2,0] = rvector.m_x*rvector.m_z*(1-cangle)+rvector.m_y*sangle rmatrix[0,1] = rvector.m_x*rvector.m_y*(1-cangle)+rvector.m_z*sangle rmatrix[1,1] = cangle+rvector.m_y^2*(1-cangle) rmatrix[2,1] = rvector.m_y*rvector.m_z*(1-cangle)-rvector.m_x*sangle rmatrix[0,2] = rvector.m_x*rvector.m_z*(1-cangle)-rvector.m_y*sangle rmatrix[1,2] = rvector.m_y*rvector.m_z*(1-cangle)+rvector.m_x*sangle rmatrix[2,2] = cangle+rvector.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_mandelbox >= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_mandelbox < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_mandelbox < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_mandelbox >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif zri = x + flip(y) zjk = z ; fold sphere onto itself if @v_mandelbox >= 102 length = (|zri| + |zjk|)^(0.5*@spower) if length= 102 length = (|zri| + |zjk|)^(0.5*@spower) if length= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_mandelbox < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_mandelbox < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_mandelbox >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif zri = x + flip(y) zjk = z endif i = i + 1 until i == @count zri = zri*scale + m_cri zjk = zjk*scale + m_cjk if @bscale defactor = defactor*scale endif spec = (cabs(zri) + cabs(zjk))/abs(defactor) endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) int i = 0 repeat if !@fold float x = real(zri) float y = imag(zri) float z = real(zjk) float derivx = 1 float derivy = 1 float derivz = 1 if @v_mandelbox < 101 if x > 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif if @v_mandelbox >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif endif i = i + 1 until i == @count derivx=derivx*scale derivy=derivy*scale derivz=derivz*scale derivx=derivx*real(zrid) derivy=derivy*imag(zrid) derivz=derivz*real(zjkd)+1 zrid = derivx + flip(derivy) + 1 zjkd = derivz endfunc protected: float scale float rad float minrad float foldx float foldy float foldz ; complex defactor float defactor Vector rvector Vector rvector2 float rmatrix[3,3] float tempx float tempy float cangle float sangle default: title = "Amazing Fractal (Mandelbrot)" heading caption = "Mandel Initialization" visible = false endheading int param v_mandelbox caption = "Version (Mandelbox)" default = 103 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_mandelbox < 103 endparam heading text = "Based upon the code of Tom Lowe presented on the FractalForum. A bailout \ value of 1024 is recomended along with a Starting \ Plane Z value of 10, an Ending Plane Z value of 20, and a Camera \ Origin Z value of 40." endheading bool param fold caption = "Alternate folding order" default = false endparam int param count caption = "Fold count" default = 1 endparam float param scale caption = "Scale" default = 3 endparam float param rad caption = "Fixed Radius" default = 1 endparam float param minrad caption = "Minimum Radius" default = 0.5 endparam float param spower caption = "Spherical power" default = 2 visible = @v_mandelbox >= 102 endparam float param foldx caption = "X fold value" default = 2 endparam float param foldxlim caption = "X fold limit" default = 1 visible = @v_mandelbox >= 101 endparam float param foldy caption = "Y fold value" default = 2 endparam float param foldylim caption = "Y fold limit" default = 1 visible = @v_mandelbox >= 101 endparam bool param noz caption = "No Z folding" default = false endparam float param foldz caption = "Z fold value" default = 2 visible = !@noz endparam float param foldzlim caption = "Z fold limit" default = 1 visible = @v_mandelbox >= 101 && !@noz endparam float param conv caption = "Convergence factor" default = 1 endparam heading text = "This should be used with the special potential only" endheading bool param bscale caption = "Include final scaling" default = false endparam complex param zri caption = "r-i plane" default = (0.0,0.0) visible = false endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) visible = false endparam heading caption = "Pre-fold" endheading bool param use caption = "Rotate around axis" default = false endparam float param xang caption = "X Rotation angle" default = 0.0 visible = @use && @v_mandelbox >= 103 endparam float param yang caption = "Y Rotation angle" default = 0.0 visible = @use && @v_mandelbox >= 103 endparam float param zang caption = "Z Rotation angle" default = 0.0 visible = @use && @v_mandelbox >= 103 endparam bool param arb caption = "Arbitrary axis rotation" default = false visible = @use endparam float param ang caption = "Rotation angle" default = 0.0 visible = @use && (@v_mandelbox < 103 || @arb) endparam heading text = "Rotation vector origin" visible = @use && (@v_mandelbox < 103 || @arb) endheading float param ox caption ="Origin X" default = 0 visible = @use && (@v_mandelbox < 103 || @arb) endparam float param oy caption ="Origin Y" default = 0 visible = @use && (@v_mandelbox < 103 || @arb) endparam float param oz caption ="Origin Z" default = 0 visible = @use && (@v_mandelbox < 103 || @arb) endparam heading text = "Rotation vector end" visible = @use && (@v_mandelbox < 103 || @arb) endheading float param ex caption ="End X" default = 1 visible = @use && (@v_mandelbox < 103 || @arb) endparam float param ey caption ="End Y" default = 1 visible = @use && (@v_mandelbox < 103 || @arb) endparam float param ez caption ="End Z" default = 1 visible = @use && (@v_mandelbox < 103 || @arb) endparam heading caption = "Post-fold" endheading bool param use2 caption = "Rotate around axis" default = false endparam float param xang2 caption = "X Rotation angle" default = 0.0 visible = @use2 && @v_mandelbox >= 103 endparam float param yang2 caption = "Y Rotation angle" default = 0.0 visible = @use2 && @v_mandelbox >= 103 endparam float param zang2 caption = "Z Rotation angle" default = 0.0 visible = @use2 && @v_mandelbox >= 103 endparam bool param arb2 caption = "Arbitrary axis rotation" default = false visible = @use2 endparam float param ang2 caption = "Rotation angle" default = 0.0 visible = @use2 && (@v_mandelbox < 103 || @arb2) endparam heading text = "Rotation vector origin" visible = @use2 && (@v_mandelbox < 103 || @arb2) endheading float param ox2 caption ="Origin X" default = 0 visible = @use2 && (@v_mandelbox < 103 || @arb2) endparam float param oy2 caption ="Origin Y" default = 0 visible = @use2 && (@v_mandelbox < 103 || @arb2) endparam float param oz2 caption ="Origin Z" default = 0 visible = @use2 && (@v_mandelbox < 103 || @arb2) endparam heading text = "Rotation vector end" visible = @use2 && (@v_mandelbox < 103 || @arb2) endheading float param ex2 caption ="End X" default = 1 visible = @use2 && (@v_mandelbox < 103 || @arb2) endparam float param ey2 caption ="End Y" default = 1 visible = @use2 && (@v_mandelbox < 103 || @arb2) endparam float param ez2 caption ="End Z" default = 1 visible = @use2 && (@v_mandelbox < 103 || @arb2) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam } class Mandelex(Quat) { ; As presented by Tslil 'Hiato' Clingman on FractalForum public: $define debug import "common.ulb" ; constructor func Mandelex(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = true m_fourth = @fourth m_ck = @ck scale = @scale minrad = @minrad foldx = @foldx foldy = @foldy foldz = @foldz endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) linx = @linx liny = @liny linz = @linz nonlinx = @nonlinx nonliny = @nonliny nonlinz = @nonlinz float length = 0 float x = real(zri) float y = imag(zri) float z = real(zjk) float len = sqrt(|m_cri| + |m_cjk|) if !@unorm len = 1 endif float x1 = real(m_cri)/len*nonlinx*@f float y1 = imag(m_cri)/len*nonliny*@f float z1 = real(m_cjk)/len*nonlinz*@f ; nonlinear pull if abs(x1) < nonlinx && abs(y1) < nonliny && abs(z1) < nonlinz if abs(x) > nonlinx && abs(y) > nonliny && abs(z) > nonlinz nonlinx = nonlinx*2 nonliny = nonliny*2 nonlinz = nonlinz*2 if x > 0 x = x - nonlinx*floor(x/nonlinx) else x = x - nonlinx*ceil(x/nonlinx) endif if y > 0 y = y - nonliny*floor(y/nonliny) else y = y - nonliny*ceil(y/nonliny) endif if z > 0 z = z - nonlinz*floor(z/nonlinz) else z = z - nonlinz*ceil(z/nonlinz) endif endif endif ; wrap box float dist float q dist = abs(x) - foldx if dist > 0 q = dist if x > 0 x = foldx-q else x = -foldx + q endif endif dist = abs(y) - foldy if dist > 0 q = dist if y > 0 y = foldy-q else y = -foldy + q endif endif dist = abs(z) - foldz if dist > 0 q = dist if z > 0 z = foldz-q else z = -foldz + q endif endif ; sphere inversion length = sqrt(x^2+y^2+z^2) if length < minrad && length != 0 x = x*sqr(minrad/length) y = y*sqr(minrad/length) z = z*sqr(minrad/length) endif x = x*scale y = y*scale z = z*scale if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif ; linear pull if abs(x) > linx && abs(y) > liny && abs(z) > linz linx = linx*2 liny = liny*2 linz = linz*2 if x < 0 x = x + linx else x = x-linx endif if y < 0 y = y + liny else y = y-liny endif if z < 0 z = z + linz else z = z-linz endif endif zri = (x + flip(y)) + m_cri zjk = z + m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) float x = real(zri) float y = imag(zri) float z = real(zjk) float derivx = 1 float derivy = 1 float derivz = 1 ; box wrap float dist float q dist = abs(x) - foldx if dist > 0 q = dist if x > 0 x = foldx-q else x = -foldx + q endif endif dist = abs(y) - foldy if dist > 0 q = dist if y > 0 y = foldy-q else y = -foldy + q endif endif dist = abs(z) - foldz if dist > 0 q = dist if z > 0 z = foldz-q else z = -foldz + q endif endif if x > 0 derivx = 1 elseif x != 0 derivx = -1 endif if y > 0 derivy = 1 elseif y != 0 derivy = -1 endif if z > 0 derivz = 1 elseif z != 0 derivz = -1 endif ; sphere invert float length = sqrt(x^2+y^2+z^2) if length < minrad && length != 0 derivx = sqr(minrad/length) derivy = sqr(minrad/length) derivz = sqr(minrad/length) endif derivx=derivx*scale derivy=derivy*scale derivz=derivz*scale derivx=derivx*real(zrid) derivy=derivy*imag(zrid) derivz=derivz*real(zjkd)+1 zrid = derivx + flip(derivy) + 1 zjkd = derivz endfunc protected: float scale float minrad float foldx float foldy float foldz float rmatrix[3,3] float tempx float tempy float cangle float sangle float linx float liny float linz float nonlinx float nonliny float nonlinz default: title = "Mandelex (Mandelbrot)" heading caption = "Mandel Initialization" visible = false endheading int param v_mandelex caption = "Version (Mandelex)" 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_mandelex < 100 endparam heading text = "Based upon the code of Tslil 'Hiato' Clingman presented on the FractalForum." endheading complex param zri caption = "r-i plane" default = (0.0,0.0) visible = false endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) visible = false endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam float param scale caption = "Scale" default = 2 endparam float param minrad caption = "Radius" default = 0.5 endparam heading caption = "Box Wrap" endheading float param foldx caption = "wrap x" default = 0.5 endparam float param foldy caption = "wrap y" default = 0.5 endparam float param foldz caption = "wrap z" default = 0.5 endparam heading caption = "Rotate" endheading float param xang caption = "X Rotation angle" default = 0.0 endparam float param yang caption = "Y Rotation angle" default = 0.0 endparam float param zang caption = "Z Rotation angle" default = 0.0 endparam heading caption = "nonLinear Pull" expanded = false endheading heading text = "Decreasing the filter value will increase the amount of 'nonLinear Pull'" endheading float param f caption = "pull filter" default = 1 endparam bool param unorm caption = "normalize cri/cjk" default = false endparam float param nonlinx caption = "nonLinear X" default = 2 endparam float param nonliny caption = "nonLinear Y" default = 2 endparam float param nonlinz caption = "nonLinear Z" default = 2 endparam heading caption = "Linear Pull" endheading float param linx caption = "Linear X" default = 2 endparam float param liny caption = "Linear Y" default = 2 endparam float param linz caption = "Linear Z" default = 2 endparam } class ConformalMandelbrot(Quat) { ; As presented by Tom Lowe on FractalForum public: import "common.ulb" ; constructor func ConformalMandelbrot(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = true m_fourth = @fourth m_ck = @ck scale = @scale foldx = @foldx foldy = @foldy foldz = @foldz diagonal = new Vector(@vx,@vy,@vz,0) diagonal.Normalize(diagonal) mx = diagonal.m_x my = diagonal.m_y mz = diagonal.m_z if (@v_conformalmandelbox < 103 || @arb) rvector = new Vector(-@ex+@ox,-@ey+@oy,-@ez+@oz,0) rvector.Normalize(rvector) endif if (@v_conformalmandelbox < 103 || @arb2) rvector2 = new Vector(-@ex2+@ox2,-@ey2+@oy2,-@ez2+@oz2,0) rvector2.Normalize(rvector2) endif endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) float x = real(zri) float y = imag(zri) float z = real(zjk) int i = 0 defactor = scale*@conv repeat if !@fold if @use if (@v_conformalmandelbox < 103 || @arb) cangle = cos(@ang*#pi/180) sangle = sin(@ang*#pi/180) rmatrix[0,0] = cangle+rvector.m_x^2*(1-cangle) rmatrix[1,0] = rvector.m_x*rvector.m_y*(1-cangle)-rvector.m_z*sangle rmatrix[2,0] = rvector.m_x*rvector.m_z*(1-cangle)+rvector.m_y*sangle rmatrix[0,1] = rvector.m_x*rvector.m_y*(1-cangle)+rvector.m_z*sangle rmatrix[1,1] = cangle+rvector.m_y^2*(1-cangle) rmatrix[2,1] = rvector.m_y*rvector.m_z*(1-cangle)-rvector.m_x*sangle rmatrix[0,2] = rvector.m_x*rvector.m_z*(1-cangle)-rvector.m_y*sangle rmatrix[1,2] = rvector.m_y*rvector.m_z*(1-cangle)+rvector.m_x*sangle rmatrix[2,2] = cangle+rvector.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_conformalmandelbox >= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_conformalmandelbox < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_conformalmandelbox < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_conformalmandelbox >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif ; vector folding dot = x*mx+y*my+z*mz x = x - 2*dot*mx y = y - 2*dot*my z = z - 2*dot*mz else zri = x + flip(y) zjk = z ; vector folding dot = x*mx+y*my+z*mz x = x - 2*dot*mx y = y - 2*dot*my z = z - 2*dot*mz if @use if (@v_conformalmandelbox < 103 || @arb) cangle = cos(@ang*#pi/180) sangle = sin(@ang*#pi/180) rmatrix[0,0] = cangle+rvector.m_x^2*(1-cangle) rmatrix[1,0] = rvector.m_x*rvector.m_y*(1-cangle)-rvector.m_z*sangle rmatrix[2,0] = rvector.m_x*rvector.m_z*(1-cangle)+rvector.m_y*sangle rmatrix[0,1] = rvector.m_x*rvector.m_y*(1-cangle)+rvector.m_z*sangle rmatrix[1,1] = cangle+rvector.m_y^2*(1-cangle) rmatrix[2,1] = rvector.m_y*rvector.m_z*(1-cangle)-rvector.m_x*sangle rmatrix[0,2] = rvector.m_x*rvector.m_z*(1-cangle)-rvector.m_y*sangle rmatrix[1,2] = rvector.m_y*rvector.m_z*(1-cangle)+rvector.m_x*sangle rmatrix[2,2] = cangle+rvector.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_conformalmandelbox >= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_conformalmandelbox < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_conformalmandelbox < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_conformalmandelbox >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif endif i = i + 1 until i == @count zri = x + flip(y) zjk = z zri = zri*scale + m_cri zjk = zjk*scale + m_cjk if @bscale defactor = defactor*scale endif spec = (cabs(zri) + cabs(zjk))/abs(defactor) endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) float x = real(zri) float y = imag(zri) float z = real(zjk) int i = 0 repeat if !@fold float derivx = 1 float derivy = 1 float derivz = 1 if @v_conformalmandelbox < 101 if x > 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif ; CtoV(zri,zjk,out) ; float dot = diagonal.dot(out) ; if dot > 1 derivx = 1 derivy = 1 derivz = 1 ; endif else float derivx = 1 float derivy = 1 float derivz = 1 ; CtoV(zri,zjk,out) ; float dot = diagonal.dot(out) ; if dot > 1 derivx = 1 derivy = 1 derivz = 1 ; endif if @v_conformalmandelbox < 101 if x > 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif endif i = i + 1 until i == @count derivx=derivx*scale derivy=derivy*scale derivz=derivz*scale derivx=derivx*real(zrid)+1 derivy=derivy*imag(zrid)+1 derivz=derivz*real(zjkd)+1 zrid = derivz + flip(derivy) zjkd = derivz endfunc protected: float scale float foldx float foldy float foldz Vector diagonal ; complex defactor float defactor Vector rvector Vector rvector2 float mx float my float mz float dot float rmatrix[3,3] float tempx float tempy float cangle float sangle default: title = "Conformal Mandelbrot" heading caption = "Mandel Initialization" visible = false endheading int param v_conformalmandelbox caption = "Version (Conformal Mandelbox)" default = 103 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_conformalmandelbox < 103 endparam heading text = "Based upon the code of Tom Lowe presented on the FractalForum. A bailout \ value of 1024 is recomended along with a Starting \ Plane Z value of 10, an Ending Plane Z value of 20, and a Camera \ Origin Z value of 40." endheading bool param fold caption = "Alternate folding order" default = false endparam int param count caption = "Fold count" default = 2 endparam float param scale caption = "Scale" default = 3 endparam float param foldx caption = "X fold value" default = 2 endparam float param foldxlim caption = "X fold limit" default = 1 visible = @v_conformalmandelbox >= 101 endparam float param foldy caption = "Y fold value" default = 2 endparam float param foldylim caption = "Y fold limit" default = 1 visible = @v_conformalmandelbox >= 101 endparam bool param noz caption = "No Z folding" default = false endparam float param foldz caption = "Z fold value" default = 2 visible = !@noz endparam float param foldzlim caption = "Z fold limit" default = 1 visible = @v_conformalmandelbox >= 101 && !@noz endparam heading text = "X, Y and Z are components of a diagonal vector. The dot product of \ the normalized vector is taken with the vector formed from zri and \ zjk. The dot product values are then used to fold zri and zjk." endheading float param vx caption = "X" default = 1 endparam float param vy caption = "Y" default = 1 endparam float param vz caption = "Z" default = 1 endparam float param conv caption = "Convergence factor" default = 1 endparam heading text = "This should be used with the special potential only" endheading bool param bscale caption = "Include final scaling" default = false endparam complex param zri caption = "r-i plane" default = (0.0,0.0) visible = false endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) visible = false endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam heading caption = "Pre-fold" endheading bool param use caption = "Rotate around axis" default = false endparam float param xang caption = "X Rotation angle" default = 0.0 visible = @use && @v_conformalmandelbox >= 103 endparam float param yang caption = "Y Rotation angle" default = 0.0 visible = @use && @v_conformalmandelbox >= 103 endparam float param zang caption = "Z Rotation angle" default = 0.0 visible = @use && @v_conformalmandelbox >= 103 endparam bool param arb caption = "Arbitrary axis rotation" default = false visible = @use endparam float param ang caption = "Rotation angle" default = 0.0 visible = @use && (@v_conformalmandelbox < 103 || @arb) endparam heading text = "Rotation vector origin" visible = @use && (@v_conformalmandelbox < 103 || @arb) endheading float param ox caption ="Origin X" default = 0 visible = @use && (@v_conformalmandelbox < 103 || @arb) endparam float param oy caption ="Origin Y" default = 0 visible = @use && (@v_conformalmandelbox < 103 || @arb) endparam float param oz caption ="Origin Z" default = 0 visible = @use && (@v_conformalmandelbox < 103 || @arb) endparam heading text = "Rotation vector end" visible = @use && (@v_conformalmandelbox < 103 || @arb) endheading float param ex caption ="End X" default = 1 visible = @use && (@v_conformalmandelbox < 103 || @arb) endparam float param ey caption ="End Y" default = 1 visible = @use && (@v_conformalmandelbox < 103 || @arb) endparam float param ez caption ="End Z" default = 1 visible = @use && (@v_conformalmandelbox < 103 || @arb) endparam heading caption = "Post-fold" endheading bool param use2 caption = "Rotate around axis" default = false endparam float param xang2 caption = "X Rotation angle" default = 0.0 visible = @use2 && @v_conformalmandelbox >= 103 endparam float param yang2 caption = "Y Rotation angle" default = 0.0 visible = @use2 && @v_conformalmandelbox >= 103 endparam float param zang2 caption = "Z Rotation angle" default = 0.0 visible = @use2 && @v_conformalmandelbox >= 103 endparam bool param arb2 caption = "Arbitrary axis rotation" default = false visible = @use2 endparam float param ang2 caption = "Rotation angle" default = 0.0 visible = @use2 && (@v_conformalmandelbox < 103 || @arb2) endparam heading text = "Rotation vector origin" visible = @use2 && (@v_conformalmandelbox < 103 || @arb2) endheading float param ox2 caption ="Origin X" default = 0 visible = @use2 && (@v_conformalmandelbox < 103 || @arb2) endparam float param oy2 caption ="Origin Y" default = 0 visible = @use2 && (@v_conformalmandelbox < 103 || @arb2) endparam float param oz2 caption ="Origin Z" default = 0 visible = @use2 && (@v_conformalmandelbox < 103 || @arb2) endparam heading text = "Rotation vector end" visible = @use2 && (@v_conformalmandelbox < 103 || @arb2) endheading float param ex2 caption ="End X" default = 1 visible = @use2 && (@v_conformalmandelbox < 103 || @arb2) endparam float param ey2 caption ="End Y" default = 1 visible = @use2 && (@v_conformalmandelbox < 103 || @arb2) endparam float param ez2 caption ="End Z" default = 1 visible = @use2 && (@v_conformalmandelbox < 103 || @arb2) endparam } class ConformalJulia(Quat) { ; As presented by Tom Lowe on FractalForum public: import "common.ulb" ; constructor func ConformalJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = false m_sphere = false m_fourth = @fourth m_ck = @ck scale = @scale foldx = @foldx foldy = @foldy foldz = @foldz diagonal = new Vector(@vx,@vy,@vz,0) diagonal.Normalize(diagonal) mx = diagonal.m_x my = diagonal.m_y mz = diagonal.m_z if (@v_conformaljuliabox < 103 || @arb) rvector = new Vector(-@ex+@ox,-@ey+@oy,-@ez+@oz,0) rvector.Normalize(rvector) endif if (@v_conformaljuliabox < 103 || @arb2) rvector2 = new Vector(-@ex2+@ox2,-@ey2+@oy2,-@ez2+@oz2,0) rvector2.Normalize(rvector2) endif endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) float x = real(zri) float y = imag(zri) float z = real(zjk) int i = 0 defactor = scale*@conv repeat if !@fold if @use if (@v_conformaljuliabox < 103 || @arb) cangle = cos(@ang*#pi/180) sangle = sin(@ang*#pi/180) rmatrix[0,0] = cangle+rvector.m_x^2*(1-cangle) rmatrix[1,0] = rvector.m_x*rvector.m_y*(1-cangle)-rvector.m_z*sangle rmatrix[2,0] = rvector.m_x*rvector.m_z*(1-cangle)+rvector.m_y*sangle rmatrix[0,1] = rvector.m_x*rvector.m_y*(1-cangle)+rvector.m_z*sangle rmatrix[1,1] = cangle+rvector.m_y^2*(1-cangle) rmatrix[2,1] = rvector.m_y*rvector.m_z*(1-cangle)-rvector.m_x*sangle rmatrix[0,2] = rvector.m_x*rvector.m_z*(1-cangle)-rvector.m_y*sangle rmatrix[1,2] = rvector.m_y*rvector.m_z*(1-cangle)+rvector.m_x*sangle rmatrix[2,2] = cangle+rvector.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_conformaljuliabox >= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_conformaljuliabox < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_conformaljuliabox < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_conformaljuliabox >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif ; vector folding dot = x*mx+y*my+z*mz x = x - 2*dot*mx y = y - 2*dot*my z = z - 2*dot*mz else zri = x + flip(y) zjk = z ; vector folding dot = x*mx+y*my+z*mz x = x - 2*dot*mx y = y - 2*dot*my z = z - 2*dot*mz if @use if (@v_conformaljuliabox < 103 || @arb) cangle = cos(@ang*#pi/180) sangle = sin(@ang*#pi/180) rmatrix[0,0] = cangle+rvector.m_x^2*(1-cangle) rmatrix[1,0] = rvector.m_x*rvector.m_y*(1-cangle)-rvector.m_z*sangle rmatrix[2,0] = rvector.m_x*rvector.m_z*(1-cangle)+rvector.m_y*sangle rmatrix[0,1] = rvector.m_x*rvector.m_y*(1-cangle)+rvector.m_z*sangle rmatrix[1,1] = cangle+rvector.m_y^2*(1-cangle) rmatrix[2,1] = rvector.m_y*rvector.m_z*(1-cangle)-rvector.m_x*sangle rmatrix[0,2] = rvector.m_x*rvector.m_z*(1-cangle)-rvector.m_y*sangle rmatrix[1,2] = rvector.m_y*rvector.m_z*(1-cangle)+rvector.m_x*sangle rmatrix[2,2] = cangle+rvector.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_conformaljuliabox >= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif if @v_conformaljuliabox < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_conformaljuliabox < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_conformaljuliabox >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif endif i = i + 1 until i == @count zri = x + flip(y) zjk = z zri = zri*scale + m_cri zjk = zjk*scale + m_cjk if @bscale defactor = defactor*scale endif spec = (cabs(zri) + cabs(zjk))/abs(defactor) endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) float x = real(zri) float y = imag(zri) float z = real(zjk) int i = 0 repeat if !@fold float derivx = 1 float derivy = 1 float derivz = 1 if @v_conformaljuliabox < 101 if x > 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif ; CtoV(zri,zjk,out) ; float dot = diagonal.dot(out) ; if dot > 1 derivx = 1 derivy = 1 derivz = 1 ; endif else float derivx = 1 float derivy = 1 float derivz = 1 ; CtoV(zri,zjk,out) ; float dot = diagonal.dot(out) ; if dot > 1 derivx = 1 derivy = 1 derivz = 1 ; endif if @v_conformaljuliabox < 101 if x > 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif endif i = i + 1 until i == @count derivx=derivx*scale derivy=derivy*scale derivz=derivz*scale derivx=derivx*real(zrid)+1 derivy=derivy*imag(zrid)+1 derivz=derivz*real(zjkd)+1 zrid = derivz + flip(derivy) zjkd = derivz endfunc protected: float scale float foldx float foldy float foldz Vector diagonal ; complex defactor float defactor Vector rvector Vector rvector2 float mx float my float mz float dot float rmatrix[3,3] float tempx float tempy float cangle float sangle default: title = "Conformal Julia" int param v_conformaljuliabox caption = "Version (Conformal Juliabox)" default = 103 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_conformaljuliabox < 103 endparam heading text = "Based upon the code of Tom Lowe presented on the FractalForum. A bailout \ value of 1024 is recomended along with a Starting \ Plane Z value of 10, an Ending Plane Z value of 20, and a Camera \ Origin Z value of 40." endheading bool param fold caption = "Alternate folding order" default = false endparam int param count caption = "Fold count" default = 2 endparam heading caption = "Julia Parameters" endheading complex param cri caption = "r-i plane" default = (1,1) endparam complex param cjk caption = "j-k plane" default = (1,0.0) endparam heading caption = "Confromal Parameters" endheading float param scale caption = "Scale" default = 3 endparam float param foldx caption = "X fold value" default = 2 endparam float param foldxlim caption = "X fold limit" default = 1 visible = @v_conformaljuliabox >= 101 endparam float param foldy caption = "Y fold value" default = 2 endparam float param foldylim caption = "Y fold limit" default = 1 visible = @v_conformaljuliabox >= 101 endparam bool param noz caption = "No Z folding" default = false endparam float param foldz caption = "Z fold value" default = 2 visible = !@noz endparam float param foldzlim caption = "Z fold limit" default = 1 visible = @v_conformaljuliabox >= 101 && !@noz endparam heading text = "X, Y and Z are components of a diagonal vector. The dot product of \ the normalized vector is taken with the vector formed from zri and \ zjk. The dot product values are then used to fold zri and zjk." endheading float param vx caption = "X" default = 1 endparam float param vy caption = "Y" default = 1 endparam float param vz caption = "Z" default = 1 endparam float param conv caption = "Convergence factor" default = 1 endparam heading text = "This should be used with the special potential only" endheading bool param bscale caption = "Include final scaling" default = false endparam heading caption = "Pre-fold" endheading bool param use caption = "Rotate around axis" default = false endparam float param xang caption = "X Rotation angle" default = 0.0 visible = @use && @v_conformaljuliabox >= 103 endparam float param yang caption = "Y Rotation angle" default = 0.0 visible = @use && @v_conformaljuliabox >= 103 endparam float param zang caption = "Z Rotation angle" default = 0.0 visible = @use && @v_conformaljuliabox >= 103 endparam bool param arb caption = "Arbitrary axis rotation" default = false visible = @use endparam float param ang caption = "Rotation angle" default = 0.0 visible = @use && (@v_conformaljuliabox < 103 || @arb) endparam heading text = "Rotation vector origin" visible = @use && (@v_conformaljuliabox < 103 || @arb) endheading float param ox caption ="Origin X" default = 0 visible = @use && (@v_conformaljuliabox < 103 || @arb) endparam float param oy caption ="Origin Y" default = 0 visible = @use && (@v_conformaljuliabox < 103 || @arb) endparam float param oz caption ="Origin Z" default = 0 visible = @use && (@v_conformaljuliabox < 103 || @arb) endparam heading text = "Rotation vector end" visible = @use && (@v_conformaljuliabox < 103 || @arb) endheading float param ex caption ="End X" default = 1 visible = @use && (@v_conformaljuliabox < 103 || @arb) endparam float param ey caption ="End Y" default = 1 visible = @use && (@v_conformaljuliabox < 103 || @arb) endparam float param ez caption ="End Z" default = 1 visible = @use && (@v_conformaljuliabox < 103 || @arb) endparam heading caption = "Post-fold" endheading bool param use2 caption = "Rotate around axis" default = false endparam float param xang2 caption = "X Rotation angle" default = 0.0 visible = @use2 && @v_conformaljuliabox >= 103 endparam float param yang2 caption = "Y Rotation angle" default = 0.0 visible = @use2 && @v_conformaljuliabox >= 103 endparam float param zang2 caption = "Z Rotation angle" default = 0.0 visible = @use2 && @v_conformaljuliabox >= 103 endparam bool param arb2 caption = "Arbitrary axis rotation" default = false visible = @use2 endparam float param ang2 caption = "Rotation angle" default = 0.0 visible = @use2 && (@v_conformaljuliabox < 103 || @arb2) endparam heading text = "Rotation vector origin" visible = @use2 && (@v_conformaljuliabox < 103 || @arb2) endheading float param ox2 caption ="Origin X" default = 0 visible = @use2 && (@v_conformaljuliabox < 103 || @arb2) endparam float param oy2 caption ="Origin Y" default = 0 visible = @use2 && (@v_conformaljuliabox < 103 || @arb2) endparam float param oz2 caption ="Origin Z" default = 0 visible = @use2 && (@v_conformaljuliabox < 103 || @arb2) endparam heading text = "Rotation vector end" visible = @use2 && (@v_conformaljuliabox < 103 || @arb2) endheading float param ex2 caption ="End X" default = 1 visible = @use2 && (@v_conformaljuliabox < 103 || @arb2) endparam float param ey2 caption ="End Y" default = 1 visible = @use2 && (@v_conformaljuliabox < 103 || @arb2) endparam float param ez2 caption ="End Z" default = 1 visible = @use2 && (@v_conformaljuliabox < 103 || @arb2) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam } class AmazingFractalJulia(Quat) { ; As presented by Tom Lowe on FractalForum public: import "common.ulb" ; constructor func AmazingFractalJulia(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = false m_sphere = true m_fourth = @fourth m_ck = @ck scale = @scale rad = @rad minrad = @minrad foldx = @foldx foldy = @foldy foldz = @foldz if (@v_mandelboxjulia < 103 || @arb) rvector = new Vector(-@ex+@ox,-@ey+@oy,-@ez+@oz,0) rvector.Normalize(rvector) endif if (@v_mandelboxjulia < 103 || @arb2) rvector2 = new Vector(-@ex2+@ox2,-@ey2+@oy2,-@ez2+@oz2,0) rvector2.Normalize(rvector2) endif endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) int i = 0 repeat defactor = scale*@conv if !@fold float x = real(zri) float y = imag(zri) float z = real(zjk) if @use if (@v_mandelboxjulia < 103 || @arb) cangle = cos(@ang*#pi/180) sangle = sin(@ang*#pi/180) rmatrix[0,0] = cangle+rvector.m_x^2*(1-cangle) rmatrix[1,0] = rvector.m_x*rvector.m_y*(1-cangle)-rvector.m_z*sangle rmatrix[2,0] = rvector.m_x*rvector.m_z*(1-cangle)+rvector.m_y*sangle rmatrix[0,1] = rvector.m_x*rvector.m_y*(1-cangle)+rvector.m_z*sangle rmatrix[1,1] = cangle+rvector.m_y^2*(1-cangle) rmatrix[2,1] = rvector.m_y*rvector.m_z*(1-cangle)-rvector.m_x*sangle rmatrix[0,2] = rvector.m_x*rvector.m_z*(1-cangle)-rvector.m_y*sangle rmatrix[1,2] = rvector.m_y*rvector.m_z*(1-cangle)+rvector.m_x*sangle rmatrix[2,2] = cangle+rvector.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_mandelboxjulia >= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif ; fold box onto itself if @v_mandelboxjulia < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if !@noz if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif endif if @use2 if (@v_mandelboxjulia < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_mandelboxjulia >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif zri = x + flip(y) zjk = z ; fold sphere onto itself if @v_mandelboxjulia >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 103 if @xang != 0 cangle = cos(@xang*#pi/180) sangle = sin(@xang*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang != 0 cangle = cos(@yang*#pi/180) sangle = sin(@yang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang != 0 cangle = cos(@zang*#pi/180) sangle = sin(@zang*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif ; fold box onto itself if @v_mandelboxjulia < 101 ; fold box onto itself if (x > 1) x = foldx - x elseif (x < -1) x = -foldx - x endif if (y > 1) y = foldy - y elseif (y < -1) y = -foldy - y endif if (z > 1) z = foldz - z elseif (z < -1) z = -foldz - z endif else if (x > @foldxlim) x = foldx - x elseif (x < -@foldxlim) x = -foldx - x endif if (y > @foldylim) y = foldy - y elseif (y < -@foldylim) y = -foldy - y endif if (z > @foldzlim) z = foldz - z elseif (z < -@foldzlim) z = -foldz - z endif endif if @use2 if (@v_mandelboxjulia < 103 || @arb2) cangle = cos(@ang2*#pi/180) sangle = sin(@ang2*#pi/180) rmatrix[0,0] = cangle+rvector2.m_x^2*(1-cangle) rmatrix[1,0] = rvector2.m_x*rvector2.m_y*(1-cangle)-rvector2.m_z*sangle rmatrix[2,0] = rvector2.m_x*rvector2.m_z*(1-cangle)+rvector2.m_y*sangle rmatrix[0,1] = rvector2.m_x*rvector2.m_y*(1-cangle)+rvector2.m_z*sangle rmatrix[1,1] = cangle+rvector2.m_y^2*(1-cangle) rmatrix[2,1] = rvector2.m_y*rvector2.m_z*(1-cangle)-rvector2.m_x*sangle rmatrix[0,2] = rvector2.m_x*rvector2.m_z*(1-cangle)-rvector2.m_y*sangle rmatrix[1,2] = rvector2.m_y*rvector2.m_z*(1-cangle)+rvector2.m_x*sangle rmatrix[2,2] = cangle+rvector2.m_z^2*(1-cangle) tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @v_mandelboxjulia >= 103 if @xang2 != 0 cangle = cos(@xang2*#pi/180) sangle = sin(@xang2*#pi/180) rmatrix[0,0] = 1 rmatrix[1,0] = 0 rmatrix[2,0] = 0 rmatrix[0,1] = 0 rmatrix[1,1] = cangle rmatrix[2,1] = -sangle rmatrix[0,2] = 0 rmatrix[1,2] = sangle rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @yang2 != 0 cangle = cos(@yang2*#pi/180) sangle = sin(@yang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = 0 rmatrix[2,0] = sangle rmatrix[0,1] = 0 rmatrix[1,1] = 1 rmatrix[2,1] = 0 rmatrix[0,2] = -sangle rmatrix[1,2] = 0 rmatrix[2,2] = cangle tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif if @zang2 != 0 cangle = cos(@zang2*#pi/180) sangle = sin(@zang2*#pi/180) rmatrix[0,0] = cangle rmatrix[1,0] = -sangle rmatrix[2,0] = 0 rmatrix[0,1] = sangle rmatrix[1,1] = cangle rmatrix[2,1] = 0 rmatrix[0,2] = 0 rmatrix[1,2] = 0 rmatrix[2,2] = 1 tempx = x tempy = y x = rmatrix[0,0]*x + rmatrix[1,0]*y + rmatrix[2,0]*z y = rmatrix[0,1]*tempx + rmatrix[1,1]*y + rmatrix[2,1]*z z = rmatrix[0,2]*tempx + rmatrix[1,2]*tempy + rmatrix[2,2]*z endif endif endif zri = x + flip(y) zjk = z endif i = i + 1 until i == @count zri = zri*scale + m_cri zjk = zjk*scale + m_cjk if @bscale defactor = defactor*scale endif spec = (cabs(zri) + cabs(zjk))/abs(defactor) endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) int i = 0 repeat if !@fold float x = real(zri) float y = imag(zri) float z = real(zjk) float derivx = 1 float derivy = 1 float derivz = 1 if @v_mandelboxjulia < 101 if x > 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif if @v_mandelboxjulia >= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length= 102 float length = (|zri| + |zjk|)^(0.5*@spower) if length 1 || x < -1 derivx=-1 else derivx=1 endif if y > 1|| y < -1 derivy=-1 else derivy=1 endif if z > 1 || z < -1 derivz=-1 else derivz=1 endif else if x > @foldxlim || x < -@foldxlim derivx=-1 else derivx=1 endif if y > @foldylim|| y < -@foldylim derivy=-1 else derivy=1 endif if !@noz if z > @foldzlim || z < -@foldzlim derivz=-1 else derivz=1 endif endif endif endif i = i + 1 until i == @count derivx=derivx*scale derivy=derivy*scale derivz=derivz*scale derivx=derivx*real(zrid)+1 derivy=derivy*imag(zrid)+1 derivz=derivz*real(zjkd)+1 zrid = derivz + flip(derivy) zjkd = derivz endfunc protected: float scale float rad float minrad float foldx float foldy float foldz complex defactor Vector rvector Vector rvector2 float rmatrix[3,3] float tempx float tempy float cangle float sangle default: title = "Amazing Fractal (Julia)" heading text = "Based upon the code of Tom Lowe presented on the FractalForum. A bailout \ value of 1024 is recomended along with a Staring Plane Z value of 10, \ and Ending Plane Z value of 20 and a Camera Origin Z value of 40." endheading int param v_mandelboxjulia caption = "Version (Mandelbox Julia)" default = 103 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_mandelboxjulia < 103 endparam bool param fold caption = "Alternate folding order" default = false endparam heading caption = "Julia Parameters" endheading complex param cri caption = "r-i plane" default = (2,-2) endparam complex param cjk caption = "j-k plane" default = (-2,0.0) endparam heading caption = "Fractal Parameters" endheading int param count caption = "Fold count" default = 1 endparam float param scale caption = "Scale" default = 3 endparam float param rad caption = "Fixed Radius" default = 1 endparam float param minrad caption = "Minimum Radius" default = 0.5 endparam float param spower caption = "Spherical power" default = 2 visible = @v_mandelboxjulia >= 102 endparam float param foldx caption = "X fold value" default = 2 endparam float param foldxlim caption = "X fold limit" default = 1 visible = @v_mandelboxjulia >= 101 endparam float param foldy caption = "Y fold value" default = 2 endparam float param foldylim caption = "Y fold limit" default = 1 visible = @v_mandelboxjulia >= 101 endparam bool param noz caption = "No Z folding" default = false endparam float param foldz caption = "Z fold value" default = 2 visible = !@noz endparam float param foldzlim caption = "Z fold limit" default = 1 visible = @v_mandelboxjulia >= 101 && !@noz endparam float param conv caption = "Convergence factor" default = 1 endparam heading text = "This should be used with the special potential only. It is not used \ in calculations for other potential methods." endheading bool param bscale caption = "Include final scaling" default = false endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam heading caption = "Pre-fold" endheading bool param use caption = "Rotate around axis" default = false endparam float param xang caption = "X Rotation angle" default = 0.0 visible = @use && @v_mandelboxjulia >= 103 endparam float param yang caption = "Y Rotation angle" default = 0.0 visible = @use && @v_mandelboxjulia >= 103 endparam float param zang caption = "Z Rotation angle" default = 0.0 visible = @use && @v_mandelboxjulia >= 103 endparam bool param arb caption = "Arbitrary axis rotation" default = false visible = @use endparam float param ang caption = "Rotation angle" default = 0.0 visible = @use && (@v_mandelboxjulia < 103 || @arb) endparam heading text = "Rotation vector origin" visible = @use && (@v_mandelboxjulia < 103 || @arb) endheading float param ox caption ="Origin X" default = 0 visible = @use && (@v_mandelboxjulia < 103 || @arb) endparam float param oy caption ="Origin Y" default = 0 visible = @use && (@v_mandelboxjulia < 103 || @arb) endparam float param oz caption ="Origin Z" default = 0 visible = @use && (@v_mandelboxjulia < 103 || @arb) endparam heading text = "Rotation vector end" visible = @use && (@v_mandelboxjulia < 103 || @arb) endheading float param ex caption ="End X" default = 1 visible = @use && (@v_mandelboxjulia < 103 || @arb) endparam float param ey caption ="End Y" default = 1 visible = @use && (@v_mandelboxjulia < 103 || @arb) endparam float param ez caption ="End Z" default = 1 visible = @use && (@v_mandelboxjulia < 103 || @arb) endparam heading caption = "Post-fold" endheading bool param use2 caption = "Rotate around axis" default = false endparam float param xang2 caption = "X Rotation angle" default = 0.0 visible = @use2 && @v_mandelboxjulia >= 103 endparam float param yang2 caption = "Y Rotation angle" default = 0.0 visible = @use2 && @v_mandelboxjulia >= 103 endparam float param zang2 caption = "Z Rotation angle" default = 0.0 visible = @use2 && @v_mandelboxjulia >= 103 endparam bool param arb2 caption = "Arbitrary axis rotation" default = false visible = @use endparam float param ang2 caption = "Rotation angle" default = 0.0 visible = @use2 && (@v_mandelboxjulia < 103 || @arb2) endparam heading text = "Rotation vector origin" visible = @use2 && (@v_mandelboxjulia < 103 || @arb2) endheading float param ox2 caption ="Origin X" default = 0 visible = @use2 && (@v_mandelboxjulia < 103 || @arb2) endparam float param oy2 caption ="Origin Y" default = 0 visible = @use2 && (@v_mandelboxjulia < 103 || @arb2) endparam float param oz2 caption ="Origin Z" default = 0 visible = @use2 && (@v_mandelboxjulia < 103 || @arb2) endparam heading text = "Rotation vector end" visible = @use2 && (@v_mandelboxjulia < 103 || @arb2) endheading float param ex2 caption ="End X" default = 1 visible = @use2 && (@v_mandelboxjulia < 103 || @arb2) endparam float param ey2 caption ="End Y" default = 1 visible = @use2 && (@v_mandelboxjulia < 103 || @arb2) endparam float param ez2 caption ="End Z" default = 1 visible = @use2 && (@v_mandelboxjulia < 103 || @arb2) endparam } class JuliaSphere(Quat) { public: import "common.ulb" ; constructor func JuliaSphere(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = false m_sphere = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) if !@altpower MD.Spower(@quadcor,@altel,@power,in,out,@pfactor,@flagtype) else MD.Spower2(@power,in,out) endif VtoC(zri,zjk,out) zri = zri + m_cri zjk = zjk + m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) MD.Spower(@quadcor,@altel,@power-1,in,out,@pfactor,@flagtype) MD.SMult(@quadcor,@altel,out,ind,cin,@pfactor,@flagtype) VtoC(zrid,zjkd,cin) zrid = @power*zrid zjkd = @power*zjkd endfunc default: title = "JuliaBulb" int param v_juliasphere caption = "Version (Julia sphere)" 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_juliasphere < 100 endparam heading text = "Uses 3D spherical coordinates in analogy to 2D polar coordinates for \ complex numbers. Over 50 variants of triplex algebra are available, \ including the original White/Nylander version and many more described \ on Jason's Softology website \ (http://softology.com.au/gallery/ \ gallerymandelbulb.htm). Many are based upon the the formulas of Tad \ Boniecki." endheading heading text = "s = x + i*y + j*z expressed as complex spherical coordinates." endheading heading caption = "Julia Parameters" endheading complex param cri caption = "r-i plane" default = (-0.75,0.25) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam float param power caption = "Julia Power" default = 2 endparam param flagtype caption = "Bulb types" enum = "Original" "Positive Z" "Cosine" "Rucker" "Reversed" "Reversed +Z"\ "Msltoe" "IQ" "Negative IQ" "XpYp3" "XpZp2" "XpYn1" "XnYp1" "XpYn3"\ "XnYp3" "XnYn3" "YpXp3" "YpXn2" "YnXp2" "YpXn3" "YnXp3" "YnXn3"\ "ZpXp3" "ZpXn2" "ZnXp2" "ZpXn3" "ZnXp3" "ZnXn3" "XpZn1" "XnZp1"\ "XpZn2" "XnZp2" "XnZn2" "YpZp2" "YpZn1" "YnZp1" "YpZn2" "YnZp2"\ "YnZn2" "ZnYp1" "ZnYn1" "ZnYp3" "Tad 20" "Tad 28" "Tad 29" "Tad 34"\ "Tad 50" "Tad 61" "Tad 84" "Tad 85" "Tad 86" "Tad 87" "Tad 52"\ "Tad 53" "Tad 93" "Tad 95" "Tad 98" "Tad 114" "Tad 116" "Tad 117"\ "Tad 122" "Tad 123" "Tad 124" "Tad 125" "Tad 176" "Tad 177"\ "Tad 180" "Tad 185" "Tad 240" "Tad 241" "Tad 244" "Tad 245"\ "Tad 248" "Tad 249" "Tad 252" "Tad 253" "Tad 270" "Tad 272"\ "Tad 304" "Tad 305" "Tad 306" "Tad 322" "Tad 342" "Tad 345"\ "Tad 368" "Tad 369" "Tad 377" "Tad 378" "Tad 412" "Tad 413"\ "Tad 464" "Tad 465" "Tad 468" "Tad 469" "Tad 473" default = 0 visible = !@altpower endparam bool param altpower caption = "Alt power function" default = false visible = @flagtype == 0 || @flagtype == 1 endparam float param pfactor caption = "Azimuth Factor" default = 1.0 visible = !@altpower endparam heading caption = "Alternate settings" visible = !@altpower && !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "The following two check boxes are alternatives to the standard \ Mandelbulb equations. They are included as they can give some \ interesting results." visible = !@altpower && !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "'alternate elevation' reverses the sign of the elevation." visible = !@altpower && !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param altel caption = "alternate elevation" default = false visible = !@altpower && !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam heading text = "'Range correction' insures that the elevation is in the range -pi/2 to pi/2 \ after all applications of the power and multiply functions." visible = !@altpower && !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param quadcor caption = "range correction" default = false visible = !@altpower && !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam } class IkenagaPowerJuliaBulb(Quat) { public: import "common.ulb" ; constructor func IkenagaPowerJuliaBulb(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = false m_sphere = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) CtoV(m_cri-1,m_cjk,cin) MD.SMult(@quadcor,@altel,cin,in,cout,@pfactor,@flagtype) VtoC(a,b,cout) MD.SPower(@quadcor,@altel,@power,in,out,@pfactor,@flagtype) VtoC(zri,zjk,out) zri = zri + a - m_cri zjk = zjk + b - m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) MD.SPower(@quadcor,@altel,@power-1,in,out,@pfactor,@flagtype) VtoC(zri,zjk,out) zri = @power*zri + m_cri - 1 zjk = @power*zjk + m_cjk CtoV(zri,zjk,in) MD.SMult(@quadcor,@altel,in,ind,outd,@pfactor,@flagtype) VtoC(zrid,zjkd,outd) zrid = zrid + 1 endfunc protected: complex a complex b default: title = "Ikenaga Power JuliaBulb" int param v_IkenagaPowerJuliaBulb caption = "Version (Ikenaga Power JuliaBulb)" 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_IkenagaPowerJuliaBulb < 100 endparam heading text = "Uses 3D spherical coordinates in analogy to 2D polar coordinates for \ complex numbers. Over 50 variants of triplex algebra are available, \ including the original White/Nylander version and many more described \ on Jason's Softology website \ (http://softology.com.au/gallery/ \ gallerymandelbulb.htm). Many are based upon the the formulas of Tad \ Boniecki." endheading heading text = "s = x + i*y + j*z expressed as complex spherical coordinates." endheading heading caption = "Julia Parameters" endheading complex param cri caption = "r-i plane" default = (-0.052050781224,0.12021484396) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam float param power caption = "Ikenaga Julia Power" default = 8 endparam param flagtype caption = "Bulb types" enum = "Original" "Positive Z" "Cosine" "Rucker" "Reversed" "Reversed +Z"\ "Msltoe" "IQ" "Negative IQ" "XpYp3" "XpZp2" "XpYn1" "XnYp1" "XpYn3"\ "XnYp3" "XnYn3" "YpXp3" "YpXn2" "YnXp2" "YpXn3" "YnXp3" "YnXn3"\ "ZpXp3" "ZpXn2" "ZnXp2" "ZpXn3" "ZnXp3" "ZnXn3" "XpZn1" "XnZp1"\ "XpZn2" "XnZp2" "XnZn2" "YpZp2" "YpZn1" "YnZp1" "YpZn2" "YnZp2"\ "YnZn2" "ZnYp1" "ZnYn1" "ZnYp3" "Tad 20" "Tad 28" "Tad 29" "Tad 34"\ "Tad 50" "Tad 61" "Tad 84" "Tad 85" "Tad 86" "Tad 87" "Tad 52"\ "Tad 53" "Tad 93" "Tad 95" "Tad 98" "Tad 114" "Tad 116" "Tad 117"\ "Tad 122" "Tad 123" "Tad 124" "Tad 125" "Tad 176" "Tad 177"\ "Tad 180" "Tad 185" "Tad 240" "Tad 241" "Tad 244" "Tad 245"\ "Tad 248" "Tad 249" "Tad 252" "Tad 253" "Tad 270" "Tad 272"\ "Tad 304" "Tad 305" "Tad 306" "Tad 322" "Tad 342" "Tad 345"\ "Tad 368" "Tad 369" "Tad 377" "Tad 378" "Tad 412" "Tad 413"\ "Tad 464" "Tad 465" "Tad 468" "Tad 469" "Tad 473" default = 0 endparam float param pfactor caption = "Azimuth Factor" default = 1.0 endparam heading caption = "Alternate settings" visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "The following two check boxes are alternatives to the standard \ Mandelbulb equations. They are included as they can give some \ interesting results." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "'alternate elevation' reverses the sign of the elevation." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param altel caption = "alternate elevation" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam heading text = "'Range correction' insures that the elevation is in the range -pi/2 to pi/2 \ after all applications of the power and multiply functions." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param quadcor caption = "range correction" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam } class IkenagaPowerMandelBulb(Quat) { public: import "common.ulb" ; constructor func IkenagaPowerMandelBulb(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = false m_sphere = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) CtoV(m_cri-1,m_cjk,cin) MD.SMult(@quadcor,@altel,cin,in,cout,@pfactor,@flagtype) VtoC(a,b,cout) MD.SPower(@quadcor,@altel,@power,in,out,@pfactor,@flagtype) VtoC(zri,zjk,out) zri = zri + a - m_cri zjk = zjk + b - m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) MD.SPower(@quadcor,@altel,@power-1,in,out,@pfactor,@flagtype) VtoC(zri,zjk,out) zri = @power*zri + m_cri - 1 zjk = @power*zjk + m_cjk CtoV(zri,zjk,in) MD.SMult(@quadcor,@altel,in,ind,outd,@pfactor,@flagtype) VtoC(zrid,zjkd,outd) zrid = zrid + 1 endfunc protected: complex a complex b default: title = "Ikenaga Power MandelBulb" int param v_IkenagaPowerMandelBulb caption = "Version (Ikenaga Power MandelBulb)" 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_IkenagaPowerMandelBulb < 100 endparam heading text = "Uses 3D spherical coordinates in analogy to 2D polar coordinates for \ complex numbers. Over 50 variants of triplex algebra are available, \ including the original White/Nylander version and many more described \ on Jason's Softology website \ (http://softology.com.au/gallery/ \ gallerymandelbulb.htm). Many are based upon the the formulas of Tad \ Boniecki." endheading heading text = "s = x + i*y + j*z expressed as complex spherical coordinates." endheading heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." visible = false endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam float param power caption = "Ikenaga Mandel Power" default = 8 endparam param flagtype caption = "Bulb types" enum = "Original" "Positive Z" "Cosine" "Rucker" "Reversed" "Reversed +Z"\ "Msltoe" "IQ" "Negative IQ" "XpYp3" "XpZp2" "XpYn1" "XnYp1" "XpYn3"\ "XnYp3" "XnYn3" "YpXp3" "YpXn2" "YnXp2" "YpXn3" "YnXp3" "YnXn3"\ "ZpXp3" "ZpXn2" "ZnXp2" "ZpXn3" "ZnXp3" "ZnXn3" "XpZn1" "XnZp1"\ "XpZn2" "XnZp2" "XnZn2" "YpZp2" "YpZn1" "YnZp1" "YpZn2" "YnZp2"\ "YnZn2" "ZnYp1" "ZnYn1" "ZnYp3" "Tad 20" "Tad 28" "Tad 29" "Tad 34"\ "Tad 50" "Tad 61" "Tad 84" "Tad 85" "Tad 86" "Tad 87" "Tad 52"\ "Tad 53" "Tad 93" "Tad 95" "Tad 98" "Tad 114" "Tad 116" "Tad 117"\ "Tad 122" "Tad 123" "Tad 124" "Tad 125" "Tad 176" "Tad 177"\ "Tad 180" "Tad 185" "Tad 240" "Tad 241" "Tad 244" "Tad 245"\ "Tad 248" "Tad 249" "Tad 252" "Tad 253" "Tad 270" "Tad 272"\ "Tad 304" "Tad 305" "Tad 306" "Tad 322" "Tad 342" "Tad 345"\ "Tad 368" "Tad 369" "Tad 377" "Tad 378" "Tad 412" "Tad 413"\ "Tad 464" "Tad 465" "Tad 468" "Tad 469" "Tad 473" default = 0 endparam float param pfactor caption = "Azimuth Factor" default = 1.0 endparam heading caption = "Alternate settings" visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "The following two check boxes are alternatives to the standard \ Mandelbulb equations. They are included as they can give some \ interesting results." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "'alternate elevation' reverses the sign of the elevation." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param altel caption = "alternate elevation" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam heading text = "'Range correction' insures that the elevation is in the range -pi/2 to pi/2 \ after all applications of the power and multiply functions." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param quadcor caption = "range correction" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam } class FrameRobertPowerJuliaBulb(Quat) { public: import "common.ulb" ; constructor func FrameRobertPowerJuliaBulb(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = false m_sphere = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) MD.SPower(@quadcor,@altel,@power,in,out,@pfactor,@flagtype) VtoC(a,b,out) MD.SPower(@quadcor,@altel,2,in,out,@pfactor,@flagtype) VtoC(zri,zjk,out) zri = zri + a/5 + m_cri zjk = zjk + b/5 + m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) MD.SPower(@quadcor,@altel,@power-1,in,out,@pfactor,@flagtype) VtoC(a,b,out) zri = @power*a/5 + 2*zri zjk = @power*b/5 + 2*zjk CtoV(zri,zjk,in) MD.SMult(@quadcor,@altel,in,ind,outd,@pfactor,@flagtype) VtoC(zrid,zjkd,outd) zrid = zrid + 1 endfunc protected: complex a complex b default: title = "FrameRobert Power JuliaBulb" int param v_FramRobertPowerJuliaBulb caption = "Version (FramRobert Power JuliaBulb)" 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_FramRobertPowerJuliaBulb < 100 endparam heading text = "Uses 3D spherical coordinates in analogy to 2D polar coordinates for \ complex numbers. Over 50 variants of triplex algebra are available, \ including the original White/Nylander version and many more described \ on Jason's Softology website \ (http://softology.com.au/gallery/ \ gallerymandelbulb.htm). Many are based upon the the formulas of Tad \ Boniecki." endheading heading text = "s = x + i*y + j*z expressed as complex spherical coordinates." endheading heading caption = "Julia Parameters" endheading complex param cri caption = "r-i plane" default = (0.30625,0) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam float param power caption = "FrameRobert Julia Power" default = 8 endparam param flagtype caption = "Bulb types" enum = "Original" "Positive Z" "Cosine" "Rucker" "Reversed" "Reversed +Z"\ "Msltoe" "IQ" "Negative IQ" "XpYp3" "XpZp2" "XpYn1" "XnYp1" "XpYn3"\ "XnYp3" "XnYn3" "YpXp3" "YpXn2" "YnXp2" "YpXn3" "YnXp3" "YnXn3"\ "ZpXp3" "ZpXn2" "ZnXp2" "ZpXn3" "ZnXp3" "ZnXn3" "XpZn1" "XnZp1"\ "XpZn2" "XnZp2" "XnZn2" "YpZp2" "YpZn1" "YnZp1" "YpZn2" "YnZp2"\ "YnZn2" "ZnYp1" "ZnYn1" "ZnYp3" "Tad 20" "Tad 28" "Tad 29" "Tad 34"\ "Tad 50" "Tad 61" "Tad 84" "Tad 85" "Tad 86" "Tad 87" "Tad 52"\ "Tad 53" "Tad 93" "Tad 95" "Tad 98" "Tad 114" "Tad 116" "Tad 117"\ "Tad 122" "Tad 123" "Tad 124" "Tad 125" "Tad 176" "Tad 177"\ "Tad 180" "Tad 185" "Tad 240" "Tad 241" "Tad 244" "Tad 245"\ "Tad 248" "Tad 249" "Tad 252" "Tad 253" "Tad 270" "Tad 272"\ "Tad 304" "Tad 305" "Tad 306" "Tad 322" "Tad 342" "Tad 345"\ "Tad 368" "Tad 369" "Tad 377" "Tad 378" "Tad 412" "Tad 413"\ "Tad 464" "Tad 465" "Tad 468" "Tad 469" "Tad 473" default = 0 endparam float param pfactor caption = "Azimuth Factor" default = 1.0 endparam heading caption = "Alternate settings" visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "The following two check boxes are alternatives to the standard \ Mandelbulb equations. They are included as they can give some \ interesting results." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "'alternate elevation' reverses the sign of the elevation." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param altel caption = "alternate elevation" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam heading text = "'Range correction' insures that the elevation is in the range -pi/2 to pi/2 \ after all applications of the power and multiply functions." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param quadcor caption = "range correction" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam } class FrameRobertPowerMandelBulb(Quat) { public: import "common.ulb" ; constructor func FrameRobertPowerMandelBulb(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = false m_sphere = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) MD.SPower(@quadcor,@altel,@power,in,out,@pfactor,@flagtype) VtoC(a,b,out) MD.SPower(@quadcor,@altel,2,in,out,@pfactor,@flagtype) VtoC(zri,zjk,out) zri = zri + a/5 + m_cri zjk = zjk + b/5 + m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) MD.SPower(@quadcor,@altel,@power-1,in,out,@pfactor,@flagtype) VtoC(a,b,out) zri = @power*a/5 + 2*zri zjk = @power*b/5 + 2*zjk CtoV(zri,zjk,in) MD.SMult(@quadcor,@altel,in,ind,outd,@pfactor,@flagtype) VtoC(zrid,zjkd,outd) zrid = zrid + 1 endfunc protected: complex a complex b default: title = "FrameRobert Power MandelBulb" int param v_FramRobertPowerMandelBulb caption = "Version (FramRobert Power MandelBulb)" 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_FramRobertPowerMandelBulb < 100 endparam heading text = "Uses 3D spherical coordinates in analogy to 2D polar coordinates for \ complex numbers. Over 50 variants of triplex algebra are available, \ including the original White/Nylander version and many more described \ on Jason's Softology website \ (http://softology.com.au/gallery/ \ gallerymandelbulb.htm). Many are based upon the the formulas of Tad \ Boniecki." endheading heading text = "s = x + i*y + j*z expressed as complex spherical coordinates." endheading heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." visible = false endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam float param power caption = "FrameRobert Mandel Power" default = 8 endparam param flagtype caption = "Bulb types" enum = "Original" "Positive Z" "Cosine" "Rucker" "Reversed" "Reversed +Z"\ "Msltoe" "IQ" "Negative IQ" "XpYp3" "XpZp2" "XpYn1" "XnYp1" "XpYn3"\ "XnYp3" "XnYn3" "YpXp3" "YpXn2" "YnXp2" "YpXn3" "YnXp3" "YnXn3"\ "ZpXp3" "ZpXn2" "ZnXp2" "ZpXn3" "ZnXp3" "ZnXn3" "XpZn1" "XnZp1"\ "XpZn2" "XnZp2" "XnZn2" "YpZp2" "YpZn1" "YnZp1" "YpZn2" "YnZp2"\ "YnZn2" "ZnYp1" "ZnYn1" "ZnYp3" "Tad 20" "Tad 28" "Tad 29" "Tad 34"\ "Tad 50" "Tad 61" "Tad 84" "Tad 85" "Tad 86" "Tad 87" "Tad 52"\ "Tad 53" "Tad 93" "Tad 95" "Tad 98" "Tad 114" "Tad 116" "Tad 117"\ "Tad 122" "Tad 123" "Tad 124" "Tad 125" "Tad 176" "Tad 177"\ "Tad 180" "Tad 185" "Tad 240" "Tad 241" "Tad 244" "Tad 245"\ "Tad 248" "Tad 249" "Tad 252" "Tad 253" "Tad 270" "Tad 272"\ "Tad 304" "Tad 305" "Tad 306" "Tad 322" "Tad 342" "Tad 345"\ "Tad 368" "Tad 369" "Tad 377" "Tad 378" "Tad 412" "Tad 413"\ "Tad 464" "Tad 465" "Tad 468" "Tad 469" "Tad 473" default = 0 endparam float param pfactor caption = "Azimuth Factor" default = 1.0 endparam heading caption = "Alternate settings" visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "The following two check boxes are alternatives to the standard \ Mandelbulb equations. They are included as they can give some \ interesting results." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "'alternate elevation' reverses the sign of the elevation." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param altel caption = "alternate elevation" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam heading text = "'Range correction' insures that the elevation is in the range -pi/2 to pi/2 \ after all applications of the power and multiply functions." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param quadcor caption = "range correction" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam } class MandelSphere(Quat) { ; Uses spherical coordinates in analogy to polar coordinates for complex numbers public: import "common.ulb" ; constructor func MandelSphere(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = false m_sphere = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) if !@altpower MD.Spower(@quadcor,@altel,@power,in,out,@pfactor,@flagtype) else MD.Spower2(@power,in,out) endif VtoC(zri,zjk,out) zri = zri + m_cri zjk = zjk + m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) MD.Spower(@quadcor,@altel,@power-1,in,out,@pfactor,@flagtype) MD.SMult(@quadcor,@altel,out,ind,cin,@pfactor,@flagtype) VtoC(zrid,zjkd,cin) zrid = @power*zrid + 1 zjkd = @power*zjkd endfunc default: title = "Mandelbulb" heading text = "Uses 3D spherical coordinates in analogy to 2D polar coordinates for \ complex numbers. Over 90 variants of triplex algebra are available, \ including the original White/Nylander version and many more described \ on Jason's Softology website \ (http://softology.com.au/gallery/ \ gallerymandelbulb.htm). Many are based upon the the formulas of Tad \ Boniecki." endheading heading text = "s = x + i*y + j*z expressed as complex spherical coordinates." endheading int param v_mandelbulb caption = "Version (Mandelbulb)" 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_mandelbulb < 100 endparam heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." visible = false endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam float param power caption = "Mandel Power" default = 8 endparam param flagtype caption = "Bulb types" enum = "Original" "Positive Z" "Cosine" "Rucker" "Reversed" "Reversed +Z"\ "Msltoe" "IQ" "Negative IQ" "XpYp3" "XpZp2" "XpYn1" "XnYp1" "XpYn3"\ "XnYp3" "XnYn3" "YpXp3" "YpXn2" "YnXp2" "YpXn3" "YnXp3" "YnXn3"\ "ZpXp3" "ZpXn2" "ZnXp2" "ZpXn3" "ZnXp3" "ZnXn3" "XpZn1" "XnZp1"\ "XpZn2" "XnZp2" "XnZn2" "YpZp2" "YpZn1" "YnZp1" "YpZn2" "YnZp2"\ "YnZn2" "ZnYp1" "ZnYn1" "ZnYp3" "Tad 20" "Tad 28" "Tad 29" "Tad 34"\ "Tad 50" "Tad 61" "Tad 84" "Tad 85" "Tad 86" "Tad 87" "Tad 52"\ "Tad 53" "Tad 93" "Tad 95" "Tad 98" "Tad 114" "Tad 116" "Tad 117"\ "Tad 122" "Tad 123" "Tad 124" "Tad 125" "Tad 176" "Tad 177"\ "Tad 180" "Tad 185" "Tad 240" "Tad 241" "Tad 244" "Tad 245"\ "Tad 248" "Tad 249" "Tad 252" "Tad 253" "Tad 270" "Tad 272"\ "Tad 304" "Tad 305" "Tad 306" "Tad 322" "Tad 342" "Tad 345"\ "Tad 368" "Tad 369" "Tad 377" "Tad 378" "Tad 412" "Tad 413"\ "Tad 464" "Tad 465" "Tad 468" "Tad 469" "Tad 473" default = 0 visible = !@altpower endparam bool param altpower caption = "Alt power function" default = false visible = @flagtype == 0 || @flagtype == 1 endparam float param pfactor caption = "Azimuth Factor" default = 1.0 visible = !@altpower endparam heading caption = "Alternate settings" visible = !@altpower && !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "The following two check boxes are alternatives to the standard \ Mandelbulb equations. They are included as they can give some \ interesting results." visible = !@altpower && !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "'alternate elevation' reverses the sign of the elevation." visible = !@altpower && !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param altel caption = "alternate elevation" default = false visible = !@altpower && !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam heading text = "'Range correction' insures that the elevation is in the range -pi/2 to pi/2 \ after all applications of the power and multiply functions." visible = !@altpower && !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param quadcor caption = "range correction" default = false visible = !@altpower && !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam } class LambdaBulb(Quat) { ; Uses spherical coordinates in analogy to polar coordinates for complex numbers public: import "common.ulb" ; constructor func LambdaBulb(Generic pparent) Quat.Quat(pparent) m_cri = @cri m_cjk = @cjk m_julia = true m_quat = false m_sphere = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) complex r = zri complex j = zjk CtoV(zri,zjk,in) MD.Spower(@quadcor,@altel,@power,in,out,@pfactor,@flagtype) VtoC(zri,zjk,out) zri = r-zri zjk = j-zjk CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) MD.SMult(@quadcor,@altel,cin,in,out,@pfactor,@flagtype) VtoC(zri,zjk,out) endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) MD.Spower(@quadcor,@altel,@power-1,in,out,@pfactor,@flagtype) VtoC(zri,zjk,out) zri = 1-@power*zri zjk = -@power*zjk CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) MD.SMult(@quadcor,@altel,cin,in,out,@pfactor,@flagtype) CtoV(zrid,zjkd,ind) MD.SMult(@quadcor,@altel,ind,out,cin,@pfactor,@flagtype) VtoC(zrid,zjkd,cin) endfunc default: title = "Lambda Bulb" heading text = "Uses 3D spherical coordinates in analogy to 2D polar coordinates for \ complex numbers. Over 50 variants of triplex algebra are available, \ including the original White/Nylander version and many more described \ on Jason's Softology website \ (http://softology.com.au/gallery/ \ gallerymandelbulb.htm). Many are based upon the the formulas of Tad \ Boniecki." endheading heading text = "s = x + i*y + j*z expressed as complex spherical coordinates." endheading int param v_lambdabulb caption = "Version (Lambdabulb)" 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_lambdabulb < 100 endparam heading caption = "Julia Parameters" endheading complex param cri caption = "r-i plane" default = (1.0625,0.2375) endparam complex param cjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam float param power caption = "Lambda Power" default = 4 endparam param flagtype caption = "Bulb types" enum = "Original" "Positive Z" "Cosine" "Rucker" "Reversed" "Reversed +Z"\ "Msltoe" "IQ" "Negative IQ" "XpYp3" "XpZp2" "XpYn1" "XnYp1" "XpYn3"\ "XnYp3" "XnYn3" "YpXp3" "YpXn2" "YnXp2" "YpXn3" "YnXp3" "YnXn3"\ "ZpXp3" "ZpXn2" "ZnXp2" "ZpXn3" "ZnXp3" "ZnXn3" "XpZn1" "XnZp1"\ "XpZn2" "XnZp2" "XnZn2" "YpZp2" "YpZn1" "YnZp1" "YpZn2" "YnZp2"\ "YnZn2" "ZnYp1" "ZnYn1" "ZnYp3" "Tad 20" "Tad 28" "Tad 29" "Tad 34"\ "Tad 50" "Tad 61" "Tad 84" "Tad 85" "Tad 86" "Tad 87" "Tad 52"\ "Tad 53" "Tad 93" "Tad 95" "Tad 98" "Tad 114" "Tad 116" "Tad 117"\ "Tad 122" "Tad 123" "Tad 124" "Tad 125" "Tad 176" "Tad 177"\ "Tad 180" "Tad 185" "Tad 240" "Tad 241" "Tad 244" "Tad 245"\ "Tad 248" "Tad 249" "Tad 252" "Tad 253" "Tad 270" "Tad 272"\ "Tad 304" "Tad 305" "Tad 306" "Tad 322" "Tad 342" "Tad 345"\ "Tad 368" "Tad 369" "Tad 377" "Tad 378" "Tad 412" "Tad 413"\ "Tad 464" "Tad 465" "Tad 468" "Tad 469" "Tad 473" default = 0 endparam float param pfactor caption = "Azimuth Factor" default = 1.0 endparam heading caption = "Alternate settings" visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "The following two check boxes are alternatives to the standard \ Mandelbulb equations. They are included as they can give some \ interesting results." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "'alternate elevation' reverses the sign of the elevation." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param altel caption = "alternate elevation" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam heading text = "'Range correction' insures that the elevation is in the range -pi/2 to pi/2 \ after all applications of the power and multiply functions." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param quadcor caption = "range correction" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam } class MandelLambdaBulb(Quat) { ; Uses spherical coordinates in analogy to polar coordinates for complex numbers public: import "common.ulb" ; constructor func MandelLambdaBulb(Generic pparent) Quat.Quat(pparent) m_mand = true m_quat = false m_sphere = true m_fourth = @fourth m_ck = @ck m_zri = (1/(@power))^(1/(@power-1)) + flip((1/(@power))^(1/(@power-1))) m_zjk = m_cjk endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) r = zri j = zjk CtoV(zri,zjk,in) MD.Spower(@quadcor,@altel,@power,in,out,@pfactor,@flagtype) VtoC(zri,zjk,out) zri = r-zri zjk = j-zjk CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) MD.SMult(@quadcor,@altel,cin,in,out,@pfactor,@flagtype) VtoC(zri,zjk,out) endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) MD.Spower(@quadcor,@altel,@power-1,in,out,@pfactor,@flagtype) VtoC(zri,zjk,out) zri = 1-@power*zri zjk = -@power*zjk CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) MD.SMult(@quadcor,@altel,cin,in,out,@pfactor,@flagtype) CtoV(zrid,zjkd,ind) MD.SMult(@quadcor,@altel,ind,out,cin,@pfactor,@flagtype) VtoC(zrid,zjkd,cin) endfunc protected: complex r complex j default: title = "Mandel Lambda Bulb" heading text = "Uses 3D spherical coordinates in analogy to 2D polar coordinates for \ complex numbers. Over 50 variants of triplex algebra are available, \ including the original White/Nylander version and many more described \ on Jason's Softology website \ (http://softology.com.au/gallery/ \ gallerymandelbulb.htm). Many are based upon the the formulas of Tad \ Boniecki." endheading heading text = "s = x + i*y + j*z expressed as complex spherical coordinates." endheading int param v_mandellambdabulb caption = "Version (Mandel Lambdabulb)" 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_mandellambdabulb < 100 endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" visible = false endparam float param ck caption = "4th Dimension Value" default = 0.0 visible = false endparam float param power caption = "Lambda Power" default = 8 endparam param flagtype caption = "Bulb types" enum = "Original" "Positive Z" "Cosine" "Rucker" "Reversed" "Reversed +Z"\ "Msltoe" "IQ" "Negative IQ" "XpYp3" "XpZp2" "XpYn1" "XnYp1" "XpYn3"\ "XnYp3" "XnYn3" "YpXp3" "YpXn2" "YnXp2" "YpXn3" "YnXp3" "YnXn3"\ "ZpXp3" "ZpXn2" "ZnXp2" "ZpXn3" "ZnXp3" "ZnXn3" "XpZn1" "XnZp1"\ "XpZn2" "XnZp2" "XnZn2" "YpZp2" "YpZn1" "YnZp1" "YpZn2" "YnZp2"\ "YnZn2" "ZnYp1" "ZnYn1" "ZnYp3" "Tad 20" "Tad 28" "Tad 29" "Tad 34"\ "Tad 50" "Tad 61" "Tad 84" "Tad 85" "Tad 86" "Tad 87" "Tad 52"\ "Tad 53" "Tad 93" "Tad 95" "Tad 98" "Tad 114" "Tad 116" "Tad 117"\ "Tad 122" "Tad 123" "Tad 124" "Tad 125" "Tad 176" "Tad 177"\ "Tad 180" "Tad 185" "Tad 240" "Tad 241" "Tad 244" "Tad 245"\ "Tad 248" "Tad 249" "Tad 252" "Tad 253" "Tad 270" "Tad 272"\ "Tad 304" "Tad 305" "Tad 306" "Tad 322" "Tad 342" "Tad 345"\ "Tad 368" "Tad 369" "Tad 377" "Tad 378" "Tad 412" "Tad 413"\ "Tad 464" "Tad 465" "Tad 468" "Tad 469" "Tad 473" default = 0 endparam float param pfactor caption = "Azimuth Factor" default = 1.0 endparam heading caption = "Alternate settings" visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "The following two check boxes are alternatives to the standard \ Mandelbulb equations. They are included as they can give some \ interesting results." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading heading text = "'alternate elevation' reverses the sign of the elevation." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param altel caption = "alternate elevation" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam heading text = "'Range correction' insures that the elevation is in the range -pi/2 to pi/2 \ after all applications of the power and multiply functions." visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endheading bool param quadcor caption = "range correction" default = false visible = !(@flagtype == 4 || @flagtype == 5|| @flagtype == 6)\ && @flagtype < 10 endparam } class IkenagaMandel(Quat) { public: import "common.ulb" ; constructor func IkenagaMandel(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_quat = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) QH.QMul(in,in,ind) ; z*z QH.QMul(in,ind,out) ; z*z*z VtoC(a,b,out) QH.QMul(cin,in,out) ; c*z VtoC(a1,b1,out) zri = a + a1 -zri - m_cri zjk = b + b1 - zjk - m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.QMul(in,in,out) ; z*z VtoC(a,b,out) a1 = 3*a + m_cri - 1 b1 = 3*b + m_cjk CtoV(a1,b1,in) QH.QMul(in,ind,out) VtoC(zrid,zjkd,out) endfunc protected: complex a complex b complex a1 complex b1 default: title = "Ikenaga Mandel Quaternion" heading text = "Uses quaternion mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ noncommutative and the inverse of any nonzero element is unique." endheading heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class JuliaBrot(Quat) { ; This is the standard brot public: import "common.ulb" ; constructor func JuliaBrot(Generic pparent) Quat.Quat(pparent) m_brot = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) zri = zri^@power2 + zjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) zrid = @power2*zri^(@power2-1)*zrid + 1 endfunc default: title = "JuliaBrot" heading text = "Uses two complex planes. The type was named by Mark Peterson, \ one of the original developers of Fractint." endheading heading text = "z = zr + i*zi; c = cr + i*ci" endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param power2 caption = "Power" default = (2,0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "cr" "ci" endparam float param ck caption = "4th Dimension Value" default = 0.5 endparam } class PhoenixBrot(Quat) { public: import "common.ulb" ; constructor func PhoenixBrot(Generic pparent) Quat.Quat(pparent) m_brot = true m_oldz = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) complex b = zri*zri + real(zjk) + imag(zjk)*m_oldzri m_oldzri = zri zri = b endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) zrid = (2*zri+imag(zjk))*zrid + 1 endfunc default: title = "PhoenixBrot" heading text = "Uses two complex planes. The type was named by Mark Peterson, \ one of the original developers of Fractint." endheading heading text = "z = zr + i*zi; c = cr + i*ci" endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "cr" "ci" endparam float param ck caption = "4th Dimension Value" default = -0.5 endparam } class IkenagaBrot(Quat) { ; This is the standard brot public: import "common.ulb" ; constructor func IkenagaBrot(Generic pparent) Quat.Quat(pparent) m_brot = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) zri = zri^3 + (zjk-1)*zri - zjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) zrid = 3*zri^2*zrid + (zjk-1)*zrid -1 endfunc default: title = "IkenagaBrot" heading text = "Uses two complex planes. The type was named by Mark Peterson, \ one of the original developers of Fractint." endheading heading text = "z = zr + i*zi; c = cr + i*ci" endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "cr" "ci" endparam float param ck caption = "4th Dimension Value" default = -0.3 endparam } class LambdaBrot(Quat) { ; This is the standard brot public: import "common.ulb" ; constructor func LambdaBrot(Generic pparent) Quat.Quat(pparent) m_brot = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) zri = zjk*zri*(1-zri^(@power-1)) endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) zrid = zjk*zrid*(1-@power*zri^(@power-1)) endfunc default: title = "LambdaBrot" heading text = "Uses two complex planes. The type was named by Mark Peterson, \ one of the original developers of Fractint." endheading heading text = "z = zr + i*zi; c = cr + i*ci" endheading heading caption = "Julia Parameters" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "cr" "ci" endparam float param ck caption = "4th Dimension Value" default = -0.7 endparam complex param power caption = "Power" default = (2.0) endparam } class IkenagaHyperMandel(Quat) { public: import "common.ulb" ; constructor func IkenagaHyperMandel(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_hyper = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) CtoV(m_cri,m_cjk,cin) QH.HMul(in,in,ind) ; z*z QH.HMul(in,ind,out) ; z*z*z VtoC(a,b,out) QH.HMul(cin,in,out) ; c*z VtoC(a1,b1,out) zri = a + a1 -zri - m_cri zjk = b + b1 - zjk - m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.HMul(in,in,out) ; z*z VtoC(a,b,out) a1 = 3*a + m_cri - 1 b1 = 3*b + m_cjk CtoV(a1,b1,in) QH.HMul(in,ind,out) VtoC(zrid,zjkd,out) endfunc protected: complex a complex b complex a1 complex b1 default: title = "Ikenaga Mandel Hypercomplex" heading text = "Uses hypercomplex mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ commutative and the inverse is not always defined. This was first \ developed extensively by Clyde Davenport." endheading heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class FrameRobertHyperMandel(Quat) { ; z*z*z/5 + z*z + c public: import "common.ulb" ; constructor func FrameRobertHyperMandel(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_hyper = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) QH.HMul(in,in,ind) ; z*z QH.HMul(in,ind,out) ; z*z*z VtoC(a,b,out) VtoC(a1,b1,ind) zri = a/5 + a1 + m_cri zjk = b/5 + b1 + m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.HMul(in,in,out) ; z*z VtoC(a,b,out) a1 = 0.6*a + 2*zri ; 0.6*z*z + 2*z b1 = 0.6*b + 2*zjk CtoV(a1,b1,in) QH.HMul(in,ind,out) ; z*dz VtoC(zrid,zjkd,out) zrid = zrid + 1 endfunc protected: complex a complex b complex a1 complex b1 default: title = "FrameRobert Mandel Hypercomplex" heading text = "Uses hypercomplex mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ commutative and the inverse is not always defined. This was first \ developed extensively by Clyde Davenport." endheading heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } class HyperMandel(Quat) { ; This is the standard Quaternion public: import "common.ulb" ; constructor func HyperMandel(Generic pparent) Quat.Quat(pparent) m_zri = @zri m_zjk = @zjk m_mand = true m_hyper = true m_fourth = @fourth m_ck = @ck endfunc ; calculates the fractal value func frcalc(complex &zri, complex &zjk) CtoV(zri,zjk,in) QH.HMul(in,in,out) VtoC(zri,zjk,out) zri = zri + m_cri zjk = zjk + m_cjk endfunc ; calculates the derivative of the fractal func drcalc(complex zri, complex zjk, complex &zrid, complex &zjkd) CtoV(zri,zjk,in) CtoV(zrid,zjkd,ind) QH.HMul(in,ind,out) VtoC(zrid,zjkd,out) zrid = 2*zrid + 1 zjkd = 2*zjkd endfunc default: title = "Mandel Hypercomplex" heading text = "Uses hypercomplex mathematics." endheading heading text = "z = zr + i*zi + j*zj + k*zk" endheading heading text = "where i, j and k are the imaginary vectors. Multiplication is \ commutative and the inverse is not always defined. This was first \ developed extensively by Clyde Davenport." endheading heading caption = "Mandel Initialization" endheading heading text = "The 'r-i plane' is the traditional complex plane. The 'j-k plane \ contains the 3rd and 4th dimensions." endheading complex param zri caption = "r-i plane" default = (0.0,0.0) endparam complex param zjk caption = "j-k plane" default = (0.0,0.0) endparam param fourth caption = "4th Dimension" default = 3 enum = "zr" "zi" "zj" "zk" endparam float param ck caption = "4th Dimension Value" default = 0.0 endparam } ;---------------------------------------- ; Convolution filters ;----------------------------------------- class REB_EmbossFilter(dmj5.ulb:DMJ_ConvolutionFilter) { ; Basic Emboss filter.
public: import "common.ulb" import "dmj5.ulb" ; contructor func REB_EmbossFilter(Generic pparent) DMJ_ConvolutionFilter.DMJ_ConvolutionFilter(pparent) int count = (@p_samples*2+1) int elements = sqr(count) setLength(m_Offsets, elements) setLength(m_Weights, elements) m_Bias = @p_bias if @v_embossfilter < 101 && @pgray m_bias = m_bias + 0.5 else if @etype != "full color" m_bias = m_bias + 0.5 endif endif m_Multiplier = 0.0 complex v = @p_radius * ((0,1) ^ (@p_angle / 90.0)) / @p_samples int j = -@p_samples int k = 0 int l = 0 while (j <= @p_samples) k = -@p_samples while (k <= @p_samples) if @v_embossfilter < 101 m_Offsets[l] = v * j/100 m_Weights[l] = (k-j) if @pgray m_Offsets[l] = v * j/100 * (0.5/@p_samples^2) endif if (j == 0 && k == 0) && !@pgray m_weights[l] = m_multiplier endif else if @etype == "full color" m_Offsets[l] = v * j/100 m_Weights[l] = (k-j) elseif @etype == "pseudo gray" m_Offsets[l] = v * j/100 * (0.5/@p_samples^2) m_Weights[l] = (k-j) elseif @etype == "Laplacian" m_Offsets[l] = v * j/100 if (l % 2 == 0) && !(j == 0 && k == 0) && (abs(j) == abs(k)) m_Weights[l] = -1 endif elseif @etype == "corner" m_Offsets[l] = v * j/100 if k <= 0 && j < 0 m_Weights[l] = 1 endif if k > 0 && j >= 0 m_Weights[l] = -1 endif elseif @etype == "extrude" m_Offsets[l] = v * j/100 if j == -@p_samples m_Weights[l] = 1 endif if j == @p_samples m_Weights[l] = -1 endif endif if (j == 0 && k == 0) if @etype == "full color" m_weights[l] = m_multiplier elseif @etype == "Laplacian" m_weights[l] = @p_samples*4 endif endif endif m_Multiplier = m_Multiplier + m_Weights[l] l = l + 1 k = k + 1 endwhile j = j + 1 endwhile if m_Multiplier == 0 m_multiplier = 1 endif m_Multiplier = 1 / m_Multiplier endfunc default: title = "Emboss Filter" int param v_embossfilter caption = "Version (Emboss Filter)" default = 101 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_embossfilter < 101 endparam float param p_bias caption = "bias" default = 0 endparam param etype caption = "Emboss Type" default = 0 enum = "full color" "pseudo gray" "Laplacian" "corner" "extrude" visible = @v_embossfilter >= 101 endparam bool param pgray caption = "Pseudo gray" default = false visible = @v_embossfilter < 101 endparam float param p_angle caption = "Angle" default = 60.0 endparam float param p_radius caption = "Filter Radius" default = 0.1 endparam int param p_samples caption = "Sample Density" default = 2 min = 1 max = 9 endparam } class REB_EdgeDetectFilter(dmj5.ulb:DMJ_ConvolutionFilter) { ; Basic Edge detection filter.
public: import "common.ulb" import "dmj5.ulb" ; contructor func REB_EdgeDetectFilter(Generic pparent) DMJ_ConvolutionFilter.DMJ_ConvolutionFilter(pparent) int count = (@p_samples*2+1) int elements = sqr(count) setLength(m_Offsets, elements) setLength(m_Weights, elements) m_Bias = @p_bias if @p_enhance m_bias = m_bias + 1.5 endif m_Multiplier = 0.0 int j = -@p_samples int k = 0 int l = 0 while (j <= @p_samples) k = -@p_samples while (k <= @p_samples) m_Offsets[l] = (@p_radius*j/@p_samples + flip(@p_radius*k/@p_samples))/100 m_Weights[l] = -1 if (j == 0 && k == 0) m_weights[l] = -m_multiplier*2 + 1 endif m_Multiplier = m_Multiplier + m_Weights[l] l = l + 1 k = k + 1 endwhile j = j + 1 endwhile if m_Multiplier == 0 m_multiplier = 1 endif m_Multiplier = 1 / m_Multiplier endfunc default: title = "Edge Detect Filter" int param v_EdgeDetect caption = "Version (Edge Detect Filter)" 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_EdgeDetect < 100 endparam float param p_bias caption = "bias" default = -1.5 endparam bool param p_enhance caption = "Edge Enhance/Sharpen" default = false endparam heading text = "For sharpening, decrease the filter radius for best effects." visible = @p_enhance endheading float param p_radius caption = "Filter Radius" default = 0.05 endparam int param p_samples caption = "Sample Density" default = 2 min = 1 max = 9 endparam } class REB_AverageBlurFilter(dmj5.ulb:DMJ_ConvolutionFilter) { ; Basic blur/smooth filter using the average value.
public: import "common.ulb" import "dmj5.ulb" ; contructor func REB_AverageBlurFilter(Generic pparent) DMJ_ConvolutionFilter.DMJ_ConvolutionFilter(pparent) int count = (@p_samples*2+1) int elements = sqr(count) setLength(m_Offsets, elements) setLength(m_Weights, elements) m_Multiplier = 0.0 endfunc func init(complex pz) if @usefocus m_bias = (cabs(pz-@focus))*@depth ; if m_bias < 1 ; m_bias = 0 ; endif else m_bias = 1 endif if m_bias*@p_radius >= @p_samples/2 m_bias = @p_samples/@p_radius/2 endif int j = -@p_samples int k = 0 int l = 0 while (j <= @p_samples) k = -@p_samples while (k <= @p_samples) m_Offsets[l] = (@p_radius*j/@p_samples + flip(@p_radius*k/@p_samples))/100*m_bias m_Weights[l] = 1 m_Multiplier = m_Multiplier + m_Weights[l] l = l + 1 k = k + 1 endwhile j = j + 1 endwhile m_Multiplier = 1 / m_Multiplier endfunc default: title = "Average Blur Filter" int param v_AverageBlur caption = "Version (Average Blur Filter)" 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_AverageBlur < 100 endparam bool param usefocus caption = "Use blur focus" default = false endparam complex param focus caption = "Focus position" default = (0,0) visible = @usefocus endparam heading text = "The depth parameter increases blur and special color effects depending \ upon the distance from the Focus Position." visible = @usefocus endheading float param depth caption = "Depth" default = 1 visible = @usefocus endparam float param p_radius caption = "Filter Radius" default = 0.1 endparam int param p_samples caption = "Sample Density" default = 2 min = 1 max = 9 endparam } class REB_LowPassFilter(dmj5.ulb:DMJ_ConvolutionFilter) { ; Quick Filter that attenuates high frequency content public: import "common.ulb" import "dmj5.ulb" ; contructor func REB_LowPassFilter(Generic pparent) DMJ_ConvolutionFilter.DMJ_ConvolutionFilter(pparent) int count = 3 int elements = sqr(count) setLength(m_Offsets, elements) setLength(m_Weights, elements) m_Multiplier = 0.0 int j = -1 int k = 0 int l = 0 while j <= 1 k = -1 while (k <= 1) m_Offsets[l] = (@p_radius*j + flip(@p_radius*k))/100 if @option == "Filter 1" m_Weights[l] = 1/9 elseif @option == "Filter 2" m_Weights[l] = 1/10 if j == 0 && k == 0 m_weights[l] = 0.2 endif elseif @option == "Filter 3" m_Weights[l] = 1/16 if j == 0 && k == 0 m_Weights[l] = 1/4 elseif j == 0 || k == 0 m_weights[l] = 1/8 endif endif l = l + 1 k = k + 1 endwhile j = j + 1 endwhile m_Multiplier = 1 endfunc default: title = "Quick Low Pass Filter" heading text = "Quick filter that attenuates high frequency color information." endheading int param v_lowpass caption = "Version (Low Pass Filter)" 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_lowpass < 100 endparam float param p_radius caption = "Filter Radius" default = 0.1 endparam param option caption = "Options" default = 0 enum = "Filter 1" "Filter 2" "Filter 3" endparam } class REB_HighPassFilter(dmj5.ulb:DMJ_ConvolutionFilter) { ; Quick Filter that attenuates low frequency content public: import "common.ulb" import "dmj5.ulb" ; contructor func REB_HighPassFilter(Generic pparent) DMJ_ConvolutionFilter.DMJ_ConvolutionFilter(pparent) int count = 3 int elements = sqr(count) setLength(m_Offsets, elements) setLength(m_Weights, elements) m_Multiplier = 0.0 int j = -1 int k = 0 int l = 0 while j <= 1 k = -1 while (k <= 1) m_Offsets[l] = (@p_radius*j + flip(@p_radius*k))/100 if @option == "Filter 3" m_Weights[l] = -1 if j == 0 && k == 0 m_weights[l] = 9 endif elseif @option == "Filter 2" m_Weights[l] = 0 if j == 0 && k == 0 m_Weights[l] = 5 elseif j == 0 || k == 0 m_weights[l] = -1 endif elseif @option == "Filter 1" m_Weights[l] = 1 if j == 0 && k == 0 m_Weights[l] = 5 elseif j == 0 || k == 0 m_weights[l] = -2 endif endif l = l + 1 k = k + 1 endwhile j = j + 1 endwhile m_Multiplier = 1 endfunc default: title = "Quick High Pass Filter" heading text = "Quick filter that attenuates low frequency color information." endheading int param v_highpass caption = "Version (Low Pass Filter)" 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_highpass < 100 endparam float param p_radius caption = "Filter Radius" default = 0.1 endparam param option caption = "Options" default = 0 enum = "Filter 1" "Filter 2" "Filter 3" endparam } class REB_FocusFilter(dmj5.ulb:DMJ_ConvolutionFilter) { public: import "common.ulb" import "dmj5.ulb" ; contructor func REB_FocusFilter(Generic pparent) DMJ_ConvolutionFilter.DMJ_ConvolutionFilter(pparent) int count = 3 int elements = sqr(count) setLength(m_Offsets, elements) setLength(m_Weights, elements) m_Multiplier = 0.0 int j = -1 int k = 0 int l = 0 while j <= 1 k = -1 while (k <= 1) m_Offsets[l] = (@p_radius*j + flip(@p_radius*k))/100 m_Weights[l] = -1 if j == 0 && k == 0 m_Weights[l] = 7 elseif j == 0 || k == 0 m_weights[l] = 0 endif l = l + 1 k = k + 1 endwhile j = j + 1 endwhile m_Multiplier = 1/3 endfunc default: title = "Quick Focus Filter" heading text = "This is a type of sharpening filter." endheading int param v_focus caption = "Version (FocusFilter)" 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_focus < 100 endparam float param p_radius caption = "Filter Radius" default = 0.1 endparam } class REB_ReduceJaggiesFilter(dmj5.ulb:DMJ_ConvolutionFilter) { public: import "common.ulb" import "dmj5.ulb" ; contructor func REB_ReduceJaggiesFilter(Generic pparent) DMJ_ConvolutionFilter.DMJ_ConvolutionFilter(pparent) int count = 5 int elements = sqr(count) setLength(m_Offsets, elements) setLength(m_Weights, elements) m_Multiplier = 0.0 int j = -2 int k = 0 int l = 0 while (j <= 2) k = -2 while (k <= 2) m_Offsets[l] = (@p_radius*j/2 + flip(@p_radius*k/2))/100 m_Weights[l] = 0 if j == 0 && k == 0 m_Weights[l] = 7 elseif (j == 0 && abs(k) == 2) || (abs(j) == 2 && k == 0) m_weights[l] = -1 elseif (j == 0 && abs(k) == 1) || (abs(j) == 1 && k == 0) m_weights[l] = 3 endif l = l + 1 k = k + 1 endwhile j = j + 1 endwhile m_Multiplier = 1/15 endfunc default: title = "Reduce Jaggies Filter" heading text = "This filter sharpens some areas and blurs other areas." endheading int param v_reducejaggies caption = "Version (Reduce Jaggies Filter)" 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_reducejaggies < 100 endparam float param p_radius caption = "Filter Radius" default = 0.2 endparam } class REB_MedianFilter(dmj5.ulb:DMJ_ConvolutionFilter) { ; Filter that selects the median value in a 3 x 3 matrix.
; Technically this is not a convolution filter.
public: import "common.ulb" import "dmj5.ulb" ; contructor func REB_MedianFilter(Generic pparent) DMJ_ConvolutionFilter.DMJ_ConvolutionFilter(pparent) int count = (@p_samples*2+1) int elements = sqr(count) setLength(m_Offsets, elements) setLength(m_Weights, elements) m_Multiplier = 0.0 int j = -@p_samples int k = 0 int l = 0 while (j <= @p_samples) k = -@p_samples while (k <= @p_samples) m_Offsets[l] = (@p_radius*j/@p_samples + flip(@p_radius*k/@p_samples))/100 m_Weights[l] = 0 l = l + 1 k = k + 1 endwhile j = j + 1 endwhile m_Multiplier = 1 endfunc default: title = "Median Filter" heading text = "This is a filter that selects the median value from a matrix centered on \ the target point. Technically it is not a convolution filter, and is \ intended for use with the Convolution Shape Wrapper or the Convolution \ Color Wrapper in reb.ulb only. Use with other plug-ins will most likely \ not give useable results." endheading int param v_median caption = "Version (Median Filter)" 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_median < 100 endparam float param p_radius caption = "Filter Radius" default = 0.1 endparam heading text = "The default sample density is for a 3 x 3 matrix, which is the recommended \ starting point." endheading int param p_samples caption = "Sample Density" default = 1 min = 1 max = 9 endparam } class REB_ConservativeSmoothingFilter(dmj5.ulb:DMJ_ConvolutionFilter) { ; Conservative smoothing works on a 3 x 3 matrix
; Technically this is not a convolution filter.
public: import "common.ulb" import "dmj5.ulb" ; contructor func REB_ConservativeSmoothingFilter(Generic pparent) DMJ_ConvolutionFilter.DMJ_ConvolutionFilter(pparent) int count = (@p_samples*2+1) int elements = sqr(count) setLength(m_Offsets, elements) setLength(m_Weights, elements) m_Multiplier = 0.0 int j = -@p_samples int k = 0 int l = 0 while (j <= @p_samples) k = -@p_samples while (k <= @p_samples) m_Offsets[l] = (@p_radius*j/@p_samples + flip(@p_radius*k/@p_samples))/100 m_Weights[l] = 0 l = l + 1 k = k + 1 endwhile j = j + 1 endwhile m_Multiplier = 1 endfunc default: title = "Conservative Smoothing Filter" heading text = "This is a de-speckling filter that looks to see if the pixel intensity is \ greater or less than any pixels in the immediate neighborhood. If the \ the pixel is set to the minimum or maximum value." endheading int param v_conservative caption = "Version (Conservative Smoothing Filter)" 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_conservative < 100 endparam float param p_radius caption = "Filter Radius" default = 0.7 endparam int param p_samples caption = "Sample Density" default = 1 min = 1 max = 9 endparam } class REB_CrimminsDespeckleFilter(dmj5.ulb:DMJ_ConvolutionFilter) { ; Conservative smoothing works on a 3 x 3 matrix
; Technically this is not a convolution filter.
public: import "common.ulb" import "dmj5.ulb" ; contructor func REB_CrimminsDespeckleFilter(Generic pparent) DMJ_ConvolutionFilter.DMJ_ConvolutionFilter(pparent) int count = 3 int elements = sqr(count) setLength(m_Offsets, elements) setLength(m_Weights, elements) m_Multiplier = 0.0 int j = -1 int k = 0 int l = 0 while j <= 1 k = -1 while (k <= 1) m_Offsets[l] = (@p_radius*j + flip(@p_radius*k))/100 m_Weights[l] = 0 l = l + 1 k = k + 1 endwhile j = j + 1 endwhile m_Multiplier = 1 endfunc default: title = "Crimmins Despeckle Filter" int param v_despeckle caption = "Version (despeckle Smoothing Filter)" 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_despeckle < 100 endparam float param p_radius caption = "Filter Radius" default = 0.1 endparam } class REB_ColorPencilFilter(dmj5.ulb:DMJ_ConvolutionFilter) { ; Filter that selects the median value in a n x n matrix.
; Technically this is not a convolution filter.
public: import "common.ulb" import "dmj5.ulb" ; contructor func REB_ColorPencilFilter(Generic pparent) DMJ_ConvolutionFilter.DMJ_ConvolutionFilter(pparent) int count = (@p_samples*2+1) int elements = sqr(count) setLength(m_Offsets, elements) setLength(m_Weights, elements) m_Multiplier = 0.0 int j = -@p_samples int k = 0 int l = 0 while (j <= @p_samples) k = -@p_samples while (k <= @p_samples) m_Offsets[l] = (@p_radius*j/@p_samples + flip(@p_radius*k/@p_samples))/100 m_Weights[l] = 0 l = l + 1 k = k + 1 endwhile j = j + 1 endwhile m_Multiplier = 1 endfunc default: title = "Color Pencil Filter" heading text = "This filter uses an algorithm based upon the code of Feng Xiao, which \ he developed to simulate the color pencil filter for theUlead \ PhotoImpact software and was part of a course on digital processing. \ Although the filter uses an nxn matrix, technically it is not \ a convolution filter, and is intended for use with the Convolution \ Shape Wrapper or the Convolution Color Wrapper in reb.ulb only. \ Use with other plug-ins will most likely not give useable results." endheading heading text = "Both Filter Radius and Sample Size may need to be adjusted to get the \ desired artistic effect." endheading int param v_colorpencil caption = "Version (Color Pencil Filter)" 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_colorpencil < 100 endparam float param p_radius caption = "Filter Radius" default = 0.1 endparam int param p_samples caption = "Sample Density" default = 3 min = 1 max = 9 endparam } class REB_OilPaintFilter(dmj5.ulb:DMJ_ConvolutionFilter) { ; Filter that selects the median value in a n x n matrix.
; Technically this is not a convolution filter.
public: import "common.ulb" import "dmj5.ulb" ; contructor func REB_OilPaintFilter(Generic pparent) DMJ_ConvolutionFilter.DMJ_ConvolutionFilter(pparent) int count = (@p_samples*2+1) int elements = sqr(count) setLength(m_Offsets, elements) setLength(m_Weights, elements) m_Multiplier = 0.0 int j = -@p_samples int k = 0 int l = 0 while (j <= @p_samples) k = -@p_samples while (k <= @p_samples) m_Offsets[l] = (@p_radius*j/@p_samples + flip(@p_radius*k/@p_samples))/100 m_Weights[l] = 0 l = l + 1 k = k + 1 endwhile j = j + 1 endwhile m_Multiplier = 1 endfunc default: title = "Oil Paint Filter" heading text = "This filter uses an algorithm based upon the code of Feng Xiao, which \ he developed to simulate the oil paint filter for theUlead \ PhotoImpact software and was part of a course on digital processing. \ Although the filter uses an nxn matrix, technically it is not \ a convolution filter, and is intended for use with the Convolution \ Shape Wrapper or the Convolution Color Wrapper in reb.ulb only. \ Use with other plug-ins will most likely not give useable results." endheading heading text = "Both Filter Radius and Sample Size may need to be adjusted to get the \ desired artistic effect." endheading int param v_oilpaint caption = "Version (Oil Paint Filter)" 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_oilpaint < 100 endparam float param p_radius caption = "Filter Radius" default = 1 endparam int param p_samples caption = "Sample Density" default = 3 min = 1 max = 9 endparam } class REB_PaintersToolboxFilter(dmj5.ulb:DMJ_VariableConvolutionFilter) { ; Linear Convolution filter with a large variety of options.
public: import "common.ulb" import "dmj5.ulb" import "jlb.ulb" ; contructor func REB_PaintersToolboxFilter(Generic pparent) DMJ_VariableConvolutionFilter.DMJ_VariableConvolutionFilter(pparent) rndi = new JLB_Random(0) rndi.Init(@seed) rndi.SetNMax(5000) int elements = (@p_samples*2+1) setLength(m_Offsets, elements) setLength(m_Weights, elements) endfunc func Init(complex pz) if @ttype == "Worley" complex fzc complex fzz float dst float dst2 complex fzc1 complex fzc2 complex fzc3 complex fzc4 complex cells[12] float distance = 0 float test = 0 complex diff = 0 int rnds[24] float rp[12] float ip[12] i = 1 rnds[0] = rndi.RandomIntInRange(@seed) while i < 24 rnds[i] = rndi.RandomIntInRange(0) i = i + 1 endwhile dst = 1e10 dst2 = 1e10 complex near = 0 complex z = (pz+(10,10))/@psize fzc = round(z) fzz = z - fzc ; create the grid fzc1 = fzc + (1,1)/2 fzc2 = fzc + (1,-1)/2 fzc3 = fzc + (-1,1)/2 fzc4 = fzc + (-1,-1)/2 ; create the random points ; cell 1 rp[0] = ((real(fzc1)-rnds[0])^5%rnds[6] - (imag(fzc1)+rnds[12])^3%rnds[18])^2 %2 - 1 ip[0] = ((real(fzc1)-rnds[1])^5%rnds[7] - (imag(fzc1)+rnds[13])^3%rnds[19])^2 %2 - 1 rp[1] = ((real(fzc1)-rnds[2])^5%rnds[8] - (imag(fzc1)+rnds[14])^3%rnds[20])^2 %2 - 1 ip[1] = ((real(fzc1)-rnds[3])^5%rnds[8] - (imag(fzc1)+rnds[15])^3%rnds[21])^2 %2 - 1 rp[2] = ((real(fzc1)-rnds[4])^5%rnds[10] - (imag(fzc1)+rnds[16])^3%rnds[22])^2 %2 - 1 ip[2] = ((real(fzc1)-rnds[5])^5%rnds[11] - (imag(fzc1)+rnds[17])^3%rnds[23])^2 %2 - 1 ; cell 2 rp[3] = ((real(fzc2)-rnds[0])^5%rnds[6] - (imag(fzc2)+rnds[12])^3%rnds[18])^2 %2 - 1 ip[3] = ((real(fzc2)-rnds[1])^5%rnds[7] - (imag(fzc2)+rnds[13])^3%rnds[19])^2 %2 - 1 rp[4] = ((real(fzc2)-rnds[2])^5%rnds[8] - (imag(fzc2)+rnds[14])^3%rnds[20])^2 %2 - 1 ip[4] = ((real(fzc2)-rnds[3])^5%rnds[8] - (imag(fzc2)+rnds[15])^3%rnds[21])^2 %2 - 1 rp[5] = ((real(fzc2)-rnds[4])^5%rnds[10] - (imag(fzc2)+rnds[16])^3%rnds[22])^2 %2 - 1 ip[5] = ((real(fzc2)-rnds[5])^5%rnds[11] - (imag(fzc2)+rnds[17])^3%rnds[23])^2 %2 - 1 ; cell 3 rp[6] = ((real(fzc3)-rnds[0])^5%rnds[6] - (imag(fzc3)+rnds[12])^3%rnds[18])^2 %2 - 1 ip[6] = ((real(fzc3)-rnds[1])^5%rnds[7] - (imag(fzc3)+rnds[13])^3%rnds[19])^2 %2 - 1 rp[7] = ((real(fzc3)-rnds[2])^5%rnds[8] - (imag(fzc3)+rnds[14])^3%rnds[20])^2 %2 - 1 ip[7] = ((real(fzc3)-rnds[3])^5%rnds[8] - (imag(fzc3)+rnds[15])^3%rnds[21])^2 %2 - 1 rp[8] = ((real(fzc3)-rnds[4])^5%rnds[10] - (imag(fzc3)+rnds[16])^3%rnds[22])^2 %2 - 1 ip[8] = ((real(fzc3)-rnds[5])^5%rnds[11] - (imag(fzc3)+rnds[17])^3%rnds[23])^2 %2 - 1 ; cell 4 rp[9] = ((real(fzc4)-rnds[0])^5%rnds[6] - (imag(fzc4)+rnds[12])^3%rnds[18])^2 %2 - 1 ip[9] = ((real(fzc4)-rnds[1])^5%rnds[7] - (imag(fzc4)+rnds[13])^3%rnds[19])^2 %2 - 1 rp[10] = ((real(fzc4)-rnds[2])^5%rnds[8] - (imag(fzc4)+rnds[14])^3%rnds[20])^2 %2 - 1 ip[10] = ((real(fzc4)-rnds[3])^5%rnds[8] - (imag(fzc4)+rnds[15])^3%rnds[21])^2 %2 - 1 rp[11] = ((real(fzc4)-rnds[4])^5%rnds[10] - (imag(fzc4)+rnds[16])^3%rnds[22])^2 %2 - 1 ip[11] = ((real(fzc4)-rnds[5])^5%rnds[11] - (imag(fzc4)+rnds[17])^3%rnds[23])^2 %2 - 1 ; put into the grids cells[0] = (rp[0] + flip(ip[0]) + (1,1))/2 cells[1] = (rp[1] + flip(ip[1]) + (1,1))/2 cells[2] = (rp[2] + flip(ip[2]) + (1,1))/2 cells[3] = (rp[3] + flip(ip[3]) + (1,-1))/2 cells[4] = (rp[4] + flip(ip[4]) + (1,-1))/2 cells[5] = (rp[5] + flip(ip[5]) + (1,-1))/2 cells[6] = (rp[6] + flip(ip[6]) + (-1,1))/2 cells[7] = (rp[7] + flip(ip[7]) + (-1,1))/2 cells[8] = (rp[8] + flip(ip[8]) + (-1,1))/2 cells[9] = (rp[9] + flip(ip[9]) + (-1,-1))/2 cells[10] = (rp[10] + flip(ip[10]) + (-1,-1))/2 cells[11] = (rp[11] + flip(ip[11]) + (-1,-1))/2 i = 0 int diffidx = 0 while i < 12 diff = fzz - cells[i] if @flavor == "Euclidian" test = cabs(diff) elseif @flavor == "Manhattan" test = (abs(real(diff))^real(@mp) + abs(imag(diff))^imag(@mp)) elseif @flavor == "Chebychev" if abs(real(diff)) > abs(imag(diff)) test = abs(real(diff)) else test = abs(imag(diff)) endif elseif @flavor == "Minkovsky" test = (abs(real(diff))^@ex + abs(imag(diff))^@ex)^(1/@ex) elseif @flavor == "Exp/Log Manhattan" test = log(exp(abs(real(diff))) + exp(abs(imag(diff)))) endif if test < dst dst2 = dst dst = test diffidx = i near = fzc + cells[i] elseif test < dst2 dst2 = test diffidx = i endif i = i + 1 endwhile diff = fzz-cells[diffidx] if @type == "Mosaic" diff = fzc * cells[diffidx]*@psize endif if @type == "Distance" distance = dst^@thick elseif @type == "2nd Distance" distance = (@smod*dst2-dst)^@thick elseif @type == "2nd Distance variant" distance = dst2^@thick elseif @type == "Mosaic" distance = cabs(1000*near) + 1000*atan(cabs(near)+#pi)%1 endif if @dmod != 0 distance = distance*@dmod endif if @type != "Mosaic" if @invert distance = abs(1-distance) endif else distance = distance % 1 endif complex fz = exp(flip(2 * #pi * sqrt(2) * distance)) m_Bias = @bias m_Multiplier = 0.0 complex fzo = 0 complex diffo = 0 j = -@p_samples int l = 0 while (j <= @p_samples) complex v = @p_radius * ((0,1) ^ (j/@p_samples*4)) /@p_samples if @soffset fzo = fz/(@offval+j) diffo = diff/(@offval+j) else fzo = fz diffo = diff endif if @offtype == "Normal" m_Offsets[l] = v*fzo elseif @offtype == "Diff" m_Offsets[l] = v*diffo elseif @offtype == "Mix" m_Offsets[l] = v*fzo*diffo endif if @weighttype == "Flavor 1" m_Weights[l] = 1 elseif @weighttype == "Flavor 2" m_Weights[l] = j elseif @weighttype == "Flavor 3" m_Weights[l] = -(@p_samples+j) if j >= @p_samples/2 m_Weights[l] = -m_weights[l] endif endif if j == 0 m_Weights[l] = m_Weights[l] + @p_centerweight * @p_samples endif m_Multiplier = m_Multiplier + m_Weights[l] l = l + 1 j = j + 1 endwhile if m_multiplier == 0 m_multiplier = 1 endif m_Multiplier = 1.0 / m_Multiplier elseif @ttype == "SFBM II" z = 0 zc1 = 0 zc2 = 0 zc3 = 0 zc4 = 0 i = 0 j = 0 jmax = 0 niter = 0 a = 0 sum = 0 x = 0 y = 0 d1 = 0 d2 = 0 d3 = 0 d4 = 0 nindex = 0 sindex = 0 scale = 1 cr1r = 0 cr1i = 0 cr2r = 0 cr2i = 0 cr3r = 0 cr3i = 0 cr4r = 0 cr4i = 0 crp1 = 0 crp2 = 0 crp3 = 0 crp4 = 0 norm = 1 if @interp == 0 niter = ceil(real(log(real(@fmm)-imag(@fmm))/log(1+@mstep))) else niter = ceil((real(@fmm)-imag(@fmm))/@mstep) endif if @mode == 0 jmax = 1 else jmax = 5 endif while j < jmax z = pz/@psize if @mode == 1 || @mode == 2 if j == 0 a = @cbl + @ctl + @cbr + @ctr + @cc;/20 elseif j == 1 z = z + @eps*(-1,-1) a = -@cbl elseif j == 2 z = z + @eps*(-1,1) a = -@ctl elseif j == 3 z = z + @eps*(1,-1) a = -@cbr elseif j == 4 z = z + @eps*(1,1) a = -@ctr endif else a = 1 endif j = j + 1 i = 0 while i < niter + 2 if i == 2 if @pptype == 0 z = (real(@pp)*(1/sqrt(imag(@ppp))*x + 1i*sqrt(imag(@ppp))*y)^real(@ppp)+(1-real(@pp))*z)*imag(@pp) else z = (real(@pp)*x^real(@ppp)*exp(imag(@ppp)*1i*y)+(1-real(@pp))*z)*imag(@pp) endif elseif i == 0 z = z/imag(@pp) endif z = z*exp(1i*pi/180*@rot) + 1 - 2i if i > 1 if @interp == 0 scale = (1+@mstep)^(i-2)*imag(@fmm) else scale = real(@fmm)-(i-1)*(@mstep+.001) endif endif i = i + 1 zc = round(scale*z)/scale zc1 = zc + (.5,.5)/scale zc2 = zc + (-.5,.5)/scale zc3 = zc + (.5,-.5)/scale zc4 = zc + (-.5,-.5)/scale cr1r = ((real(zc1)-859-i)^5 % (132+i) - (imag(zc1)+328+i)^3 % (113+i))^2 %2 - 1 if @noise != 6 && @noise != 8 && @noise != 10 && @noise != 12 && @noise != 14 cr2r = ((real(zc2)-859-i)^5 % (132+i) - (imag(zc2)+328+i)^3 % (113+i))^2 %2 - 1 cr3r = ((real(zc3)-859-i)^5 % (132+i) - (imag(zc3)+328+i)^3 % (113+i))^2 %2 - 1 cr4r = ((real(zc4)-859-i)^5 % (132+i) - (imag(zc4)+328+i)^3 % (113+i))^2 %2 - 1 endif if @noise == 0 || @noise == 5 cr1i = ((real(zc1)-465+i)^3 % (120+i) - (imag(zc1)-756+i)^2 % (107+i))^2 %2 - 1 cr2i = ((real(zc2)-465+i)^3 % (120+i) - (imag(zc2)-756+i)^2 % (107+i))^2 %2 - 1 cr3i = ((real(zc3)-465+i)^3 % (120+i) - (imag(zc3)-756+i)^2 % (107+i))^2 %2 - 1 cr4i = ((real(zc4)-465+i)^3 % (120+i) - (imag(zc4)-756+i)^2 % (107+i))^2 %2 - 1 endif if @noise == 0 v1 = (z - zc1)*scale v2 = (z - zc2)*scale v3 = (z - zc3)*scale v4 = (z - zc4)*scale crp1 = cr1r*real(v1) + cr1i*imag(v1) crp2 = cr2r*real(v2) + cr2i*imag(v2) crp3 = cr3r*real(v3) + cr3i*imag(v3) crp4 = cr4r*real(v4) + cr4i*imag(v4) elseif @noise == 1 crp1 = cr1r crp2 = cr1r crp3 = cr1r crp4 = cr1r norm = .5 elseif @noise == 2 crp1 = cr1r crp2 = cr2r crp3 = cr1r crp4 = cr2r norm = .5 elseif @noise == 3 crp1 = cr1r crp2 = cr2r crp3 = cr3r crp4 = cr2r norm = .5 elseif @noise == 4 crp1 = -cr1r crp2 = cr2r crp3 = cr3r crp4 = -cr4r norm = .5 elseif @noise == 5 crp1 = cr1r*abs(real(z-zc)*scale)^real(@noisep) + cr1i*abs(imag(z-zc)*scale)^imag(@noisep) crp2 = cr2r*abs(real(z-zc)*scale)^real(@noisep) + cr2i*abs(imag(z-zc)*scale)^imag(@noisep) crp3 = cr3r*abs(real(z-zc)*scale)^real(@noisep) + cr3i*abs(imag(z-zc)*scale)^imag(@noisep) crp4 = cr4r*abs(real(z-zc)*scale)^real(@noisep) + cr4i*abs(imag(z-zc)*scale)^imag(@noisep) norm = .2 elseif @noise == 6 crp1 = (cabs(z-zc)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 7 crp1 = cr1r*(cabs(z-zc)*scale-imag(@noisep))^real(@noisep) crp2 = cr2r*(cabs(z-zc)*scale-imag(@noisep))^real(@noisep) crp3 = cr3r*(cabs(z-zc)*scale-imag(@noisep))^real(@noisep) crp4 = cr4r*(cabs(z-zc)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 8 arg = atan2(z-zc) arg = -round(arg/(2*pi)*4)/4*(2*pi) ztest = (z-zc)*exp(1i*arg) crp1 = (real(ztest)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 9 arg = atan2(z-zc) arg = -round(arg/(2*pi)*4)/4*(2*pi) ztest = (z-zc)*exp(1i*arg) crp1 = cr1r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp2 = cr2r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp3 = cr3r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp4 = cr4r*(real(ztest)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 10 arg = atan2(z-zc) arg = -round(arg/(2*pi)*8)/8*(2*pi) ztest = (z-zc)*exp(1i*arg) crp1 = (real(ztest)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 11 arg = atan2(z-zc) arg = -round(arg/(2*pi)*8)/8*(2*pi) ztest = (z-zc)*exp(1i*arg) crp1 = cr1r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp2 = cr2r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp3 = cr3r*(real(ztest)*scale-imag(@noisep))^real(@noisep) crp4 = cr4r*(real(ztest)*scale-imag(@noisep))^real(@noisep) norm = .4 elseif @noise == 12 ztest = z - zc if real(cr1r) > 0 d1 = abs(cabs(ztest*scale+(.5,.5))-.5) d2 = abs(cabs(ztest*scale-(.5,.5))-.5) if d2 < d1 d1 = d2 endif else d1 = abs(cabs(ztest*scale+(.5,-.5))-.5) d2 = abs(cabs(ztest*scale-(.5,-.5))-.5) if d2 < d1 d1 = d2 endif endif crp1 = d1^real(@noisep) norm = .4 elseif @noise == 13 ztest = z - zc if real(cr1r) > 0 d1 = abs(cabs(ztest*scale+(.5,.5))-.5) d2 = abs(cabs(ztest*scale-(.5,.5))-.5) if d2 < d1 d1 = d2 endif else d1 = abs(cabs(ztest*scale+(.5,-.5))-.5) d2 = abs(cabs(ztest*scale-(.5,-.5))-.5) if d2 < d1 d1 = d2 endif endif crp1 = cr1r*(d1^real(@noisep)-imag(@noisep)) crp2 = cr2r*(d1^real(@noisep)-imag(@noisep)) crp3 = cr3r*(d1^real(@noisep)-imag(@noisep)) crp4 = cr4r*(d1^real(@noisep)-imag(@noisep)) norm = .4 elseif @noise == 14 ztest = (z - zc)*scale if real(cr1r) > 0 d1 = abs(real(ztest) - imag(ztest) -.5) d2 = abs(real(ztest) - imag(ztest) +.5) if d2 < d1 d1 = d2 endif else d1 = abs(real(ztest) + imag(ztest) -.5) d2 = abs(real(ztest) + imag(ztest) +.5) if d2 < d1 d1 = d2 endif endif crp1 = d1^real(@noisep) norm = .4 elseif @noise == 15 ztest = (z - zc)*scale if real(cr1r) > 0 d1 = abs(real(ztest) - imag(ztest) -.5) d2 = abs(real(ztest) - imag(ztest) +.5) if d2 < d1 d1 = d2 endif else d1 = abs(real(ztest) + imag(ztest) -.5) d2 = abs(real(ztest) + imag(ztest) +.5) if d2 < d1 d1 = d2 endif endif crp1 = cr1r*(d1^real(@noisep)-imag(@noisep)) crp2 = cr2r*(d1^real(@noisep)-imag(@noisep)) crp3 = cr3r*(d1^real(@noisep)-imag(@noisep)) crp4 = cr4r*(d1^real(@noisep)-imag(@noisep)) norm = .4 elseif @noise == 16 endif if @noise == 6 || @noise == 8 || @noise == 10 || @noise == 12 || @noise == 14 nindex = crp1 else d1 = real(z - zc)*scale + 0.5 d2 = (1 - d1) d3 = imag(z - zc)*scale + 0.5 d4 = (1 - d3) d1 = (.5 + .5*sin(pi*d1-pi/2))^@power d2 = (.5 + .5*sin(pi*d2-pi/2))^@power d3 = (.5 + .5*sin(pi*d3-pi/2))^@power d4 = (.5 + .5*sin(pi*d4-pi/2))^@power nindex = crp1*d1*d3 + crp3*d1*d4 + crp2*d2*d3 + crp4*d2*d4 endif if @f1 == 1 nindex = real(sin(100*real(@fp1)*nindex+imag(@fp1)))/10 elseif @f1 == 2 nindex = real(@fp1)*10*nindex+2+imag(@fp1) if abs(nindex) > 1 nindex = 1 endif nindex = real(asin(nindex))/4 elseif @f1 == 3 nindex = 20*real(@fp1)*nindex+1+imag(@fp1) if abs(nindex) > 1 nindex = 1 endif nindex = real(acos(nindex))/4 elseif @f1 == 4 nindex = real(atanh(20*real(@fp1)*nindex+imag(@fp1)))/8 elseif @f1 == 5 nindex = (20*nindex+imag(@fp1))^(2+real(@fp1))/160 elseif @f1 == 6 nindex = real((15*nindex+imag(@fp1))^(.1*real(@fp1))) elseif @f1 == 7 nindex = real(exp(10*real(@fp1)*nindex+imag(@fp1)-.5))/8 elseif @f1 == 8 nindex = real(round(5*real(@fp1)*nindex+imag(@fp1)/5))/4 elseif @f1 == 9 nindex = real(round(15*real(@fp1)*nindex+imag(@fp1)/5)^.1)/3 elseif @f1 == 10 if real(@fp1)<0.0 nindex = (sin(-(real(z)+(4+imag(@fp1))*nindex))+cos(-(imag(z)+(4+imag(@fp1))*nindex)))/15 else nindex = (sin(5*sqrt(real(@fp1))*(real(z)+(4+imag(@fp1))*nindex))+cos(5*1/sqrt(real(@fp1))*(imag(z)+(4+imag(@fp1))*nindex)))/15 endif endif if @f2 == 1 nindex = real(sin(100*real(@fp2)*nindex+imag(@fp2)))/10 elseif @f2 == 2 nindex = real(@fp2)*10*nindex+2+imag(@fp2) if abs(nindex) > 1 nindex = 1 endif nindex = real(asin(nindex))/4 elseif @f2 == 3 nindex = 20*real(@fp2)*nindex+1+imag(@fp2) if abs(nindex) > 1 nindex = 1 endif nindex = real(acos(nindex))/4 elseif @f2 == 4 nindex = real(atanh(20*real(@fp2)*nindex+imag(@fp2)))/8 elseif @f2 == 5 nindex = (20*nindex+imag(@fp2))^(2+real(@fp2))/160 elseif @f2 == 6 nindex = real((15*nindex+imag(@fp2))^(.1*real(@fp2))) elseif @f2 == 7 nindex = real(exp(10*real(@fp2)*nindex+imag(@fp2)-.5))/8 elseif @f2 == 8 nindex = real(round(5*real(@fp2)*nindex+imag(@fp2)/5))/4 elseif @f2 == 9 nindex = real(round(15*real(@fp2)*nindex+imag(@fp2)/5)^.1)/3 elseif @f2 == 10 if real(@fp2)<0.0 nindex = (sin(-(real(z)+(4+imag(@fp2))*nindex))+cos(-(imag(z)+(4+imag(@fp2))*nindex)))/15 else nindex = (sin(5*sqrt(real(@fp2))*(real(z)+(4+imag(@fp2))*nindex))+cos(5*1/sqrt(real(@fp2))*(imag(z)+(4+imag(@fp2))*nindex)))/15 endif endif nindex = real(nindex^@power2) if i == 1 x = nindex elseif i == 2 y = nindex else sindex = sindex + nindex/scale^@beta endif endwhile if @mode != 2 sum = sum + a*sindex else sum = sum + a*abs(sindex) endif sindex = 0 scale = 1 endwhile if @mode == 2 sum = 3*abs(sum) endif if @mode == 1 sindex = sum/(10*@eps*(abs(@cbl + @ctl + @cbr + @ctr)+1)) else sindex = sum endif if @interp == 0 d = 2*norm*sindex/(niter)^.5 else d = .4*norm*sindex endif z = exp(flip(2 * #pi * sqrt(2) * d)) m_Bias = @bias m_Multiplier = 0.0 complex fzo = 0 j = -@p_samples int l = 0 while (j <= @p_samples) complex v = @p_radius * ((0,1) ^ (j/@p_samples*4)) /@p_samples if @soffset fzo = z/(@offval+j) else fzo = z endif if @offtypes == "Normal" m_Offsets[l] = v*fzo else m_Offsets[l] = v*fzo*sum endif if @weighttype == "Flavor 1" m_Weights[l] = 1 elseif @weighttype == "Flavor 2" m_Weights[l] = j elseif @weighttype == "Flavor 3" m_Weights[l] = -(@p_samples+j) if j >= @p_samples/2 m_Weights[l] = -m_weights[l] endif endif if j == 0 m_Weights[l] = m_Weights[l] + @p_centerweight * @p_samples endif m_Multiplier = m_Multiplier + m_Weights[l] l = l + 1 j = j + 1 endwhile if m_multiplier == 0 m_multiplier = 1 endif m_Multiplier = 1.0 / m_Multiplier endif endfunc protected: JLB_Random rndi complex z complex zc1 complex zc2 complex zc3 complex zc4 int i int j int jmax int niter float a float sum float x float y float d1 float d2 float d3 float d4 float nindex float sindex float scale float cr1r float cr1i float cr2r float cr2i float cr3r float cr3i float cr4r float cr4i float crp1 float crp2 float crp3 float crp4 float norm float d default: title = "Painter's Toolbox Filter" int param v_painterstoolbox caption = "Version (Painter's Toolbox Filter)" 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_painterstoolbox < 100 endparam heading text = "This is a linear convolution filter which uses a variety of parameters \ from a Worley texture generator or from Sam Monnier's SFBM II texture \ generator . Worley textures have been widely used \ in cinematic animation, a notable example being the movie Shrek. \ A wide variety of artistic effects can be obtained." endheading param ttype caption = "Texture Type" enum = "Worley" "SFBM II" default = 0 endparam float param bias caption = "Bias" default = 0.0 endparam float param p_centerweight caption = "Center Weight" default = 1 hint = "Sets the extra weight that will be applied to the center position. Increasing this will reduce the amount of blur and allow the original image to appear more crisply." endparam float param p_radius caption = "Filter Radius" default = 0.2 hint = "Sets the radius of the filter. A smaller radius will result in less blurring." endparam int param p_samples caption = "Sample Density" default = 9 min = 1 max = 9 hint = "Sets the density of samples used to compute the blur. Increasing the density will dramatically increase the rendering time (increasing with 4x the square of the density) but for very wide blurs you will need to do this to get even blurring." endparam heading text = "Texture parameters." visible = @ttype == "Worley" endheading param offtype caption = "Offset Type" default = 0 enum = "Normal" "Diff" "Mix" visible = @ttype == "Worley" endparam param offtypes caption = "Offset Type" default = 0 enum = "Normal" "Sum" visible = @ttype == "SFBM II" endparam bool param soffset caption = "Scale offset" default = true endparam float param offval caption = "Offset scale value" default = 1 visible = @soffset endparam param weighttype caption = "Weight Type" default = 1 enum = "Flavor 1" "Flavor 2" "Flavor 3" endparam param flavor caption = "Flavor" default = 1 enum = "Chebychev" "Euclidian" "Manhattan" "Exp/Log Manhattan" "Minkovsky" visible = @ttype == "Worley" endparam float param ex caption = "Minkovsky param" default = 0.25 visible = @flavor == "Minkovsky" && @ttype == "Worley" endparam complex param mp caption = "Manhattan pwr" default = (1,1) visible = @flavor == "Manhattan" && @ttype == "Worley" endparam param type caption = "Worley type" default = 1 enum = "Distance" "2nd Distance" "2nd Distance variant" "Mosaic" visible = @ttype == "Worley" endparam float param smod caption = "2nd dist mod" default = 1.0 visible = @type == "2nd Distance" && @offtype =="Normal" && @ttype == "Worley" endparam param psize caption = "Pattern Size" default = 0.05 endparam float param thick caption = "Thickness" default = 1 visible = @offtype == "Normal" && @ttype == "Worley" endparam float param dmod caption = "Dist modulator" default = 0.0 min = 0.0 visible = @offtype == "Normal" endparam bool param invert caption = "Invert" default = false visible = @type != "Mosaic" && @offtype =="Normal" && @ttype == "Worley" endparam int param seed caption = "Random seed" default = 123 visible = @ttype == "Worley" endparam param noise caption = "Noise Function" default = 0 enum = "Perlin" "Raw Gird" "Strips" "Corners" "Checkerboard" \ "Soft Gird" "Circles" "Soft Circles" "Squares" "Soft Squares" \ "Octogons" "Soft Octogons" "Roundy Truchet" "Soft Roundy Truchet" \ "Squarry Truchet" "Soft Squarry Truchet" visible = @ttype == "SFBM II" endparam param noisep caption = "Noise F. Parameters" default = (.2,.5) hint = "Noise Function Parameters" visible = @ttype == "SFBM II" endparam param f1 caption = "texture 1" default = 0 enum = "Original" "Wavy" "Blobs" "Cut" "Messy" "Soft I" "Strings" "Soft II" "Sharp" "String-Sharp" "Random Phase" visible = @ttype == "SFBM II" endparam param fp1 caption = "texture 1 Parameters" default = (1,0) visible = @ttype == "SFBM II" endparam param f2 caption = "texture 2" default = 0 enum = "Original" "Wavy" "Blobs" "Cut" "Messy" "Soft I" "Strings" "Soft II" "Sharp" "String-Sharp" "Random Phase" visible = @ttype == "SFBM II" endparam param fp2 caption = "texture 2 Parameters" default = (1,0) visible = @ttype == "SFBM II" endparam param mode caption = "Mode" default = 0 enum = "Normal" "Convolution" "Absolute Convolution" visible = @ttype == "SFBM II" endparam param beta caption = "Beta (Spectral Density Parameter)" default = 1.0 hint = "Spectral Density Exponent" visible = @ttype == "SFBM II" endparam param power caption = "Power" default = 2.0 visible = @ttype == "SFBM II" endparam param power2 caption = "Post-Power" default = 1.0 visible = @ttype == "SFBM II" endparam param pp caption = "Pre-Processing" default = (0,1) visible = @ttype == "SFBM II" endparam param pptype caption = "Pre-Processing Type" default = 0 enum = "Cartesian" "Polar" hint = "Pre-Processing Type" visible = @ttype == "SFBM II" endparam param ppp caption = "Pre-P. Power and Aspect" default = (1,1) hint = "Pre-Processing Power and Aspect" visible = @ttype == "SFBM II" endparam param rot caption = "Rotation Step" default = 28.0 visible = @ttype == "SFBM II" endparam param mstep caption = "Frequency Separation" default = 1.0 hint = "Frequency Separation" visible = @ttype == "SFBM II" endparam param fmm caption = "Inv. of max/min Frequency" default = (40,1) hint = "Inverse of max/min Frequency" visible = @ttype == "SFBM II" endparam param interp caption = "Frequency Interpolation" default = 0 enum = "Logarithmic" "Linear" hint = "Frequency Interpolation" visible = @ttype == "SFBM II" endparam param cc caption = "Center Extra Weight" default = 0.0 visible = @ttype == "SFBM II" endparam param cbl caption = "Bottom Left Weight" default = 1.0 visible = @ttype == "SFBM II" endparam param ctl caption = "Top Left Weight" default = 0.0 visible = @ttype == "SFBM II" endparam param cbr caption = "Bottom Right Weight" default = 0.0 visible = @ttype == "SFBM II" endparam param ctr caption = "Top Right Weight" default = 0.0 visible = @ttype == "SFBM II" endparam param eps caption = "Epsilon" default = 0.006 visible = @ttype == "SFBM II" endparam } class REB_NullFilter(dmj5.ulb:DMJ_ConvolutionFilter) { public: import "common.ulb" import "dmj5.ulb" ; contructor func REB_NullFilter(Generic pparent) DMJ_ConvolutionFilter.DMJ_ConvolutionFilter(pparent) int elements = 1 setLength(m_Offsets, elements) setLength(m_Weights, elements) m_offsets[0] = 0 m_weights[0] = 1 m_multiplier = 1 endfunc default: title = "Null Filter" int param v_nullfilter caption = "Version (Null Filter)" 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_nullfilter < 100 endparam } ;---------------------------------------- ; Generator Classes ;----------------------------------------- class REB_KerrysSelect(common.ulb:Generator) { ; based upon the selection criteria in a private version of ; Kerry Mitchell's RRL code. public: import "common.ulb" import "dmj5.ulb" ; Constructor func REB_KerrysSelect(Generic pparent) Generator.Generator(pparent) do_last=0 fib1=0 fib2=0 gfac=0 gi=0 gj=0 ; ; clear do_this array ; gi=-1 while(gi<#maxiter) gi=gi+1 do_this[gi]=false endwhile ; ; set up counter for final iteration ; if((@dolast==0)||(@dolast>#maxiter)) do_last=#maxiter else do_last=@dolast endif ; ; create array of Fibonacci numbers ; gi=0 while(gi<#maxiter) gi=gi+1 fib[gi]=false endwhile fib1=0 fib2=1 gi=1 while(gi<#maxiter) fib[gi]=true fib1=fib2 fib2=gi gi=fib1+fib2 endwhile ; ; create array of triangular numbers ; gi=0 while(gi<#maxiter) gi=gi+1 tri[gi]=false endwhile gi=0 gj=1 while(gi<#maxiter) tri[gi]=true gi=gi+gj gj=gj+1 endwhile ; ; set do_this flag if that iteration is to be used ; gi=@do_first-1 while(gi<(do_last-1)) gi=gi+1 if(@modtype=="do all") ; do each iteration do_this[gi]=true elseif(@modtype=="do every n") ; do every nth gj=(gi-@do_first+#maxiter*@modbase)%@modbase if(gj==0) do_this[gi]=true endif elseif(@modtype=="skip every n") ; skip every nth gj=(gi-@do_first+#maxiter*@modbase)%@modbase if(gj>0) do_this[gi]=true endif elseif(@modtype=="do primes") ; do if iteration # is prime gj=1 gfac=2 while(gj<(gi-1)) gj=gj+1 if((gi%gj)==0) gfac=gfac+1 endif endwhile if(gfac==2) do_this[gi]=true endif elseif(@modtype=="skip primes") ; do if iteration # is not prime if(gi==1) do_this[gi]=true endif gj=1 gfac=2 while(gj<(gi-1)) gj=gj+1 if((gi%gj)==0) gfac=gfac+1 endif endwhile if(gfac>2) do_this[gi]=true endif elseif(@modtype=="do Fibonacci") ; do if iteration is a Fibonacci # if(fib[gi]==true) do_this[gi]=true endif elseif(@modtype=="skip Fibonacci") ; do if iteration is not a Fibonacci # if(fib[gi]==false) do_this[gi]=true endif elseif(@modtype=="do triangular") ; do if iteration is a triangular # if(tri[gi]==true) do_this[gi]=true endif elseif(@modtype=="skip triangular") ; do if iteration is not a triangular # if(tri[gi]==false) do_this[gi]=true endif elseif(@modtype=="blocks") ; blocks of trap some, then skip some gj=((gi-@do_first)%@block_size)+1 if(gj<=@block_trap) do_this[gi]=true endif endif endwhile endfunc float func Init(float pz) Generator.Init(pz) iter = 0 m_BailedOut = false return pz endfunc float func Iterate(float pz) Generator.Iterate(pz) iter=iter+1 if(do_this[iter]==true) return 1 else return 0 endif endfunc protected: bool do_this[round(#maxiter+1)] bool fib[round(#maxiter+1)] bool tri[round(#maxiter+1)] int do_last int fib1 int fib2 int gfac int gi int gj int iter default: title = "Kerry's Select" int param v_reb_kerryselect caption = "Version (Kerry's Select)" 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_reb_kerryselect < 100 endparam heading caption="Selected iterations parameters" endheading param modtype caption="mod type" default=0 enum="do all" "do every n" "skip every n" "do primes" "skip primes"\ "do Fibonacci" "skip Fibonacci" "do triangular" "skip triangular" \ "blocks" endparam int param modbase caption="n" default=2 min=2 hint="The 'n' for type 'every n'; at least 2." visible=((@modtype=="do every n")||(@modtype=="skip every n")) endparam int param block_size caption="block size" default=4 min=3 visible=(@modtype=="blocks") endparam int param block_trap caption="block trap" default=2 min=1 visible=(@modtype=="blocks") endparam int param do_first caption="first iteration" default=1 min=1 hint="Start with this iteration." endparam int param dolast caption="last iteration" default=0 min=0 hint="End on this iteration; use 0 for maximum iterations." endparam } ;-------------------------------------------------- ; Formula classes for embossing ;-------------------------------------------------- Class REB_EmbossFormula(common.ulb:Generic) { public: import "common.ulb" ; constructor func REB_EmbossFormula(Generic pparent) endfunc complex func Init(complex pz) rotangle=-@rotd/180*#pi tz = 0 rz = 0 return pz endfunc float func Iterate(complex pz,float &tz) return 1 endfunc protected: float tz float rz float rotangle default: int param v_REB_EmbossFormula caption = "Version (Emboss Formula)" 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_REB_EmbossFormula < 100 endparam float param rotd caption="rotation angle" default=0 hint="degrees" endparam } Class REB_EmbossRRL(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossRRL(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile rz=@ac*cos(@bc*tz)+@as*sin(@bs*tz) return rz endfunc default: title = "Rose Range Lite" int param v_RoseRangeLite caption = "Version (Rose Range Lite)" 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_RoseRangeLite< 100 endparam float param ac caption="cos amplitude" default=1 endparam float param bc caption="cos frequency" default=3 endparam float param as caption="sin amplitude" default=0 endparam float param bs caption="sin frequency" default=0 endparam } Class REB_KCCEmbossAmpersandTrap(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_KCCEmbossAmpersandTrap(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) float d = 1e20 tz=atan2(pz)+rotangle pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real( pz) y = imag( pz) ; Compute the Ampersand Curve. d = cabs(@fn1((@fn2(y^(2*@shapeAdjust3))-@fn3(x^2+(1-@shapeAdjust4)))* \ @fn4((x^@shapeAdjust5)-1)*(@shapeAdjust1*@fn5(x)-@shapeAdjust2)- \ 4*(@fn6(x^2*@shapeAdjust6)+@fn7(y^(2*@shapeAdjust7))-2* \ @fn8(x^@shapeAdjust8))^2))-@distort return d endfunc protected: float x float y default: title = "KCC Ampersand Trap" int param v_KCCAmpersandTrap caption = "Version (KCC Ampersand Trap)" 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_KCCAmpersandTrap< 100 endparam float param scale caption = "scale" default = 1 endparam param adv caption = "Advanced Options" hint = "Additional shaping parameters and functions." default = false endparam float param distort caption = "Fission" hint = "Generally stretches and splits the elements" default = 0 visible = @adv endparam float param shapeAdjust1 caption = "Shape Adj. I" default = 1.0 hint = "Shape adjustment parameter I." endparam float param shapeAdjust2 caption = "Shape Adj. II" default = 1.0 hint = "Shape adjustment parameter II." endparam float param shapeAdjust3 caption = "Shape Adj. III" default = 1.0 hint = "Shape adjustment parameter III." visible = @adv endparam float param shapeAdjust4 caption = "Shape Adj. IV" default = 1.0 hint = "Shape adjustment parameter IV." visible = @adv endparam float param shapeAdjust5 caption = "Shape Adj. V" default = 1.0 hint = "Shape adjustment parameter V." visible = @adv endparam float param shapeAdjust6 caption = "Shape Adj. VI" default = 1.0 hint = "Shape adjustment parameter VI." visible = @adv endparam float param shapeAdjust7 caption = "Shape Adj. VII" default = 1.0 hint = "Shape adjustment parameter VII." visible = @adv endparam float param shapeAdjust8 caption = "Shape Adj. VIII" default = 1.0 hint = "Shape adjustment parameter VIII." visible = @adv endparam func fn1 default = abs () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn2 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn3 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn4 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn5 caption = "Function 5" default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn6 caption = "Function 6" default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn7 caption = "Function 7" default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn8 caption = "Function 8" default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc } Class REB_KCCEmbossBicuspidTrap(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_KCCEmbossBicuspidTrap(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) float d = 1e20 tz=atan2(pz)+rotangle pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real( pz ) y = imag( pz ) d = cabs(@fn1(@fn2(x^(2*@shapeAdjust2)-@shapeAdjust1^2)* \ @fn3(x^@shapeAdjust3-@shapeAdjust1)^2+ \ @fn4(y^(2*@shapeAdjust4)-@shapeAdjust1^2)^2))-@distort return d endfunc protected: float x float y default: title = "KCC Bicuspid Trap" int param v_KCCBicuspidTrap caption = "Version (KCC Bicuspid Trap)" 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_KCCBicuspidTrap< 100 endparam param adv caption = "Advanced Options" hint = "Additional shaping parameters and functions." default = false endparam float param distort caption = "Fission" hint = "Generally stretches and splits the elements" default = 0 visible = @adv endparam float param shapeAdjust1 caption = "Shape Adj. I" default = 1.0 hint = "Shape adjustment parameter I." endparam float param shapeAdjust2 caption = "Shape Adj. II" default = 1.0 hint = "Shape adjustment parameter II." endparam float param shapeAdjust3 caption = "Shape Adj. III" default = 1.0 hint = "Shape adjustment parameter III." visible = @adv endparam float param shapeAdjust4 caption = "Shape Adj. IV" default = 1.0 hint = "Shape adjustment parameter IV." visible = @adv endparam func fn1 default = abs () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn2 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn3 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn4 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc } Class REB_KCCEmbossCockedHatTrap(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_KCCEmbossCockedHatTrap(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) float d = 1e20 tz=atan2(pz)+rotangle pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real( pz ) y = imag( pz ) d = cabs(@fn1(@fn2(x^2*@shapeAdjust3)+2*@shapeAdjust1*@fn3(y^@shapeAdjust4)- \ @shapeAdjust1^2)^2-@fn4(y^(3-@shapeAdjust5))* \ (@shapeAdjust2^2-@fn5(x^2*@shapeAdjust6)))-@distort return d endfunc protected: float x float y float minDist default: title = "KCC Cocked Hat Trap" int param v_KCCCockedHatTrap caption = "Version (KCC Cocked Hat Trap)" 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_KCCCockedHatTrap< 100 endparam param adv caption = "Advanced Options" hint = "Additional shaping parameters and functions." default = false endparam float param distort caption = "Fission" hint = "Generally stretches and splits the elements" default = 0 visible = @adv endparam float param shapeAdjust1 caption = "Shape Adj. I" default = 1.0 hint = "Shape adjustment parameter I." endparam float param shapeAdjust2 caption = "Shape Adj. II" default = 1.0 hint = "Shape adjustment parameter II." endparam float param shapeAdjust3 caption = "Shape Adj. III" default = 1.0 hint = "Shape adjustment parameter III." visible = @adv endparam float param shapeAdjust4 caption = "Shape Adj. IV" default = 1.0 hint = "Shape adjustment parameter IV." visible = @adv endparam float param shapeAdjust5 caption = "Shape Adj. V" default = 1.0 hint = "Shape adjustment parameter V." visible = @adv endparam float param shapeAdjust6 caption = "Shape Adj. VI" default = 1.0 hint = "Shape adjustment parameter VI." visible = @adv endparam func fn1 default = abs () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn2 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn3 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn4 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn5 caption = "Function 5" default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc } Class REB_KCCEmbossDurersConchoidTrap(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_KCCEmbossDurersConchoidTrap(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) float d = 1e20 tz=atan2(pz)+rotangle pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real( pz ) y = imag( pz ) d = cabs(@fn1(2*@fn2(y^(1+@shapeAdjust3))*(@fn3(x^(1+@shapeAdjust4))+ \ @fn4(y^2*@shapeAdjust5))-2*@shapeAdjust2* \ @fn5(y^2+(1-@shapeAdjust6))*(@fn6(x^@shapeAdjust7)+ \ @fn7(y+(1-@shapeAdjust8)))+(@shapeAdjust2^2-3*@shapeAdjust1^2)* \ @fn8(y^(1+@shapeAdjust9))-@shapeAdjust1^2* \ @fn9(x^2*@shapeAdjust10)+2*@shapeAdjust1^2*@shapeAdjust2* \ (@fn10(x^@shapeAdjust11)+@fn11(y^@shapeAdjust12))+ \ @shapeAdjust1^2*(@shapeAdjust1^2-@shapeAdjust2^2)))-@distort return d endfunc protected: float x float y default: title = "KCC Durers Conchoid Trap" int param v_KCCDurersConchoidTrap caption = "Version (KCC Durers Conchoid Trap)" 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_KCCDurersConchoidTrap< 100 endparam param adv caption = "Advanced Options" hint = "Additional shaping parameters and functions." default = false endparam float param distort caption = "Fission" hint = "Generally stretches and splits the elements" default = 0 visible = @adv endparam float param shapeAdjust1 caption = "Shape Adj. I" default = 1.0 hint = "Shape adjustment parameter I." endparam float param shapeAdjust2 caption = "Shape Adj. II" default = 1.0 hint = "Shape adjustment parameter II." endparam float param shapeAdjust3 caption = "Shape Adj. III" default = 1.0 hint = "Shape adjustment parameter III." visible = @adv endparam float param shapeAdjust4 caption = "Shape Adj. IV" default = 1.0 hint = "Shape adjustment parameter IV." visible = @adv endparam float param shapeAdjust5 caption = "Shape Adj. V" default = 1.0 hint = "Shape adjustment parameter V." visible = @adv endparam float param shapeAdjust6 caption = "Shape Adj. VI" default = 1.0 hint = "Shape adjustment parameter VI." visible = @adv endparam float param shapeAdjust7 caption = "Shape Adj. VII" default = 1.0 hint = "Shape adjustment parameter VII." visible = @adv endparam float param shapeAdjust8 caption = "Shape Adj. VIII" default = 1.0 hint = "Shape adjustment parameter VIII." visible = @adv endparam float param shapeAdjust9 caption = "Shape Adj. IX" default = 1.0 hint = "Shape adjustment parameter IX." visible = @adv endparam float param shapeAdjust10 caption = "Shape Adj. X" default = 1.0 hint = "Shape adjustment parameter X." visible = @adv endparam float param shapeAdjust11 caption = "Shape Adj. XI" default = 1.0 hint = "Shape adjustment parameter XI." visible = @adv endparam float param shapeAdjust12 caption = "Shape Adj. XII" default = 1.0 hint = "Shape adjustment parameter XII." visible = @adv endparam func fn1 default = abs () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn2 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn3 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn4 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn5 caption = "Function 5" default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn6 caption = "Function 6" default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn7 caption = "Function 7" default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn8 caption = "Function 8" default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn9 caption = "Function 9" default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn10 caption = "Function 10" default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn11 caption = "Function 11" default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc } Class REB_KCCKepplersFoliumTrap(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_KCCKepplersFoliumTrap(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) pz = ApplyRatioAndSize( pz ) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile x = real( pz ) y = imag( pz ) pz = @fn1(((@fn2(x^@shapeAdjust3)-@shapeAdjust2)^2+ \ @fn3(y^2+(1-@shapeAdjust4)))*(@fn4(x+(1-@shapeAdjust5))* \ (@fn5(x-(@shapeAdjust6-1))-@shapeAdjust2)+@fn6 \ (y^(1+@shapeAdjust7)))-4*@shapeAdjust1* \ (abs(@fn7(x+(@shapeAdjust8-1)))-@shapeAdjust2)* \ @fn8(y^(2*@shapeAdjust9)))-@distort minDist = abs(real(pz)) if( minDist < @width ) return minDist ; return minDist else return 1e20 endif endfunc complex func ApplyRatioAndSize( complex pz ) pz = pz / @size float x = sqrt( @ratio ) * real( pz ) float y = 1 / sqrt( @ratio ) * imag( pz ) return x + flip( y ) endfunc protected: float x float y float minDist default: title = "KCC Kepplers Folium Trap" int param v_KCCKepplersFoliumTrap caption = "Version (KCC Kepplers Folium Trap)" 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_KCCKepplersFoliumTrap< 100 endparam float param size caption = "Size" default = 1.0 hint = "The size of the trap shape." endparam float param width caption = "Width" default = 2 hint = "The width of the trap." endparam float param ratio caption = "H/W Ratio" default = 1.0 hint = "The ration of height to width." endparam param adv caption = "Advanced Options" hint = "Additional shaping parameters and functions." default = false endparam float param distort caption = "Fission" hint = "Generally stretches and splits the elements" default = 0 visible = @adv endparam float param shapeAdjust1 caption = "Shape Adj. I" default = 1.0 hint = "Shape adjustment parameter I." endparam float param shapeAdjust2 caption = "Shape Adj. II" default = 1.0 hint = "Shape adjustment parameter II." endparam float param shapeAdjust3 caption = "Shape Adj. III" default = 1.0 hint = "Shape adjustment parameter III." visible = @adv endparam float param shapeAdjust4 caption = "Shape Adj. IV" default = 1.0 hint = "Shape adjustment parameter IV." visible = @adv endparam float param shapeAdjust5 caption = "Shape Adj. V" default = 1.0 hint = "Shape adjustment parameter V." visible = @adv endparam float param shapeAdjust6 caption = "Shape Adj. VI" default = 1.0 hint = "Shape adjustment parameter VI." visible = @adv endparam float param shapeAdjust7 caption = "Shape Adj. VII" default = 1.0 hint = "Shape adjustment parameter VII." visible = @adv endparam float param shapeAdjust8 caption = "Shape Adj. VIII" default = 1.0 hint = "Shape adjustment parameter VIII." visible = @adv endparam float param shapeAdjust9 caption = "Shape Adj. IX" default = 1.0 hint = "Shape adjustment parameter IX." visible = @adv endparam func fn1 default = abs () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn2 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn3 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn4 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn5 caption = "Function 5" default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn6 caption = "Function 6" default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn7 caption = "Function 7" default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn8 caption = "Function 8" default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc } Class REB_KCCKnotCurveTrap(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_KCCKnotCurveTrap(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) pz = ApplyRatioAndSize( pz ) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile x = real( pz ) y = imag( pz ) pz = @fn1((@fn2(x^(1+@shapeAdjust1)-1)^2)-@fn3(y^2*@shapeAdjust2)* \ (3+2*@fn4(y*@shapeAdjust3)))-@distort minDist = abs(real(pz)) if( minDist < @width ) return minDist ; return minDist else return 1e20 endif endfunc complex func ApplyRatioAndSize( complex pz ) pz = pz / @size float x = sqrt( @ratio ) * real( pz ) float y = 1 / sqrt( @ratio ) * imag( pz ) return x + flip( y ) endfunc protected: float x float y float minDist default: title = "KCC Knot Curve Trap" int param v_KCCKnotCurveTrap caption = "Version (KCC Knot Curve Trap)" 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_KCCKnotCurveTrap< 100 endparam float param size caption = "Size" default = 1.0 hint = "The size of the trap shape." endparam float param width caption = "Width" default = 2 hint = "The width of the trap." endparam float param ratio caption = "H/W Ratio" default = 1.0 hint = "The ration of height to width." endparam param adv caption = "Advanced Options" hint = "Additional shaping parameters and functions." default = false endparam float param distort caption = "Fission" hint = "Generally stretches and splits the elements" default = 0 visible = @adv endparam float param shapeAdjust1 caption = "Shape Adj. I" default = 1.0 hint = "Shape adjustment parameter I." endparam float param shapeAdjust2 caption = "Shape Adj. II" default = 1.0 hint = "Shape adjustment parameter II." endparam float param shapeAdjust3 caption = "Shape Adj. III" default = 1.0 hint = "Shape adjustment parameter III." visible = @adv endparam func fn1 default = abs () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn2 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn3 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc func fn4 default = ident () hint = "Changes the shapes of the elements and their relations to each other" visible = @adv endfunc } class REB_EmbossDoodads(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossDoodads(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) x = 0 y = 0 zr = 0 zi = 0 zz = 0 z1 = 0 a2 = 0 s1 = 0 g1 = 0 ff = 0 gc = 0 zc = 0 fc = 0 zr1 = 0 zi1 = 0 fmr = real(@fm) fmi = imag(@fm) sn = 1 if @m % 2 == 1 sn = -1 endif vsa = sn*@sa/10 vsb = abs(@sb/10) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile if @rotvar == "no rotation" z1 = pz zc = @fn4(z1) zr = real(zc) zi = imag(zc) else if @rotvar == "variant 1" z1 = pz*tz else z1 = pz endif if @rotvar == "variant 2" zc = @fn4(z1*tz) else zc = @fn4(z1) endif if @rotvar == "variant 3" zr = real(zc)*tz zi = imag(zc)*tz else zr = real(zc) zi = imag(zc) endif endif if (@m > 3 && @m < 26) || @mr == 5 || @mr == 8 \ || @mr == 9 || @mr == 12 gc = @fn3(@fn1(@fn2(z1))) g1 = cabs(gc) endif if @m == 7 || @mr == 5 a2 = atan2(gc) endif if @m == 8 || @m == 9 || @m == 12 || @m == 13 \ || @m > 19 || @mr == 9 || @mr == 11 s1 = cabs(zc) endif if @m == 12 || @m == 13 || @m == 22 || @m == 23 \ || @m == 26 || @m == 27 || @mr == 10 || @mr == 12 ff = cabs(@fn3(@fn1(real(z1))+@fn2(imag(z1)))) endif if @m >27 fc = @fn3(@fn1(real(z1))+flip(@fn2(imag(z1)))) endif if @mr < 5 || @mr >= 13 zr1 = real(@fn1(zr*fmr)) zi1 = real(@fn2(zi*fmi)) endif if @mrf zr1 = abs(zr1) zi1 = abs(zi1) endif if @mr == 0 zz = real(@fn3(zr1*zi1)) elseif @mr == 1 zz = real(@fn3(zr1+zi1)) elseif @mr == 2 zz = real(@fn3(zr1/zi1)) elseif @mr == 3 zz = real(@fn3(zi1^zr1)) elseif @mr == 4 zz = real(@fn3(zr1^zi1)) elseif @mr == 5 zz = real(@fn4(@fn3(abs(@fn1(g1*fmr)-@fn2(a2*fmi))))) elseif @mr == 6 if !@mrf zz = real(atan(@fn3(@fn1(zr*fmr)) \ /(@fn3(@fn2(zi^2*fmi))))) else zz = real(atan(@fn3(abs(@fn1(zr*fmr)) \ /(@fn3(abs(@fn2(zi^2*fmi))))))) endif elseif @mr == 7 zz = cabs(recip(@fn3(@fn2(@fn1(zc*fmr*2))))) elseif @mr == 8 zz = real(@fn3(@fn1(abs((g1-zr)*fmr/(g1-zi)*fmi))))^.1 elseif @mr == 9 float temp = abs((g1-zr)*fmr/(g1+1e-20)) zz = real(@fn3(abs(@fn1(temp)-@fn2(s1*fmi)))) elseif @mr == 10 zz = cabs(@fn4(ff*fmr-gc*fmi))^2 elseif @mr == 11 zz = cabs(@fn4(s1-1)*fmr/(s1+1)*fmi) elseif @mr == 12 zz = cabs(@fn4(g1)*fmr/(ff)*fmi) elseif @mr == 13 zz = real(@fn3(zi1/zr1)) elseif @mr == 14 zz = real(@fn3((zi1*zr1)/(zi1+zr1))) elseif @mr == 15 zz = real(@fn3((zi1-zr1)/(zi1+zr1))) endif if @m < 2 y = zr elseif @m == 2 || @m == 3 y = zr*3-zi elseif @m == 4 y = abs(g1^3/(zr-g1)) elseif @m == 5 y = zr/2+g1 elseif @m == 6 y = g1^3 elseif @m == 7 y = g1^2/a2 elseif @m == 8 || @m == 9 y = zr*s1/zi elseif @m == 10 || @m == 11 y = g1^2 elseif @m == 12 || @m == 13 y = g1-abs((ff-g1)/s1) elseif @m == 14 || @m == 15 y = g1-zr/g1 elseif @m == 16 || @m == 17 y = g1-abs(zr/g1) elseif @m == 18 || @m == 19 y = g1 elseif @m == 20 || @m == 21 y = s1*.1/g1^2 elseif @m == 22 || @m == 23 y = g1^2-abs((ff-g1)/s1) elseif @m == 24 || @m == 25 y = g1^2-s1 elseif @m == 26 || @m == 27 y = ff else y = imag(fc) endif y = real(@fn9(y - @tad/10)) if @sa < 0 && sn == -1 y = y * (-@sa+5)/5 vsa = sn*@sa/20 endif if @sb > 0 y = y % vsb endif if @m % 2 == 0 x = zz - @mul*(real(abs(@fn1(y - abs(@fn2(y)))))) else x = zz - @mul*y endif if @sb < 0 x = x % vsb endif x = x + vsa xb = (@fn8(x + flip(y)))^@pwr if @rotvar == "variant 4" zz = cabs(z1 - xb)*tz else zz = cabs(z1 - xb) endif return zz endfunc protected: float x float y float zr float zi float zz float a2 float s1 float g1 float ff complex gc complex zc complex fc complex z1 float zr1 float zi1 float fmr float fmi int sn float vsa float vsb default: title = "Doodads" int param v_doodad caption = "Version (Doodads)" 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_doodad < 100 endparam param rotvar caption = "Rot angle variants" enum = "no rotation" "variant 1" "variant 2" "variant 3" "variant 4" endparam param trp caption = "More Trap Parameters" hint = "Additional parameters less frequently used." default = true endparam param m caption = " Trap Mode" enum = "1" "2" "3" "4" "5" "6" "7" "8" \ "9" "A" "B" "C" "D" "E" "F" "G" \ "H" "I" "J" "K" "L" "M" "N" "O" \ "P" "Q" "R" "S" "T" "U" default = 0 endparam param mr caption = "Flavor" enum = "A" "B" "C" "D" "E" "F" "G" \ "H" "I" "J" "K" "L" "M" "N" \ "O" "P" default = 0 endparam param mrf caption = "Apply ABS to Flavor" default = false visible = @mr < 5 && @trp endparam param tad caption = "Trap Addend" default = 0.0 visible = @trp endparam param fm caption = "Flavor Multiplier" default = (1,1) visible = @trp endparam param pwr caption = "`Trap Power'" default = 3.0 visible = @trp endparam param mul caption = " Trap Multiplier" default = 3.0 visible = @trp endparam param sb caption = "'Ripple' Control" hint = "A few Trap Modes are unaffected by this \ parameter. Useful Range is -50 to 50" default = 0.0 visible = @trp endparam param sa caption = "Expand+|-Contract" hint = "Useful Range is around -10 to 10" default = 0.0 visible = @trp endparam heading caption = "Functions" endheading func fn4 caption = "Initial function" default = ident() endfunc func fn1 caption = "Real function" default = ident() endfunc func fn2 caption = "Imag function" default = ident() endfunc func fn3 caption = "Overall function" default = ident() endfunc func fn9 caption = "First Trap function" default = ident() visible = @trp endfunc func fn8 caption = "Final Trap function" default = ident() endfunc } Class REB_EmbossLimaconOfPascal(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossLimaconOfPascal(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 0.05*@b + @a*cos(tz) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Limacon Of Pascal" int param v_LimaconOfPascal caption = "Version (Limacon Of Pascal)" 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_LimaconOfPascal< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects shape and scale of trap." endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossKappaCurve(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossKappaCurve(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 0.1*@a*tan(tz) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Kappa Curve" int param v_KappaCurve caption = "Version (Kappa Curve)" 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_KappaCurve< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossKampyleofEudoxus(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossKampyleofEudoxus(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 0.02*@a/cos(tz)^2 if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Kampyle of Eudoxus" int param v_KampyleofEudoxus caption = "Version (Kampyle of Eudoxus)" 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_KampyleofEudoxus< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossHyperbolicSpiral(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossHyperbolicSpiral(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = @a/tz if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Hyperbolic Spiral" int param v_HyperbolicSpiral caption = "Version (Hyperbolic Spiral)" 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_HyperbolicSpiral< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossHyperbola(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossHyperbola(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 0.35*@a*(1/cos(2*tz))^0.5 if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Hyperbola" int param v_Hyperbola caption = "Version (Hyperbola)" 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_Hyperbola< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossHipopede(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossHipopede(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = (0.5*@b*(0.5*@a-(0.5*@b)^2*cos(tz)))^0.5 if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Hipopede" int param v_Hipopede caption = "Version (Hipopede)" 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_Hipopede< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossHeartCurve(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossHeartCurve(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile tz = (7.5*@a*tz)%1 float x = 0.33*@b*sin(tz)*cos(tz)*log(abs(tz)) float y = 0.33*@b*abs(tz)^0.3*cos(tz)^0.5 rz = cabs(x + flip(y)) return rz endfunc default: title = "Heart Curve" int param v_HeartCurve caption = "Version (Heart Curve)" 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_HeartCurve< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam } Class REB_EmbossFoliumOfDescartes(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossFoliumOfDescartes(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 0.3*@a*tan(tz)/(cos(tz)*(1+tan(tz)^3)) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Folium Of Descartes" int param v_FoliumOfDescartes caption = "Version (Folium Of Descartes)" 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_FoliumOfDescartes< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossFermatsSpiral(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossFermatsSpiral(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 2*@a*tz^0.5 if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Fermat's Spiral" int param v_FermatsSpiral caption = "Version (Fermat's Spiral)" 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_FermatsSpiral< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossEquiangularSpiral(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossEquiangularSpiral(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = @a*exp(tz*cotan(@b/2)) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Equiangular Spiral" int param v_EquiangularSpiral caption = "Version (Equiangular Spiral)" 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_EquiangularSpiral< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossEpispiral(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossEpispiral(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 0.25*@a/cos(@pn*tz) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Epispiral" int param v_Epispiral caption = "Version (Epispiral)" 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_Epispiral< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam int param pn caption = "Polar integer" default = 3 hint = "Affects shape and scale of trap." endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossEightCurve(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossEightCurve(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = @a*cos(tz)^(-2)*cos(2*tz)^0.5 if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Eight Curve" int param v_EightCurve caption = "Version (Eight Curve)" 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_EightCurve< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossDipoleCurve(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossDipoleCurve(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = @a*(cos(tz))^2 if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Dipole Curve" int param v_DipoleCurve caption = "Version (Dipole Curve)" 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_DipoleCurve< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossDevilsCurve(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossDevilsCurvem(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = (((0.5*@a*sin(tz))^2-(0.2*@b*cos(tz))^2)/(sin(tz)^2-cos(tz)^2))^0.5 if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Devil's Curve" int param v_DevilsCurve caption = "Version (Devil's Curve)" 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_DevilsCurve< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects shape and scale of trap." endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossConchoidOfDeSluze(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossConchoidOfDeSluze(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = @a*(1/cos(tz) - 1.5*@b*cos(tz)) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Conchoid Of DeSluze" int param v_ConchoidOfDeSluze caption = "Version (Conchoid Of DeSluze)" 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_ConchoidOfDeSluze< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossCotesSpiral(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCotesSpiral(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = @a/cosh(@b*tz) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Cote's Spiral" int param v_CotesSpiral caption = "Version (Cote's Spiral)" 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_CotesSpiral< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossConchoid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossConchoid(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 0.1*(@a + @b*cos(tz))/cos(tz) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Conchoid" int param v_Conchoid caption = "Version (Conchoid)" 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_Conchoid< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects shape and scale of trap." endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossCochleoid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCochleoid(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 1.25*@a*sin(tz)/tz if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Cochleoid" int param v_Cochleoid caption = "Version (Cochleoid)" 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_Cochleoid< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossCissoidofDiocles(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCissoidofDiocles(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float x = 0 float y = 0 if @altformula pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = x*(x^2+y^2)-2*@aa*y^2-cabs(pz)*@offset else rz = x*(x^2+y^2)-2*@aa*y^2-@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif else float rr = 0.2*@a*sin(tz)*tan(tz) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif endif return rz endfunc default: title = "Cissoid of Diocles" int param v_CissoidofDiocles caption = "Version (Cissoid of Diocles)" 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_CissoidofDiocles< 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "parameter a" default = 1 hint = "Affects spread and scale of trap" visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" visible = !@altformula endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" visible = !@altformula endparam } Class REB_EmbossCircleTangent(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCircleTangent(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 0.5*@a*(1+@b/10*sin(tz)^(8*@c)) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Circle Tangent" int param v_CircleTangent caption = "Version (Circle Tangent)" 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_CircleTangent< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param c caption = "3rd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossCircle(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCircle(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = @a*sin(tz)^2 + 0.2*@b*cos(tz)^2 if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Circle" int param v_Circle caption = "Version (Circle)" 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_Circle< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossCayleysSextic(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCayleysSextic(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float x = 0 float y = 0 if @altformula pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = -@aa^3*x^3-48*@aa*x*(x^2+y^2)^2+64*(x^2+y^2)^3-3*@aa^2*(x^2+y^2)*(5*x^2+9*y^2)-cabs(pz)*@offset else rz = -@aa^3*x^3-48*@aa*x*(x^2+y^2)^2+64*(x^2+y^2)^3-3*@aa^2*(x^2+y^2)*(5*x^2+9*y^2)-@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif else float rr = 1.5*@a*cos(tz)^3 if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif endif return rz endfunc default: title = "Cayleys Sextic" int param v_CayleysSextic caption = "Version (Cayleys Sextic)" 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_CayleysSextic< 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "parameter a" default = 1 hint = "Affects spread and scale of trap" visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" visible = !@altformula endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" visible = !@altformula endparam } Class REB_EmbossCassiniOvals(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCassiniOvals(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 0 if @negroot rr = 0.5*@a*(cos(2*tz)-((@b*0.1/(@a*0.5))^4-sin(2*tz)^2)^0.5)^0.5 else rr = 0.5*@a*(cos(2*tz)+((@b*0.1/(@a*0.5))^4-sin(2*tz)^2)^0.5)^0.5 endif if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "CassiniOvals" int param v_CassiniOvals caption = "Version (CassiniOvals)" 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_CassiniOvals< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam param negroot caption = "Quad Neg Root" default = false endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossButterfly(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossButterfly(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float x = 0 float y = 0 if @altformula pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = y^6+x^6-x^2-cabs(pz)*@offset else rz = y^6+x^6-x^2-@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif else float rr = 0.25*@a*(exp(sin(tz))-2*cos(4*tz)+sin(1/24*(2*tz-#pi))) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif endif return rz endfunc default: title = "Butterfly" int param v_Butterfly caption = "Version (Butterfly)" 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_Butterfly< 100 endparam heading text = "The 'Alternate formula' is a sextic polynomial form while the regular form\ is exponential and uses trigometric functions." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" visible = !@altformula endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" visible = !@altformula endparam } Class REB_EmbossAppleSurface(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossAppleSurface(Generic pparent) xrot = (0,1)^(@xang/90) yrot = (0,1)^(@yang/90) temp = 0 endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) float x = (cos(real(pz))*(4 + 3.8*cos(imag(pz))))*@ap*@scale2 float y = (sin(real(pz))*(4 + 3.8*cos(imag(pz))))*@ap*@scale2 float z = ((cos(imag(pz)) + sin(imag(pz)) - 1)+\ (1 + sin(imag(pz)))*log(1 - #pi*imag(pz) / 10) +\ 7.5*sin(imag(pz)))*@ap*@scale2 ; ; Y axis rotation ; temp = x + flip(z) temp = temp*yrot x = real(temp) z = imag(temp) ; ; X axis rotation ; temp = y + flip(z) temp = temp*xrot y = real(temp) z = imag(temp) ; calculate 3D distance float d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +z^2)*@scale if @usez if @ttz == "cabs(z)" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*cabs(pz)-z)^2)*@scale elseif @ttz == "real+imag z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz)+imag(pz))-z)^2)*@scale elseif @ttz == "real z" d = sqrt((imag(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(real(pz))-z)^2)*@scale elseif @ttz == "real z" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*(imag(pz))-z)^2)*@scale elseif @ttz == "angle pz" d = sqrt((real(pz)-x)^2 + (imag(pz)-y)^2 +(@sz*atan2(pz)-z)^2)*@scale endif endif tz = atan2(x+flip(y)) return d endfunc protected: complex xrot complex yrot complex temp default: title = "Apple Surface" heading text = "This is a 3D parametric surface." endheading int param v_AppleSurface caption = "Version (Trap Shape AppleSurface)" 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_AppleSurface < 100 endparam heading text = "The parameter 'rotation angle' is not used for Apple Surface" endheading float param xang caption = "X rotation" default = -75 endparam float param yang caption = "Y rotation" default = 20 endparam float param scale2 caption = "Precale" default = 1.0 endparam float param scale caption = "Scale" default = 0.2 endparam bool param usez caption = "fractal z for z value" default = false endparam param ttz caption = "fractal z type" enum = "cabs(z)" "real+imag z" "real z" "imag z" "angle pz" default = 0 visible = @usez endparam float param sz caption = "fractal z scale" default = 1 visible = @usez endparam float param ap caption = "param" default = 0.1 endparam } Class REB_EmbossBifolium(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossBifolium(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float x = 0 float y = 0 if @altformula pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = (x^2+y^2)^2-(x-@aa*y)*x^2-cabs(pz)*@offset else rz = (x^2+y^2)^2-(x-@aa*y)*x^2-@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif else float rr = 4*@a*sin(tz)*sin(tz)*cos(tz) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif endif return rz endfunc default: title = "Bifolium" int param v_Bifolium caption = "Version (Bifolium)" 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_Bifolium< 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 0.3 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "Bifolium param" default = 5.0 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" visible = !@altformula endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" visible = !@altformula endparam } Class REB_EmbossOphiuride(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossOphiuride(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = (0.01*@b*sin(tz)-@a*cos(tz))*tan(tz) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Ophiuride" int param v_Ophiuride caption = "Version (Ophiuride)" 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_Ophiuride< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossObliqueStrophoid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossObliqueStrophoid(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = @a*sin(@b-2*tz)/sin(@b-tz) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Oblique Strophoid" int param v_ObliqueStrophoid caption = "Version (Oblique Strophoid)" 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_ObliqueStrophoid< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossNodalCurve(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossNodalCurve(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = @a*tan(@b*tz) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Nodal Curve" int param v_NodalCurve caption = "Version (Nodal Curve)" 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_NodalCurve< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossMalteseCross(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossMalteseCross(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 0.2*@a/(cos(tz)*sin(tz)*(cos(tz)^2-sin(tz)^2))^0.5 if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Maltese Cross" int param v_MalteseCross caption = "Version (Maltese Cross)" 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_MalteseCross< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossLogSpiral(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossLogSpiral(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = exp(@a*tz) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Log Spiral" int param v_LogSpiral caption = "Version (Log Spiral)" 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_LogSpiral< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossLituus(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossLituus(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 0.25*@a/tz^0.5 if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Lituus" int param v_Lituus caption = "Version (Lituus)" 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_Lituus< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossCardioid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCardioid(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float x = 0 float y = 0 if @altformula pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = (x^2+y^2-2*@aa*x)^2-4*@aa^2*(x^2+y^2)-cabs(pz)*@offset else rz = (x^2+y^2-2*@aa*x)^2-4*@aa^2*(x^2+y^2)-@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif else float rr = @a*(1-cos(tz)) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif endif return rz endfunc default: title = "Cardioid" int param v_Cardioid caption = "Version (Cardioid)" 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_Cardioid< 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "parameter a" default = 0.75 hint = "Affects spread and scale of trap" visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" visible = !@altformula endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" visible = !@altformula endparam } Class REB_EmbossBulletNose(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossBulletNose(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float x = 0 float y = 0 if @altformula pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = @aa^2*y^2-@ab^2*x^2-x^2*y^2-cabs(pz)*@offset else rz = @aa^2*y^2-@ab^2*x^2-x^2*y^2-@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif else float rr = 0.25*@a*(@b^2*sin(tz)^2-(2*@c)^2*cos(tz)^2)^0.5/(sin(tz)*cos(tz)) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif endif return rz endfunc default: title = "Bullet Nose" int param v_BulletNose caption = "Version (Bullet Nose)" 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_BulletNose< 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "parameter a" default = 1 visible = @altformula endparam float param ab caption = "parameter b" default = 1 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param c caption = "3rd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" visible = !@altformula endparam } Class REB_EmbossAtomSpiral(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossAtomSpiral(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 0.5*@a*tz/(tz + @b*0.25) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Atom Spiral" int param v_AtomSpiral caption = "Version (Atom Spiral)" 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_AtomSpiral< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossREBAstroid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossREBAstroid(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float x = 0 float y = 0 complex af1 = 0 complex af2 = 0 complex as = 0 if @altformula pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = x^(2/3)+y^(2/3)-@a^(2/3)-cabs(pz)*@offset else rz = x^(2/3)+y^(2/3)-@a^(2/3)-@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif else af1 = @afn1(tz)^real(@pwr) af2 = @afn2(tz)^imag(@pwr) as = @ar*(af1+ flip(af2)) rz = cabs(as) endif return rz endfunc default: title = "Astroid REB" int param v_REBAstroid caption = "Version (Astroid REB)" 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_REBAstroid< 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param a caption = "parameter a" default = 1 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param ar caption = "Radius" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam complex param pwr caption = "Power" default = (3,3) hint = "Affects shape and scale of trap." visible = !@altformula endparam func afn1 caption = "Function #1" default = cos() visible = !@altformula endfunc func afn2 caption = "Function #2" default = sin() visible = !@altformula endfunc } Class REB_EmbossNephroid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossNephroid(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile complex af1 = 3*@afn1(tz) - @afn1(tz/3) complex af2 = 3*@afn2(tz) - @afn2(tz/3) complex as = 0.5*@a*(af1+flip(af2)) rz = cabs(as) return rz endfunc default: title = "Nephroid" int param v_Nephroid caption = "Version (Nephroid)" 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_Nephroid< 100 endparam float param a caption = "Polar Parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam func afn1 caption = "Function #1" default = cos() endfunc func afn2 caption = "Function #2" default = sin() endfunc } Class REB_EmbossBean(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossBean(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float x = 0 float y = 0 complex af1 = 0 complex as = 0 if @altformula pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = (x^2+y^2)^2-x^3-y^3-cabs(pz)*@offset else rz = (x^2+y^2)^2-x^3-y^3-@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif else af1 = @a*(@afn1(tz)^real(@pwr)+@afn2(tz)^imag(@pwr)) as = (af1*cos(tz) + flip(af1*sin(tz))) rz = cabs(as) endif return rz endfunc default: title = "Bean" int param v_Bean caption = "Version (Bean)" 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_Bean< 100 endparam bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" visible = !@altformula endparam complex param pwr caption = "Power" default = (3,3) hint = "Affects shape and scale of trap." visible = !@altformula endparam func afn1 caption = "Function #1" default = cos() visible = !@altformula endfunc func afn2 caption = "Function #2" default = sin() visible = !@altformula endfunc } Class REB_EmbossBicorn(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossBicorn(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float x = 0 float y = 0 if @altformula pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = y^2*(@aa^2-x^2)-(x^2+2*@aa*y-@aa^2)^2+cabs(pz)*@offset else rz = y^2*(@aa^2-x^2)-(x^2+2*@aa*y-@aa^2)^2+@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif else float af1 = @a*sin(tz) float af2 = @a*cos(tz)^2*(2+cos(tz))/(3+sin(tz)^2) complex as = (af1 + flip(af2)) rz = cabs(as) endif return rz endfunc default: title = "Bicorn" int param v_Bicorn caption = "Version (Bicorn)" 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_Bicorn< 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "Bicorn parameter" default = 1.25 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" visible = !@altformula endparam } Class REB_EmbossCruciform(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCruciform(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float af1 = 0.1*@a/cos(tz) float af2 = 0.02*@b/sin(tz) complex as = (af1 + flip(af2)) rz = cabs(as) return rz endfunc default: title = "Cruciform" int param v_Cruciform caption = "Version (Cruciform)" 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_Cruciform< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam } Class REB_EmbossBow(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossBow(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float x = 0 float y = 0 if @altformula pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = x^4-x^2*y+y^3-cabs(pz)*@offset else rz = x^4-x^2*y+y^3-@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif else float af1 = 0.1*@a*(1-tan(tz)^2)*cos(tz) float af2 = 0.1*@b*(1-tan(tz)^2)*sin(tz) complex as = (af1 + flip(af2)) rz = cabs(as) endif return rz endfunc default: title = "Bow" int param v_Bow caption = "Version (Bow)" 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_Bow< 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 0.25 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam } Class REB_EmbossAtzemaSpiral(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossAtzemaSpiral(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float af1 = 0.5*@a*(sin(tz)/tz-2*cos(tz)-tz*sin(tz)) float af2 = 0.05*@b*(cos(tz)/tz-2*sin(tz)+tz*cos(tz)) complex as = (af1 + flip(af2)) rz = cabs(as) return rz endfunc default: title = "Atzema Spiral" int param v_AtzemaSpiral caption = "Version (Atzema Spiral)" 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_AtzemaSpiral< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam } Class REB_EmbossArcsOfSamothrace(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossArcsOfSamothrace(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float x = 0 float y = 0 if @altformula pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) if !@cmplx x = real(@fn1(pz)) y = imag(@fn2(pz)) else x = real(@fn1(pz)) y = imag(@fn1(pz)) endif if @ref == "pz" rz = x^2*(@a1*x^2-@a2*y^2)^2-y^2*(x^2+y^2)-cabs(pz)*@offset else rz = x^2*(@a1*x^2-@a2*y^2)^2-y^2*(x^2+y^2)-@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif else float rr = @a*tan(tz)/(1+4*@b*cos(1.25*@c*tz)) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif endif return rz endfunc default: title = "Arcs Of Samothrace" int param v_ArcsOfSamothrace caption = "Version (Arcs Of Samothrace)" 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_ArcsOfSamothrace< 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam bool param adv caption = "advanced" default = false visible = @altformula endparam float param a1 caption = "parameter a1" default = 3 visible = @adv && @altformula endparam float param a2 caption = "parameter a2" default = 1 visible = @adv && @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam bool param cmplx caption = "Apply to complex" default = false visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula && !@cmplx endfunc float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param c caption = "3rd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" visible = !@altformula endparam } Class REB_EmbossCatenaryInvolute(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCatenaryInvolute(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile tz = tz*@scale float x = 1.5*@a*(tz-tanh(tz)) float y = 1.5*@a/cosh(tz) complex as = x + flip(y) rz = cabs(as) return rz endfunc default: title = "Catenary Involute" int param v_CatenaryInvolute caption = "Version (Catenary Involute)" 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_CatenaryInvolute< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam } Class REB_EmbossCircleInvolute(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCircleInvolute(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale float x = @a*(cos(tz) + tz*sin(tz)) float y = @a*(sin(tz) - tz*cos(tz)) complex as = x + flip(y) rz = cabs(as) return rz endfunc default: title = "Circle Involute" int param v_CircleInvolute caption = "Version (Circle Involute)" 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_CircleInvolute< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossArchimedes(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossArchimedes(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = rr = @a*tz if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Archimedes" int param v_Archimedes caption = "Version (Archimedes)" 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_Archimedes< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossArachnida1(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossArachnida1(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float x = 0 float y = 0 float rr = 0.25*@a*sin(@pi*tz)/sin((@pi-1)*tz) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Arachnida 1" int param v_Arachnida1 caption = "Version (Arachnida 1)" 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_Arachnida1< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam int param pi caption = "Polar integer" default = 3 hint = "Affects shape and scale of trap." endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossAmpersand(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossAmpersand(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle ; while tz <= 0 ; tz = tz + 2*#pi ; endwhile float x = 0 float y = 0 pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) if !@cmplx x = real(@fn1(pz)) y = imag(@fn2(pz)) else x = real(@fn1(pz)) y = imag(@fn1(pz)) endif if @ref == "pz" rz = (y^2-x^2)*(x-@a1)*(@a2*x-@a3)-@a4*(x^2+y^2-@a5*x)^2+cabs(pz)*@offset else rz = (y^2-x^2)*(x-@a1)*(@a2*x-@a3)-@a4*(x^2+y^2-@a5*x)^2+@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif return rz endfunc default: title = "Ampersand" int param v_Ampersand caption = "Version (Ampersand)" 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_Ampersand< 100 endparam float param scale caption = "scale" default = 1 endparam float param width caption = "width" default = 1 endparam bool param adv caption = "advanced" default = false endparam float param a1 caption = "parameter a1" default = 1 visible = @adv endparam float param a2 caption = "parameter a2" default = 2 visible = @adv endparam float param a3 caption = "parameter a3" default = 3 visible = @adv endparam float param a4 caption = "parameter a4" default = 4 visible = @adv endparam float param a5 caption = "parameter a5" default = 2 visible = @adv endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" endparam bool param cmplx caption = "Apply to complex" default = false endparam func fn1 caption = "Function 1" default = ident() endfunc func fn2 caption = "Function 2" default = ident() visible = !@cmplx endfunc } Class REB_EmbossAtriphtaloid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossAtriphtaloid(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle float x = 0 float y = 0 pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = x^4*(x^2+y^2)-(@ps*@aa*x^2-@ps*@ab)^2+cabs(pz)*@offset else rz = x^4*(x^2+y^2)-(@ps*@aa*x^2-@ps*@ab)^2+@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif return rz endfunc default: title = "Atriphtaloid" int param v_Atriphtaloid caption = "Version (Atriphtaloid)" 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_Atriphtaloid< 100 endparam float param scale caption = "scale" default = 1 endparam float param width caption = "width" default = 1 endparam float param aa caption = "parameter a" default = 5 hint = "Affects spread and scale of trap" endparam float param ab caption = "parameter b" default = 1.0 hint = "Affects spread and scale of trap" endparam float param ps caption = "param scaler" default = 0.4 hint = "Affects spread and scale of trap" endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" endparam func fn1 caption = "Function 1" default = ident() endfunc func fn2 caption = "Function 2" default = ident() endfunc } Class REB_EmbossTrott(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossTrott(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle float x = 0 float y = 0 pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = 144*(x^4+y^4)-225*(x^2+y^2)+350*x^2*y^2+81-cabs(pz)*@offset else rz = 144*(x^4+y^4)-225*(x^2+y^2)+350*x^2*y^2+81-@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif return rz endfunc default: title = "Trott" int param v_Trott caption = "Version (Trott)" 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_Trott< 100 endparam float param scale caption = "scale" default = 1 endparam float param width caption = "width" default = 1 endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" endparam func fn1 caption = "Function 1" default = ident() endfunc func fn2 caption = "Function 2" default = ident() endfunc } Class REB_EmbossBesace(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossBesace(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle float x = 0 float y = 0 pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = (y+@aa*x^2)^2-x^2+x^4-cabs(pz)*@offset else rz = (y+@aa*x^2)^2-x^2+x^4-@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif return rz endfunc default: title = "Besace" int param v_Besace caption = "Version (Besace)" 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_Besace< 100 endparam float param scale caption = "scale" default = 1 endparam float param width caption = "width" default = 1 endparam float param aa caption = "Besace parameter" default = 2 endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" endparam func fn1 caption = "Function 1" default = ident() endfunc func fn2 caption = "Function 2" default = ident() endfunc } Class REB_EmbossBicuspid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossBicuspid(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle float x = 0 float y = 0 pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = (x^2-@aa^2)*(x-@aa)^2+(y^2-@aa^2)^2+cabs(pz)*@offset else rz = (x^2-@aa^2)*(x-@aa)^2+(y^2-@aa^2)^2+@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif return rz endfunc default: title = "Bicuspid" int param v_Bicuspid caption = "Version (Bicuspid)" 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_Bicuspid< 100 endparam float param scale caption = "scale" default = 1 endparam float param width caption = "width" default = 1 endparam float param aa caption = "parameter a" default = 1 endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" endparam func fn1 caption = "Function 1" default = ident() endfunc func fn2 caption = "Function 2" default = ident() endfunc } Class REB_EmbossBurnsideCurve(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossBurnsideCurve(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle float x = 0 float y = 0 pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = y^2-x*(x^4-@a1)-cabs(pz)*@offset else rz = y^2-x*(x^4-@a1)-@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif return rz endfunc default: title = "Burnside Curve" int param v_BurnsideCurve caption = "Version (Burnside Curve)" 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_BurnsideCurve< 100 endparam float param scale caption = "scale" default = 1 endparam float param width caption = "width" default = 1 endparam float param a1 caption = "parameter a" default = 1 endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" endparam func fn1 caption = "Function 1" default = ident() endfunc func fn2 caption = "Function 2" default = ident() endfunc } Class REB_EmbossArachnida2(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossArachnida2(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 0.25*@a*sin(@pi*tz)/sin((@pi+1)*tz) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Arachnida 2" int param v_Arachnida2 caption = "Version (Arachnida 2)" 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_Arachnida2< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam int param pi caption = "Polar integer" default = 3 hint = "Affects shape and scale of trap." endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossGielis(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossGielis(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = @a*(abs(cos(2*@b*tz))^@pa + abs(sin(2*@b*tz))^@pb)^@pc if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Gielis" int param v_Gielis caption = "Version (Gielis)" 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_Gielis< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param pa caption = "Power a" default = 10.0 hint = "Affects spread and scale of trap" endparam float param pb caption = "Power b" default = 10.0 hint = "Affects spread and scale of trap" endparam float param pc caption = "Power c" default = 0.2 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossAstroidCatacaustic(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossAstroidCatacaustic(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale float x = 5*@a*cos(tz)*(8+5*cos(2*tz)+3*cos(6*tz))/(13+3*cos(4*tz)) float y = 20*@a*sin(tz)^3*(7+6*cos(2*tz)+3*cos(4*tz))/(13+3*cos(4*tz)) rz = cabs(x + flip(y)) return rz endfunc default: title = "Astroid Catacaustic" int param v_AstroidCatacaustic caption = "Version (Astroid Catacaustic)" 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_AstroidCatacaustic< 100 endparam float param a caption = "Polar parameter" default = 0.25 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossAstroidEvolute(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossAstroidEvolute(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale float x = 0.78*@a*0.5*(3*cos(tz)-cos(3*tz)) float y = 0.78*@a*0.5*(3*sin(tz)+sin(3*tz)) rz = cabs(x + flip(y)) return rz endfunc default: title = "Astroid Evolute" int param v_AstroidEvolute caption = "Version (Astroid Evolute)" 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_AstroidEvolute< 100 endparam float param a caption = "Polar parameter" default = 0.25 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossCissoidofDioclesCatacaustic(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCissoidofDioclesCatacaustic(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale float x = -12*@a*tz^2*(tz^2-1)/(tz^2+1)^2 float y = 24*@a*tz^3/(tz^2+1)^2 rz = cabs(x + flip(y)) return rz endfunc default: title = "Cissoid of Diocles Catacaustic" int param v_CissoidofDioclesCatacaustic caption = "Version (Cissoid of Diocles Catacaustic)" 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_CissoidofDioclesCatacaustic< 100 endparam float param a caption = "Polar parameter" default = 0.1 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 2.0 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossChebychev(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossChebychev(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale*5 y = @a*cos(@n*acos(sin(tz))) x = @a*cos(@n*acos(cos(tz))) rz = cabs(x + flip(y)) return rz endfunc default: title = "Chebychev" int param v_Chebychev caption = "Version (Chebychev)" 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_Chebychev< 100 endparam int param n caption = "Chebychev number" default = 2 min = 2 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossDampedSine(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossDampedSine(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale float x = 5*@a*tz float y = 5*@a*sin(tz)/tz rz = cabs(x + flip(y)) return rz endfunc default: title = "Damped Sine" int param v_DampedSine caption = "Version (Damped Sine)" 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_DampedSine< 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param scale caption = "scale" default = 0.5 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 0 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossCayleysSexticEvolute(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCayleysSexticEvolute(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale float x = 0.25*@a*(2+3*cos(tz)-cos(3*tz)) float y = @a*sin(tz)^3 rz = cabs(x + flip(y)) return rz endfunc default: title = "Cayleys Sextic Evolute" int param v_CayleysSexticEvolute caption = "Version (Cayleys Sextic Evolute)" 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_CayleysSexticEvolute< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossCardioidInvolute(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCardioidInvolute(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale float x = 2*@a + 3*@a*cos(tz)*(1-cos(tz)) float y = 3*@a*sin(tz)*(1-cos(tz)) rz = cabs(x + flip(y)) return rz endfunc default: title = "Cardioid Involute" int param v_CardioidInvolute caption = "Version (Cardioid Involute)" 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_CardioidInvolute< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossCevasTrisectrix(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCevasTrisectrix(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float x = 0 float y = 0 if @altformula pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = (x^2+y^2)^3-((@aa+1)*x^2-(@aa-1)*y^2)^2-cabs(pz)*@offset else rz = (x^2+y^2)^3-((@aa+1)*x^2-(@aa-1)*y^2)^2-@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif else float rr = 2.5*@a*(1+@b*sin(2*tz)) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif endif return rz endfunc default: title = "Ceva's Trisectrix" int param v_CevasTrisectrix caption = "Version (Ceva's Trisectrix)" 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_CevasTrisectrix< 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "parameter a" default = 1 hint = "Affects spread and scale of trap" visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" visible = !@altformula endparam } Class REB_EmbossCircleCatacaustic(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCircleCatacaustic(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float af1 = 2*@b*(1-3*2*@b*cos(tz)+2*2*@b*cos(tz)^3)/(-(1+2*(2*@b)^2)+3*2*@b*cos(tz)) float af2 = 2*(2*@b)^2*sin(tz)^3/(1+2*(2*@b)^2-3*2*@b*cos(tz)) complex as = @a*(af1 + flip(af2)) rz = cabs(as) return rz endfunc default: title = "Circle Catacaustic" int param v_CircleCatacaustic caption = "Version (Circle Catacaustic)" 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_CircleCatacaustic< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam } Class REB_EmbossRoseOfTroy(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossRoseOfTroy(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = @c*(1+10*@a*sin(4*@b*tz)) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Rose Of Troy" int param v_RoseOfTroy caption = "Version (Rose Of Troy)" 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_RoseOfTroy< 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects shape and scale of trap." endparam float param c caption = "3rd Polar parameter" default = 0.5 hint = "Affects shape and scale of trap." endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossRose(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossRose(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = @a*cos(tz) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Rose" int param v_Rose caption = "Version (Rose)" 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_Rose< 100 endparam float param a caption = "Polar parameter" default = 0.4 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossCycloidOfSeva(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCycloidOfSeva(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 0.5*@a*(1+2*cos(2*tz)) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Cycloid Of Seva" int param v_CycloidOfSeva caption = "Version (Cycloid Of Seva)" 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_CycloidOfSeva< 100 endparam float param a caption = "Polar parameter" default = 0.25 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossDeltoid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossDeltoid(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle endif tz = tz*@scale float x = @a*(2*cos(tz)+cos(2*tz)) float y = @a*(2*sin(tz)-sin(2*tz)) rz = cabs(x + flip(y)) return rz endfunc default: title = "Deltoid" int param v_Deltoid caption = "Version (Deltoid)" 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_Deltoid< 100 endparam float param a caption = "Polar parameter" default = 0.12 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossFishCurve(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossFishCurve(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile tz = 5*@a*tz float x = @b*(cos(tz) - sin(tz)^2/sqrt(2)) float y = @b*cos(tz)*sin(tz) rz = cabs(x + flip(y)) return rz endfunc default: title = "Fish Curve" int param v_FishCurve caption = "Version (Fish Curve)" 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_FishCurve< 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam } Class REB_EmbossFreethsNephroid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossFreethsNephroid(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = 0.5*@a*(1+2*sin(tz/2)) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Freeth's Nephroid" int param v_FreethsNephroid caption = "Version (Freeth's Nephroid)" 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_FreethsNephroid< 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } Class REB_EmbossGearCurve(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossGearCurve(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile complex af1 = (0.25*@a+1/(5*@b)*tanh(5*@b*sin(@pn*tz)))*cos(tz) complex af2 = (0.25*@a+1/(5*@b)*tanh(5*@b*sin(@pn*tz)))*sin(tz) rz = cabs(af1 + flip(af2)) return rz endfunc default: title = "Gear Curve" int param v_GearCurve caption = "Version (Gear Curve)" 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_GearCurve< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 0.1 hint = "Affects spread and scale of trap" endparam int param pn caption = "Polar integer" default = 3 hint = "Affects spread and scale of trap" endparam } Class REB_EmbossLogSpiralCatacaustic(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossLogSpiralCatacaustic(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile complex af1 = 0.2*@b*exp(0.1*@b*tz)*(0.1*@b*cos(tz)-sin(tz))/(1+(0.1*@b)^2) complex af2 = 0.2*@b*exp(0.1*@b*tz)*(0.1*@b*cos(tz)+sin(tz))/(1+(0.1*@b)^2) complex as = @a*(af1 + flip(af2)) rz = cabs(as) return rz endfunc default: title = "Log Spiral Catacaustic" int param v_LogSpiralCatacaustic caption = "Version (Log Spiral Catacaustic)" 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_LogSpiralCatacaustic< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam } Class REB_EmbossPiriform(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossPiriform(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile complex af1 = 0.1*@a*(1+sin(tz)) complex af2 = 0.1*@b*cos(tz)*(1+sin(tz)) complex as = (af1 + flip(af2)) rz = cabs(as) return rz endfunc default: title = "Piriform" int param v_Piriform caption = "Version (Piriform)" 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_Piriform< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam } Class REB_EmbossEllipseCatacaustic(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossEllipseCatacaustic(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile complex af1 = 4*@a*(@a-@b)*(@a*@b)*sin(tz)^3/(@a^2+@b^2+(@b^2-@a^2)*cos(2*tz)) complex af2 = 4*@b*(@b^2-@a^2)*cos(tz)^3/(@a^2+@b^2+3*(@b^2-@a^2)*cos(2*tz)) complex as = 0.1*(af1 + flip(af2)) rz = cabs(as) return rz endfunc default: title = "Ellipse Catacaustic" int param v_EllipseCatacaustic caption = "Version (Ellipse Catacaustic)" 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_EllipseCatacaustic< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam } Class REB_EmbossEllipseEvolute(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossEllipseEvolute(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile complex af1 = (@a^2-(0.7*@b)^2)/@a*@afn1(tz)^(real(@pwr)) complex af2 = ((0.7*@b)^2-@a^2)/(0.7*@b)*@afn2(tz)^(imag(@pwr)) complex as = 0.1*(af1 + flip(af2)) rz = cabs(as) return rz endfunc default: title = "Ellipse Evolute" int param v_EllipseEvolute caption = "Version (Ellipse Evolute)" 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_EllipseEvolute< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam complex param pwr caption = "Power" default = (3,3) hint = "Affects shape and scale of trap." endparam func afn1 caption = "Function #1" default = cos() endfunc func afn2 caption = "Function #2" default = sin() endfunc } Class REB_EmbossEpicycloid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossEpicycloid(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile complex af1 = (5*@a+@b)*@afn1(tz) - @b*@afn1((5*@a+@b)*tz/@b) complex af2 = (5*@a+@b)*@afn2(tz) - @b*@afn2((5*@a+@b)*tz/@b) complex as = 0.1*(af1 + flip(af2)) rz = cabs(as) return rz endfunc default: title = "Epicycloid" int param v_Epicycloid caption = "Version (Epicycloid)" 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_Epicycloid< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam func afn1 caption = "Function #1" default = cos() endfunc func afn2 caption = "Function #2" default = sin() endfunc } Class REB_EmbossDeltoidCatacaustic(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossDeltoidCatacaustic(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile complex af1 = 3*@afn1(tz) + @afn1(3*tz+#pi/2*@b) - @afn1(#pi/2*@b) complex af2 = 3*@afn2(tz) + @afn2(3*tz+#pi/2*@b) - @afn2(#pi/2*@b) complex as = 0.25*@a*(af1 + flip(af2)) rz = cabs(as) return rz endfunc default: title = "Deltoid Catacaustic" int param v_DeltoidCatacaustic caption = "Version (Deltoid Catacaustic)" 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_DeltoidCatacaustic< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam func afn1 caption = "Function #1" default = cos() endfunc func afn2 caption = "Function #2" default = sin() endfunc } Class REB_EmbossCurtateCycloid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCurtateCycloid(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile complex af1 = @a*tz - 0.1*@b*@afn2(tz) complex af2 = @a - 0.1*@b*@afn1(tz) complex as = (af1 + flip(af2)) rz = cabs(as) return rz endfunc default: title = "Curtate Cycloid" int param v_CurtateCycloid caption = "Version (Curtate Cycloid)" 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_CurtateCycloid< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 0.1 hint = "Affects spread and scale of trap" endparam func afn1 caption = "Function #1" default = cos() endfunc func afn2 caption = "Function #2" default = sin() endfunc } Class REB_EmbossHermite(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossHermite(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) float x = 0 float y = 0 if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@b if @htype == 0 if @n == "2" x = @a*(cos(tz)^2 - 1) y = @a*(sin(tz)^2 - 1) elseif @n == "3" x = @a*(cos(tz)^3 - 3*cos(tz))/3 y = @a*(sin(tz)^3 - 3*sin(tz))/3 elseif @n == "4" x = @a*(cos(tz)^4 - 6*cos(tz)^2 + 3)/3 y = @a*(sin(tz)^4 - 6*sin(tz)^2 + 3)/3 elseif @n == "5" x = @a*(cos(tz)^5 - 10*cos(tz)^3 + 15*cos(tz))/15 y = @a*(sin(tz)^5 - 10*sin(tz)^3 + 15*sin(tz))/15 elseif @n == "6" x = @a*(cos(tz)^6 - 15*cos(tz)^4 + 45*cos(tz)^2 - 15)/15 y = @a*(sin(tz)^6 - 15*sin(tz)^4 + 45*sin(tz)^2 - 15)/15 elseif @n == "7" x = @a*(cos(tz)^7 - 21*cos(tz)^5 + 105*cos(tz)^3 - 105*cos(tz))/105 y = @a*(sin(tz)^7 - 21*sin(tz)^5 + 105*sin(tz)^3 - 105*sin(tz))/105 elseif @n == "8" x = @a*(cos(tz)^8 - 28*cos(tz)^6 + 210*cos(tz)^4 - 420*cos(tz)^2 + 105)/105 y = @a*(sin(tz)^8 - 28*sin(tz)^6 + 210*sin(tz)^4 - 420*sin(tz)^2 + 105)/105 elseif @n == "9" x = @a*(cos(tz)^9 - 36*cos(tz)^7 + 378*cos(tz)^5 - 1260*cos(tz)^3 + 945*cos(tz))/945 y = @a*(sin(tz)^9 - 36*sin(tz)^7 + 378*sin(tz)^5 - 1260*sin(tz)^3 + 945*sin(tz))/945 elseif @n == "10" x = @a*(cos(tz)^10 - 45*cos(tz)^8 + 630*cos(tz)^6 - 3150*cos(tz)^4 + 4275*cos(tz)^2 - 945)/945 y = @a*(sin(tz)^10 - 45*sin(tz)^8 + 630*sin(tz)^6 - 3150*sin(tz)^4 + 4275*sin(tz)^2 - 945)/945 endif else if @n == "2" x = @a*4*(cos(tz)^2 - 2)/2 y = @a*4*(sin(tz)^2 - 2)/2 elseif @n == "3" x = @a*8*(cos(tz)^3 - 12*cos(tz))/144 y = @a*8*(sin(tz)^3 - 12*sin(tz))/144 elseif @n == "4" x = @a*16*(cos(tz)^4 - 48*cos(tz)^2 + 12)/288 y = @a*16*(sin(tz)^4 - 48*sin(tz)^2 + 12)/288 elseif @n == "5" x = @a*32*(cos(tz)^5 - 160*cos(tz)^3 + 120*cos(tz))/2880 y = @a*32*(sin(tz)^5 - 160*sin(tz)^3 + 120*sin(tz))/2880 elseif @n == "6" x = @a*64*(cos(tz)^6 - 480*cos(tz)^4 + 720*cos(tz)^2 - 120)/14400 y = @a*64*(sin(tz)^6 - 480*sin(tz)^4 + 720*sin(tz)^2 - 120)/14400 elseif @n == "7" x = @a*128*(cos(tz)^7 - 1344*cos(tz)^5 + 3360*cos(tz)^3 - 1680*cos(tz))/113000 y = @a*128*(sin(tz)^7 - 1344*sin(tz)^5 + 3360*sin(tz)^3 - 1680*sin(tz))/113000 elseif @n == "8" x = @a*256*(cos(tz)^8 - 3584*cos(tz)^6 + 13440*cos(tz)^4 - 13440*cos(tz)^2 + 1680)/564480 y = @a*256*(sin(tz)^8 - 3584*sin(tz)^6 + 13440*sin(tz)^4 - 13440*sin(tz)^2 + 1680)/564480 elseif @n == "9" x = @a*512*(cos(tz)^9 - 9216*cos(tz)^7 + 48384*cos(tz)^5 - 80640*cos(tz)^3 + 30240*cos(tz))/1e7 y = @a*512*(sin(tz)^9 - 9216*sin(tz)^7 + 48384*sin(tz)^5 - 80640*sin(tz)^3 + 30240*sin(tz))/1e7 elseif @n == "10" x = @a*1024*(cos(tz)^10 - 23040*cos(tz)^8 + 161280*cos(tz)^6 - 403200*cos(tz)^4 + 302400*cos(tz)^2 - 20340)/1e8 y = @a*1024*(sin(tz)^10 - 23040*sin(tz)^8 + 161280*sin(tz)^6 - 403200*sin(tz)^4 + 302400*sin(tz)^2 - 20340)/1e8 endif endif rz = cabs(x + flip(y)) return rz endfunc default: title = "Hermite" int param v_Hermite caption = "Version (Hermite)" 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_Hermite< 100 endparam param n caption = "Hermite number" default = 0 enum = "2" "3" "4" "5" "6" "7" "8" "9" "10" endparam param htype caption = "Hermite type" default = 0 enum = "probabilist" "physicist" endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossCornoid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCornoid(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale*10 float x = @a*cos(tz)*(1-2*sin(tz)^2) float y = @a*sin(tz)*(1+2*cos(tz)^2) rz = cabs(x + flip(y)) return rz endfunc default: title = "Cornoid" int param v_Cornoid caption = "Version (Cornoid)" 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_Cornoid< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossParabolaEvolute(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossParabolaEvolute(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale float x = 0.78*@a*0.5*(1+6*tz^2) float y = 0.78*@a*4*tz^3 rz = cabs(x + flip(y)) return rz endfunc default: title = "Parabola Evolute" int param v_ParabolaEvolute caption = "Version (Parabola Evolute)" 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_ParabolaEvolute< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossNaturalLogCatacaustic(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossNaturalLogCatacaustic(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale float x = @a*cosh(tz) float y = @a*(tz-1) rz = cabs(x + flip(y)) return rz endfunc default: title = "Natural Log Catacaustic" int param v_NaturalLogCatacaustic caption = "Version (Natural Log Catacaustic)" 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_NaturalLogCatacaustic< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossLogSpiralEvolute(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossLogSpiralEvolute(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale float x = @a*@b*exp(@b*tz)*sin(tz) float y = @a*@b*exp(@b*tz)*cos(tz) rz = cabs(x + flip(y)) return rz endfunc default: title = "Log Spiral Evolute" int param v_LogSpiralEvolute caption = "Version (Log Spira lEvolute)" 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_LogSpiralEvolute< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossLissajous(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossLissajous(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = @scale*tz float x = 2.5*@a*sin(tz) float y = 2.5*@a*sin(10*@b*tz+@c) rz = cabs(x + flip(y)) return rz endfunc default: title = "Lissajous" int param v_Lissajous caption = "Version (Lissajous)" 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_Lissajous< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param c caption = "3rd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossLaguerre(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossLaguerre(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale*5 float x = 0 float y = 0 if @n == "2" y = @a*(Sin(tz)^2 - 4*sin(tz) + 2)/2 x = @a*(cos(tz)^2 - 4*cos(tz) + 2)/2 elseif @n == "3" y = @a*(-sin(tz)^3 + 9*sin(tz)^2 - 18*sin(tz) + 6)/6 x = @a*(-cos(tz)^3 + 9*cos(tz)^2 - 18*cos(tz) + 6)/6 elseif @n == "4" y = @a*(sin(tz)^4 - 16*sin(tz)^3 + 72*sin(tz)^2 - 96*sin(tz) + 24)/24 x = @a*(cos(tz)^4 - 16*cos(tz)^3 + 72*cos(tz)^2 - 96*cos(tz) + 24)/24 elseif @n == "5" y = @a*(-sin(tz)^5 + 25*sin(tz)^4 - 200*sin(tz)^3 + 600*sin(tz)^2 - 600*sin(tz) + 120)/120 x = @a*(-cos(tz)^5 + 25*cos(tz)^4 - 200*cos(tz)^3 + 600*cos(tz)^2 - 600*cos(tz) + 120)/120 elseif @n == "6" y = @a*(sin(tz)^6 - 36*sin(tz)^5 + 450*sin(tz)^4 - 2400*sin(tz)^3 + 5400*sin(tz)^2 \ -4320*sin(tz) + 720)/720 x = @a*(cos(tz)^6 - 36*cos(tz)^5 + 450*cos(tz)^4 - 2400*cos(tz)^3 + 5400*cos(tz)^2 \ -4320*cos(tz) + 720)/720 endif rz = cabs(x + flip(y)) return rz endfunc default: title = "Laguerre" int param v_Laguerre caption = "Version (Laguerre)" 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_Laguerre< 100 endparam param n caption = "Laguerre number" default = 0 enum = "2" "3" "4" "5" "6" endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossLegendre(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossLegendre(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale float x = 0 float y = 0 if @n == "2" y = 5*@a*(3*sin(tz)^2 - 1)/2 x = 5*@a*(3*cos(tz)^2 - 1)/2 elseif @n == "3" y = 5*@a*(5*sin(tz)^3 - 3*sin(tz))/2 x = 5*@a*(5*cos(tz)^3 - 3*cos(tz))/2 elseif @n == "4" y = 5*@a*(35*sin(tz)^4 - 30*sin(tz)^2 + 3)/8 x = 5*@a*(35*cos(tz)^4 - 30*cos(tz)^2 + 3)/8 elseif @n == "5" y = 5*@a*(63*sin(tz)^5 - 70*sin(tz)^3 + 15*sin(tz))/8 x = 5*@a*(63*cos(tz)^5 - 70*cos(tz)^3 + 15*cos(tz))/8 elseif @n == "6" y = 5*@a*(231*sin(tz)^6 - 315*sin(tz)^4 + 105*sin(tz)^2 -5)/16 x = 5*@a*(231*cos(tz)^6 - 315*cos(tz)^4 + 105*cos(tz)^2 -5)/16 endif rz = cabs(x + flip(y)) return rz endfunc default: title = "Legendre" int param v_Legendre caption = "Version (Legendre)" 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_Legendre< 100 endparam param n caption = "Legendre number" default = 0 enum = "2" "3" "4" "5" "6" endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossInfiniteQuadrifolium(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossInfiniteQuadrifolium(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale*6.28 float x = 2*@a*(tz^3-tz)*(tz-1)/(tz^3+1)^2 float y = 2*@a*(tz^3-tz)*(tz+1)/(tz^3+1)^2 rz = cabs(x + flip(y)) return rz endfunc default: title = "Infinite Quadrifolium" int param v_InfiniteQuadrifolium caption = "Version (Infinite Quadrifolium)" 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_InfiniteQuadrifolium< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossHypotrochoid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossHypotrochoid(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz *@scale float x = (@a*6-@b*0.3)*cos(tz) + 1.3*@c*cos((6*@a/(@b*0.3)-1)*tz) float y = (@a*6-@b*0.3)*sin(tz) - 1.3*@c*sin((6*@a/(@b*0.3)-1)*tz) rz = cabs(x + flip(y)) return rz endfunc default: title = "Hypotrochoid" int param v_Hypotrochoid caption = "Version (Hypotrochoid)" 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_Hypotrochoid< 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param c caption = "3rd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossHypocycloid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossHypocycloid(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz *@scale float x = @a*((1-@b*3)*cos(3*@b*tz)+3*@b*@c*cos((1-3*@b)*tz)) float y = @a*((1-@b*3)*sin(3*@b*tz)-3*@b*@c*sin((1-3*@b)*tz)) rz = cabs(x + flip(y)) return rz endfunc default: title = "Hypocycloid" int param v_Hypocycloid caption = "Version (Hypocycloid)" 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_Hypocycloid< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param c caption = "3rd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossHandwritingCurve(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossHandwritingCurve(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale float x = @a*(tz-4*@b*sin(tz)) float y = @a*(1-4*@b*sin(tz)) rz = cabs(x + flip(y)) return rz endfunc default: title = "Handwriting Curve" int param v_HandwritingCurve caption = "Version (Handwriting Curve)" 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_HandwritingCurve< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossEpitrochoid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossEpitrochoid(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale float x = (@a*2.5+@b*0.6)*cos(tz) - 1.3*@c*cos((2.5*@a/(@b*0.6)+1)*tz) float y = (@a*2.5+@b*0.6)*sin(tz) - 1.3*@c*sin((2.5*@a/(@b*0.6)+1)*tz) rz = cabs(x + flip(y)) return rz endfunc default: title = "Epitrochoid" int param v_Epitrochoid caption = "Version (Epitrochoid)" 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_Epitrochoid< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param c caption = "3rd Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossCycloidCatacaustic(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCycloidCatacaustic(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale float x = @a*2.5*(0.5*tz-sin(0.5*tz)) float y = @a*2.5*(1-cos(0.5*tz)) rz = cabs(x + flip(y)) return rz endfunc default: title = "Cycloid Catacaustic" int param v_CycloidCatacaustic caption = "Version (Cycloid Catacaustic)" 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_CycloidCatacaustic< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 hint = "Affects spread and scale of trap" endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossConchoidOfACircle(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossConchoidOfACircle(Generic pparent) endfunc float func Iterate(complex pz,float &tz) if @partype == "cabs(z)" tz = cabs(pz)+rotangle elseif @partype == "real(z)" tz = real(pz)+rotangle elseif @partype == "imag(z)" tz = imag(pz)+rotangle elseif @partype == "real(z) + imag(z)" tz = real(pz) + imag(pz)+rotangle elseif @partype == "real(z) * imag(z)" tz = real(pz) * imag(pz)+rotangle elseif @partype == "angle" tz = atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile endif tz = tz*@scale float h = sqrt((sin(tz)- @c)^2 + cos(tz)^2) float x = 2.5*@a*(sin(tz) + @b*(sin(tz)-@c)/h) float y = 2.5*@a*(cos(tz) + @b*cos(tz)/h) rz = cabs(x + flip(y)) return rz endfunc default: title = "Conchoid Of A Circle" int param v_ConchoidOfACircle caption = "Version (Conchoid Of A Circle)" 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_ConchoidOfACircle< 100 endparam float param a caption = "Polar parameter" default = 0.5 hint = "Affects spread and scale of trap" endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param c caption = "3rd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" endparam float param scale caption = "Scale" default = 1.0 endparam param partype caption = "Param Type" default = 5 enum = "cabs(z)" "real(z)" "imag(z)" "real(z) + imag(z)" "real(z) * imag(z)" \ "angle" endparam } Class REB_EmbossCapricornoid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCapricornoid(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float x = 0 float y = 0 if @altformula pz = pz/@scale pz = pz*(cos(rotangle)+flip(sin(rotangle))) x = real(@fn1(pz)) y = imag(@fn2(pz)) if @ref == "pz" rz = @aa^2*(x^4+x^2*y^2)-@ab*(x^4+y^4)-@ab*(2*x^2*y^2-2*@aa*y^3+@aa^2*y^2-2*@aa*x^2*y) -cabs(pz)*@offset else rz = @aa^2*(x^4+x^2*y^2)-@ab*(x^4+y^4)-@ab*(2*x^2*y^2-2*@aa*y^3+@aa^2*y^2-2*@aa*x^2*y)-@offset endif if abs(rz) < @width rz =abs(rz) else rz = 1e20 endif else float rr = 0.5*@a*sin(tz)/(0.5*@b + 0.35*@c*cos(tz)) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif endif return rz endfunc default: title = "Capricornoid" int param v_Capricornoid caption = "Version (Capricornoid)" 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_Capricornoid< 100 endparam heading text = "The 'Alternate formula' is a polynomial form which may give a more \ accurate rendering of the trap shape." endheading bool param altformula caption = "Alternate formula" default = false endparam float param scale caption = "scale" default = 1 visible = @altformula endparam float param width caption = "width" default = 1 visible = @altformula endparam float param aa caption = "parameter a" default = 1 hint = "Affects spread and scale of trap" visible = @altformula endparam float param ab caption = "parameter b" default = 1.0 hint = "Affects spread and scale of trap" visible = @altformula endparam param ref caption = "offset reference" default = 0 enum = "zero" "pz" visible = @altformula endparam float param offset caption = "Offset" default = 0.0 hint = "Trap offset" visible = @altformula endparam func fn1 caption = "Function 1" default = ident() visible = @altformula endfunc func fn2 caption = "Function 2" default = ident() visible = @altformula endfunc float param a caption = "Polar parameter" default = 1 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param b caption = "2nd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam float param c caption = "3rd Polar parameter" default = 1.0 hint = "Affects spread and scale of trap" visible = !@altformula endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" visible = !@altformula endparam } Class REB_EmbossPoinsotSpiral1(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossPoinsotSpiral1(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle float rr = @a/cosh(@pn*tz) rz= cabs(rr*(cos(tz) + flip(sin(tz)))) return rz endfunc default: title = "Poinsot Spiral 1" int param v_PoinsotSpiral1 caption = "Version (Poinsot Spiral 1)" 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_PoinsotSpiral1< 100 endparam float param a caption = "Polar parameter" default = 1 hint = "Affects spread and scale of trap" endparam int param pn caption = "Polar integer" default = 3 hint = "Affects shape and scale of trap." endparam } class REB_EmbossCycloid(REB_EmbossFormula) { public: import "common.ulb" ; constructor func REB_EmbossCycloid(Generic pparent) endfunc complex func Init(complex pz) REB_EmbossFormula.Init(pz) return pz endfunc float func Iterate(complex pz,float &tz) tz=atan2(pz)+rotangle while tz <= 0 tz = tz + 2*#pi endwhile float rr = @a+cabs(pz) if @var == "Variant 1" rz= cabs(rr*(cos(tz) + flip(sin(tz)))) else rz= rr*(cos(tz) + sin(tz)) endif return rz endfunc default: title = "Cycloid" int param v_Cycloid caption = "Version (Cycloid)" 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_Cycloid< 100 endparam float param a caption = "Polar parameter" default = 0.2 hint = "Affects spread and scale of trap" endparam param var caption = "Variants" default = 0 enum = "Variant 1" "Variant 2" endparam } ;------------------------------------------- ; L-Systems ;------------------------------------------- class LSystem(ThreeD) { public: import "common.ulb" ; constructor func LSystem(Generic pparent) ThreeD.ThreeD(pparent) i = 0 j = 0 k = 0 setLength(axiom, @alen+1) setLength(repro1, @rlen1+1) setLength(repro2, @rlen2+1) setLength(main, asize) setLength(newmain, asize) setLength(stackx,@stacksize) setLength(stacky,@stacksize) setLength(stackz,@stacksize) setLength(stackt,@stacksize) didpop = false stindex = 0 ;set the axiom array while i < @alen if i == 0 axiom[i] = @ax1 elseif i == 1 axiom[i] = @ax2 elseif i == 2 axiom[i] = @ax3 elseif i == 3 axiom[i] = @ax4 elseif i == 4 axiom[i] = @ax5 elseif i == 5 axiom[i] = @ax6 elseif i == 6 axiom[i] = @ax7 endif i = i+1 endwhile i = 0 while i < @alen if axiom[i] > 0 axiom[i] = axiom[i] + 3 endif i = i + 1 endwhile i = 0 while i < @alen main[i] = axiom[i] i = i + 1 endwhile mainl = @alen i = 0 while i < asize use.m_elements[i] = true i = i + 1 endwhile ; set reproduction array #1 i = 0 while i < @rlen1 if i == 0 repro1[i] = @rule11 elseif i == 1 repro1[i] = @rule21 elseif i == 2 repro1[i] = @rule31 elseif i == 3 repro1[i] = @rule41 elseif i == 4 repro1[i] = @rule51 elseif i == 5 repro1[i] = @rule61 elseif i == 6 repro1[i] = @rule71 elseif i == 7 repro1[i] = @rule81 elseif i == 8 repro1[i] = @rule91 elseif i == 9 repro1[i] = @rule101 elseif i == 10 repro1[i] = @rule111 elseif i == 11 repro1[i] = @rule121 elseif i == 12 repro1[i] = @rule131 elseif i == 13 repro1[i] = @rule141 elseif i == 14 repro1[i] = @rule151 elseif i == 15 repro1[i] = @rule161 elseif i == 16 repro1[i] = @rule171 elseif i == 17 repro1[i] = @rule181 elseif i == 18 repro1[i] = @rule191 elseif i == 19 repro1[i] = @rule201 endif i = i + 1 endwhile ; set reproduction array #2 i = 0 while i < @rlen2 if i == 0 repro2[i] = @rule12 elseif i == 1 repro2[i] = @rule22 elseif i == 2 repro2[i] = @rule32 elseif i == 3 repro2[i] = @rule42 elseif i == 4 repro2[i] = @rule52 elseif i == 5 repro2[i] = @rule62 elseif i == 6 repro2[i] = @rule72 elseif i == 7 repro2[i] = @rule82 elseif i == 8 repro1[i] = @rule92 elseif i == 9 repro2[i] = @rule102 elseif i == 10 repro2[i] = @rule112 elseif i == 11 repro2[i] = @rule122 elseif i == 12 repro2[i] = @rule132 elseif i == 13 repro2[i] = @rule142 elseif i == 14 repro2[i] = @rule152 elseif i == 15 repro2[i] = @rule162 elseif i == 16 repro2[i] = @rule172 elseif i == 17 repro2[i] = @rule182 elseif i == 18 repro2[i] = @rule192 elseif i == 19 repro2[i] = @rule202 endif i = i + 1 endwhile i = 0 k = 0 j = 0 ; rewrite into main for the chosen number of iterations ; this may be redone as a recursive function in the future. while j < @iter ;repro #1 i = 0 while i < mainl if main[i] == 0 ii = 0 while ii < @rlen1 newmain[k] = repro1[ii] ii = ii + 1 k =k + 1 endwhile elseif main[i] == 1 ii = 0 while ii < @rlen2 newmain[k] = repro2[ii] ii = ii + 1 k =k + 1 endwhile else newmain[k] = main[i] k = k + 1 endif i = i + 1 endwhile newmainl = k ; copy newmain to main ii = 0 while ii < newmainl main[ii] = newmain[ii] ii = ii + 1 endwhile mainl = newmainl j = j + 1 k = 0 endwhile complex xrot = (0,1)^(@xang/90) complex yrot = (0,1)^(@yang/90) complex temp = 0 ; ; Generate the points for the lines ; ; starting point x.m_elements[0] = 0 y.m_elements[0] = 0 y.m_elements[0] = 0 float theta = 0 k = 1 i = 0 while i < mainl if main[i] == 0 if !didpop x.m_elements[k] = x.m_elements[k-1]+cos(theta*#pi/180)*@size/sqrt(mainl) y.m_elements[k] = y.m_elements[k-1]+sin(theta*#pi/180)*@size/sqrt(mainl) z.m_elements[k] = 0 else x.m_elements[k] = popx+cos(poptheta*#pi/180)*@size/sqrt(mainl) y.m_elements[k] = popy+sin(poptheta*#pi/180)*@size/sqrt(mainl) z.m_elements[k] = 0 theta = poptheta didpop = false use.m_elements[sk] = false endif k = k + 1 elseif main[i] == 1 if !didpop x.m_elements[k] = x.m_elements[k-1]+cos(theta*#pi/180)*@size/sqrt(mainl) y.m_elements[k] = y.m_elements[k-1]+sin(theta*#pi/180)*@size/sqrt(mainl) z.m_elements[k] = 0 else x.m_elements[k] = popx+cos(poptheta*#pi/180)*@size/sqrt(mainl) y.m_elements[k] = popy+sin(poptheta*#pi/180)*@size/sqrt(mainl) z.m_elements[k] = 0 theta = poptheta didpop = false use.m_elements[sk] = false endif k = k + 1 elseif main[i] == 2 x.m_elements[k] = x.m_elements[k-1]+cos(theta*#pi/180)*@size/sqrt(mainl) y.m_elements[k] = y.m_elements[k-1]+sin(theta*#pi/180)*@size/sqrt(mainl) z.m_elements[k] = 0 use.m_elements[k-1] = false k = k + 1 elseif main[i] == 3 x.m_elements[k] = x.m_elements[k-1]+cos(theta*#pi/180)*@size/sqrt(mainl) y.m_elements[k] = y.m_elements[k-1]+sin(theta*#pi/180)*@size/sqrt(mainl) z.m_elements[k] = 0 use.m_elements[k-1] = false k = k + 1 elseif main[i] == 4 theta = theta + @tangle if theta >= 360 theta = theta -360 endif elseif main[i] == 5 theta = theta - @tangle if theta <= -360 theta = theta +360 endif elseif main[i] == 6 push(x.m_elements[k],y.m_elements[k],z.m_elements[k],theta,k) elseif main[i] == 7 pop(popx,popy,popz,poptheta,sk) didpop = true endif i = i + 1 endwhile use.m_elements[k-1] = false i = 0 ;rotations while i <= k ; ; Y axis rotation ; temp = x.m_elements[i] + flip(z.m_elements[i]) temp = temp*yrot x.m_elements[i] = real(temp) z.m_elements[i] = imag(temp) ; ; X axis rotation ; temp = y.m_elements[i] + flip(z.m_elements[i]) temp = temp*xrot y.m_elements[i] = real(temp) z.m_elements[i] = imag(temp) if z.m_elements[i] <= zmin zmin = z.m_elements[i] endif if z.m_elements[i] >= zmax zmax = z.m_elements[i] endif i = i + 1 endwhile endfunc func push(float x, float y, float z, float theta,int k) stackx[stindex] = x stacky[stindex] = y stackz[stindex] = z stackt[stindex] = theta stackk[stindex] = k stindex = stindex + 1 endfunc func pop(float &x, float &y, float &z, float &theta,int &k) x = stackx[stindex] y = stacky[stindex] z = stackz[stindex] theta = stackt[stindex] sk = stackk[stindex] stindex = stindex -1 endfunc private: int axiom[] int repro1[] int repro2[] int main[] int newmain[] int ii int mainl int newmainl float stackx[] float stacky[] float stackz[] float stackt[] int stackk[] float popx float popy float popz float poptheta int stindex bool didpop int sk default: title = "L Systems" int param v_lsystem caption = "Version (L Systems)" 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_lsystem < 100 endparam int param iter caption = "L-Sysem Iterations" default = 0 endparam int param stacksize caption = "stack size" default = 1000 endparam bool param show caption = "Show rules" endparam heading caption = "Rules" visible = @show endheading heading text = "The rule set includes:" visible = @show endheading heading text = " F move forward" visible = @show endheading heading text = " G move forward" visible = @show endheading heading text = " f move forward without drawing" visible = @show endheading heading text = " g move forward without drawing" visible = @show endheading heading text = " + turn left" visible = @show endheading heading text = " - turn right" visible = @show endheading heading text = " [ push stack" visible = @show endheading heading text = " ] pop stack" visible = @show endheading float param tangle caption = "turn angle" default = 90.0 endparam heading caption = "Axiom" endheading int param alen caption = "axiom length" default = 7 max = 7 endparam param ax1 caption = "axiom1" enum = "F" "+" "-" default = 0 visible = @alen >= 1 endparam param ax2 caption = "axiom2" enum = "F" "+" "-" default = 1 visible = @alen >= 2 endparam param ax3 caption = "axiom3" enum = "F" "+" "-" default = 0 visible = @alen >= 3 endparam param ax4 caption = "axiom4" enum = "F" "+" "-" default = 1 visible = @alen >= 4 endparam param ax5 caption = "axiom5" enum = "F" "+" "-" default = 0 visible = @alen >= 5 endparam param ax6 caption = "axiom6" enum = "F" "+" "-" default = 1 visible = @alen >= 6 endparam param ax7 caption = "axiom7" enum = "F" "+" "-" default = 0 visible = @alen >= 7 endparam heading caption = "Reproduction rules" endheading heading caption = " Reproduction rule 1" endheading int param rlen1 caption = "rule length" default = 20 endparam param rule11 caption = "rule 1" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 0 visible = @rlen1 >= 1 endparam param rule21 caption = "rule 2" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 4 visible = @rlen1 >= 2 endparam param rule31 caption = "rule 3" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 0 visible = @rlen1 >= 3 endparam param rule41 caption = "rule 4" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 5 visible = @rlen1 >= 4 endparam param rule51 caption = "rule 5" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 0 visible = @rlen1 >= 5 endparam param rule61 caption = "rule 6" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 5 visible = @rlen1 >= 6 endparam param rule71 caption = "rule 7" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 0 visible = @rlen1 >= 7 endparam param rule81 caption = "rule 8" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 0 visible = @rlen1 >= 8 endparam param rule91 caption = "rule 9" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 4 visible = @rlen1 >= 9 endparam param rule101 caption = "rule 10" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 0 visible = @rlen1 >= 10 endparam param rule111 caption = "rule 11" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 4 visible = @rlen1 >= 11 endparam param rule121 caption = "rule 12" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 0 visible = @rlen1 >= 12 endparam param rule131 caption = "rule 13" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 5 visible = @rlen1 >= 13 endparam param rule141 caption = "rule 14" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 0 visible = @rlen1 >= 14 endparam param rule151 caption = "rule 15" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 0 visible = @rlen1 >= 15 endparam param rule161 caption = "rule 16" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 0 visible = @rlen1 >= 16 endparam param rule171 caption = "rule 17" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 0 visible = @rlen1 >= 17 endparam param rule181 caption = "rule 18" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 0 visible = @rlen1 >= 18 endparam param rule191 caption = "rule 19" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 0 visible = @rlen1 >= 19 endparam param rule201 caption = "rule 20" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 0 visible = @rlen1 >= 20 endparam heading caption = " Reproduction rule 2" endheading int param rlen2 caption = "rule length" default = 0 max = 20 endparam param rule12 caption = "rule 1" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 1 endparam param rule22 caption = "rule 2" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 2 endparam param rule32 caption = "rule 3" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 3 endparam param rule42 caption = "rule 4" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 4 endparam param rule52 caption = "rule 5" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 5 endparam param rule62 caption = "rule 6" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 6 endparam param rule72 caption = "rule 7" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 7 endparam param rule82 caption = "rule 8" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 8 endparam param rule92 caption = "rule 9" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 9 endparam param rule102 caption = "rule 10" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 10 endparam param rule112 caption = "rule 11" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 11 endparam param rule122 caption = "rule 12" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 12 endparam param rule132 caption = "rule 13" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 13 endparam param rule142 caption = "rule 14" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 14 endparam param rule152 caption = "rule 15" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 15 endparam param rule162 caption = "rule 16" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 16 endparam param rule172 caption = "rule 17" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 17 endparam param rule182 caption = "rule 18" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 18 endparam param rule192 caption = "rule 19" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 19 endparam param rule202 caption = "rule 20" enum = "F" "G""f" "g" "+" "-" "[" "]" default = 1 visible = @rlen2 >= 20 endparam float param size caption = "size" default = 1.0 endparam float param xang caption = "X rotation" default = -20 endparam float param yang caption = "Y rotation" default = 30 endparam } class Barnsley_Variation_Switch(reb.ulb:Switch) { public: import "common.ulb" import "reb.ulb" ; constructor func Barnsley_Variation_Switch(Generic pparent) Switch.Switch(pparent) m_mand = @p_mand m_jul = @p_jul m_bailout = @p_upperbailout m_bailout2 = @p_lowerbailout m_c = @m_c m_test = @test endfunc ; initialize the formula complex func Init(complex pz) Switch.Init(pz) if @mans && @stype == "Julia" m_c = @seed m_mand = false m_jul = true endif if @mans && @stype == "Mandelbrot" m_mand = true m_jul = false endif if m_mand m_c = pz pz = @start endif return pz endfunc ; call for each iterated point complex func Iterate(complex pz) Switch.Iterate(pz) if real(pz) >= 0 pz = (pz - @var1) ^ m_c else pz = (pz + @var1) ^ m_c endif return pz endfunc ; Override the default function for bailout bool func IsBailedOut(complex pz) bool bail = false if m_test == 0 bail = (|pz| > m_bailout) elseif m_test == 1 bail = (sqr(real(pz)) > m_bailout) elseif m_test == 2 bail = (sqr(imag(pz)) > m_bailout) elseif m_test == 3 bail = (sqr(real(pz)) > m_bailout || sqr(imag(pz)) > m_bailout) elseif m_test == 4 bail = (sqr(real(pz)) > m_bailout && sqr(imag(pz)) > m_bailout) elseif m_test == 5 bail = (sqr(abs(real(pz)) + abs(imag(pz))) > m_bailout) elseif m_test == 6 bail = (sqr(real(pz) + imag(pz)) > m_bailout) endif return bail endfunc default: title = "Barnsley_Variation Switch" int param v_Barnsley_Variation_Switch caption = "Version (Barnsley_Variation Switch)" 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_Barnsley_Variation_Switch < 100 endparam heading text = "The 'Manual Switch' option overrides the switching capability of \ 'Object Formula Switch' and 'Object Formula \ Switch Lite'. Use the normal switch capabilities instead with these \ formulas." endheading param start caption = "Starting Point" default = (0.0, 0.0) endparam float param var1 caption = "Shift" default = 1 endparam bool param mans caption = "Manual Switch" default = false endparam param stype caption = "Type" default = 0 enum = "Mandelbrot" "Julia" visible = @mans endparam bool param p_mand caption = "Mandel Type" default = true visible = false endparam bool param p_jul caption = "Julia Type" default = false visible = false endparam complex param m_c caption = "Julia Seed" default = (0,0) visible = false endparam complex param seed caption = "Julia Seed" default = (0,0) visible = @mans && @stype == "Julia" endparam param test caption = "Bailout Test" default = 0 enum = "mod" "real" "imag" "or" "and" "manh" "manr" hint = "mod is the standard bailout. The remaining bailout methods are \ from Fractint." endparam float param p_upperbailout caption = "Bailout value (Divergent)" default = 1e6 min = 1.0 endparam float param p_lowerbailout caption = "Bailout value" default = 1e-10 visible = false endparam complex param p_power ; Overrides p_power from Formula caption = "Power" default = (2,0) visible = false endparam }