Padrão de Curvas Dinâmicas 02

2026-01-08

"""2026-01-08
Padrão de Curvas Dinâmicas 02
Curvas que reagem à posição do mouse, criando um padrão fluído e em movimento.
ericof.com|https://openprocessing.org/sketch/2699138
png
Sketch,py5,CreativeCoding
"""

from sketches.utils.draw import canvas
from sketches.utils.draw.cores.paletas import gera_paleta
from sketches.utils.helpers import sketches as helpers

import py5


sketch = helpers.info_for_sketch(__file__, __doc__)

num: float = 4.0
tnum: float = 24.0
mult: float = 1.0
start: float = 0.0
stretch: float = 5.0
lm: py5.Py5Vector = py5.Py5Vector(0, 0)


def setup():
    global lm
    py5.size(*helpers.DIMENSOES.external, py5.P3D)
    py5.background("ivory")
    py5.no_cursor()


def desenha_padroes(largura, altura, paleta):
    global num, tnum, mult, start, stretch, lm
    target = py5.Py5Vector(py5.mouse_x, py5.mouse_y)
    lm = lm.lerp(target, 0.1)
    target_stretch = py5.floor(py5.remap(py5.mouse_y, 0, py5.height, 0.2, 6))
    stretch = py5.lerp(stretch, target_stretch, 0.1)
    num = py5.lerp(num, tnum, 0.1)
    mult = py5.lerp(mult, py5.remap(py5.mouse_x, 0, py5.width, 1, 4), 0.1)
    start = py5.lerp(start, py5.remap(py5.mouse_y, 0, py5.width, -12, 12), 0.1)
    # translucent fade
    py5.no_stroke()
    py5.fill(255, 255, 240, int(0.25 * 255))
    py5.rect(0, 0, py5.width, py5.height)

    # mouse marker
    # py5.fill(0, 20)
    # py5.ellipse(lm.x, lm.y, 20, 20)
    with py5.push():
        cor = paleta[0]
        paleta.rotate(1)
        py5.translate(largura / 2, altura / 2)
        py5.scale(0.95)
        py5.stroke(cor)
        py5.no_fill()
        py5.stroke_weight(0.8 * altura / 628)
        n = int(num)
        for i in range(n):
            a = py5.PI + i * py5.TAU / n

            # first pair (mirrored with scale(-1, 1))
            with py5.push():
                py5.rotate(a)
                cor = paleta[0]
                paleta.rotate(1)
                py5.stroke(cor)
                py5.curve(
                    -start * altura / 6,
                    -altura * stretch,
                    0,
                    altura / 48,
                    0,
                    altura / 2,
                    start * 3 * altura / 9,
                    3 * altura / 2,
                )
                py5.scale(-1, 1)
                py5.curve(
                    -start * altura / 6,
                    -altura * stretch,
                    0,
                    altura / 48,
                    0,
                    altura / 2,
                    start * 3 * altura / 9,
                    3 * altura / 2,
                )

            # second pair (scaled by mult and -mult)
            with py5.push():
                py5.rotate(a)

                with py5.push():
                    cor = paleta[0]
                    paleta.rotate(1)
                    py5.stroke(cor)
                    py5.scale(mult, 1)
                    py5.curve(
                        -start * altura / 6,
                        -altura * stretch,
                        0,
                        altura / 48,
                        0,
                        altura / 2,
                        start * 3 * altura / 9,
                        3 * altura / 2,
                    )

                with py5.push():
                    cor = paleta[0]
                    paleta.rotate(1)
                    py5.stroke(cor)
                    py5.scale(-mult, 1)
                    py5.curve(
                        -start * altura / 6,
                        -altura * stretch,
                        0,
                        altura / 48,
                        0,
                        altura / 2,
                        start * 3 * altura / 9,
                        3 * altura / 2,
                    )


def draw():
    largura, altura = helpers.DIMENSOES.internal
    py5.background("ivory")
    paleta = gera_paleta("brasil-03", True)
    with py5.push():
        py5.translate(*helpers.DIMENSOES.pos_interno, -10)
        desenha_padroes(largura, altura, paleta)

    py5.window_title(
        f"Mouse: {int(lm.x), int(lm.y)} "
        f"Num: {num:.2f} "
        f"Mult: {mult:.2f} "
        f"Stretch: {stretch:.2f}"
    )
    # Credits and go
    cor_fundo = py5.color(0)
    canvas.sketch_frame(
        sketch, cor_fundo, "large_transparent_white", "transparent_white"
    )


def key_pressed():
    key = py5.key
    if key == " ":
        save_and_close()


def save_and_close():
    py5.no_loop()
    canvas.save_sketch_image(sketch)
    py5.exit_sketch()


if __name__ == "__main__":
    py5.run_sketch()