mmf
Class MMF_SwitchGradientSlope

Object
  extended by common:Generic
      extended by common:Formula
          extended by mmf:MMF_SwitchFormula
              extended by mmf:MMF_SwitchGradientSlope

class 
MMF_SwitchFormula:MMF_SwitchGradientSlope

Creates 3D lighting effects when combined with the Lighting or Mixed Lighting (direct) colouring algorithms.
Allows "slope" colouring from any formula, any colouring.
Written by David Makin based on Standard_Slope by Damien Jones
Original May 2008


Ultra Fractal Source

Toggle UF Source Code Display

 class MMF_SwitchGradientSlope(MMF_SwitchFormula) {
 ;
 ; Creates 3D lighting effects when combined with the
 ; Lighting or Mixed Lighting (direct) colouring algorithms.<br>
 ; Allows "slope" colouring from any formula, any colouring.<br>
 ;
 ; Written by David Makin based on Standard_Slope by Damien Jones<br>
 ; Original May 2008<br>
 ;
 public:
   import "common.ulb"
 
   ; @param pparent the parent, generally "this" for the parent, or zero
   func MMF_SwitchGradientSlope(Generic pparent)
     MMF_SwitchFormula(pparent)
     fHelper[0] = new @helperClass(this)
     fHelper[1] = new @helperClass(this)
     fHelper[2] = new @helperClass(this)
     fTransfer[0] = new @transferClass(this)
     fTransfer[1] = new @transferClass(this)
     fTransfer[2] = new @transferClass(this)
     if @mode>0
 ; If using 'Colouring+Lighting" pre-compute some constants
       float rot = (270.0-@angle)*(#pi/180.0)  ; degrees to radians conversion
       float ele = @elevation*(#pi/180.0)
 ; The lighting Normal
       lx = cos(rot) * cos(ele)
       ly = sin(rot) * cos(ele)
       lz = sin(ele)
 ; Scale for adjusting light value accounting for ambient level
       amb = 0.5*(1.0 - @ambient)
     endif
   endfunc
 
   func SetParams(bool f,complex v)
     if !@p_manual
       fType = f
       fValue = fConstant = v
     endif
     fHelper[0].SetParams(f,v)  ; This was a bug in the first release but
     fHelper[1].SetParams(f,v)  ; as it happens the problem was simply fixed
     fHelper[2].SetParams(f,v)  ; by removing the "manual override" params
                                ; from future use since they aren't needed
                                ; because the manual override in the child
                                ; switch formula is sufficient.
                                ; f,v here should have been fType,fConstant
   endfunc
 
   complex func Init(complex 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
     fTransfer[0].Init(pz)
     fTransfer[1].Init(pz + @offset)
     fTransfer[2].Init(pz + flip(@offset))
     fIteration = 0
     return z1
   endfunc
 
   complex func Iterate(complex pz)
 ; We can't use the pz value because we need to keep track of three z values.
     fIteration = fIteration + 1
     complex z1 = fHelper[0].Iterate()
     m_BailedOut = fHelper[0].IsBailedOut()
     fHelper[1].Iterate()
     if @earlyout
       m_BailedOut = m_BailedOut || fHelper[1].IsBailedOut()
     endif
     fHelper[2].Iterate()
     if @earlyout
       m_BailedOut = m_BailedOut || fHelper[2].IsBailedOut()
     endif
     if !m_BailedOut ; for normal UF behaviour don't call iterate for
                     ; the colouring formula if we've bailed out
       fHelper[0].IterateCol()
       fHelper[1].IterateCol()
       fHelper[2].IterateCol()
     endif
     if m_BailedOut || fIteration == #maxiter ; done or last
 ; Get "height" offsets - note that "vz" would be -@offset
       float e1 = fHelper[0].GetHeight()
       float vy = fTransfer[0].Iterate(e1)
       float vx = fTransfer[1].Iterate(fHelper[1].GetHeight()) - vy
       float vy = fTransfer[2].Iterate(fHelper[2].GetHeight()) - vy
 ; normalising scale
       float vd = 1.0/sqrt(sqr(vx)+sqr(vy)+sqr(@offset))
       if @mode==0
         return vd*(vx + flip(vy)); fudge z from vector (vz is implied)
       else
 ; return the colouring value as real and the light value as imaginary
 ; note that + lz*offset is a double negative i.e. + -lz*-@offset
         return e1 + flip(@ambient + amb*(1.0+vd*(lx*vx + ly*vy + lz*@offset)))
       endif
     else ; didn't compute z this time
 ; use primary iteration value to keep periodicity working
       return z1
     endif
   endfunc
 
   complex func GetPrimaryExponent()
     return fHelper[0].GetPrimaryExponent()
   endfunc
 
   float func GetUpperBailout()
     return fHelper[0].GetUpperBailout()
   endfunc
   
   float func GetLowerBailout()
     return fHelper[0].GetLowerBailout()
   endfunc
 
 private:
   MMF_SwitchGradientSlopeHelper fHelper[3]
   Transfer fTransfer[3]
   float lx
   float ly
   float lz
   float amb
   int fIteration
 
 default:
   title = "Switch Gradient Slope"
   rating = recommended
   heading
     text = "Tip: Use with the Standard Lighting coloring algorithms \
             or reb5.ucl-Lighting with Textures or the Mixed \
             Lighting (direct) colouring algorithm from mmf.ulb."
   endheading
   int param v_mmfswitchgradientslope
     caption = "Version (Switch Gradient Slope)"
     enum = "1.0"
     default = 0
     hint = "This field is to absolutely ensure backward compatibility, \
             the default will always be set to the latest version, but \
             there may be some cases where an older effect that you like \
             is lost in an update and you could still use it by selecting \
             the older version number."
     visible = false
   endparam
   bool param p_manual
     visible = false
   endparam
   bool param p_mandy
     visible = false
   endparam
   complex param p_start
     visible = false
   endparam
   complex param p_seed
     visible = 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, the deeper you zoom \
             the smaller the value needs to be to keep detail."
   endparam
   bool param earlyout
     caption = "Early Out"
     default = false
     hint = "This formula iterates 3 points to get the normal for the slope \
             colouring, normally all 3 points are iterated until the primary \
             point bails out. Unfortunately with some colourings this can lead \
             to a NAN (not a number) problem, typically at higher zooms \
             producing areas of solid flat lighting. If you think you have \
             this problem try enabling 'Early Out' which terminates iteration \
             as soon as any one of the three points bails out."
   endparam
   int param mode
     caption = "Method"
     enum = "Lighting" "Colouring+Lighting"
     default = 0
     hint = "'Lighting' is for colouring using the standard 'Lighting' method \
             'Colouring+Lighting' is for use with the \
             'Mixed Lighting (direct)' colouring."
   endparam
   float param angle
     caption = "Light Rotation"
     default = 90.0
     hint = "Gives the rotation of the light source, in degrees. With 0 \
             degrees, the light comes from above. Positive values give \
             clockwise rotation."
     visible = @mode==1
   endparam
   float param elevation
     caption = "Light Elevation"
     default = 30.0
     hint = "Gives the elevation of the light source, in degrees."
     visible = @mode==1
   endparam
   float param ambient
     caption = "Ambient Light"
     default = 0.0
     min = -1.0
     max = 1.0
     hint = "Specifies the level of ambient light."
     visible = @mode==1
   endparam
   Transfer param transferClass
     caption = "Height Transfer"
     default = TrapTransfer
     hint = "Selects a class to transform the calculated height value."
     expanded = false
   endparam
   MMF_SwitchGradientSlopeHelper param helperClass
     selectable = false
   endparam
   complex param p_power ; Hide p_power from Formula
     visible = false
   endparam
 }
 


Constructor Summary
MMF_SwitchGradientSlope()
           
MMF_SwitchGradientSlope(Generic pparent)
           
 
Method Summary
 float GetLowerBailout()
          Determine the lower bailout boundary.
 complex GetPrimaryExponent()
          Determine the primary exponent.
 float GetUpperBailout()
          Determine the upper bailout boundary.
 complex Init(complex pz)
          Set up for a sequence of values
 complex Iterate(complex pz)
          Produce the next value in the sequence
 void SetParams(boolean f, complex v)
           
 
Methods inherited from class common:Formula
IsBailedOut
 
Methods inherited from class common:Generic
GetParent
 
Methods inherited from class Object
 

Constructor Detail

MMF_SwitchGradientSlope

public MMF_SwitchGradientSlope(Generic pparent)
Parameters:
pparent - the parent, generally "this" for the parent, or zero

MMF_SwitchGradientSlope

public MMF_SwitchGradientSlope()
Method Detail

SetParams

public void SetParams(boolean f,
                      complex v)
Overrides:
SetParams in class MMF_SwitchFormula
Parameters:
f - flag for Mandelbrot or Julia mode, is true for Mandelbrots
v - the value to be used as the start value or constant

Init

public complex Init(complex pz)
Description copied from class: Formula
Set up for a sequence of values

This function will be called at the beginning of each sequence of values (e.g. at the beginning of each fractal orbit).

Overrides:
Init in class Formula
Parameters:
pz - seed value for the sequence; for a normal fractal formula, this will be #pixel
Returns:
first value in the sequence; this corresponds to #z in a fractal formula

Iterate

public complex Iterate(complex pz)
Description copied from class: Formula
Produce the next value in the sequence

As long as the sequence has not bailed out, this function will be continually called to produce sequence values.

Overrides:
Iterate in class Formula
Parameters:
pz - previous value in the sequence; corresponds to #z in a fractal formula. Note that you should always use this value for computing the next iteration, rather than a saved value, as the calling code may modify the returned value before passing it back to the next Iterate() call.
Returns:
the next value in the sequence

GetPrimaryExponent

public complex GetPrimaryExponent()
Description copied from class: Formula
Determine the primary exponent.

Many fractals can be characterized by an exponent value that is useful to other formulas, so we provide that here. If your formula does not need or use this value, override the p_power parameter and make it hidden.

Overrides:
GetPrimaryExponent in class Formula
Returns:
the primary exponent parameter

GetUpperBailout

public float GetUpperBailout()
Description copied from class: Formula
Determine the upper bailout boundary.

By default, we return a simple fixed value. Divergent formulas will override this function and return the real parameter.

Overrides:
GetUpperBailout in class Formula
Returns:
the upper bailout parameter

GetLowerBailout

public float GetLowerBailout()
Description copied from class: Formula
Determine the lower bailout boundary.

By default, we return a simple fixed value. Convergent formulas will override this function and return the real parameter.

Overrides:
GetLowerBailout in class Formula
Returns:
the lower bailout parameter