extract-curves 0.1.1-mswin32
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog +21 -0
- data/bin/ec_rect2polar +22 -0
- data/bin/ec_rect2polar.rb +22 -0
- data/bin/ec_rev_lines +5 -0
- data/bin/ec_rev_lines.rb +5 -0
- data/bin/ec_sph_area +30 -0
- data/bin/ec_sph_area.rb +30 -0
- data/bin/extract_curves +1670 -0
- data/bin/extract_curves.rb +1670 -0
- data/ruby_ext/pav/extconf.rb +22 -0
- data/ruby_ext/pav/pav.dll +0 -0
- data/ruby_libs/pav/attr_cache.rb +211 -0
- data/ruby_libs/pav/attr_cache.t1.rb +32 -0
- data/ruby_libs/pav/cache.rb +31 -0
- data/ruby_libs/pav/collection/std.rb +58 -0
- data/ruby_libs/pav/dbg_log.rb +458 -0
- data/ruby_libs/pav/floatsio.rb +53 -0
- data/ruby_libs/pav/generator_cache.rb +165 -0
- data/ruby_libs/pav/graph/node.rb +602 -0
- data/ruby_libs/pav/graph/node_grp.rb +865 -0
- data/ruby_libs/pav/gtk.rb +6 -0
- data/ruby_libs/pav/gtk/button.rb +118 -0
- data/ruby_libs/pav/gtk/dialog.rb +29 -0
- data/ruby_libs/pav/gtk/guiobj.rb +772 -0
- data/ruby_libs/pav/gtk/icons.rb +124 -0
- data/ruby_libs/pav/gtk/rulers.rb +264 -0
- data/ruby_libs/pav/gtk/toolbar.rb +189 -0
- data/ruby_libs/pav/guiobj.rb +2 -0
- data/ruby_libs/pav/guiobj/info_asm.rb +41 -0
- data/ruby_libs/pav/guiobj/method.rb +211 -0
- data/ruby_libs/pav/guiobj/obj.rb +134 -0
- data/ruby_libs/pav/guiobj/signals.rb +9 -0
- data/ruby_libs/pav/heap.rb +54 -0
- data/ruby_libs/pav/icons/alt_handle.xpm +3832 -0
- data/ruby_libs/pav/icons/alt_handle_hover.xpm +3368 -0
- data/ruby_libs/pav/icons/alt_handle_pressed.xpm +3828 -0
- data/ruby_libs/pav/icons/blob.gif +0 -0
- data/ruby_libs/pav/icons/contour.gif +0 -0
- data/ruby_libs/pav/icons/contour_carpet.gif +0 -0
- data/ruby_libs/pav/icons/curve.gif +0 -0
- data/ruby_libs/pav/icons/curve_carpet.gif +0 -0
- data/ruby_libs/pav/icons/expand_closed.xpm +1791 -0
- data/ruby_libs/pav/icons/expand_closed_hover.xpm +1775 -0
- data/ruby_libs/pav/icons/expand_open.xpm +1788 -0
- data/ruby_libs/pav/icons/expand_open_hover.xpm +1752 -0
- data/ruby_libs/pav/icons/extract_curves/extract_curves-icon-rgb.ppm +14 -0
- data/ruby_libs/pav/icons/extract_curves/extract_curves-logo-rgb.gif +0 -0
- data/ruby_libs/pav/icons/extract_curves/trace_mark.xpm +38 -0
- data/ruby_libs/pav/icons/handle.xpm +213 -0
- data/ruby_libs/pav/icons/loop.gif +0 -0
- data/ruby_libs/pav/icons/loop_carpet.gif +0 -0
- data/ruby_libs/pav/icons/next.xpm +29 -0
- data/ruby_libs/pav/icons/next_hover.xpm +315 -0
- data/ruby_libs/pav/icons/next_pressed.xpm +144 -0
- data/ruby_libs/pav/icons/prev.xpm +29 -0
- data/ruby_libs/pav/icons/prev_hover.xpm +315 -0
- data/ruby_libs/pav/icons/prev_pressed.xpm +144 -0
- data/ruby_libs/pav/icons/shaved-core.gif +0 -0
- data/ruby_libs/pav/icons/vnext.xpm +29 -0
- data/ruby_libs/pav/icons/vprev.xpm +29 -0
- data/ruby_libs/pav/numeric/ext.rb +21 -0
- data/ruby_libs/pav/patterns/hsep.gif +0 -0
- data/ruby_libs/pav/patterns/tnode.gif +0 -0
- data/ruby_libs/pav/patterns/tnode_w_link.gif +0 -0
- data/ruby_libs/pav/patterns/vlink.gif +0 -0
- data/ruby_libs/pav/patterns/vsep.gif +0 -0
- data/ruby_libs/pav/patterns/yg_hrope.xpm +492 -0
- data/ruby_libs/pav/patterns/yg_hrope_thick.xpm +1904 -0
- data/ruby_libs/pav/patterns/yg_hrope_thin.xpm +130 -0
- data/ruby_libs/pav/patterns/yg_tnode.xpm +180 -0
- data/ruby_libs/pav/patterns/yg_tnode_thick.xpm +615 -0
- data/ruby_libs/pav/patterns/yg_tnode_thin.xpm +55 -0
- data/ruby_libs/pav/patterns/yg_tnode_w_link.xpm +190 -0
- data/ruby_libs/pav/patterns/yg_tnode_w_link_thick.xpm +676 -0
- data/ruby_libs/pav/patterns/yg_tnode_w_link_thin.xpm +62 -0
- data/ruby_libs/pav/patterns/yg_vrope.xpm +563 -0
- data/ruby_libs/pav/patterns/yg_vrope_thick.xpm +2047 -0
- data/ruby_libs/pav/patterns/yg_vrope_thin.xpm +166 -0
- data/ruby_libs/pav/pav_find.rb +90 -0
- data/ruby_libs/pav/pix.rb +402 -0
- data/ruby_libs/pav/pix/aapix.rb +378 -0
- data/ruby_libs/pav/pix/blob.rb +678 -0
- data/ruby_libs/pav/pix/circle.rb +73 -0
- data/ruby_libs/pav/pix/contour.rb +676 -0
- data/ruby_libs/pav/pix/contour/calc_situations.rb +9 -0
- data/ruby_libs/pav/pix/contour/carp_calc.rb +212 -0
- data/ruby_libs/pav/pix/contour/situations.dmp +0 -0
- data/ruby_libs/pav/pix/contour/situations.rb +21 -0
- data/ruby_libs/pav/pix/curve.rb +1544 -0
- data/ruby_libs/pav/pix/img_obj.rb +865 -0
- data/ruby_libs/pav/pix/node.rb +159 -0
- data/ruby_libs/pav/pix/shaved_core.rb +697 -0
- data/ruby_libs/pav/pix/subpix.rb +212 -0
- data/ruby_libs/pav/rand_accessible.rb +16 -0
- data/ruby_libs/pav/rangeset.rb +63 -0
- data/ruby_libs/pav/search.rb +210 -0
- data/ruby_libs/pav/set.rb +130 -0
- data/ruby_libs/pav/string/bits.rb +523 -0
- data/ruby_libs/pav/string/ext.rb +58 -0
- data/ruby_libs/pav/string/observable.rb +155 -0
- data/ruby_libs/pav/string/text.rb +79 -0
- data/ruby_libs/pav/string/words.rb +42 -0
- data/ruby_libs/pav/sub_arr.rb +56 -0
- data/ruby_libs/pav/traced_obj.rb +79 -0
- data/web/index.html +280 -0
- data/web/media/icons/alt_handle.xpm +3832 -0
- data/web/media/icons/alt_handle_hover.xpm +3368 -0
- data/web/media/icons/alt_handle_pressed.xpm +3828 -0
- data/web/media/icons/blob.gif +0 -0
- data/web/media/icons/contour.gif +0 -0
- data/web/media/icons/contour_carpet.gif +0 -0
- data/web/media/icons/curve.gif +0 -0
- data/web/media/icons/curve_carpet.gif +0 -0
- data/web/media/icons/expand_closed.xpm +1791 -0
- data/web/media/icons/expand_closed_hover.xpm +1775 -0
- data/web/media/icons/expand_open.xpm +1788 -0
- data/web/media/icons/expand_open_hover.xpm +1752 -0
- data/web/media/icons/extract_curves/extract_curves-icon-rgb.ppm +14 -0
- data/web/media/icons/extract_curves/extract_curves-logo-rgb.gif +0 -0
- data/web/media/icons/extract_curves/trace_mark.xpm +38 -0
- data/web/media/icons/handle.xpm +213 -0
- data/web/media/icons/loop.gif +0 -0
- data/web/media/icons/loop_carpet.gif +0 -0
- data/web/media/icons/next.xpm +29 -0
- data/web/media/icons/next_hover.xpm +315 -0
- data/web/media/icons/next_pressed.xpm +144 -0
- data/web/media/icons/prev.xpm +29 -0
- data/web/media/icons/prev_hover.xpm +315 -0
- data/web/media/icons/prev_pressed.xpm +144 -0
- data/web/media/icons/shaved-core.gif +0 -0
- data/web/media/icons/vnext.xpm +29 -0
- data/web/media/icons/vprev.xpm +29 -0
- data/web/media/title.jpeg +0 -0
- data/web/stylesheets/default.css +20 -0
- 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,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
|