diff --git a/engine-proto/ConstructionViewer.jl b/engine-proto/ConstructionViewer.jl new file mode 100644 index 0000000..efa7293 --- /dev/null +++ b/engine-proto/ConstructionViewer.jl @@ -0,0 +1,123 @@ +module Viewer + +using Blink +using Colors + +export ConstructionViewer, display! + +# === Blink utilities === + +append_to_head!(w, type, content) = @js w begin + @var element = document.createElement($type) + element.appendChild(document.createTextNode($content)) + document.head.appendChild(element) +end + +style!(w, stylesheet) = append_to_head!(w, "style", stylesheet) + +script!(w, code) = append_to_head!(w, "script", code) + +# === construction viewer === + +mutable struct ConstructionViewer + win::Window + + function ConstructionViewer() + # create window and open developer console + win = Window() + opentools(win) + + # set stylesheet + style!(win, """ + /* needed to keep Ganja canvas from blowing up */ + canvas { + min-width: 600px; + max-width: 600px; + min-height: 600px; + max-height: 600px; + } + """) + + # load Ganja.js + loadjs!(win, "https://unpkg.com/ganja.js") + + # create global functions and variables + script!(win, """ + // create algebra + var CGA3 = Algebra(4, 1); + + // initialize element list and palette + var elements = []; + var palette = []; + + // declare visualization handle + var graph; + + // create scene function + function scene() { + commands = []; + for (let n = 0; n < elements.length; ++n) { + commands.push(palette[n], elements[n]); + } + return commands; + } + """) + + # create view + @js win begin + graph = CGA3.graph( + scene, + Dict( + "conformal" => true, + "gl" => true, + "grid" => true + ) + ) + document.body.replaceChildren(graph) + end + + new(win) + end +end + +function display!(viewer::ConstructionViewer, elements::Matrix) + # load elements + elements_full = [ + [0; elt; fill(0, 26)] + for elt in eachcol(elements) + ] + @js viewer.win elements = $elements_full.map((elt) -> @new CGA3(elt)) + + # generate palette. this is Gadfly's `default_discrete_colors` palette, + # available under the MIT license + palette = distinguishable_colors( + length(elements_full), + [LCHab(70, 60, 240)], + transform = c -> deuteranopic(c, 0.5), + lchoices = Float64[65, 70, 75, 80], + cchoices = Float64[0, 50, 60, 70], + hchoices = range(0, stop=330, length=24) + ) + palette_packed = [RGB24(c).color for c in palette] + @js viewer.win palette = $palette_packed + + # update view + @js viewer.win requestAnimationFrame(graph.update.bind(graph, scene)); +end + +end + +# ~~~ sandbox setup ~~~ + +# in the default view, e4 + e5 is the point at infinity +elements = sqrt(0.5) * BigFloat[ + 1 1 -1 -1 0; + 1 -1 1 -1 0; + 1 -1 -1 1 0; + 0 0 0 0 -sqrt(6); + 1 1 1 1 2 +] + +# show construction +viewer = Viewer.ConstructionViewer() +Viewer.display!(viewer, elements) \ No newline at end of file diff --git a/engine-proto/ganja-test/ganja-test.html b/engine-proto/ganja-test/ganja-test.html new file mode 100644 index 0000000..d6efc90 --- /dev/null +++ b/engine-proto/ganja-test/ganja-test.html @@ -0,0 +1,76 @@ + + + + + + + +

+ + + diff --git a/engine-proto/ganja-test/ganja-test.jl b/engine-proto/ganja-test/ganja-test.jl new file mode 100644 index 0000000..6c55061 --- /dev/null +++ b/engine-proto/ganja-test/ganja-test.jl @@ -0,0 +1,127 @@ +using Blink +using Colors + +# === utilities === + +append_to_head!(w, type, content) = @js w begin + @var element = document.createElement($type) + element.appendChild(document.createTextNode($content)) + document.head.appendChild(element) +end + +style!(w, stylesheet) = append_to_head!(w, "style", stylesheet) + +script!(w, code) = append_to_head!(w, "script", code) + +function add_element!(vec) + # add element + full_vec = [0; vec; fill(0, 26)] + n = @js win elements.push(@new CGA3($full_vec)) + + # generate palette. this is Gadfly's `default_discrete_colors` palette, + # available under the MIT license + palette = distinguishable_colors( + n, + [LCHab(70, 60, 240)], + transform = c -> deuteranopic(c, 0.5), + lchoices = Float64[65, 70, 75, 80], + cchoices = Float64[0, 50, 60, 70], + hchoices = range(0, stop=330, length=24) + ) + palette_packed = [RGB24(c).color for c in palette] + @js win palette = $palette_packed +end + +# === build page === + +# create window and open developer console +win = Window() +opentools(win) + +# set stylesheet +style!(win, """ + body { + background-color: #ffe0f0; + } + + /* needed to keep Ganja canvas from blowing up */ + canvas { + min-width: 600px; + max-width: 600px; + min-height: 600px; + max-height: 600px; + } +""") + +# load Ganja.js +loadjs!(win, "https://unpkg.com/ganja.js") + +# create global functions and variables +script!(win, """ + // create algebra + var CGA3 = Algebra(4, 1); + + // initialize element list and palette + var elements = []; + var palette = []; + + // declare visualization handle + var graph; + + // create scene function + function scene() { + commands = []; + for (let n = 0; n < elements.length; ++n) { + commands.push(palette[n], elements[n]); + } + return commands; + } + + function flip() { + let last = elements.length - 1; + for (let n = 0; n < last; ++n) { + // reflect + elements[n] = CGA3.Mul(CGA3.Mul(elements[last], elements[n]), elements[last]); + + // de-noise + for (let k = 6; k < elements[n].length; ++k) { + elements[n][k] = 0; + } + } + requestAnimationFrame(graph.update.bind(graph, scene)); + } +""") + +# set up controls +body!(win, """ +

+""", async = false) + +# === set up visualization === + +# list elements. in the default view, e4 + e5 is the point at infinity +elements = sqrt(0.5) * BigFloat[ + 1 1 -1 -1 0; + 1 -1 1 -1 0; + 1 -1 -1 1 0; + 0 0 0 0 -sqrt(6); + 1 1 1 1 2 +] + +# load elements +for vec in eachcol(elements) + add_element!(vec) +end + +# initialize visualization +@js win begin + graph = CGA3.graph( + scene, + Dict( + "conformal" => true, + "gl" => true, + "grid" => true + ) + ) + document.body.appendChild(graph) +end \ No newline at end of file