extract-curves 0.1.1-mswin32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. data/Changelog +21 -0
  2. data/bin/ec_rect2polar +22 -0
  3. data/bin/ec_rect2polar.rb +22 -0
  4. data/bin/ec_rev_lines +5 -0
  5. data/bin/ec_rev_lines.rb +5 -0
  6. data/bin/ec_sph_area +30 -0
  7. data/bin/ec_sph_area.rb +30 -0
  8. data/bin/extract_curves +1670 -0
  9. data/bin/extract_curves.rb +1670 -0
  10. data/ruby_ext/pav/extconf.rb +22 -0
  11. data/ruby_ext/pav/pav.dll +0 -0
  12. data/ruby_libs/pav/attr_cache.rb +211 -0
  13. data/ruby_libs/pav/attr_cache.t1.rb +32 -0
  14. data/ruby_libs/pav/cache.rb +31 -0
  15. data/ruby_libs/pav/collection/std.rb +58 -0
  16. data/ruby_libs/pav/dbg_log.rb +458 -0
  17. data/ruby_libs/pav/floatsio.rb +53 -0
  18. data/ruby_libs/pav/generator_cache.rb +165 -0
  19. data/ruby_libs/pav/graph/node.rb +602 -0
  20. data/ruby_libs/pav/graph/node_grp.rb +865 -0
  21. data/ruby_libs/pav/gtk.rb +6 -0
  22. data/ruby_libs/pav/gtk/button.rb +118 -0
  23. data/ruby_libs/pav/gtk/dialog.rb +29 -0
  24. data/ruby_libs/pav/gtk/guiobj.rb +772 -0
  25. data/ruby_libs/pav/gtk/icons.rb +124 -0
  26. data/ruby_libs/pav/gtk/rulers.rb +264 -0
  27. data/ruby_libs/pav/gtk/toolbar.rb +189 -0
  28. data/ruby_libs/pav/guiobj.rb +2 -0
  29. data/ruby_libs/pav/guiobj/info_asm.rb +41 -0
  30. data/ruby_libs/pav/guiobj/method.rb +211 -0
  31. data/ruby_libs/pav/guiobj/obj.rb +134 -0
  32. data/ruby_libs/pav/guiobj/signals.rb +9 -0
  33. data/ruby_libs/pav/heap.rb +54 -0
  34. data/ruby_libs/pav/icons/alt_handle.xpm +3832 -0
  35. data/ruby_libs/pav/icons/alt_handle_hover.xpm +3368 -0
  36. data/ruby_libs/pav/icons/alt_handle_pressed.xpm +3828 -0
  37. data/ruby_libs/pav/icons/blob.gif +0 -0
  38. data/ruby_libs/pav/icons/contour.gif +0 -0
  39. data/ruby_libs/pav/icons/contour_carpet.gif +0 -0
  40. data/ruby_libs/pav/icons/curve.gif +0 -0
  41. data/ruby_libs/pav/icons/curve_carpet.gif +0 -0
  42. data/ruby_libs/pav/icons/expand_closed.xpm +1791 -0
  43. data/ruby_libs/pav/icons/expand_closed_hover.xpm +1775 -0
  44. data/ruby_libs/pav/icons/expand_open.xpm +1788 -0
  45. data/ruby_libs/pav/icons/expand_open_hover.xpm +1752 -0
  46. data/ruby_libs/pav/icons/extract_curves/extract_curves-icon-rgb.ppm +14 -0
  47. data/ruby_libs/pav/icons/extract_curves/extract_curves-logo-rgb.gif +0 -0
  48. data/ruby_libs/pav/icons/extract_curves/trace_mark.xpm +38 -0
  49. data/ruby_libs/pav/icons/handle.xpm +213 -0
  50. data/ruby_libs/pav/icons/loop.gif +0 -0
  51. data/ruby_libs/pav/icons/loop_carpet.gif +0 -0
  52. data/ruby_libs/pav/icons/next.xpm +29 -0
  53. data/ruby_libs/pav/icons/next_hover.xpm +315 -0
  54. data/ruby_libs/pav/icons/next_pressed.xpm +144 -0
  55. data/ruby_libs/pav/icons/prev.xpm +29 -0
  56. data/ruby_libs/pav/icons/prev_hover.xpm +315 -0
  57. data/ruby_libs/pav/icons/prev_pressed.xpm +144 -0
  58. data/ruby_libs/pav/icons/shaved-core.gif +0 -0
  59. data/ruby_libs/pav/icons/vnext.xpm +29 -0
  60. data/ruby_libs/pav/icons/vprev.xpm +29 -0
  61. data/ruby_libs/pav/numeric/ext.rb +21 -0
  62. data/ruby_libs/pav/patterns/hsep.gif +0 -0
  63. data/ruby_libs/pav/patterns/tnode.gif +0 -0
  64. data/ruby_libs/pav/patterns/tnode_w_link.gif +0 -0
  65. data/ruby_libs/pav/patterns/vlink.gif +0 -0
  66. data/ruby_libs/pav/patterns/vsep.gif +0 -0
  67. data/ruby_libs/pav/patterns/yg_hrope.xpm +492 -0
  68. data/ruby_libs/pav/patterns/yg_hrope_thick.xpm +1904 -0
  69. data/ruby_libs/pav/patterns/yg_hrope_thin.xpm +130 -0
  70. data/ruby_libs/pav/patterns/yg_tnode.xpm +180 -0
  71. data/ruby_libs/pav/patterns/yg_tnode_thick.xpm +615 -0
  72. data/ruby_libs/pav/patterns/yg_tnode_thin.xpm +55 -0
  73. data/ruby_libs/pav/patterns/yg_tnode_w_link.xpm +190 -0
  74. data/ruby_libs/pav/patterns/yg_tnode_w_link_thick.xpm +676 -0
  75. data/ruby_libs/pav/patterns/yg_tnode_w_link_thin.xpm +62 -0
  76. data/ruby_libs/pav/patterns/yg_vrope.xpm +563 -0
  77. data/ruby_libs/pav/patterns/yg_vrope_thick.xpm +2047 -0
  78. data/ruby_libs/pav/patterns/yg_vrope_thin.xpm +166 -0
  79. data/ruby_libs/pav/pav_find.rb +90 -0
  80. data/ruby_libs/pav/pix.rb +402 -0
  81. data/ruby_libs/pav/pix/aapix.rb +378 -0
  82. data/ruby_libs/pav/pix/blob.rb +678 -0
  83. data/ruby_libs/pav/pix/circle.rb +73 -0
  84. data/ruby_libs/pav/pix/contour.rb +676 -0
  85. data/ruby_libs/pav/pix/contour/calc_situations.rb +9 -0
  86. data/ruby_libs/pav/pix/contour/carp_calc.rb +212 -0
  87. data/ruby_libs/pav/pix/contour/situations.dmp +0 -0
  88. data/ruby_libs/pav/pix/contour/situations.rb +21 -0
  89. data/ruby_libs/pav/pix/curve.rb +1544 -0
  90. data/ruby_libs/pav/pix/img_obj.rb +865 -0
  91. data/ruby_libs/pav/pix/node.rb +159 -0
  92. data/ruby_libs/pav/pix/shaved_core.rb +697 -0
  93. data/ruby_libs/pav/pix/subpix.rb +212 -0
  94. data/ruby_libs/pav/rand_accessible.rb +16 -0
  95. data/ruby_libs/pav/rangeset.rb +63 -0
  96. data/ruby_libs/pav/search.rb +210 -0
  97. data/ruby_libs/pav/set.rb +130 -0
  98. data/ruby_libs/pav/string/bits.rb +523 -0
  99. data/ruby_libs/pav/string/ext.rb +58 -0
  100. data/ruby_libs/pav/string/observable.rb +155 -0
  101. data/ruby_libs/pav/string/text.rb +79 -0
  102. data/ruby_libs/pav/string/words.rb +42 -0
  103. data/ruby_libs/pav/sub_arr.rb +56 -0
  104. data/ruby_libs/pav/traced_obj.rb +79 -0
  105. data/web/index.html +280 -0
  106. data/web/media/icons/alt_handle.xpm +3832 -0
  107. data/web/media/icons/alt_handle_hover.xpm +3368 -0
  108. data/web/media/icons/alt_handle_pressed.xpm +3828 -0
  109. data/web/media/icons/blob.gif +0 -0
  110. data/web/media/icons/contour.gif +0 -0
  111. data/web/media/icons/contour_carpet.gif +0 -0
  112. data/web/media/icons/curve.gif +0 -0
  113. data/web/media/icons/curve_carpet.gif +0 -0
  114. data/web/media/icons/expand_closed.xpm +1791 -0
  115. data/web/media/icons/expand_closed_hover.xpm +1775 -0
  116. data/web/media/icons/expand_open.xpm +1788 -0
  117. data/web/media/icons/expand_open_hover.xpm +1752 -0
  118. data/web/media/icons/extract_curves/extract_curves-icon-rgb.ppm +14 -0
  119. data/web/media/icons/extract_curves/extract_curves-logo-rgb.gif +0 -0
  120. data/web/media/icons/extract_curves/trace_mark.xpm +38 -0
  121. data/web/media/icons/handle.xpm +213 -0
  122. data/web/media/icons/loop.gif +0 -0
  123. data/web/media/icons/loop_carpet.gif +0 -0
  124. data/web/media/icons/next.xpm +29 -0
  125. data/web/media/icons/next_hover.xpm +315 -0
  126. data/web/media/icons/next_pressed.xpm +144 -0
  127. data/web/media/icons/prev.xpm +29 -0
  128. data/web/media/icons/prev_hover.xpm +315 -0
  129. data/web/media/icons/prev_pressed.xpm +144 -0
  130. data/web/media/icons/shaved-core.gif +0 -0
  131. data/web/media/icons/vnext.xpm +29 -0
  132. data/web/media/icons/vprev.xpm +29 -0
  133. data/web/media/title.jpeg +0 -0
  134. data/web/stylesheets/default.css +20 -0
  135. metadata +192 -0
@@ -0,0 +1,212 @@
1
+ require 'pav/pix'
2
+
3
+ module PPix
4
+
5
+ class PixbufPix
6
+ def subpix8(sub_n)
7
+ @subpix8 = [] unless @subpix8
8
+ tmp = @subpix8[sub_n]
9
+ return tmp if tmp
10
+ @subpix8[sub_n] = Subpix8.new(self, sub_n)
11
+ end
12
+
13
+ def subpix4(sub_n)
14
+ @subpix4 = [] unless @subpix4
15
+ tmp = @subpix4[sub_n]
16
+ return tmp if tmp
17
+ @subpix4[sub_n] = Subpix4.new(self, sub_n)
18
+ end
19
+ end
20
+
21
+ class SubXy < Xy
22
+ attr_accessor :sub_n
23
+
24
+ def initialize(x, y, sub_n)
25
+ super(x, y)
26
+ @sub_n = sub_n
27
+ end
28
+
29
+ def yxn
30
+ self.yx + [@sub_n]
31
+ end
32
+
33
+ def to_s
34
+ "(#{self.x}, #{self.y}, sub=#{@sub_n})"
35
+ end
36
+
37
+ def inspect
38
+ idmem = self.object_id & ( (1 << (8*self.object_id.size)) - 1 )
39
+ "<#{self.class.name}:0x%x: " % idmem + self.to_s + ">"
40
+ end
41
+
42
+ def <=>(subxy)
43
+ self.yxn <=> subxy.yxn
44
+ end
45
+
46
+ def eql?(subxy)
47
+ subxy && self.y == subxy.y && self.x == subxy.x &&
48
+ self.sub_n == subxy.sub_n
49
+ end
50
+ end
51
+
52
+ class Subpix < SubXy
53
+ attr_reader :img_pix
54
+
55
+ def self.mk_sub_n_neighbs(adj_subpix_order)
56
+ subpix_cnt = 2*adj_subpix_order.length
57
+ ofs1 = adj_subpix_order.length - 2
58
+ ofs2 = adj_subpix_order.length + 2
59
+ (0...subpix_cnt).collect { |n|
60
+ res = [ SubXy.new(0, 0, (n-1) % subpix_cnt),
61
+ SubXy.new(0, 0, (n+1) % subpix_cnt)]
62
+ if (n & 1) == 0
63
+ a1 = adj_subpix_order[n/2 - 1]
64
+ a2 = adj_subpix_order[n/2]
65
+ res[1,0]=[SubXy.new(a1.x,a1.y,(n+ofs1) % subpix_cnt)]
66
+ res << SubXy.new(a2.x,a2.y,(n+ofs2) % subpix_cnt)
67
+ else
68
+ a1_2 = adj_subpix_order[n/2]
69
+ res[1,0] = [SubXy.new(a1_2.x, a1_2.y,
70
+ (n + adj_subpix_order.length) % subpix_cnt)]
71
+ end
72
+ res
73
+ } << (0...subpix_cnt).collect { |n| SubXy.new(0, 0, n) }
74
+ end
75
+
76
+ def self.path_to_s(path)
77
+ path.collect { |subpix| subpix.to_s }.join(" ")
78
+ end
79
+
80
+ def initialize(img_pix, sub_n)
81
+ @img_pix = img_pix
82
+ super(@img_pix.x, @img_pix.y, sub_n)
83
+ end
84
+
85
+ def adj
86
+ self.neighbs.find_all { |ngb|
87
+ ngb.img_pix.x >= 0 &&
88
+ ngb.img_pix.x < ngb.img_pix.pixbuf.picture_width &&
89
+ ngb.img_pix.y >= 0 &&
90
+ ngb.img_pix.y < ngb.img_pix.pixbuf.picture_height
91
+ }
92
+ end
93
+
94
+ cache_attr! :adj
95
+ end
96
+
97
+ class Subpix8 < Subpix
98
+ SUB_N_NEIGHBS = Subpix.mk_sub_n_neighbs(Xy::ADJ8_CCW_ORDER)
99
+ SUB_N_BORDER = SUB_N_NEIGHBS
100
+
101
+ def neighbs
102
+ SUB_N_NEIGHBS[@sub_n].collect { |ngb_spec|
103
+ @img_pix.pixbuf.get_pix(@img_pix.x + ngb_spec.dx,
104
+ @img_pix.y + ngb_spec.dy).
105
+ subpix8(ngb_spec.sub_n)
106
+ }
107
+ end
108
+
109
+ def neighbs_into(res=[])
110
+ res.clear
111
+ SUB_N_NEIGHBS[@sub_n].each { |ngb_spec|
112
+ res << @img_pix.pixbuf.get_pix(@img_pix.x + ngb_spec.dx,
113
+ @img_pix.y+ngb_spec.dy).subpix8(ngb_spec.sub_n)
114
+ }
115
+ res
116
+ end
117
+
118
+ alias_method :border, :neighbs
119
+ alias_method :border_into, :neighbs_into
120
+
121
+ def self.vertical?(sub_n)
122
+ [7, 15].include?(sub_n)
123
+ end
124
+
125
+ def self.horizontal?(sub_n)
126
+ [3, 11].include?(sub_n)
127
+ end
128
+
129
+ def vertical?
130
+ [7, 15].include?(@sub_n)
131
+ end
132
+
133
+ def horizontal?
134
+ [3, 11].include?(@sub_n)
135
+ end
136
+
137
+ def to_s
138
+ "(#{self.x}, #{self.y}, sub8=#{self.sub_n})"
139
+ end
140
+
141
+ cache_attr! :neighbs, :border
142
+ end
143
+
144
+ class Subpix4 < Subpix
145
+ SUB_N_NEIGHBS = Subpix.mk_sub_n_neighbs(PixbufPix::ADJ4_CCW_ORDER)
146
+ SUB_N_BORDER = (0...8).collect { |i|
147
+ res = SUB_N_NEIGHBS[i]
148
+ if i & 1 == 0
149
+ a = PixbufPix::ADJ8_CCW_ORDER[i]
150
+ res += [SubXy.new(a.x, a.y, (i+4) % 8)]
151
+ end
152
+ res
153
+ } << SUB_N_NEIGHBS.last
154
+
155
+ def neighbs
156
+ SUB_N_NEIGHBS[@sub_n].collect { |ngb_spec|
157
+ @img_pix.pixbuf.get_pix(@img_pix.x + ngb_spec.dx,
158
+ @img_pix.y + ngb_spec.dy).
159
+ subpix4(ngb_spec.sub_n)
160
+ }
161
+ end
162
+
163
+ def border
164
+ SUB_N_BORDER[@sub_n].collect { |ngb_spec|
165
+ @img_pix.pixbuf.get_pix(@img_pix.x + ngb_spec.dx,
166
+ @img_pix.y + ngb_spec.dy).
167
+ subpix4(ngb_spec.sub_n)
168
+ }
169
+ end
170
+
171
+ def neighbs_into(res=[])
172
+ res.clear
173
+ SUB_N_NEIGHBS[@sub_n].each { |ngb_spec|
174
+ res << @img_pix.pixbuf.get_pix(@img_pix.x + ngb_spec.dx,
175
+ @img_pix.y+ngb_spec.dy).subpix4(ngb_spec.sub_n)
176
+ }
177
+ res
178
+ end
179
+
180
+ def border_into(res=[])
181
+ res.clear
182
+ SUB_N_BORDER[@sub_n].each { |ngb_spec|
183
+ res << @img_pix.pixbuf.get_pix(@img_pix.x + ngb_spec.dx,
184
+ @img_pix.y+ngb_spec.dy).subpix4(ngb_spec.sub_n)
185
+ }
186
+ res
187
+ end
188
+
189
+ def self.vertical?(sub_n)
190
+ [3, 7].include?(sub_n)
191
+ end
192
+
193
+ def self.horizontal?(sub_n)
194
+ [1, 5].include?(sub_n)
195
+ end
196
+
197
+ def vertical?
198
+ [3, 7].include?(@sub_n)
199
+ end
200
+
201
+ def horizontal?
202
+ [1, 5].include?(@sub_n)
203
+ end
204
+
205
+ def to_s
206
+ "(#{self.x}, #{self.y}, sub4=#{self.sub_n})"
207
+ end
208
+
209
+ cache_attr! :neighbs, :border
210
+ end
211
+
212
+ end
@@ -0,0 +1,16 @@
1
+ module RandomlyReadable
2
+
3
+ def [](i, len=nil)
4
+ if len
5
+ is = i...i+len
6
+ else
7
+ if i.kind_of?(Integer)
8
+ return at(i)
9
+ else
10
+ is = i
11
+ end
12
+ end
13
+ is.collect { |i| at(i) }
14
+ end
15
+
16
+ end
@@ -0,0 +1,63 @@
1
+ require 'pav/search'
2
+
3
+ class RangeSet
4
+ attr_accessor :ranges
5
+
6
+ def initialize
7
+ @ranges = []
8
+ @cmp_proc = proc { |range, n| range[0] <=> n }
9
+ end
10
+
11
+ def extend_range_to(range_i, end_n)
12
+ j = range_i
13
+ j += 1 while j+1 < @ranges.length && @ranges[j+1][0] <= end_n
14
+ end_n = @ranges[j][1] if @ranges[j][1] > end_n
15
+ @ranges[range_i][1] = end_n
16
+ @ranges[range_i+1..j] = nil
17
+ end
18
+
19
+ def merge_range!(start_n, end_n)
20
+ if (i = PSearch.bsearch(@ranges, start_n, &@cmp_proc)) >= 0
21
+ self.extend_range_to(i, end_n)
22
+ else
23
+ i = -i-1
24
+ if i > 0 && @ranges[i-1][1] >= start_n
25
+ self.extend_range_to(i-1, end_n)
26
+ elsif i < @ranges.length && @ranges[i][0] <= end_n
27
+ @ranges[i][0] = start_n
28
+ self.extend_range_to(i, end_n)
29
+ else
30
+ @ranges[i, 0] = [[start_n, end_n]]
31
+ end
32
+ end
33
+ end
34
+
35
+ def include?(n)
36
+ return true if (i = PSearch.bsearch(@ranges, n, &@cmp_proc))>=0
37
+ i = -i-1
38
+ i > 0 && @ranges[i-1][1] >= n
39
+ end
40
+
41
+ alias_method :member?, :include?
42
+
43
+ def range_end(n)
44
+ if (i = PSearch.bsearch(@ranges, n, &@cmp_proc)) >= 0
45
+ @ranges[i][1]
46
+ else
47
+ i = -i-1
48
+ if i > 0 && @ranges[i-1][1] >= n
49
+ @ranges[i-1][1]
50
+ else
51
+ n
52
+ end
53
+ end
54
+ end
55
+
56
+ def inspect
57
+ idmem = self.object_id & ( (1 << (8*self.object_id.size)) - 1 )
58
+ "#<#{self.class.name}:0x%x: " % idmem + @ranges.collect { |r|
59
+ "#{r[0]}..#{r[1]}"}.join(", ") + ">"
60
+ end
61
+
62
+ alias_method :to_s, :inspect
63
+ end
@@ -0,0 +1,210 @@
1
+ require 'pav/heap'
2
+
3
+ module PSearch
4
+
5
+ def self.bsearch(arr, lm, start_i=0, end_i=nil) # &block = optional comparator
6
+ end_i = arr.length-1 if !end_i
7
+ if block_given?
8
+ while start_i < end_i
9
+ mid_i = (end_i + start_i) / 2
10
+ if (leg = yield(arr[mid_i], lm)) > 0
11
+ end_i = mid_i-1
12
+ elsif leg < 0
13
+ start_i = mid_i+1
14
+ else
15
+ return mid_i
16
+ end
17
+ end
18
+ if start_i == end_i
19
+ if (leg = yield(arr[start_i], lm)) == 0
20
+ return start_i
21
+ elsif leg > 0
22
+ return -start_i-1
23
+ else
24
+ return -start_i-2
25
+ end
26
+ end
27
+ else
28
+ while start_i < end_i
29
+ mid_i = (end_i + start_i) / 2
30
+ if (val = arr[mid_i]) > lm
31
+ end_i = mid_i-1
32
+ elsif val < lm
33
+ start_i = mid_i+1
34
+ else
35
+ return mid_i
36
+ end
37
+ end
38
+ if start_i == end_i
39
+ if arr[start_i] == lm
40
+ return start_i
41
+ elsif arr[start_i] > lm
42
+ return -start_i-1
43
+ else
44
+ return -start_i-2
45
+ end
46
+ end
47
+ end
48
+ -start_i-1
49
+ end
50
+
51
+ def self.path_cache_get_path(path_cache, start_pos, pos, get_pos_id_proc=nil)
52
+ #$PDbgLog.sig_call(self)
53
+ #$PDbgLog.print_msg "start_pos=#{start_pos}, pos=#{pos}: "
54
+ # $PDbgLog.print_msg "path_cache: #{path_cache.keys.sort.collect{|k|
55
+ # k.inspect+'=>[' + path_cache[k].join(', ') + ']'}.join('; ')}: "
56
+ res = []
57
+ if get_pos_id_proc
58
+ pos, to_link = *path_cache[get_pos_id_proc.call(pos)]
59
+ return res unless to_link
60
+ start_pos_id = get_pos_id_proc.call(start_pos)
61
+ while to_link
62
+ res << to_link
63
+ break if get_pos_id_proc.call(pos) == start_pos_id
64
+ pos, to_link = *path_cache[get_pos_id_proc.call(pos)]
65
+ end
66
+ else
67
+ pos, to_link = *path_cache[pos]
68
+ return res unless pos
69
+ while to_link
70
+ res << to_link
71
+ break if pos == start_pos
72
+ pos, to_link = *path_cache[pos]
73
+ end
74
+ end
75
+ #$PDbgLog.sig_return(res.join(' '))
76
+ res
77
+ end
78
+
79
+ # Wave (breadth) / Dijkstra search:
80
+ def self.first_loop(start_pos, dest_proc, max_lev=1.0/0.0, get_pos_id_proc=nil)
81
+ # &get_neighb_posns
82
+ #$PDbgLog.sig_call(self)
83
+ path_cache={}
84
+ tail = PMinHeap.new { |frm1,frm2| frm1[1] <=> frm2[1] }
85
+ if get_pos_id_proc
86
+ yield(start_pos, 0).each { |args| neighb, to_link, neighb_lev = *args
87
+ unless (path_cache.include?(get_pos_id_proc.call(neighb)) &&
88
+ path_cache[get_pos_id_proc.call(neighb)][2] <= neighb_lev) ||
89
+ neighb_lev > max_lev
90
+ tail.push([neighb, neighb_lev])
91
+ path_cache[get_pos_id_proc.call(neighb)] =
92
+ [start_pos, to_link, neighb_lev]
93
+ end
94
+ }
95
+ while !tail.empty?
96
+ #$PDbgLog.puts_msg "tail: " + tail.collect { |frm|
97
+ # (frm[0] ? frm[0].coords_to_s : frm[0].inspect) +
98
+ # ":#{frm[1]}" }.join(" ")
99
+ pos, lev = *tail.pop
100
+ next if (tmp=path_cache[get_pos_id_proc.call(pos)])&& tmp[2]<lev
101
+ if dest_proc.call(pos, lev)
102
+ (res = self.path_cache_get_path(path_cache, start_pos,
103
+ pos, get_pos_id_proc)).reverse!
104
+ #$PDbgLog.sig_return
105
+ return res
106
+ end
107
+ yield(pos, lev).each { |args| neighb, to_link,neighb_lev = *args
108
+ unless ((tmp=path_cache[get_pos_id_proc.call(neighb)])&&
109
+ tmp[2] <= neighb_lev) || neighb_lev > max_lev
110
+ tail.push([neighb, neighb_lev])
111
+ path_cache[get_pos_id_proc.call(neighb)] =
112
+ [pos, to_link, neighb_lev]
113
+ end
114
+ }
115
+ end
116
+ #$PDbgLog.sig_return("nil")
117
+ nil
118
+ else
119
+ yield(start_pos, 0).each { |args| neighb, to_link, neighb_lev = *args
120
+ unless (path_cache.include?(neighb) &&
121
+ path_cache[neighb][2] <= neighb_lev) || neighb_lev > max_lev
122
+ tail.push([neighb, neighb_lev])
123
+ path_cache[neighb] = [start_pos, to_link, neighb_lev]
124
+ end
125
+ }
126
+ while !tail.empty?
127
+ #$PDbgLog.puts_msg "tail: " + tail.collect { |frm|
128
+ # (frm[0] ? frm[0].coords_to_s : frm[0].inspect) +
129
+ # ":#{frm[1]}" }.join(" ")
130
+ pos, lev = *tail.pop
131
+ next if path_cache.include?(pos) && path_cache[pos][2] < lev
132
+ if dest_proc.call(pos, lev)
133
+ (res = self.path_cache_get_path(path_cache, start_pos,
134
+ pos)).reverse!
135
+ #$PDbgLog.sig_return
136
+ return res
137
+ end
138
+ yield(pos, lev).each { |args| neighb, to_link,neighb_lev = *args
139
+ unless (path_cache.include?(neighb) &&
140
+ path_cache[neighb][2] <= neighb_lev) ||
141
+ neighb_lev > max_lev
142
+ tail.push([neighb, neighb_lev])
143
+ path_cache[neighb] = [pos, to_link, neighb_lev]
144
+ end
145
+ }
146
+ end
147
+ #$PDbgLog.sig_return("nil")
148
+ nil
149
+ end
150
+ end
151
+
152
+ # Find a loop which functions without a repetition of a connection in the
153
+ # _undirected_ graph of positions.
154
+ def self.first_norep_loop(start_pos, max_lev=1.0/0.0, max_len=1.0/0.0,
155
+ get_pos_id_proc=nil) # &get_neighb_posns
156
+ #$PDbgLog.sig_call(self)
157
+ tail = PMinHeap.new { |frm1,frm2| frm1[1] <=> frm2[1] }
158
+ get_pos_id_proc = proc { |a| a } unless get_pos_id_proc
159
+ start_pos_id = get_pos_id_proc.call(start_pos)
160
+ path_cache = {start_pos_id => [nil, nil, 0, -1]}
161
+ sol = nil
162
+ yield(start_pos, 0).each_with_index { |args, thr_i|
163
+ neighb, to_link, neighb_lev = *args
164
+ next if neighb_lev > max_lev
165
+ if (tmp=path_cache[get_pos_id_proc.call(neighb)])
166
+ len = tmp[2] + neighb_lev
167
+ if (!sol || sol[3] > len) && len <= max_len
168
+ sol = [neighb, start_pos, to_link, len]
169
+ end
170
+ else
171
+ tail.push([neighb, neighb_lev, thr_i])
172
+ path_cache[get_pos_id_proc.call(neighb)] =
173
+ [start_pos, to_link, neighb_lev, thr_i]
174
+ end
175
+ }
176
+ loop do
177
+ if sol
178
+ p1 = self.path_cache_get_path(path_cache, start_pos,
179
+ sol[0], get_pos_id_proc)
180
+ path_cache[get_pos_id_proc.call(sol[0])] = [sol[1],
181
+ sol[2]]
182
+ #$PDbgLog.sig_return
183
+ return [p1, self.path_cache_get_path(path_cache,
184
+ start_pos, sol[0], get_pos_id_proc), sol[3]]
185
+ end
186
+ if tail.empty?
187
+ #$PDbgLog.sig_return("nil")
188
+ return nil
189
+ end
190
+ pos, lev, thr_i = *tail.pop
191
+ next if (tmp=path_cache[get_pos_id_proc.call(pos)]) &&tmp[2]<lev
192
+ yield(pos, lev).each { |args| neighb, to_link,neighb_lev = *args
193
+ next if neighb_lev > max_lev ||
194
+ get_pos_id_proc.call(neighb) == start_pos_id
195
+ if (tmp=path_cache[get_pos_id_proc.call(neighb)]) &&
196
+ tmp[3] != thr_i
197
+ if (len=tmp[2] + neighb_lev) <= max_len &&
198
+ (!sol || sol[3] > len)
199
+ sol = [neighb, pos, to_link, len]
200
+ end
201
+ elsif !tmp || tmp[2] > neighb_lev
202
+ tail.push([neighb, neighb_lev, thr_i])
203
+ path_cache[get_pos_id_proc.call(neighb)] =
204
+ [pos, to_link, neighb_lev, thr_i]
205
+ end
206
+ }
207
+ end
208
+ end
209
+
210
+ end