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

164
LINES

< > BotCompany Repo | #1035627 // G22_RegionToSSIs_v2 - full conversion with cohesion and fewest SSIs (WORKS)

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

Transpiled version (12679L) is out of date.

1  
srecord noeq G22_RegionToSSIs_v2(IImageRegion region) extends Meta {
2  
  Color color;
3  
  L<SSI> ssis;
4  
  new L<GrowingSSI> growingSSIs;
5  
  settable bool withDiagonals;
6  
  settable bool checkCoherence = true;
7  
  settable bool checkStreaks = true;
8  
  
9  
  private int x1, y;
10  
  
11  
  class GrowingSSI {
12  
    settable int y1;
13  
    new ShortBuffer data;
14  
    
15  
    int y2() { ret y1+l(data)/2; }
16  
    
17  
    SSI finish() {
18  
      ret addAndReturn(ssis, new SSI(y1, y2()).data(data.toArray())
19  
        .color(color));
20  
    }
21  
    
22  
    bool isEmpty() { ret data.isEmpty(); }
23  
    int lastx1() { ret data.get(l(data)-2); }
24  
    int lastx2() { ret data.get(l(data)-1); }
25  
    IntRange lastRange() { ret isEmpty() ? null : intRange(lastx1(), lastx2()); }
26  
    
27  
    // can add this line without breaking coherence?
28  
    bool canAdd(IntRange r) {
29  
      ret isEmpty()
30  
        || intRangesOverlapNempty(r.start, r.end, lastx1()-diag(), lastx2()+diag());
31  
    }
32  
    
33  
    void add(IntRange r) {
34  
      if (checkCoherence() && !canAdd(r))
35  
        fail("Coherence fail", +lastx1(), +lastx2(), +r);
36  
      
37  
      data.add(toShort_enforce(r.start));
38  
      data.add(toShort_enforce(r.end));
39  
    }
40  
  }
41  
  
42  
  void finishSSI(int iSSI) {
43  
    growingSSIs.remove(iSSI).finish();
44  
  }
45  
  
46  
  private GrowingSSI startSSI(int iSSI default l(growingSSIs), IntRange range) {
47  
    if (scaffoldingEnabled()) printVars("startSSI", +iSSI, +range);
48  
    var ssi = new GrowingSSI().y1(y);
49  
    ssi.add(range);
50  
    ret addAndReturn(growingSSIs, iSSI, ssi);
51  
  }
52  
  
53  
  L<IntRange> lastStreaks() {
54  
    ret reallyLazyMap(growingSSIs, -> .lastRange());
55  
  }
56  
  
57  
  int diag() { ret withDiagonals ? 1 : 0; }
58  
  
59  
  L<SSI> get() {
60  
    if (region == null) null;
61  
    
62  
    color = region.color();
63  
    ssis = new L;
64  
    Rect r = region.bounds();
65  
    int x1 = this.x1 = r.x1(), y1 = r.y1(), y2 = r.y2(), h = y2-y1, w = r.w;
66  
    bool scaff = scaffoldingEnabled();
67  
    
68  
    for (y = y1; y < y2; y++) {
69  
      reMutable y;
70  
      L<IntRange> streaks = shiftIntRanges(x1, genericStreaks(w, x -> region.contains(x1+x, y)));
71  
      
72  
      var lastStreaks = lastStreaks();
73  
      if (checkStreaks())
74  
        assertProperStreaks(lastStreaks);
75  
      
76  
      // advance iSSI & iStreak simultaneously
77  
      int iStreak = 0, iSSI = 0;
78  
      int nStreaks = l(streaks);
79  
      
80  
      if (scaff) printVars(+y, +lastStreaks, +streaks);
81  
82  
      while ping (iStreak < nStreaks) {
83  
        var range = streaks.get(iStreak);
84  
        var ssi = _get(growingSSIs, iSSI);
85  
        if (scaff) printVars(+y, +iStreak, +iSSI, +range, ssi := ssi?.lastRange());
86  
        
87  
        // case 1:
88  
        //           ------
89  
        // -------
90  
        //
91  
        // case 2:
92  
        //
93  
        // -------
94  
        // (left of current SSI or to the right of everything)
95  
        if (ssi == null || range.end <= ssi.lastx1()-diag()) {
96  
          startSSI(iSSI++, range);
97  
          ++iStreak;
98  
          continue;
99  
        }
100  
        
101  
        // Now we know that we have another SSI.
102  
        
103  
        // case 3:
104  
        // -------
105  
        //          ------
106  
        // (Just end current SSI and do streak again.)
107  
        if (range.start >= ssi.lastx2()+diag()) {
108  
          finishSSI(iSSI);
109  
          continue;
110  
        }
111  
        
112  
        // Now we know the streak and the SSI overlap.
113  
        // Find out if we have a choice on the top or on the bottom.
114  
        
115  
        // Check choices for streak
116  
        int jStreak = iStreak+1;
117  
        while (jStreak < nStreaks && ssi.canAdd(streaks.get(jStreak)))
118  
          ++jStreak;
119  
120  
        // Check choices for SSI
121  
        int jSSI = iSSI+1;
122  
        while (jSSI < l(growingSSIs) && growingSSIs.get(jSSI).canAdd(range))
123  
          ++jSSI;
124  
          
125  
        int nSSI = jSSI-iSSI, nStreak = jStreak-iStreak;
126  
        if (scaff) printVars(+nSSI, +nStreak);
127  
        new Best<Int> best;
128  
          
129  
        if (nSSI > 1) {
130  
          if (nStreak > 1)
131  
            fail("ANOMALY", +nSSI, +nStreak,
132  
              ssis := subList(lastStreaks(), iSSI, jSSI),
133  
              streaks := subList(streaks, iStreak, jStreak));  
134  
              
135  
          // Choose longest SSI
136  
          for (int idx = iSSI; idx < jSSI; idx++)
137  
            best.put(idx, l(growingSSIs.get(idx).lastRange()));
138  
          jSSI = best!;
139  
          
140  
          while (jSSI-- > iSSI) finishSSI(iSSI);
141  
        } else if (nStreak > 1) {
142  
          // Choose longest streak
143  
          for (int idx = iStreak; idx < jStreak; idx++)
144  
            best.put(idx, l(streaks.get(idx)));
145  
          jStreak = best!;
146  
          
147  
          while (iStreak < jStreak)
148  
            startSSI(iSSI++, streaks.get(iStreak++));
149  
        }
150  
        
151  
        // add line to SSI
152  
        growingSSIs.get(iSSI++).add(streaks.get(iStreak++));
153  
      }
154  
      
155  
      // remaining SSIs are unpaired, close them
156  
      while (iSSI < l(growingSSIs)) finishSSI(iSSI);
157  
    }
158  
    
159  
    // finish all remaining SSIs
160  
    for (ssi : cloneAndClear(growingSSIs)) ssi.finish();
161  
    
162  
    ret ssis;
163  
  }
164  
}

Author comment

Began life as a copy of #1035608

download  show line numbers  debug dex  old transpilations   

Travelled to 2 computer(s): elmgxqgtpvxh, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1035627
Snippet name: G22_RegionToSSIs_v2 - full conversion with cohesion and fewest SSIs (WORKS)
Eternal ID of this version: #1035627/50
Text MD5: 7e2e563fa358d1a98f42cfc5e090c70a
Author: stefan
Category: javax / gazelle 22
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-07-25 10:50:34
Source code size: 5058 bytes / 164 lines
Pitched / IR pitched: No / No
Views / Downloads: 176 / 415
Version history: 49 change(s)
Referenced in: [show references]