2025 Rally

(define
  title "rally"
  coords1 [[404.671 -93.259]
           [-172.973 -346.625]
           [-89.671 357.031]
           [-54.188 -177.869]] ~
  (gen/2d min: -500 max: 500)
  coords2 [[419.368 -327.731]
           [329.579 -241.316]
           [84.750 -146.025]
           [261.420 267.813]] ~
  (gen/2d min: -500 max: 500)
  coords3 [[-491.881 296.505]
           [-382.603 443.651]
           [-123.308 47.655]
           [155.607 6.378]] ~
  (gen/2d min: -500 max: 500)

  col-fn-1 (col/build-procedural a: [0.794 0.002 0.101] ~ (gen/scalar)
                                 b: [0.821 0.724 0.671] ~ (gen/scalar)
                                 c: [0.610 0.539 0.329] ~ (gen/scalar)
                                 d: [0.622 0.534 0.445] ~ (gen/scalar)
                                 alpha: 0.08)
  col-fn-2 (col/build-procedural a: [0.334 0.875 0.663] ~ (gen/scalar)
                                 b: [0.401 0.013 0.646] ~ (gen/scalar)
                                 c: [0.069 0.860 0.241] ~ (gen/scalar)
                                 d: [0.303 0.389 0.014] ~ (gen/scalar)
                                 alpha: 0.08))

(fn (wash vol: 200
          line-width: 70
          line-segments: 5
          colour: (col/rgb r: 0.627 g: 0.627 b: 0.627 alpha: 0.4)
          seed: 272)
  (define
    w/3 (/ canvas/width 3)
    h/3 (/ canvas/height 3)
    tessellation line-segments)
  (loop (d from: -20 to: 1020 inc: 20)
    (bezier tessellation
            line-width
            coords: [[0            (wash-n x: 0            d seed vol)]
                     [w/3          (wash-n x: w/3          d seed vol)]
                     [(* w/3 2)    (wash-n x: (* w/3 2)    d seed vol)]
                     [canvas/width (wash-n x: canvas/width d seed vol)]]
            colour)

    (bezier tessellation
            line-width
            coords: [[(wash-n x: 0             d seed vol) 0]
                     [(wash-n x: h/3           d seed vol) h/3]
                     [(wash-n x: (* h/3 2)     d seed vol) (* h/3 2)]
                     [(wash-n x: canvas/height d seed vol) canvas/height]]
            colour)))


(fn (wash-n x: 0 d: 0 seed: 0 vol: 1)
  (+ d (* vol (prng/perlin x y: d z: seed))))

(fn (interesting-circle position: [500 500]
                        colour: red
                        seed: 123
                        radius: 300)
  (define
    rng (prng/build min: 0 max: 1 seed: seed)
    srng (prng/build min: -1 max: 1 seed: seed))

  (on-matrix-stack
    (translate vector: position)
    (scale scalar: (/ radius 210))
    (loop (i to: 8)
      (on-matrix-stack
        (define
          outer-exterior (+ (* (rng.prng/value) 40) 170)
          outer-interior (+ (* (rng.prng/value) 90)  80)
          inner-exterior (+ (* (rng.prng/value) 50) 100)
          inner-interior (+ (* (rng.prng/value) 100)  0))

        (rotate angle: (* 360 (rng.prng/value)))
        ;; outer ring
        (circle-slice tessellation: 80
                      position: [0 0]
                      colour: (col/lighten from: colour
                                           value: (* 540 ~ (gen/int min: 20 max: 600) (srng.prng/value)))
                      angle-start: 0
                      angle-end: 320
                      width: outer-exterior
                      inner-width: outer-interior
                      height: outer-exterior
                      inner-height: outer-interior)
        ;; inner ring
        (circle-slice tessellation: 50
                      position: [0 0]
                      colour: (col/lighten from: colour
                                           value: (* 297 ~ (gen/int min: 10 max: 400) (srng.prng/value)))
                      angle-start: 0
                      angle-end: 320
                      width: inner-exterior
                      inner-width: inner-interior
                      height: inner-exterior
                      inner-height: inner-interior)))
    ;; centre fill
    (circle-slice tessellation: 50
                  position: [0 0]
                  colour: (col/lighten from: colour
                                       value: (* 124 ~ (gen/int min: 5 max: 200) (srng.prng/value)))
                  angle-start: 0
                  angle-end: 360
                  radius: 30)))

(fn (flowery)
  (loop (t from: 0 upto: 1 inc: (/ 1 199))
    (poly coords: [(interp/bezier t: t coords: coords1)
                   (interp/bezier t: t coords: coords2)
                   (interp/bezier t: t coords: coords3)]
          colours: [(col/value from: col-fn-1 t: t)
                    (col/value from: col-fn-2 t: (- 1 t))
                    (col/value from: col-fn-1 t: t)])))

(fn (fg1)
  (on-matrix-stack
    (translate vector: [(/ canvas/width 2) 200])
    (scale scalar: 1.410 ~ (gen/scalar min: 1.2 max: 1.7))
    (rotate angle: 16 ~ (gen/int max: 360))
    (repeat/rotate-mirrored fn: (address-of flowery)
                            copies: 10 ~ (gen/int min: 1 max: 10))))



(fn (bg2)
  (define
    seed-radius 6.036 ~ (gen/scalar min: 6 max: 8)
    scale-factor 4
    phi (/ (sqrt 4.265 ~ (gen/scalar min: 4 max: 6)) 8.687 ~ (gen/scalar min: 8 max: 10))
    seeds 200
    focalpoint (focal/build-point ~ (gen/select from: '(focal/build-point
                                                        focal/build-hline
                                                        focal/build-vline))
                                  position: [527 ~ (gen/int max: canvas/width)
                                             175 ~ (gen/int max: canvas/height)]
                                  distance: 679 ~ (gen/int min: (/ canvas/width 2) max: canvas/width)))

  (on-matrix-stack
    (translate vector: [500 0])
    (scale scalar: 20)
    (loop (i from: 0 to: seeds)         ;todo
      (define
        theta (/ (* (- seeds i) math/TAU) phi)
        r (* scale-factor (sqrt (- seeds i)))
        position [(* r (math/cos from: theta))
                  (* r (math/sin from: theta))]
        colour (col/set-alpha from: (col/value from: col-fn-1 t: (focal/value from: focalpoint position: position))
                              value: 0.4))
      ;; don't render some of the offscreen circles
      (if (> (get-y from: position) -10)
          (interesting-circle position: position
                              radius: seed-radius
                              colour: colour
                              seed: (- seeds i))))))



(wash colour: (col/value from: col-fn-1 t: 0.1))
(bg2)
(fg1)