extract-curves 0.1.1-i586-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.so +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