Skip to content
Snippets Groups Projects
Select Git revision
  • 7ec5d66f5a84249a5284f2d833a54961a0a97467
  • master default protected
2 results

macro_dice.md

  • frect.js 3.31 KiB
    import constant from "./fconstant.js";
    import jiggle from "./fjiggle.js";
    
    const quadtree = d3.quadtree
    
    function x(d) {
      return d.x + d.vx;
    }
    
    function y(d) {
      return d.y + d.vy;
    }
    
    export default function(radius) {
      var nodes,
          radii,
          strength = 1,
          iterations = 1
    
      if (typeof radius !== "function") radius = constant(radius == null ? 1 : +radius)
    
      function force() {
        var i, n = nodes.length,
            tree,
            node,
            xi,
            yi,
            ri,
            ri2;
    
        for (var k = 0; k < iterations; ++k) {
          // we pass to the qt, x and y as they will be computed in the
          // next step (see fn's above)
          tree = quadtree(nodes, x, y)
          for (i = 0; i < n; ++i) {
            node = nodes[i]
            // node left, right (a note: .bb.x- should be 0-based)
            var nxl = node.x + node.bb.x1
            var nxr = node.x + node.bb.x2
            var nyt = node.y + node.bb.y1
            var nyb = node.y + node.bb.y2
            // node center-by-bounding-box
            var cnx = (nxr - nxl) / 2 + nxl
            var cny = (nyb - nyt) / 2 + nyt
            // for each node, visit each...
            //console.log(`visit ${node.index}`)
            tree.visit(apply)
          }
        }
    
        function apply(quad, x0, y0, x1, y1) {
          let updated = false
          var data = quad.data, r
          if (data) {
            var rj = data.r
            r = ri + rj
            // prevents from op'ing twice
            if (data.index > node.index) {
              // quad.data is the node,
              // by domain intersections...
              //                              | -------- x ------ |
              //          | ------------ x ------ |
              // | ---- x --- |
              // data left, right
              let dxl = data.x + data.bb.x1
              let dxr = data.x + data.bb.x2
              // dxr or dxl within nx,
              if(nxl < dxr && dxr < nxr || nxl < dxl && dxl < nxr){
                // now write these
                let dyt = data.y + data.bb.y1
                let dyb = data.y + data.bb.y2
                // and check,
                if(nyt < dyt && dyt < nyb || nyt < dyb && dyb < nyb){
                  updated = true
                  // ok then, compute centers to find a direction for force-exertion
                  // maybe should also do this in prepare also (and the node data, only once)
                  let cdx = (dxr - dxl) / 2 + dxl
                  let cdy = (dyb - dyt) / 2 + dyt
                  // x overlap term
                  let xo = 0
                  if(cnx < cdx){
                    xo = nxr - dxl
                  } else {
                    xo = nxl - dxr
                  }
                  // y overlap term
                  let yo = 0
                  if(cny < cdy){
                    yo = nyb - dyt
                  } else {
                    yo = nyt - dyb
                  }
                  // just assert one axis
                  if(Math.abs(xo) > Math.abs(yo)){
                    node.vy -= yo * strength
                    data.vy += yo * strength
                  } else {
                    node.vx -= xo * strength
                    data.vx += xo * strength
                  }
                }
              }
            }
            return
          } // end if-data
          return updated 
        } // end apply()
      }
    
      function initialize() {
        if (!nodes) return
      }
    
      force.initialize = function(_) {
        nodes = _
        initialize()
      }
    
      force.strength = function(_) {
        return arguments.length ? (strength = +_, force) : strength
      }
    
      return force
    }