Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

152
LINES

< > BotCompany Repo | #1033638 // QuadTreeBitMatrix

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (5832L/33K).

sclass QuadTreeBitMatrix > WidthAndHeightImpl is BitMatrix {
  sclass Node {
    int compositeNodeCount() { ret 0; }
  }
  sclass Prim > Node {}
  sclass On  > Prim {} static new On  on;
  sclass Off > Prim {} static new Off off;
  
  sclass Composite > Node {
    Node a, b, c, d;
    
    void set(int idx, Node n) {
      if (idx == 0) a = n;
      if (idx == 1) b = n;
      if (idx == 2) c = n;
      if (idx == 3) d = n;
    }
    
    *(Node n) {
      a = b = c = d = n;
    }
    
    bool simplifiable() {
      ret allEq(a, b, c, d);
    }
    
    int compositeNodeCount() { ret 1+
      a.compositeNodeCount() +
      b.compositeNodeCount() +
      c.compositeNodeCount() +
      d.compositeNodeCount();
    }
  }
  
  Node root = off;
  
  *() {}
  *(int *width, int *height) {}
  
  int half(int x) { ret roundUpToPowerOfTwo((x+1)/2); }
  int halfX(Rect r) { ret r.x+half(r.w); }
  int halfY(Rect r) { ret r.y+half(r.h); }
  
  Rect rectA(Rect r) { ret rect(r.x, r.y, half(r.w), half(r.h)); }
  Rect rectB(Rect r) { ret rectFromPoints(r.x+half(r.w), r.y, r.x2(), halfY(r)); }
  Rect rectC(Rect r) { ret rectFromPoints(r.x, r.y+half(r.h), r.x+half(r.w), r.y2()); }
  Rect rectD(Rect r) { ret rectFromPoints(r.x+half(r.w), r.y+half(r.h), r.x2(), r.y2()); }
  
  // have to return Bool (not bool) to satisfy BitMatrix interface
  public Bool get(int x, int y) {
    Node node = root;
    Rect r = rect(0, 0, width, height);
    while (node cast Composite) {
      int hx = halfX(r), hy = halfY(r);
      if (y < hy)
        if (x < hx) {
          node = node.a; r = rectA(r);
        } else {
          node = node.b; r = rectB(r);
        }
      else
        if (x < hx) {
          node = node.c; r = rectC(r);
        } else {
          node = node.d; r = rectD(r);
        }
      ifdef QuadTreeBitMatrix_debug
        printVars(+x, +y, +hx, +hy);
      endifdef
    }
    ret node == on;
  }
  
  public void set(int x, int y, Bool b default true) {
    set(pointRect(x, y), b);
  }
  
  void set(Rect r, bool b) {
    set(rootCursor(), r, b);
  }
  
  scaffolded void set(Cursor cursor, Rect r, bool b) {
    // no intersection? exit
    if (!rectsIntersect(r, cursor.r)) ret;
      
    // fully contained? replace with primitive
    if (rectContains(r, cursor.r))
      cursor.replace(b ? on : off);
    else {
      // partial intersection - turn into composite  
      cursor.turnIntoComposite();
      
      for (Cursor c : cursor.subCursors())
        set(c, r, b);
    }
    
    cursor.simplify();
  }
  
  class Cursor {
    settable Composite parent;
    settable int indexInParent;
    
    settable Rect r;
    settable Node node;
    
    L<Cursor> subCursors() {
      if (node cast Composite)
        ret ll(
          subCursor(0, node.a, rectA(r)),
          subCursor(1, node.b, rectB(r)),
          subCursor(2, node.c, rectC(r)),
          subCursor(3, node.d, rectD(r)));
      ret emptyList();
    }
    
    Cursor subCursor(int idx, Node n, Rect r) {
      ret new Cursor().r(r).node(n)
        .parent((Composite) node).indexInParent(idx);
    }
    
    scaffolded void turnIntoComposite {
      if (!node instanceof Composite)
        replace(new Composite(node));
    }
    
    scaffolded void replace(Node n) {
      if (node == n) ret;
      node = n;
      if (parent == null)
        root = n;
      else
        parent.set(indexInParent, n);
    }
    
    // opposite of turnIntoComposite
    scaffolded void simplify {
      if (node cast Composite && node.simplifiable())
        replace(node.a);
    }
    
    /*toString {
      ret stdToString(this);
    }*/
  }
  
  Cursor rootCursor() {
    ret new Cursor().r(bounds()).node(root);
  }
  
  int compositeNodeCount() { ret root.compositeNodeCount(); }
}

Author comment

Began life as a copy of #1026939

download  show line numbers  debug dex  old transpilations   

Travelled to 3 computer(s): bhatertpkbcr, ekrmjmnbrukm, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1033638
Snippet name: QuadTreeBitMatrix
Eternal ID of this version: #1033638/37
Text MD5: cef3379ab5e3e8859c62628b37e7e6bb
Transpilation MD5: 1c41c2b2dcd97b2c92133c2f7ef5408b
Author: stefan
Category: javax /
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-12-26 23:03:35
Source code size: 3917 bytes / 152 lines
Pitched / IR pitched: No / No
Views / Downloads: 203 / 437
Version history: 36 change(s)
Referenced in: [show references]