# A more complicated py5 sketch

**URL:** <https://discourse.processing.org/t/a-more-complicated-py5-sketch/30848>\
**Category:** Gallery\
**Created:** [June 22, 2021, 8:12am UTC](https://discourse.processing.org/t/a-more-complicated-py5-sketch/30848 "2021-06-22T08:12:50Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![monkstone](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/monkstone/32/64_2.png) [@monkstone](https://discourse.processing.org/u/monkstone)\
**Post date:** [June 22, 2021, 8:12am UTC](https://discourse.processing.org/t/a-more-complicated-py5-sketch/30848/1 "2021-06-22T08:12:51Z")

</div>

There is a Newton Fractal sketch on [Jorg Kantel blog](http://blog.schockwellenreiter.de/) that I converted to run with py5:-

```python
import py5
import cmath

imgx = 512
imgy = 512

# Drawing area
# xa = 1.126
xa = -2.0
xb = 2.0
ya = -2.0
yb = 2.0

maxIt = 20 # max iterations allowed
h = 1e-6 # stepsize for numerical derivative
eps = 1e-3 # max error allowed

def f(z):
    # return cmath.sin(z)
    # return z*z*z*z*z*z - 1.0
    return z*(z*z*z*z*z*z - 1.0)
    
def settings():
	py5.size(imgx, imgy)    

def setup():
    global img    
    img = py5.create_image(py5.width, py5.height, 1) # 1 = RGB
    py5.no_loop()

def draw():
    global img
    py5.load_pixels()
    img.load_pixels()
    for y in range(imgy):
        zy = y*(yb - ya)/(imgy - 1) + ya
        for x in range(imgx):
            zx = x*(xb - xa)/(imgx - 1) + xa
            z = complex(zx, zy)
            for i in range(maxIt):
                # Complex numerical derivative
                dz = (f(z + complex(h, h)) - f(z))/complex(h, h)
                if dz != 0:
                    z0 = z - f(z)/dz # Newton iteration
                if abs(z0 - z) < eps:
                    # Stop when close enough to any root
                    break
                z = z0
                
            loc = x + y * py5.width
            # pixels[loc] = color(i%5*64, i%9*32, i%17*16)   
            py5.pixels[loc] = py5.color(i%5*64, i%17*16, i%9*32)
    py5.update_pixels()
    
py5.run_sketch()

```

Here is sketch running from geany on my RaspberryPI4 see [New Python Processing project: Py5 - #11 by monkstone](https://discourse.processing.org/t/new-python-processing-project-py5/30837/11)

 ![Screenshot_2021-06-22_09-08-51](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/7/76448f36472f4b1f1e3dd4888b2cc1f7f1e8fe7e.png)

---

<div class="post-metadata">

**Author:** ![tabreturn](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tabreturn/32/3697_2.png) [@tabreturn](https://discourse.processing.org/u/tabreturn)\
**Post date:** [June 22, 2021, 9:29am UTC](https://discourse.processing.org/t/a-more-complicated-py5-sketch/30848/2 "2021-06-22T09:29:31Z")

</div>

Very cool!

BTW: there’s a `run_sketch.py` file located in `lib/python3.X/site-packages/py5_tools/tools/` that you can use to run py5 in _Imported mode_. This requires no `import py5` line or `py5.` prefixes. Also, it supports ‘static’ mode sketches – so if you don’t want animation, you can skip the `setup()` and `draw()` functions.

I compressed the code a little to avoid invoking a scroll pane 😉

```python
xa, xb, ya, yb = -2.0, 2.0, -2.0, 2.0
maxIt, h, eps = 20, 1e-6, 1e-3
def f(z): return z*(z*z*z*z*z*z - 1.0)

size(512, 512)
load_pixels()

for y in range(height):
    zy = y*(yb - ya)/(height - 1) + ya
    for x in range(width):
        zx = x*(xb - xa)/(width - 1) + xa
        z = complex(zx, zy)
        for i in range(maxIt):
            dz = (f(z + complex(h, h)) - f(z))/complex(h, h)
            if dz != 0: z0 = z - f(z)/dz
            if abs(z0 - z) < eps: break
            z = z0
        loc = x + y * width 
        pixels[loc] = color(i%5*64, i%17*16, i%9*32)

update_pixels()

```

---

<div class="post-metadata">

**Author:** ![monkstone](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/monkstone/32/64_2.png) [@monkstone](https://discourse.processing.org/u/monkstone)\
**Post date:** [June 22, 2021, 10:20am UTC](https://discourse.processing.org/t/a-more-complicated-py5-sketch/30848/3 "2021-06-22T10:20:57Z")

</div>

I tested your version with both java-16-graalvm and java-16-openjdk on my linux box adding print(millis()) after update\_pixels, and again no performance improvement with graalvm _cf_ my experience with ruby-processing. Installed a whole pile faster on linux box (Archlinux) cf RaspberryPI, I needed to add pip as well as wheel this time though:-

```bash
sudo pacman -S python-pip
sudo pacman -S python-wheel

```

---

<div class="post-metadata">

**Author:** ![monkstone](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/monkstone/32/64_2.png) [@monkstone](https://discourse.processing.org/u/monkstone)\
**Post date:** [June 22, 2021, 1:14pm UTC](https://discourse.processing.org/t/a-more-complicated-py5-sketch/30848/4 "2021-06-22T13:14:34Z")

</div>

Regarding py5 performance, Jim Schmitz has written some [interesting notes](https://py5.ixora.io/tutorials/exceptions-debugging-performance/). It might be interesting to explore writing java extensions, I have written such extensions for my ruby-processing projects (but jruby support for [extensions](https://github.com/jruby/jruby/wiki/Method-Signatures-and-Annotations-in-JRuby-extensions) is probably better established).
