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

106
LINES

< > BotCompany Repo | #1034965 // G22RegionThinner - thin a region [abandoned, replaced by G22RegionThinner_v2]

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

Transpiled version (8993L) is out of date.

srecord noeq G22RegionThinner(IImageRegion<?> originalRegion) is Steppable {
  Rect bounds;
  
  // true = part of region
  // index is in bounds coordinates
  bool[] pixels;
  
  gettable IImageRegion region = new {
    public Rect bounds() { ret bounds; }
  
    public bool contains(int x, int y) {
      ret containsPt(bounds, x, y) && pixels[idx(x, y)];
    }
    
    public ItIt<Pt> pixelIterator() {
      ret iff_null(new IF0<Pt> {
        int idx = 0;
        
        public Pt get() {
          for (; idx < pixels.length; idx++)
            if (pixels[idx])
              ret idxToPt(idx++);
          null;
        }
      });
    }
  };
  
  int idx(int x, int y) {
    ret (y-bounds.y)*bounds.w+x-bounds.x;
  }
  
  Pt idxToPt(int idx) {
    ret pt(bounds.x+(idx % bounds.w), bounds.y+idx/bounds.w);
  }
  
  void init {
    if (bounds != null) ret;
    bounds = originalRegion.bounds();
    pixels = new bool[area(bounds)];
    for (Pt p : originalRegion.pixelIterator())
      pixels[idx(p.x, p.y)] = true;
  }
  
  bool change;
  
  public bool step() {
    init();
    
    change = false;

    L<PtBuffer> traces = g22_allBorderTraces_withDiagonals(region);
    
    for (points : traces) {
      if (eq(first(points), last(points))) removeLast(points);
      
      for i over points: {
        ping();
        if (deletableBorderPoint(points, i)) {
          Pt p = points.get(i);
          pixels[idx(p.x, p.y)] = false;
          set change;
        }
      }
      points.clear();
    }

    ret change;
  }
  
  bool deletableBorderPoint(PtBuffer points, int i) {
    L<Pt> range = cyclicSubList(points, i-1, i+2);
    Pt lastPoint = cyclicGet(points, i-1);
    Pt p = points.get(i);
    Pt diff = ptDiff(p, lastPoint);
    Pt l = ptPlus(p, rotatePtLeft(diff));
    Pt r = ptPlus(p, rotatePtRight(diff));
    bool deletable = !range.contains(l) && region.contains(l)
      || !range.contains(r) && region.contains(r);
    printVars ifdef G22RegionThinner_debug(+range, +p, +l, +r, +deletable);
    ret deletable;
  }
  
  bool deletableBorderPoint_v1(PtBuffer points, int i) {
    L<Pt> range = cyclicSubList(points, i-1, i+2);
    Pt p = points.get(i);
        
    // check all 8 points around border point
    for (int dir = 1; dir <= 8; dir++) {
      Pt p2 = ptPlus(p, onePathDirection(dir));
      
      // If neighboring point is in region but not in current border,
      // it makes the border point deletable
      
      if (region.contains(p2.x, p2.y)
        && !range.contains(p2)) {
          printVars ifdef G22RegionThinner_debug("deletable point", +p, +dir, +p2, +range);
          ret true;
        }
    }

    false;
  }
  
  IImageRegion get() { ret region; }
}

download  show line numbers  debug dex  old transpilations   

Travelled to 4 computer(s): bhatertpkbcr, ekrmjmnbrukm, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1034965
Snippet name: G22RegionThinner - thin a region [abandoned, replaced by G22RegionThinner_v2]
Eternal ID of this version: #1034965/22
Text MD5: 6c348b0fa62b2d5cf3e1a7e59656be20
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-03-21 22:54:50
Source code size: 2816 bytes / 106 lines
Pitched / IR pitched: No / No
Views / Downloads: 159 / 290
Version history: 21 change(s)
Referenced in: #1003674 - Standard Classes + Interfaces (LIVE continued in #1034167)
#1034983 - G22RegionThinner_v2 - thin a region to 1 pixel wide [OK]