1 | // both the outer outline and the outline of a hole are called a "trace" |
2 | // should return outer outline first and then outline of holes |
3 | |
4 | srecord noeq RegionBorder_innerPoints(BWImage_FastRegions regions, int iRegion) extends AbstractSteppable { |
5 | event newTrace(bool isHole); |
6 | event foundPoint(Pt p); |
7 | event traceDone; |
8 | |
9 | int w, x, y, dir; |
10 | BWImage_FastRegions.RegionIterator it; |
11 | BitSet seen; |
12 | bool tracing; |
13 | gettable bool tracingHole; |
14 | |
15 | // directions (0 = right, 1 = down, 2 = left, 3 = up) |
16 | static Pt[] directions = { |
17 | pt(1, 0), pt(0, 1), pt(-1, 0), pt(0, -1) // r, d, l, u |
18 | }; |
19 | |
20 | void init { |
21 | w = regions.w; |
22 | seen = new BitSet; |
23 | it = regions.regionIterator(iRegion); |
24 | } |
25 | |
26 | public bool step() { |
27 | if (seen == null) init(); |
28 | |
29 | if (tracing) { |
30 | int pos = y*w+x; |
31 | if (seen.get(pos)) { |
32 | traceDone(); |
33 | tracing = false; |
34 | true; |
35 | } |
36 | seen.set(pos); |
37 | foundPoint(x, y); |
38 | |
39 | for (int turn = 3; turn <= 6; turn++) { // try left, straight, right, back |
40 | int newDir = (dir+turn) & 3; |
41 | Pt d = directions[newDir]; |
42 | int x2 = x+d.x, y2 = y+d.y; |
43 | bool b = regions.inRegion(iRegion, x2, y2); |
44 | ifdef RegionBorder_innerPoints_debug |
45 | printVars(+x, +y, +dir, +turn, +newDir, +x2, +y2, +b); |
46 | endifdef |
47 | if (b) { |
48 | x = x2; y = y2; dir = newDir; |
49 | true; |
50 | } |
51 | } |
52 | |
53 | true; // i think this ends the trace in next iteration |
54 | } else { |
55 | // search for border pixel |
56 | |
57 | if (!it.next()) false; // done |
58 | x = it.x(); y = it.y(); |
59 | |
60 | if (seen.get(y*w+x)) true; // seen pixel before |
61 | |
62 | // if pixel above is empty, walk to the right |
63 | if (!regions.inRegion(iRegion, x, y-1)) |
64 | ret true with startTrace(0); |
65 | |
66 | // if pixel on the left is empty, walk upwards |
67 | if (!regions.inRegion(iRegion, x-1, y)) |
68 | ret true with startTrace(3); |
69 | |
70 | // if pixel on the right is empty, walk downwards |
71 | if (!regions.inRegion(iRegion, x+1, y)) |
72 | ret true with startTrace(1); |
73 | |
74 | // if pixel below is empty, walk left |
75 | if (!regions.inRegion(iRegion, x, y+1)) |
76 | ret true with startTrace(2); |
77 | |
78 | // not a border pixel, continue search |
79 | true; |
80 | } |
81 | } |
82 | |
83 | void startTrace(int dir) { |
84 | this.dir = dir; |
85 | set tracing; |
86 | newTrace(tracingHole); |
87 | set tracingHole; |
88 | } |
89 | |
90 | void foundPoint(int x, int y) { foundPoint(pt(x, y)); } |
91 | |
92 | void runAndPrint { |
93 | onNewTrace(hole -> print(!hole ? "new outline" : "new hole")); |
94 | onTraceDone(-> print("traceDone")); |
95 | onFoundPoint(p -> print("foundPoint " + p)); |
96 | stepMaxWithStats(this, 10000); |
97 | } |
98 | } |
Began life as a copy of #1033941
download show line numbers debug dex old transpilations
Travelled to 3 computer(s): bhatertpkbcr, mowyntqkapby, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1034080 |
Snippet name: | RegionBorder_innerPoints - find region outline [backup] |
Eternal ID of this version: | #1034080/1 |
Text MD5: | 894207f3856e1008011c210e706ad3f1 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-01-21 04:34:27 |
Source code size: | 2798 bytes / 98 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 116 / 136 |
Referenced in: | [show references] |