mmf
Class MMF_Magnet1DistanceEstimator

Object
  extended by common:Generic
      extended by common:Coloring
          extended by common:GradientColoring
              extended by mmf:DistanceEstimatorBase
                  extended by mmf:MMF_Magnet1DistanceEstimator

class 
DistanceEstimatorBase:MMF_Magnet1DistanceEstimator

Distance Estimator for the Magnet 1 formula.


Ultra Fractal Source

Toggle UF Source Code Display

 class MMF_Magnet1DistanceEstimator(DistanceEstimatorBase) {
 ; Distance Estimator for the Magnet 1 formula.
 public:
   import "common.ulb"
   ; @param pparent the parent, generally "this" for the parent, or zero
   func MMF_Magnet1DistanceEstimator(Generic pparent)
     DistanceEstimatorBase.DistanceEstimatorBase(pparent)
   endfunc
   ; @param pz
   ; @param ppixel
   func Init(complex pz, complex ppixel)
     DistanceEstimatorBase.Init(pz, ppixel)
     zold = pz
     odz = 1.0
     if @fixit
       complex fz = 0.0
       complex gz = 0.0
       if @julia
         fz = sqr(pz) + (@seed - 1.0)
         gz = 2.0*pz + (@seed - 2.0)
       else
         fz = sqr(pz) + (m_Pixel - 1.0)
         gz = 2.0*pz + (m_Pixel - 2.0)
       endif
       complex dfz = 2.0*pz
       complex dgz = 2.0
       dz = 2.0*fz*(dfz*gz - fz*dgz)/gz^3.0
     elseif @julia
       dz = (2.0*sqr(pz) + (2.0*@seed - 4.0)*pz - 2.0*@seed + 2.0) \
            /sqr(2.0*pz + @seed - 2.0)
     else
       dz = (2.0*sqr(pz) + (2.0*m_Pixel - 4.0)*pz - 2.0*m_Pixel + 2.0) \
            /sqr(2.0*pz + m_Pixel - 2.0)
     endif
   endfunc
   ; @param pz
   func Iterate(complex pz)
 ;    m_Iterations = m_Iterations + 1
     zold = pz
     odz = dz
     if @fixit
       complex fz = 0.0
       complex gz = 0.0
       if @julia
         fz = sqr(pz) + (@seed - 1.0)
         gz = 2.0*pz + (@seed - 2.0)
       else
         fz = sqr(pz) + (m_Pixel - 1.0)
         gz = 2.0*pz + (m_Pixel - 2.0)
       endif
       complex dfz = 2.0*pz
       complex dgz = 2.0
       dz = dz*2.0*fz*(dfz*gz - fz*dgz)/gz^3.0
     elseif @julia
       dz = dz*((2.0*sqr(pz) + (2.0*@seed - 4.0)*pz - 2.0*@seed + 2.0) \
            /sqr(2.0*pz + @seed - 2.0))
     else
       dz = dz*((2.0*sqr(pz) + (2.0*m_Pixel - 4.0)*pz - 2.0*m_Pixel + 2.0) \
            /sqr(2.0*pz + m_Pixel - 2.0))
     endif
   endfunc
   ; @param pz
   ; @return the gradient index
   float func ResultIndex(complex pz)
     float a = 0.0
     float d = 0.0
     complex zv = pz - zold
     if |zv|<1.0 && @method!=1
       if @modec=="Angle" || @modec=="Combined"
         if (a = atan2(zv/(dz-odz))*(0.5/#pi))<0.0
           a = a + 1.0
         endif
         if @modec=="Angle"
           return a
         endif
       endif
       if @modec=="Distance" || @modec=="Combined"
         if @fixit
           d = cabs(zv)
           d = -d*log(d)/cabs(dz-odz)
         else
           d = |(dz-odz)/zv|^0.0625 ; Note that this is from trial and error
         endif
         if @modec=="Distance"
           return d
         endif
       endif
     elseif @method>0 && |zv|>=1.0
       if @mode=="Angle" || @mode=="Combined"
         if @fixit
           if (a = atan2(pz/dz)*(0.5/#pi))<0.0
             a = a + 1.0
           endif
         elseif (a = atan2(dz)*(0.5/#pi))<0.0
           a = a + 1.0
         endif
         if @mode=="Angle"
           return a
         endif
       endif
       if @mode=="Distance" || @mode=="Combined"
         if @fixit
           d = cabs(pz)
           d = d*log(d)/cabs(dz)
         else
 ; again from trial and error:
           d = ((1.0-log(0.5*log(|@bailout|))+log(0.5*log(|pz|)))*|dz|)^0.0625
         endif
         if @mode=="Distance"
           return d
         endif
       endif
     else
       m_Solid = true
     endif
     return a+d
   endfunc
   ; @param pz
   ; @return the distance
   float func ResultDistance(complex pz)
     if |pz-zold|<1.0
       if @fixit
         float d = cabs(pz-zold)
         return -d*log(d)/cabs(dz-odz)
       endif
       return |(dz-odz)/(pz-zold)|^0.0625 ; Note that this is from trial and error
     else
       if @fixit
         float d = cabs(pz)
         return d*log(d)/cabs(dz)
       endif
       return ((1.0-log(0.5*log(|@bailout|))+log(0.5*log(|pz|)))*|dz|)^0.0625
     endif
   endfunc
   ; @param pz
   ; @return the angle (from 0 to 1)
   float func ResultAngle(complex pz)
     float r = 0.0
     if |pz-zold|<1.0
       if (r=atan2((pz-zold)/(dz-odz))*(0.5/#pi))<0.0
         r = r + 1.0
       endif
     else
       if @fixit
         r = atan2(pz/dz)*(0.5/#pi)
       else
         r = atan2(dz)*(0.5/#pi)
       endif
       if r<0.0
         r = r + 1.0
       endif
     endif
     return r
   endfunc
 
 protected:
   complex zold
   complex odz
 
 default:
   title = "MMF Magnet 1 Distance Estimator"
   int param v_mmf_magnet1distanceestimator
     caption = "Version (MMF Magnet 1 Distance Estimator)"
     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
   heading
     text = "Note that this colouring is only based on distance estimation, \
             it's not accurate at true distance estimation."
   endheading
   bool param fixit
     caption = "Fix the DE"
     default = false
     hint = "When enabled the colouring is closer to true distance estimation \
             but less useful for image mapping."
   endparam
   bool param julia
     caption = "Julia ?"
     default = false
     hint = "Enable when the main formula is a Julia."
   endparam
   complex param seed
     caption = "Julia Seed"
     default = (0,0)
     hint = "Set to the value of the Julia seed in the main formula."
     visible = @julia
   endparam
   int param method
     caption = "Method"
     enum = "Convergent" "Divergent" "Both"
     default = 2
     hint = "When plugged into 'MMF Field Estimator' you should use 'Both'."
   endparam
   int param modec
     caption = "Convergent Mode"
     enum = "Distance" "Angle" "Combined"
     default = 0
     visible = @method!=1
   endparam
   int param mode
     caption = "Divergent Mode"
     enum = "Distance" "Angle" "Combined"
     default = 0
     visible = @method>0
   endparam
   float param bailout
     caption = "Divergent Bailout"
     default = 1e20
     visible = @method>0
   endparam
 }
 


Constructor Summary
MMF_Magnet1DistanceEstimator()
           
MMF_Magnet1DistanceEstimator(Generic pparent)
           
 
Method Summary
 void Init(complex pz, complex ppixel)
          Set up for a sequence of values
 void Iterate(complex pz)
          Process the next value in the sequence
 float ResultAngle(complex pz)
           
 float ResultDistance(complex pz)
           
 float ResultIndex(complex pz)
          Produce a resulting color index after a sequence is finished
 
Methods inherited from class common:GradientColoring
IsGradient, IsSolid, Result
 
Methods inherited from class common:Coloring
GetPixel
 
Methods inherited from class common:Generic
GetParent
 
Methods inherited from class Object
 

Constructor Detail

MMF_Magnet1DistanceEstimator

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

MMF_Magnet1DistanceEstimator

public MMF_Magnet1DistanceEstimator()
Method Detail

Init

public void Init(complex pz,
                 complex ppixel)
Description copied from class: GradientColoring
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 GradientColoring
Parameters:
pz -
ppixel -

Iterate

public void Iterate(complex pz)
Description copied from class: GradientColoring
Process 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. Note that such processing generally will not know in advance precisely how long the sequence is, and should be prepared to deal with sequences of arbitrary length.

Your coloring may determine at some point that a solid color should be used rather than an index value.

Overrides:
Iterate in class GradientColoring
Parameters:
pz -

ResultIndex

public float ResultIndex(complex pz)
Description copied from class: GradientColoring
Produce a resulting color index after a sequence is finished

This corresponds to the final: section in a coloring formula. Once it is called, no further calls to Iterate() should be made without calling Init() first.

Overrides:
ResultIndex in class GradientColoring
Parameters:
pz -
Returns:
the gradient index

ResultDistance

public float ResultDistance(complex pz)
Overrides:
ResultDistance in class DistanceEstimatorBase
Parameters:
pz -
Returns:
the distance

ResultAngle

public float ResultAngle(complex pz)
Overrides:
ResultAngle in class DistanceEstimatorBase
Parameters:
pz -
Returns:
the angle (from 0 to 1)