-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
443 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
(executable | ||
(name main) | ||
(libraries mandelbrot core_unix.command_unix)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
open! Core | ||
|
||
let () = Command_unix.run Mandelbrot.command |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
(*_ Intentionally left empty. *) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
open! Core | ||
|
||
type t = | ||
{ real : float | ||
; imaginary : float | ||
} | ||
[@@deriving sexp_of] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
open! Core | ||
|
||
type t = | ||
{ real : float | ||
; imaginary : float | ||
} | ||
[@@deriving sexp_of] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
open! Core | ||
open! Bonsai | ||
open Capytui | ||
open Bonsai.Let_syntax | ||
|
||
type t = | ||
| Basic | ||
| Unicode | ||
| Green | ||
[@@deriving enumerate] | ||
|
||
type action = | ||
| Next | ||
| Prev | ||
|
||
let component = | ||
let all = Array.of_list all in | ||
let%sub current, inject = | ||
Bonsai.state_machine0 | ||
~default_model:0 | ||
~apply_action:(fun _ x action -> | ||
let offset = match action with Prev -> -1 | Next -> 1 in | ||
(x + offset) % Array.length all) | ||
() | ||
in | ||
let%arr current = current | ||
and inject = inject in | ||
all.(current), inject | ||
;; | ||
|
||
let iter_on_pixels result ~f = | ||
let rows = | ||
Array.to_list result | ||
|> List.map ~f:(fun row -> | ||
let columns = Array.to_list row |> List.map ~f in | ||
Node.hcat columns) | ||
in | ||
Node.vcat rows | ||
;; | ||
|
||
let draw t = | ||
let%sub text = Text.component in | ||
let%sub flavor = Capytui_catpuccin.flavor in | ||
match%sub t with | ||
| Basic -> | ||
let%arr text = text in | ||
fun ~max_iterations result -> | ||
let string = | ||
String.concat_array ~sep:"\n" | ||
@@ Array.map result ~f:(fun line -> | ||
String.concat_array | ||
@@ Array.map line ~f:(fun iteration -> | ||
if iteration > max_iterations / 2 then "X" else ".")) | ||
in | ||
Node.vcat (String.split ~on:'\n' string |> List.map ~f:text) | ||
| Unicode -> | ||
let%arr text = text | ||
and flavor = flavor in | ||
fun ~max_iterations result -> | ||
iter_on_pixels result ~f:(fun iteration -> | ||
if iteration > max_iterations / 2 | ||
then | ||
text | ||
~attrs: | ||
[ Attr.background_color (Capytui_catpuccin.color ~flavor Text) | ||
] | ||
" " | ||
else text " ") | ||
| Green -> | ||
let%arr text = text in | ||
fun ~max_iterations result -> | ||
iter_on_pixels result ~f:(fun iteration -> | ||
let quotient = | ||
Float.of_int iteration /. Float.of_int max_iterations | ||
in | ||
let color = | ||
Render.lerp 0.0 255.0 (Percent.of_mult quotient) |> Int.of_float | ||
in | ||
if iteration > max_iterations / 2 | ||
then | ||
text | ||
~attrs: | ||
[ Attr.background_color | ||
(Attr.Color.rgb ~r:color ~g:255 ~b:color) | ||
] | ||
" " | ||
else | ||
text | ||
~attrs: | ||
[ Attr.background_color (Attr.Color.rgb ~r:0 ~g:color ~b:0) ] | ||
" ") | ||
;; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
open! Core | ||
open Bonsai | ||
open Capytui | ||
|
||
type t = | ||
| Basic | ||
| Unicode | ||
| Green | ||
[@@deriving enumerate] | ||
|
||
type action = | ||
| Next | ||
| Prev | ||
|
||
val component : (t * (action -> unit Effect.t)) Computation.t | ||
|
||
val draw | ||
: t Value.t | ||
-> (max_iterations:int -> int array array -> Node.t) Computation.t |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
(library | ||
(name mandelbrot) | ||
(libraries core bonsai capytui async capytui_catpuccin) | ||
(preprocess | ||
(pps ppx_jane bonsai.ppx_bonsai))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
open! Core | ||
open Async | ||
open! Bonsai | ||
open! Capytui | ||
open! Bonsai.Let_syntax | ||
|
||
module View_port = struct | ||
type t = | ||
{ center : Complex.t | ||
; scale : Percent.t | ||
; max_iterations : int | ||
} | ||
|
||
type action = | ||
| Zoom_in | ||
| Zoom_out | ||
| Up | ||
| Down | ||
| Left | ||
| Right | ||
| Increase_iterations | ||
| Decreate_iterations | ||
|
||
let default = | ||
let center = { Complex.real = 0.0; imaginary = 0.0 } | ||
and scale = Percent.one_hundred_percent | ||
and max_iterations = 1_000 in | ||
{ center; scale; max_iterations } | ||
;; | ||
|
||
let apply_action _ { center; scale; max_iterations } action = | ||
let center = | ||
let multiple = 0.1 *. Percent.to_mult scale in | ||
match action with | ||
| Zoom_in | Zoom_out | Increase_iterations | Decreate_iterations -> | ||
center | ||
| Up -> { center with imaginary = center.imaginary -. multiple } | ||
| Down -> { center with imaginary = center.imaginary +. multiple } | ||
| Left -> { center with real = center.real -. multiple } | ||
| Right -> { center with real = center.real +. multiple } | ||
and scale = | ||
match action with | ||
| Zoom_in -> Percent.( * ) scale (Percent.of_mult 0.9) | ||
| Zoom_out -> Percent.( * ) scale (Percent.of_mult (1.0 /. 0.9)) | ||
| Up | Down | Left | Right | Increase_iterations | Decreate_iterations | ||
-> | ||
scale | ||
and max_iterations = | ||
match action with | ||
| Increase_iterations -> max_iterations + 100 | ||
| Decreate_iterations -> Int.max 100 (max_iterations - 100) | ||
| _ -> max_iterations | ||
in | ||
{ center; scale; max_iterations } | ||
;; | ||
|
||
let component = | ||
Bonsai.state_machine0 ~default_model:default ~apply_action () | ||
;; | ||
end | ||
|
||
let backdrop = | ||
let%sub dimensions = Capytui.terminal_dimensions in | ||
let%sub flavor = Capytui_catpuccin.flavor in | ||
let%arr { height; width } = dimensions | ||
and flavor = flavor in | ||
Node.vcat | ||
(List.init height ~f:(fun _ -> | ||
Node.text | ||
~attrs: | ||
[ Attr.background_color (Capytui_catpuccin.color ~flavor Crust) ] | ||
(String.make width ' '))) | ||
;; | ||
|
||
let app = | ||
let%sub dimensions = Capytui.terminal_dimensions in | ||
let%sub { center; scale; max_iterations }, inject = View_port.component in | ||
let%sub drawing_style, inject_drawing_style = Drawing_style.component in | ||
let%sub handler = | ||
let%arr inject = inject | ||
and inject_drawing_style = inject_drawing_style in | ||
fun (event : Event.t) -> | ||
match event with | ||
| `Key (`ASCII '+', []) -> inject Zoom_in | ||
| `Key (`ASCII '-', []) -> inject Zoom_out | ||
| `Key (`ASCII 'j', []) -> inject Down | ||
| `Key (`ASCII 'k', []) -> inject Up | ||
| `Key (`ASCII 'h', []) -> inject Left | ||
| `Key (`ASCII 'l', []) -> inject Right | ||
| `Key (`ASCII 'u', []) -> inject Increase_iterations | ||
| `Key (`ASCII 'd', []) -> inject Decreate_iterations | ||
| `Key (`ASCII 'n', []) -> inject_drawing_style Next | ||
| `Key (`ASCII 'N', []) -> inject_drawing_style Prev | ||
| _ -> Effect.Ignore | ||
in | ||
let%sub () = Capytui.listen_to_events handler in | ||
let%sub result = | ||
let%arr dimensions = dimensions | ||
and center = center | ||
and scale = scale | ||
and max_iterations = max_iterations in | ||
Render.render ~center ~scale ~max_iterations ~dimensions | ||
in | ||
let%sub draw = Drawing_style.draw drawing_style in | ||
let%sub rendered = | ||
let%arr result = result | ||
and draw = draw | ||
and max_iterations = max_iterations in | ||
draw ~max_iterations result | ||
in | ||
let%sub backdrop = backdrop in | ||
let%arr rendered = rendered | ||
and backdrop = backdrop in | ||
Node.zcat [ rendered; backdrop ] | ||
;; | ||
|
||
let command = | ||
Command.async_or_error | ||
~summary:{|A small mandelbrot demo.|} | ||
[%map_open.Command | ||
let () = return () in | ||
fun () -> | ||
let open Deferred.Or_error.Let_syntax in | ||
let%bind () = Capytui.start app in | ||
return ()] | ||
;; | ||
|
||
module For_testing = struct | ||
module Render = Render | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
open! Core | ||
|
||
val command : Command.t | ||
|
||
module For_testing : sig | ||
module Render = Render | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
open! Core | ||
open Capytui | ||
|
||
let lerp v0 v1 t = | ||
let t = Percent.to_mult t in | ||
v0 +. (t *. (v1 -. v0)) | ||
;; | ||
|
||
let render | ||
~center | ||
~scale | ||
~max_iterations | ||
~dimensions:({ width; height } : Dimensions.t) | ||
= | ||
let center = | ||
{ Complex.real = center.Complex.real -. 0.765 | ||
; imaginary = center.imaginary | ||
} | ||
in | ||
let left = center.real -. (1.235 *. Percent.to_mult scale) | ||
and right = center.real +. (1.235 *. Percent.to_mult scale) | ||
and top = center.imaginary -. (1.12 *. Percent.to_mult scale) | ||
and bottom = center.imaginary +. (1.12 *. Percent.to_mult scale) in | ||
Array.init height ~f:(fun y -> | ||
let y = Int.to_float y | ||
and height = Int.to_float height in | ||
Array.init width ~f:(fun x -> | ||
let x = Int.to_float x | ||
and width = Int.to_float width in | ||
let x0 = lerp left right (Percent.of_mult (x /. width)) | ||
and y0 = lerp top bottom (Percent.of_mult (y /. height)) in | ||
let x = ref 0.0 | ||
and y = ref 0.0 | ||
and iteration = ref 0 in | ||
let ( <= ) = Float.( <= ) in | ||
while | ||
(!x *. !x) +. (!y *. !y) <= 2.0 *. 2.0 && !iteration < max_iterations | ||
do | ||
let xtemp = (!x *. !x) -. (!y *. !y) +. x0 in | ||
y := (2.0 *. !x *. !y) +. y0; | ||
x := xtemp; | ||
incr iteration | ||
done; | ||
!iteration)) | ||
;; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
open! Core | ||
open Capytui | ||
|
||
val lerp : float -> float -> Percent.t -> float | ||
|
||
val render | ||
: center:Complex.t | ||
-> scale:Percent.t | ||
-> max_iterations:int | ||
-> dimensions:Dimensions.t | ||
-> int array array |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
open! Core | ||
open Bonsai.Let_syntax | ||
open Capytui | ||
|
||
let component = | ||
let%sub flavor = Capytui_catpuccin.flavor in | ||
let%arr flavor = flavor in | ||
let crust = Capytui_catpuccin.color ~flavor Crust in | ||
let text = Capytui_catpuccin.color ~flavor Text in | ||
fun ?(attrs = []) string -> | ||
Node.text | ||
~attrs: | ||
([ Attr.background_color crust; Attr.foreground_color text ] @ attrs) | ||
string | ||
;; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
open! Core | ||
open Bonsai | ||
open Capytui | ||
|
||
val component : (?attrs:Attr.t list -> string -> Node.t) Computation.t |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
open! Core |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
open! Core |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
(library | ||
(name test_mandelbrot) | ||
(libraries mandelbrot core bonsai capytui) | ||
(inline_tests) | ||
(preprocess | ||
(pps ppx_jane))) |
Oops, something went wrong.