## mmf Class MMF_Magnet2DistanceEstimator

```Object
common:Generic
common:Coloring
mmf:DistanceEstimatorBase
mmf:MMF_Magnet2DistanceEstimator
```

`class DistanceEstimatorBase:MMF_Magnet2DistanceEstimator`

Distance Estimator for the Magnet 2 formula.

Ultra Fractal Source
``` class MMF_Magnet2DistanceEstimator(DistanceEstimatorBase) {
; Distance Estimator for the Magnet 2 formula.
public:
import "common.ulb"
; @param pparent the parent, generally "this" for the parent, or zero
func MMF_Magnet2DistanceEstimator(Generic pparent)
DistanceEstimatorBase.DistanceEstimatorBase(pparent)
endfunc
; @param pz
; @param ppixel
func Init(complex pz, complex ppixel)
DistanceEstimatorBase.Init(pz, ppixel)
complex fz = (0,0)
complex gz = (0,0)
complex dfz = (0,0)
complex dgz = (0,0)
zold = pz
odz = 1.0
; Note that the running derivative calculation could be optimised
if @julia
fz = pz^3.0 + (3.0*(@seed - 1.0))*pz + ((@seed - 1.0)*(@seed - 2.0))
gz = 3.0*sqr(pz) + (3.0*(@seed - 2.0))*pz \
+ ((@seed - 1.0)*(@seed - 2.0)) + 1.0
dfz = 3.0*sqr(pz) + (3.0*(@seed - 1.0))
dgz = 6.0*pz + (3.0*(@seed - 2.0))
else
fz = pz^3.0 + (3.0*(m_Pixel - 1.0))*pz + ((m_Pixel - 1.0)*(m_Pixel - 2.0))
gz = 3.0*sqr(pz) + (3.0*(m_Pixel - 2.0))*pz \
+ ((m_Pixel - 1.0)*(m_Pixel - 2.0)) + 1.0
dfz = 3.0*sqr(pz) + (3.0*(m_Pixel - 1.0))
dgz = 6.0*pz + (3.0*(m_Pixel - 2.0))
endif
dz = fz*(dfz*gz - fz*dgz)/gz^3.0
if @fixit
dz = 2.0*dz
endif
endfunc
; @param pz
func Iterate(complex pz)
if @fixit
m_Iterations = m_Iterations + 1
endif
complex fz = (0,0)
complex gz = (0,0)
complex dfz = (0,0)
complex dgz = (0,0)
zold = pz
odz = dz
if @julia
fz = pz^3.0 + (3.0*(@seed - 1.0))*pz + ((@seed - 1.0)*(@seed - 2.0))
gz = 3.0*sqr(pz) + (3.0*(@seed - 2.0))*pz \
+ ((@seed - 1.0)*(@seed - 2.0)) + 1.0
dfz = 3.0*sqr(pz) + (3.0*(@seed - 1.0))
dgz = 6.0*pz + (3.0*(@seed - 2.0))
else
fz = pz^3.0 + (3.0*(m_Pixel - 1.0))*pz + ((m_Pixel - 1.0)*(m_Pixel - 2.0))
gz = 3.0*sqr(pz) + (3.0*(m_Pixel - 2.0))*pz \
+ ((m_Pixel - 1.0)*(m_Pixel - 2.0)) + 1.0
dfz = 3.0*sqr(pz) + (3.0*(m_Pixel - 1.0))
dgz = 6.0*pz + (3.0*(m_Pixel - 2.0))
endif
dz = dz*fz*(dfz*gz - fz*dgz)/gz^3.0
if @fixit
dz = 2.0*dz
endif
endfunc
; @param pz
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 = 3.0*|(dz-odz)/zv^@cfudge|^0.03125 ; 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 (a = atan2(pz/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*log(pz)/dz)
if m_Iterations>0
a = cabs(zold*log(zold)/odz)
d = d + (d - a)*(log(0.5*log(@bailout))-log(0.5*log(|pz|))) \
/log(log(|pz|)/log(|zold|))
endif
else
; again from trial and error:
d = |dz/pz|^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)
else
return 3.0*|(dz-odz)/(pz-zold)^@cfudge|^0.03125 ; Note that this is from trial and error
endif
else
if @fixit
float d = cabs(pz*log(pz)/dz)
if m_Iterations>0
float a = cabs(zold*log(zold)/odz)
d = d + (d - a)*(log(0.5*log(@bailout))-log(0.5*log(|pz|))) \
/log(log(|pz|)/log(|zold|))
endif
return d
else
return |dz/pz|^0.0625
endif
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
elseif (r = atan2(pz/dz)*(0.5/#pi))<0.0
r = r + 1.0
endif
return r
endfunc

protected:
complex zold
complex odz

default:
title = "MMF Magnet 2 Distance Estimator"
int param v_mmf_magnet2distanceestimator
caption = "Version (MMF Magnet 2 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
text = "Note that this colouring is only based on distance estimation, \
it's not accurate at true distance estimation."
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
bool param fixit
caption = "True DE"
default = false
hint = "When enabled the distance modes are much closer to true \
distance estimation however this is probably not as useful \
a colouring method for image mapping as the default."
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
float param cfudge
default = 0.962
hint = "Use to remove iteration breaks."
visible = @method!=1 && @modec!=1 && !@fixit
endparam
int param mode
caption = "Divergent Mode"
enum = "Distance" "Angle" "Combined"
default = 0
visible = @method>0
endparam
float param bailout
caption = "Divergent Bailout"
default = 65536.0
visible = @method>0
endparam
}
```

Constructor Summary
`MMF_Magnet2DistanceEstimator()`

`MMF_Magnet2DistanceEstimator(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

`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_Magnet2DistanceEstimator

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

### MMF_Magnet2DistanceEstimator

`public MMF_Magnet2DistanceEstimator()`
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:

### 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)