I wrote a class that's a subclass of common.ulbsmileivergentFormula. ←wth why a smiley?

The formula is purpose-built for a coloring algorithm where it is used hardcodedly (not as a class param), and I need to set the @p_bailout parameter to what the coloring needs (also hardcoded). Is there a way to do that, without writing my own m_bailout 'replacement' member in the class and overriding IsBailedOut() (basically ignoring half of what makes DivergentFormula useful)?

I'm using the object like this (WIP):

669d7569a6689.png

Both work-in-progress codes:

class AtomDomainCalculator(common.ulb:DivergentFormula) {
; Mark Jeronimus, 2024-07-21
public:
  func DivergentFormula(Generic pparent)
    DivergentFormula.DivergentFormula(pparent)
  endfunc

  complex func Init(complex pz) ;override
    DivergentFormula.Init(pz)
    m_c = pz
    m_bestAtomDist = 1e10
    m_foundAtomDomain = 0
    return 0
  endfunc

  complex func Iterate(complex pz) ;override
      Formula.Iterate(pz)
    pz = pz ^ @p_power + m_c

    float dist = log(|pz|) - m_Iterations ^ m_swellPower * m_swellPressure
    if m_bestAtomDist > dist
      m_bestAtomDist = dist
      m_foundAtomDomain = m_Iterations
    endif

    return pz
  endfunc

  func setSwellPressure(float swellPressure)
    m_swellPressure = swellPressure
  endfunc

  func setSwellPower(float swellPower)
    m_swellPower = swellPower
  endfunc

protected:
  float m_swellPressure
  float m_swellPower

  complex m_c

  float m_bestAtomDist
  int m_foundAtomDomain
}

AtomDomainsGradient() {
; Mark Jeronimus, 2024-07-21
global:
  import "jlb.ulb"
  $define debug

  complex span = exp(flip(#angle)) * 2 / #magn
  complex eps = span/#width
  print("span=", span, ", eps=", eps)


  complex func calculateAtomDomain(const complex c)
    AtomDomainCalculator calc = new AtomDomainCalculator(0)
    calc.@p_bailout = 1E10 ; ← here
    calc.setSwellPressure(@swellPressure)
    calc.setSwellPower(@swellPower)

    complex z = calc.Init(c)

    ;repeat
    ;  z = calc.Iterate(z)
    ;until calc.IsBailedOut(z) || calc.get >= #maxiter

    print("Test! ", z)
    return c
  endfunc

  calculateAtomDomain(#center - (span + flip(span)))
  calculateAtomDomain(#center - (span - flip(span)))
  calculateAtomDomain(#center + (span - flip(span)))
  calculateAtomDomain(#center + (span + flip(span)))
init:
  float bestAtomDistC = 1e10
  float bestAtomDistX = 1e10
  float bestAtomDistY = 1e10
  int foundAtomDomainC = 0
  int foundAtomDomainX = 0
  int foundAtomDomainY = 0

  complex cX = #pixel + eps
  complex cY = #pixel + flip(eps)
  complex zX = 0
  complex zY = 0

  int iter = 0
loop:
  zX = sqr(zX) + cX
  zY = sqr(zY) + cY
  print(iter, ": ", #z - zX)

  float modification = -iter ^ @swellPower * @swellPressure

  float distC = log(|#z|) + modification
  float distX = log(|zX|) + modification
  float distY = log(|zY|) + modification

  if bestAtomDistC > distC
    bestAtomDistC = distC
    foundAtomDomainC = iter
  endif
  if bestAtomDistX > distX
    bestAtomDistX = distX
    foundAtomDomainX = iter
  endif
  if bestAtomDistY > distY
    bestAtomDistY = distY
    foundAtomDomainY = iter
  endif

  iter = iter + 1
final:
  if foundAtomDomain < 0
    #solid = true
  elseif !@shading
    #color = gradient(foundAtomDomainC / 400)
  else
    bestAtomDistC = @offset - bestAtomDistC

    if bestAtomDistC < 0
      float col = 0
    else
      if @findOffset
         if (bestAtomDistC > 10)
           float col = 1
         else
           float col = 0.5
         endif
      else
        bestAtomDistC = bestAtomDistC * exp(@density)
        if bestAtomDist < 0
          float col = 0
        else
          float col = bestAtomDistC / (1 + bestAtomDistC) ; Sigmoid soft-limiting to 1.0
        endif
      endif
    endif

    ;print(bestAtomDistC, ", ", col)

    if !@colorize
       #color = gradient(col * 399 / 400)
    else
        color gra = gradient(foundAtomDomainC / 400)
        #color = rgb(red(gra) * col, green(gra) * col, blue(gra) * col)
    endif
  endif
default:
  title = "mjd Atom domains Gradient"
  float param swellPressure
    caption = "Swell pressure"
    default = 40
    hint = "Be very careful with increasing this. \
            Sometimes 0.005 is already enough, \
            sometimes you need 500, or -500."
  endparam
  float param swellPower
    caption = "Swell power"
    default = 0.125
    min = 0.0
    max = 1.0
    hint = "Raise the iteration number to this power to shrink higher \
            iteration atom domains"
  endparam
  bool param shading
  default = true
    caption = "Shading"
  endparam
  bool param findOffset
    caption = "Find offset"
    default = true
    visible = @shading
  endparam
  float param offset
    caption = "Offset (use Explore!)"
    visible = @shading
  endparam
  float param density
    caption = "Density (use Explore!)"
    default = 0
    visible = @shading && !@findOffset
  endparam
  bool param colorize
    caption = "Colorize"
    default = false
    visible = @shading && !@findOffset
  endparam
}
I wrote a class that&#039;s a subclass of `common.ulb:DivergentFormula`. &larr;wth why a smiley? The formula is purpose-built for a coloring algorithm where it is used hardcodedly (not as a class param), and I need to set the `@p_bailout` parameter to what the coloring needs (also hardcoded). Is there a way to do that, without writing my own `m_bailout` &#039;replacement&#039; member in the class and overriding `IsBailedOut()` (basically ignoring half of what makes `DivergentFormula` useful)? I&#039;m using the object like this (WIP): ![669d7569a6689.png](serve/attachment&amp;path=669d7569a6689.png) Both work-in-progress codes: ```` class AtomDomainCalculator(common.ulb:DivergentFormula) { ; Mark Jeronimus, 2024-07-21 public: func DivergentFormula(Generic pparent) DivergentFormula.DivergentFormula(pparent) endfunc complex func Init(complex pz) ;override DivergentFormula.Init(pz) m_c = pz m_bestAtomDist = 1e10 m_foundAtomDomain = 0 return 0 endfunc complex func Iterate(complex pz) ;override Formula.Iterate(pz) pz = pz ^ @p_power + m_c float dist = log(|pz|) - m_Iterations ^ m_swellPower * m_swellPressure if m_bestAtomDist &gt; dist m_bestAtomDist = dist m_foundAtomDomain = m_Iterations endif return pz endfunc func setSwellPressure(float swellPressure) m_swellPressure = swellPressure endfunc func setSwellPower(float swellPower) m_swellPower = swellPower endfunc protected: float m_swellPressure float m_swellPower complex m_c float m_bestAtomDist int m_foundAtomDomain } AtomDomainsGradient() { ; Mark Jeronimus, 2024-07-21 global: import &quot;jlb.ulb&quot; $define debug complex span = exp(flip(#angle)) * 2 / #magn complex eps = span/#width print(&quot;span=&quot;, span, &quot;, eps=&quot;, eps) complex func calculateAtomDomain(const complex c) AtomDomainCalculator calc = new AtomDomainCalculator(0) calc.@p_bailout = 1E10 ; &larr; here calc.setSwellPressure(@swellPressure) calc.setSwellPower(@swellPower) complex z = calc.Init(c) ;repeat ; z = calc.Iterate(z) ;until calc.IsBailedOut(z) || calc.get &gt;= #maxiter print(&quot;Test! &quot;, z) return c endfunc calculateAtomDomain(#center - (span + flip(span))) calculateAtomDomain(#center - (span - flip(span))) calculateAtomDomain(#center + (span - flip(span))) calculateAtomDomain(#center + (span + flip(span))) init: float bestAtomDistC = 1e10 float bestAtomDistX = 1e10 float bestAtomDistY = 1e10 int foundAtomDomainC = 0 int foundAtomDomainX = 0 int foundAtomDomainY = 0 complex cX = #pixel + eps complex cY = #pixel + flip(eps) complex zX = 0 complex zY = 0 int iter = 0 loop: zX = sqr(zX) + cX zY = sqr(zY) + cY print(iter, &quot;: &quot;, #z - zX) float modification = -iter ^ @swellPower * @swellPressure float distC = log(|#z|) + modification float distX = log(|zX|) + modification float distY = log(|zY|) + modification if bestAtomDistC &gt; distC bestAtomDistC = distC foundAtomDomainC = iter endif if bestAtomDistX &gt; distX bestAtomDistX = distX foundAtomDomainX = iter endif if bestAtomDistY &gt; distY bestAtomDistY = distY foundAtomDomainY = iter endif iter = iter + 1 final: if foundAtomDomain &lt; 0 #solid = true elseif !@shading #color = gradient(foundAtomDomainC / 400) else bestAtomDistC = @offset - bestAtomDistC if bestAtomDistC &lt; 0 float col = 0 else if @findOffset if (bestAtomDistC &gt; 10) float col = 1 else float col = 0.5 endif else bestAtomDistC = bestAtomDistC * exp(@density) if bestAtomDist &lt; 0 float col = 0 else float col = bestAtomDistC / (1 + bestAtomDistC) ; Sigmoid soft-limiting to 1.0 endif endif endif ;print(bestAtomDistC, &quot;, &quot;, col) if !@colorize #color = gradient(col * 399 / 400) else color gra = gradient(foundAtomDomainC / 400) #color = rgb(red(gra) * col, green(gra) * col, blue(gra) * col) endif endif default: title = &quot;mjd Atom domains Gradient&quot; float param swellPressure caption = &quot;Swell pressure&quot; default = 40 hint = &quot;Be very careful with increasing this. \ Sometimes 0.005 is already enough, \ sometimes you need 500, or -500.&quot; endparam float param swellPower caption = &quot;Swell power&quot; default = 0.125 min = 0.0 max = 1.0 hint = &quot;Raise the iteration number to this power to shrink higher \ iteration atom domains&quot; endparam bool param shading default = true caption = &quot;Shading&quot; endparam bool param findOffset caption = &quot;Find offset&quot; default = true visible = @shading endparam float param offset caption = &quot;Offset (use Explore!)&quot; visible = @shading endparam float param density caption = &quot;Density (use Explore!)&quot; default = 0 visible = @shading &amp;&amp; !@findOffset endparam bool param colorize caption = &quot;Colorize&quot; default = false visible = @shading &amp;&amp; !@findOffset endparam } ````
edited Jul 22 at 6:28 am
 
0
reply

I agree that would be very useful. The problem however is that parameters are actually constants in the compiler -- it recompiles the formula whenever you change a parameter which allows it to optimize depending on the current value. Changing parameter values on the fly like you're doing here requires a different implementation.

I agree that would be very useful. The problem however is that parameters are actually constants in the compiler -- it recompiles the formula whenever you change a parameter which allows it to optimize depending on the current value. Changing parameter values on the fly like you&#039;re doing here requires a different implementation.

Ultra Fractal author

 
0
reply
61
views
1
replies
2
followers
live preview
Enter at least 10 characters.
WARNING: You mentioned %MENTIONS%, but they cannot see this message and will not be notified
Saving...
Saved
All posts under this topic will be deleted ?
Pending draft ... Click to resume editing
Discard draft