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 | } |
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: | 261 / 505 |
Version history: | 49 change(s) |
Referenced in: | [show references] |