Loading templates/bg_graph.html 0 → 100644 +10 −0 Original line number Diff line number Diff line <div id="knWrapper"> <h4 class="d-konami m-2">Multidirectional Dijkstra background by Spak</h4> <button type="button" class="btn btn-light m-2 d-konami" data-toggle="modal" data-target="#knCustomizeModal"> Customize </button> <button type="button" class="btn btn-light m-2 d-konami" data-kn-fn="redraw"> Redraw </button> <svg class="w-100 h-100 position-fixed z-lowest" id="graph"></svg> </div> No newline at end of file templates/home.html +2 −1 Original line number Diff line number Diff line Loading @@ -6,11 +6,12 @@ {% block title %}{{ this.title }}{% endblock %} {% block body %} <body> {% include 'konami.html' %} <div class="container-fluid h-md-100 px-0"> <div class="row h-md-100 mx-0"> <div class="col-md-6 col-lg-5 order-md-2 inner-shadow px-0 h-100"> <div class="scrollable-md"> <svg class="w-100 h-100 position-fixed z-lowest" id="graph"></svg> {% include 'bg_graph.html' %} <header class="my-3 mx-3"> <h1><img src="{{ '/images/logo.svg' | url}}" alt="Mittelab" class="logo d-block mx-auto"></h1> <p class="text-monospace text-center lead"> Loading templates/konami.html 0 → 100644 +137 −0 Original line number Diff line number Diff line <div class="modal fade" id="knCustomizeModal" tabindex="-1" role="dialog" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content bg-dark border-secondary outer-shadow"> <div class="modal-header border-secondary"> <h5 class="modal-title">Customize multi-directional Dijkstra</h5> <button type="button" class="close text-white" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <form> <div class="form-group form-row mb-1"> <label for="knNSources" class="col text-right col-form-label col-form-label-sm">Num. of terminals</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knNSources" value="10" min="2"> </div> </div> <div class="form-group form-row mb-1"> <label for="knGridUnit" class="col text-right col-form-label col-form-label-sm">Grid unit</label> <div class="input-group input-group-sm col-5"> <input id="knGridUnit" type="number" class="form-control-sm form-control" aria-describedby="knPx" min="5" value="30"> <div class="input-group-append"> <span class="input-group-text" id="knPx">px</span> </div> </div> </div> <div class="form-group form-row mb-1"> <label for="knCostNodeW" class="col text-right col-form-label col-form-label-sm">Edge cost node weight</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knCostNodeW" value="5" min="0" step="0.1"> </div> </div> <div class="form-group form-row mb-1"> <label for="knCostRndFrac" class="col text-right col-form-label col-form-label-sm">Edge cost random fraction</label> <div class="col-5"> <input type="range" class="form-control-sm form-control-range" id="knCostRndFrac" value="0.6" min="0.0" max="1.0" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knFeasCenterX" class="col text-right col-form-label col-form-label-sm">Node clearance center X</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knFeasCenterX" value="0.5" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knFeasCenterY" class="col text-right col-form-label col-form-label-sm">Node clearance center Y</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knFeasCenterY" value="0.3" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knFeasRad" class="col text-right col-form-label col-form-label-sm">Node clearance radius</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knFeasRad" value="0.2" min="0" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knFeasFalloff" class="col text-right col-form-label col-form-label-sm">Node clearance falloff radius</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knFeasFalloff" value="0.3" min="0" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knFeasFalloffExp" class="col text-right col-form-label col-form-label-sm">Node clearance falloff exponent</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knFeasFalloffExp" value="0.8" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knFeasRndFrac" class="col text-right col-form-label col-form-label-sm">Node clearance random fraction</label> <div class="col-5"> <input type="range" class="form-control-sm form-control-range" id="knFeasRndFrac" value="0.3" min="0.0" max="1.0" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knLblPcPerFrame" class="col text-right col-form-label col-form-label-sm">Max grid fraction labeled per frame</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knLblPcPerFrame" min="0.0" max="1.0" value="0.004" step="0.0001"> </div> </div> <div class="form-group form-row mb-1"> <label for="knOpacity" class="col text-right col-form-label col-form-label-sm">Opacity</label> <div class="col-5"> <input type="range" class="form-control-sm form-control-range" id="knOpacity" value="0.45" min="0.0" max="1.0" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knOpacityTempLbl" class="col text-right col-form-label col-form-label-sm">Temporary label opacity</label> <div class="col-5"> <input type="range" class="form-control-sm form-control-range" id="knOpacityTempLbl" value="0.23" min="0.0" max="1.0" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knOpacityShortestPath" class="col text-right col-form-label col-form-label-sm">Shortest path opacity</label> <div class="col-5"> <input type="range" class="form-control-sm form-control-range" id="knOpacityShortestPath" value="0.36" min="0.0" max="1.0" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knStrokeWShortestPath" class="col text-right col-form-label col-form-label-sm">Shortest path stroke width</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knStrokeWShortestPath" min="0.0" value="5" step="0.1"> </div> </div> <div class="form-group form-row mb-1"> <label for="knTrunkCol" class="col text-right col-form-label col-form-label-sm">Steiner tree path color</label> <div class="col-5"> <input type="text" class="form-control-sm form-control" id="knTrunkCol" value="#444"> </div> </div> <div class="form-group form-row mb-1"> <label for="knRayCol" class="col text-right col-form-label col-form-label-sm">Secondary path color</label> <div class="col-5"> <input type="text" class="form-control-sm form-control" id="knRayCol" value="#fff"> </div> </div> <div class="form-group form-row mb-1"> <label for="knRootRad" class="col text-right col-form-label col-form-label-sm">Terminal radius</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knRootRad" min="0.0" value="6" step="0.1"> </div> </div> <div class="form-group form-row mb-1"> <label for="knRootCol" class="col text-right col-form-label col-form-label-sm">Terminal color</label> <div class="col-5"> <input type="text" class="form-control-sm form-control" id="knRootCol" value="#444"> </div> </div> </form> </div> <div class="modal-footer border-secondary"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> <button type="button" class="btn btn-light" data-kn-fn="redraw">Redraw</button> </div> </div> </div> </div> No newline at end of file templates/page.html +2 −1 Original line number Diff line number Diff line Loading @@ -2,7 +2,8 @@ {% block title %}{{ this.title }}{% endblock %} {% block body %} <body class="inner-shadow"> <svg class="w-100 h-100 position-fixed z-lowest" id="graph"></svg> {% include 'bg_graph.html' %} {% include 'konami.html' %} <div class="container-fluid h-md-100"> <div class="row h-100"> <div class="col-md-5 col-lg-4 col-xl-3 col-xxl-2 px-0"> Loading webpack/js/mlab.js +63 −32 Original line number Diff line number Diff line Loading @@ -6,21 +6,43 @@ require('typeface-ubuntu'); import Konami from 'konami'; new Konami(function () { alert('Konami Code!') }); const Snap = require( "imports-loader?this=>window,fix=>module.exports=0!snapsvg/dist/snap.svg.js" ); import {Dijkstra, GridGraph} from "./grid"; import $ from 'jquery'; function paintTree() { const GRID_UNIT = 30 const N_SOURCES = 10 const OPACITY = 0.45 const TRUNK_COL = '#444' //'#7fc0c2' const RAY_COL = '#fff' //'#fff' const ROOT_COL = '#444' //'#222' function getSetting(camelId, defaultVal) { let settingInput = $(`#kn${camelId}`) let value = defaultVal if (settingInput.length == 1) { value = settingInput.val() } console.log(`Graph setting ${camelId}: ${value}`) return value } const GRID_UNIT = getSetting('GridUnit', 30) const N_SOURCES = getSetting('NSources', 10) const COST_NODE_W = getSetting('CostNodeW', 5.) const COST_RND_FRAC = getSetting('CostRndFrac', 0.6) const FEAS_CENTER = [getSetting('FeasCenterX', 0.5), getSetting('FeasCenterY', 0.3)] const FEAS_RAD = getSetting('FeasRad', 0.2) const FEAS_FALLOFF = getSetting('FeasFalloff', 0.3) const FEAS_FALLOFF_EXP = getSetting('FeasFalloffExp', 0.8) const FEAS_RND_FRAC = getSetting('FeasRndFrac', 0.3) const LBL_PC_PER_FRAME = getSetting('LblPcPerFrame', 1. / 250.) const OPACITY = getSetting('Opacity', 0.45) const OPACITY_TEMP_LBL = getSetting('OpacityTempLbl', 0.23) const OPACITY_SHORTEST_PATH = getSetting('OpacityShortestPath', 0.36) const STROKEW_SHORTEST_PATH = getSetting('StrokeWShortestPath', 5) const ROOT_RAD = getSetting('RootRad', 6) const TRUNK_COL = getSetting('TrunkCol', '#444') const RAY_COL = getSetting('RayCol', '#fff') const ROOT_COL = getSetting('RootCol', '#444') const graph = $('#graph') const W = graph.width() Loading @@ -30,7 +52,7 @@ function paintTree() { console.log(`Grid graph: ${N_X}×${N_Y}`) const LBLS_PER_FRAME = N_X * N_Y / 250 const LBLS_PER_FRAME = N_X * N_Y * LBL_PC_PER_FRAME const embed = pos => [(W - N_X * GRID_UNIT) / 2 + pos[0] * GRID_UNIT, (H - N_Y * GRID_UNIT) / 2 + pos[1] * GRID_UNIT] Loading @@ -46,18 +68,13 @@ function paintTree() { let pos = grid.getNodeXY(node) pos[0] /= N_X pos[1] /= N_Y const center = [0.5, 0.3] const radius = 0.2 const falloff = 0.3 const exp = 0.8 const rand_fraction = 0.3 // Actual math: const dx = center[0] - pos[0] const dy = center[1] - pos[1] const dx = FEAS_CENTER[0] - pos[0] const dy = FEAS_CENTER[1] - pos[1] const l2 = Math.sqrt(dx * dx + dy * dy) const unit_l2 = Math.max(Math.min((l2 - radius) / falloff, 1.), 0.) const l2_pow_law = Math.pow(unit_l2, exp) const rand_lerp = l2_pow_law * (1. - rand_fraction) + rand_fraction * Math.random() const unit_l2 = Math.max(Math.min((l2 - FEAS_RAD) / FEAS_FALLOFF, 1.), 0.) const l2_pow_law = Math.pow(unit_l2, FEAS_FALLOFF_EXP) const rand_lerp = l2_pow_law * (1. - FEAS_RND_FRAC) + FEAS_RND_FRAC * Math.random() return rand_lerp } Loading Loading @@ -85,17 +102,15 @@ function paintTree() { const dir = grid.getEdgeDirection(edge) // base l2 cost const l2 = dir_l2_len[dir2idx(dir)] const node_weight = 5. const rand_fraction = 0.6 // Add a random component const artificial_cost = (1. + (Math.random() - 1.) * rand_fraction) * node_weight * (1. - node_feasibility(node)) const artificial_cost = (1. + (Math.random() - 1.) * COST_RND_FRAC) * COST_NODE_W * (1. - node_feasibility(node)) return l2 + artificial_cost } let algo = new Dijkstra(grid, edge_cost, { found_candidate: function (node, edge, other_node) { ensure_edge(edge) edges[edge].attr('opacity', 0.5 * OPACITY) edges[edge].attr('opacity', OPACITY_TEMP_LBL) }, remove_candidate: function (node, edge, other_node) { edges[edge].attr('opacity', 0.) Loading @@ -105,16 +120,16 @@ function paintTree() { if (algo.labels[other_node].backlink != null) { edges[algo.labels[other_node].backlink].attr('opacity', 0.) } edges[edge].attr('opacity', 0.5 * OPACITY) edges[edge].attr('opacity', OPACITY_TEMP_LBL) }, add_source: function(node, owner) { if (owner < N_SOURCES) { node_group.circle(...embed(grid.getNodeXY(node)), 6) node_group.circle(...embed(grid.getNodeXY(node)), ROOT_RAD) .attr('stroke', TRUNK_COL) .attr('strokeOpacity', 0.8 * OPACITY) .attr('strokeWidth', 5) .attr('strokeOpacity', OPACITY_SHORTEST_PATH) .attr('strokeWidth', STROKEW_SHORTEST_PATH) .attr('fill', ROOT_COL) .attr('fillOpacity', 0.8 * OPACITY) .attr('fillOpacity', OPACITY_SHORTEST_PATH) } } }) Loading @@ -141,8 +156,8 @@ function paintTree() { edges[edge] .attr('opacity', 1.) .attr('stroke', TRUNK_COL) .attr('strokeOpacity', 0.8 * OPACITY) .attr('strokeWidth', 5) .attr('strokeOpacity', OPACITY_SHORTEST_PATH) .attr('strokeWidth', STROKEW_SHORTEST_PATH) }) if (algo.isRouted()) { clearInterval(anim) Loading @@ -153,7 +168,21 @@ function paintTree() { } document.addEventListener('DOMContentLoaded', () => { $('[data-kn-fn="redraw"]').click(paintTree) paintTree() new Konami(function () { $('#knWrapper') .prependTo('body') .addClass('fixed-fill') .addClass('z-konami') .addClass('inner-shadow') .addClass('bg-dark') $('#graph') .removeClass('position-fixed') .addClass('fixed-fill') $('.d-konami').removeClass('d-konami') }); }); let resizeTimer = null Loading @@ -177,3 +206,5 @@ window.addEventListener('resize', () => { } }, 250) }); Loading
templates/bg_graph.html 0 → 100644 +10 −0 Original line number Diff line number Diff line <div id="knWrapper"> <h4 class="d-konami m-2">Multidirectional Dijkstra background by Spak</h4> <button type="button" class="btn btn-light m-2 d-konami" data-toggle="modal" data-target="#knCustomizeModal"> Customize </button> <button type="button" class="btn btn-light m-2 d-konami" data-kn-fn="redraw"> Redraw </button> <svg class="w-100 h-100 position-fixed z-lowest" id="graph"></svg> </div> No newline at end of file
templates/home.html +2 −1 Original line number Diff line number Diff line Loading @@ -6,11 +6,12 @@ {% block title %}{{ this.title }}{% endblock %} {% block body %} <body> {% include 'konami.html' %} <div class="container-fluid h-md-100 px-0"> <div class="row h-md-100 mx-0"> <div class="col-md-6 col-lg-5 order-md-2 inner-shadow px-0 h-100"> <div class="scrollable-md"> <svg class="w-100 h-100 position-fixed z-lowest" id="graph"></svg> {% include 'bg_graph.html' %} <header class="my-3 mx-3"> <h1><img src="{{ '/images/logo.svg' | url}}" alt="Mittelab" class="logo d-block mx-auto"></h1> <p class="text-monospace text-center lead"> Loading
templates/konami.html 0 → 100644 +137 −0 Original line number Diff line number Diff line <div class="modal fade" id="knCustomizeModal" tabindex="-1" role="dialog" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content bg-dark border-secondary outer-shadow"> <div class="modal-header border-secondary"> <h5 class="modal-title">Customize multi-directional Dijkstra</h5> <button type="button" class="close text-white" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <form> <div class="form-group form-row mb-1"> <label for="knNSources" class="col text-right col-form-label col-form-label-sm">Num. of terminals</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knNSources" value="10" min="2"> </div> </div> <div class="form-group form-row mb-1"> <label for="knGridUnit" class="col text-right col-form-label col-form-label-sm">Grid unit</label> <div class="input-group input-group-sm col-5"> <input id="knGridUnit" type="number" class="form-control-sm form-control" aria-describedby="knPx" min="5" value="30"> <div class="input-group-append"> <span class="input-group-text" id="knPx">px</span> </div> </div> </div> <div class="form-group form-row mb-1"> <label for="knCostNodeW" class="col text-right col-form-label col-form-label-sm">Edge cost node weight</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knCostNodeW" value="5" min="0" step="0.1"> </div> </div> <div class="form-group form-row mb-1"> <label for="knCostRndFrac" class="col text-right col-form-label col-form-label-sm">Edge cost random fraction</label> <div class="col-5"> <input type="range" class="form-control-sm form-control-range" id="knCostRndFrac" value="0.6" min="0.0" max="1.0" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knFeasCenterX" class="col text-right col-form-label col-form-label-sm">Node clearance center X</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knFeasCenterX" value="0.5" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knFeasCenterY" class="col text-right col-form-label col-form-label-sm">Node clearance center Y</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knFeasCenterY" value="0.3" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knFeasRad" class="col text-right col-form-label col-form-label-sm">Node clearance radius</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knFeasRad" value="0.2" min="0" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knFeasFalloff" class="col text-right col-form-label col-form-label-sm">Node clearance falloff radius</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knFeasFalloff" value="0.3" min="0" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knFeasFalloffExp" class="col text-right col-form-label col-form-label-sm">Node clearance falloff exponent</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knFeasFalloffExp" value="0.8" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knFeasRndFrac" class="col text-right col-form-label col-form-label-sm">Node clearance random fraction</label> <div class="col-5"> <input type="range" class="form-control-sm form-control-range" id="knFeasRndFrac" value="0.3" min="0.0" max="1.0" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knLblPcPerFrame" class="col text-right col-form-label col-form-label-sm">Max grid fraction labeled per frame</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knLblPcPerFrame" min="0.0" max="1.0" value="0.004" step="0.0001"> </div> </div> <div class="form-group form-row mb-1"> <label for="knOpacity" class="col text-right col-form-label col-form-label-sm">Opacity</label> <div class="col-5"> <input type="range" class="form-control-sm form-control-range" id="knOpacity" value="0.45" min="0.0" max="1.0" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knOpacityTempLbl" class="col text-right col-form-label col-form-label-sm">Temporary label opacity</label> <div class="col-5"> <input type="range" class="form-control-sm form-control-range" id="knOpacityTempLbl" value="0.23" min="0.0" max="1.0" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knOpacityShortestPath" class="col text-right col-form-label col-form-label-sm">Shortest path opacity</label> <div class="col-5"> <input type="range" class="form-control-sm form-control-range" id="knOpacityShortestPath" value="0.36" min="0.0" max="1.0" step="0.01"> </div> </div> <div class="form-group form-row mb-1"> <label for="knStrokeWShortestPath" class="col text-right col-form-label col-form-label-sm">Shortest path stroke width</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knStrokeWShortestPath" min="0.0" value="5" step="0.1"> </div> </div> <div class="form-group form-row mb-1"> <label for="knTrunkCol" class="col text-right col-form-label col-form-label-sm">Steiner tree path color</label> <div class="col-5"> <input type="text" class="form-control-sm form-control" id="knTrunkCol" value="#444"> </div> </div> <div class="form-group form-row mb-1"> <label for="knRayCol" class="col text-right col-form-label col-form-label-sm">Secondary path color</label> <div class="col-5"> <input type="text" class="form-control-sm form-control" id="knRayCol" value="#fff"> </div> </div> <div class="form-group form-row mb-1"> <label for="knRootRad" class="col text-right col-form-label col-form-label-sm">Terminal radius</label> <div class="col-5"> <input type="number" class="form-control-sm form-control" id="knRootRad" min="0.0" value="6" step="0.1"> </div> </div> <div class="form-group form-row mb-1"> <label for="knRootCol" class="col text-right col-form-label col-form-label-sm">Terminal color</label> <div class="col-5"> <input type="text" class="form-control-sm form-control" id="knRootCol" value="#444"> </div> </div> </form> </div> <div class="modal-footer border-secondary"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> <button type="button" class="btn btn-light" data-kn-fn="redraw">Redraw</button> </div> </div> </div> </div> No newline at end of file
templates/page.html +2 −1 Original line number Diff line number Diff line Loading @@ -2,7 +2,8 @@ {% block title %}{{ this.title }}{% endblock %} {% block body %} <body class="inner-shadow"> <svg class="w-100 h-100 position-fixed z-lowest" id="graph"></svg> {% include 'bg_graph.html' %} {% include 'konami.html' %} <div class="container-fluid h-md-100"> <div class="row h-100"> <div class="col-md-5 col-lg-4 col-xl-3 col-xxl-2 px-0"> Loading
webpack/js/mlab.js +63 −32 Original line number Diff line number Diff line Loading @@ -6,21 +6,43 @@ require('typeface-ubuntu'); import Konami from 'konami'; new Konami(function () { alert('Konami Code!') }); const Snap = require( "imports-loader?this=>window,fix=>module.exports=0!snapsvg/dist/snap.svg.js" ); import {Dijkstra, GridGraph} from "./grid"; import $ from 'jquery'; function paintTree() { const GRID_UNIT = 30 const N_SOURCES = 10 const OPACITY = 0.45 const TRUNK_COL = '#444' //'#7fc0c2' const RAY_COL = '#fff' //'#fff' const ROOT_COL = '#444' //'#222' function getSetting(camelId, defaultVal) { let settingInput = $(`#kn${camelId}`) let value = defaultVal if (settingInput.length == 1) { value = settingInput.val() } console.log(`Graph setting ${camelId}: ${value}`) return value } const GRID_UNIT = getSetting('GridUnit', 30) const N_SOURCES = getSetting('NSources', 10) const COST_NODE_W = getSetting('CostNodeW', 5.) const COST_RND_FRAC = getSetting('CostRndFrac', 0.6) const FEAS_CENTER = [getSetting('FeasCenterX', 0.5), getSetting('FeasCenterY', 0.3)] const FEAS_RAD = getSetting('FeasRad', 0.2) const FEAS_FALLOFF = getSetting('FeasFalloff', 0.3) const FEAS_FALLOFF_EXP = getSetting('FeasFalloffExp', 0.8) const FEAS_RND_FRAC = getSetting('FeasRndFrac', 0.3) const LBL_PC_PER_FRAME = getSetting('LblPcPerFrame', 1. / 250.) const OPACITY = getSetting('Opacity', 0.45) const OPACITY_TEMP_LBL = getSetting('OpacityTempLbl', 0.23) const OPACITY_SHORTEST_PATH = getSetting('OpacityShortestPath', 0.36) const STROKEW_SHORTEST_PATH = getSetting('StrokeWShortestPath', 5) const ROOT_RAD = getSetting('RootRad', 6) const TRUNK_COL = getSetting('TrunkCol', '#444') const RAY_COL = getSetting('RayCol', '#fff') const ROOT_COL = getSetting('RootCol', '#444') const graph = $('#graph') const W = graph.width() Loading @@ -30,7 +52,7 @@ function paintTree() { console.log(`Grid graph: ${N_X}×${N_Y}`) const LBLS_PER_FRAME = N_X * N_Y / 250 const LBLS_PER_FRAME = N_X * N_Y * LBL_PC_PER_FRAME const embed = pos => [(W - N_X * GRID_UNIT) / 2 + pos[0] * GRID_UNIT, (H - N_Y * GRID_UNIT) / 2 + pos[1] * GRID_UNIT] Loading @@ -46,18 +68,13 @@ function paintTree() { let pos = grid.getNodeXY(node) pos[0] /= N_X pos[1] /= N_Y const center = [0.5, 0.3] const radius = 0.2 const falloff = 0.3 const exp = 0.8 const rand_fraction = 0.3 // Actual math: const dx = center[0] - pos[0] const dy = center[1] - pos[1] const dx = FEAS_CENTER[0] - pos[0] const dy = FEAS_CENTER[1] - pos[1] const l2 = Math.sqrt(dx * dx + dy * dy) const unit_l2 = Math.max(Math.min((l2 - radius) / falloff, 1.), 0.) const l2_pow_law = Math.pow(unit_l2, exp) const rand_lerp = l2_pow_law * (1. - rand_fraction) + rand_fraction * Math.random() const unit_l2 = Math.max(Math.min((l2 - FEAS_RAD) / FEAS_FALLOFF, 1.), 0.) const l2_pow_law = Math.pow(unit_l2, FEAS_FALLOFF_EXP) const rand_lerp = l2_pow_law * (1. - FEAS_RND_FRAC) + FEAS_RND_FRAC * Math.random() return rand_lerp } Loading Loading @@ -85,17 +102,15 @@ function paintTree() { const dir = grid.getEdgeDirection(edge) // base l2 cost const l2 = dir_l2_len[dir2idx(dir)] const node_weight = 5. const rand_fraction = 0.6 // Add a random component const artificial_cost = (1. + (Math.random() - 1.) * rand_fraction) * node_weight * (1. - node_feasibility(node)) const artificial_cost = (1. + (Math.random() - 1.) * COST_RND_FRAC) * COST_NODE_W * (1. - node_feasibility(node)) return l2 + artificial_cost } let algo = new Dijkstra(grid, edge_cost, { found_candidate: function (node, edge, other_node) { ensure_edge(edge) edges[edge].attr('opacity', 0.5 * OPACITY) edges[edge].attr('opacity', OPACITY_TEMP_LBL) }, remove_candidate: function (node, edge, other_node) { edges[edge].attr('opacity', 0.) Loading @@ -105,16 +120,16 @@ function paintTree() { if (algo.labels[other_node].backlink != null) { edges[algo.labels[other_node].backlink].attr('opacity', 0.) } edges[edge].attr('opacity', 0.5 * OPACITY) edges[edge].attr('opacity', OPACITY_TEMP_LBL) }, add_source: function(node, owner) { if (owner < N_SOURCES) { node_group.circle(...embed(grid.getNodeXY(node)), 6) node_group.circle(...embed(grid.getNodeXY(node)), ROOT_RAD) .attr('stroke', TRUNK_COL) .attr('strokeOpacity', 0.8 * OPACITY) .attr('strokeWidth', 5) .attr('strokeOpacity', OPACITY_SHORTEST_PATH) .attr('strokeWidth', STROKEW_SHORTEST_PATH) .attr('fill', ROOT_COL) .attr('fillOpacity', 0.8 * OPACITY) .attr('fillOpacity', OPACITY_SHORTEST_PATH) } } }) Loading @@ -141,8 +156,8 @@ function paintTree() { edges[edge] .attr('opacity', 1.) .attr('stroke', TRUNK_COL) .attr('strokeOpacity', 0.8 * OPACITY) .attr('strokeWidth', 5) .attr('strokeOpacity', OPACITY_SHORTEST_PATH) .attr('strokeWidth', STROKEW_SHORTEST_PATH) }) if (algo.isRouted()) { clearInterval(anim) Loading @@ -153,7 +168,21 @@ function paintTree() { } document.addEventListener('DOMContentLoaded', () => { $('[data-kn-fn="redraw"]').click(paintTree) paintTree() new Konami(function () { $('#knWrapper') .prependTo('body') .addClass('fixed-fill') .addClass('z-konami') .addClass('inner-shadow') .addClass('bg-dark') $('#graph') .removeClass('position-fixed') .addClass('fixed-fill') $('.d-konami').removeClass('d-konami') }); }); let resizeTimer = null Loading @@ -177,3 +206,5 @@ window.addEventListener('resize', () => { } }, 250) });