extract_curves 0.0.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 (99) hide show
  1. data/CVS/Entries +4 -0
  2. data/CVS/Repository +1 -0
  3. data/CVS/Root +1 -0
  4. data/bin/CVS/Entries +5 -0
  5. data/bin/CVS/Repository +1 -0
  6. data/bin/CVS/Root +1 -0
  7. data/bin/ec_rect2polar.rb +22 -0
  8. data/bin/ec_rev_lines.rb +5 -0
  9. data/bin/ec_sph_area.rb +30 -0
  10. data/bin/extract_curves.rb +2145 -0
  11. data/ruby_ext/CVS/Entries +1 -0
  12. data/ruby_ext/CVS/Repository +1 -0
  13. data/ruby_ext/CVS/Root +1 -0
  14. data/ruby_ext/pav/CVS/Entries +14 -0
  15. data/ruby_ext/pav/CVS/Repository +1 -0
  16. data/ruby_ext/pav/CVS/Root +1 -0
  17. data/ruby_ext/pav/extconf.rb +22 -0
  18. data/ruby_ext/pav/pav.so +0 -0
  19. data/ruby_libs/CVS/Entries +1 -0
  20. data/ruby_libs/CVS/Repository +1 -0
  21. data/ruby_libs/CVS/Root +1 -0
  22. data/ruby_libs/pav/CVS/Entries +20 -0
  23. data/ruby_libs/pav/CVS/Repository +1 -0
  24. data/ruby_libs/pav/CVS/Root +1 -0
  25. data/ruby_libs/pav/attr_cache.rb +211 -0
  26. data/ruby_libs/pav/attr_cache.t1.rb +32 -0
  27. data/ruby_libs/pav/cache.rb +31 -0
  28. data/ruby_libs/pav/dbg_log.rb +458 -0
  29. data/ruby_libs/pav/floatsio.rb +53 -0
  30. data/ruby_libs/pav/generator_cache.rb +165 -0
  31. data/ruby_libs/pav/gtk/CVS/Entries +4 -0
  32. data/ruby_libs/pav/gtk/CVS/Repository +1 -0
  33. data/ruby_libs/pav/gtk/CVS/Root +1 -0
  34. data/ruby_libs/pav/gtk/button.rb +130 -0
  35. data/ruby_libs/pav/gtk/icons.rb +87 -0
  36. data/ruby_libs/pav/gtk/toolbar.rb +192 -0
  37. data/ruby_libs/pav/heap.rb +54 -0
  38. data/ruby_libs/pav/icons/CVS/Entries +17 -0
  39. data/ruby_libs/pav/icons/CVS/Repository +1 -0
  40. data/ruby_libs/pav/icons/CVS/Root +1 -0
  41. data/ruby_libs/pav/icons/alt_handle.xpm +3832 -0
  42. data/ruby_libs/pav/icons/alt_handle_hover.xpm +3368 -0
  43. data/ruby_libs/pav/icons/alt_handle_pressed.xpm +3828 -0
  44. data/ruby_libs/pav/icons/extract_curves/CVS/Entries +6 -0
  45. data/ruby_libs/pav/icons/extract_curves/CVS/Repository +1 -0
  46. data/ruby_libs/pav/icons/extract_curves/CVS/Root +1 -0
  47. data/ruby_libs/pav/icons/extract_curves/extract_curves-icon-rgb.ppm +14 -0
  48. data/ruby_libs/pav/icons/extract_curves/extract_curves-logo-rgb.gif +0 -0
  49. data/ruby_libs/pav/icons/extract_curves/trace_mark.xpm +38 -0
  50. data/ruby_libs/pav/icons/handle.xpm +213 -0
  51. data/ruby_libs/pav/icons/next.xpm +29 -0
  52. data/ruby_libs/pav/icons/next_hover.xpm +315 -0
  53. data/ruby_libs/pav/icons/next_pressed.xpm +144 -0
  54. data/ruby_libs/pav/icons/prev.xpm +29 -0
  55. data/ruby_libs/pav/icons/prev_hover.xpm +315 -0
  56. data/ruby_libs/pav/icons/prev_pressed.xpm +144 -0
  57. data/ruby_libs/pav/icons/vnext.xpm +29 -0
  58. data/ruby_libs/pav/icons/vprev.xpm +29 -0
  59. data/ruby_libs/pav/numeric/CVS/Entries +2 -0
  60. data/ruby_libs/pav/numeric/CVS/Repository +1 -0
  61. data/ruby_libs/pav/numeric/CVS/Root +1 -0
  62. data/ruby_libs/pav/numeric/ext.rb +13 -0
  63. data/ruby_libs/pav/pav_find.rb +90 -0
  64. data/ruby_libs/pav/pix/CVS/Entries +11 -0
  65. data/ruby_libs/pav/pix/CVS/Repository +1 -0
  66. data/ruby_libs/pav/pix/CVS/Root +1 -0
  67. data/ruby_libs/pav/pix/aapix.rb +378 -0
  68. data/ruby_libs/pav/pix/blob.rb +543 -0
  69. data/ruby_libs/pav/pix/circle.rb +73 -0
  70. data/ruby_libs/pav/pix/contour/CVS/Entries +5 -0
  71. data/ruby_libs/pav/pix/contour/CVS/Repository +1 -0
  72. data/ruby_libs/pav/pix/contour/CVS/Root +1 -0
  73. data/ruby_libs/pav/pix/contour/calc_situations.rb +9 -0
  74. data/ruby_libs/pav/pix/contour/carp_calc.rb +212 -0
  75. data/ruby_libs/pav/pix/contour/situations.dmp +0 -0
  76. data/ruby_libs/pav/pix/contour/situations.rb +21 -0
  77. data/ruby_libs/pav/pix/contour.rb +644 -0
  78. data/ruby_libs/pav/pix/curve.rb +1508 -0
  79. data/ruby_libs/pav/pix/img_obj.rb +751 -0
  80. data/ruby_libs/pav/pix/node.rb +712 -0
  81. data/ruby_libs/pav/pix/node_grp.rb +853 -0
  82. data/ruby_libs/pav/pix/shaved_core.rb +534 -0
  83. data/ruby_libs/pav/pix/subpix.rb +212 -0
  84. data/ruby_libs/pav/pix.rb +402 -0
  85. data/ruby_libs/pav/rand_accessible.rb +16 -0
  86. data/ruby_libs/pav/rangeset.rb +63 -0
  87. data/ruby_libs/pav/search.rb +210 -0
  88. data/ruby_libs/pav/set.rb +20 -0
  89. data/ruby_libs/pav/string/CVS/Entries +6 -0
  90. data/ruby_libs/pav/string/CVS/Repository +1 -0
  91. data/ruby_libs/pav/string/CVS/Root +1 -0
  92. data/ruby_libs/pav/string/bits.rb +523 -0
  93. data/ruby_libs/pav/string/ext.rb +58 -0
  94. data/ruby_libs/pav/string/observable.rb +155 -0
  95. data/ruby_libs/pav/string/text.rb +79 -0
  96. data/ruby_libs/pav/string/words.rb +42 -0
  97. data/ruby_libs/pav/sub_arr.rb +55 -0
  98. data/ruby_libs/pav/traced_obj.rb +79 -0
  99. metadata +147 -0
@@ -0,0 +1,751 @@
1
+ require 'set'
2
+ require 'pav/pix'
3
+ require 'pav/heap'
4
+
5
+ module PPix
6
+
7
+ module MPixbufPix
8
+ def img_obj_subpix8(sub_n)
9
+ # @img_obj_subpix8 = [] unless @img_obj_subpix8
10
+ # tmp = @img_obj_subpix8[sub_n]
11
+ # return tmp if tmp
12
+ #$PDbgLog.sig_call(self)
13
+ #$PDbgLog.puts_msg self.coords_to_s + ", sub_n=#{sub_n}"
14
+ #res =
15
+ #@img_obj_subpix8[sub_n] =
16
+ ImageObjectSubpix.new(Subpix8.new(self, sub_n))
17
+ #$PDbgLog.puts_msg res.inspect
18
+ #$PDbgLog.sig_return
19
+ #res
20
+ end
21
+
22
+ def connections(&get_neighbs)
23
+ #$PDbgLog.sig_call(self)
24
+ #$PDbgLog.print_msg(self.coords_to_s)
25
+ res = []
26
+ visited = {}
27
+ for neighb in yield(self)
28
+ #$PDbgLog.print_msg " neighb#{neighb.coords_to_s}: "
29
+ next if visited.include?(neighb.a_yx)
30
+ res << [tmp_pix=neighb]
31
+ prev_pix = self
32
+ while (pix_ngbs = yield(tmp_pix)).length == 2
33
+ if pix_ngbs.first.a_eql?(prev_pix)
34
+ prev_pix = tmp_pix
35
+ tmp_pix = pix_ngbs.last
36
+ else
37
+ prev_pix = tmp_pix
38
+ tmp_pix = pix_ngbs.first
39
+ end
40
+ res.last << tmp_pix
41
+ if self.a_eql?(tmp_pix)
42
+ visited[prev_pix.a_yx] = true
43
+ break
44
+ end
45
+ end
46
+ #$PDbgLog.puts_msg "."
47
+ end
48
+ #$PDbgLog.sig_return
49
+ res
50
+ end
51
+
52
+ def rev_conn_idx(conns, conn_i, rev_conns)
53
+ #$PDbgLog.sig_call(self)
54
+ #$PDbgLog.puts_msg "(#{conn_i}) from (#{self.x}, #{self.y})."
55
+ path = conns[conn_i]
56
+ #$PDbgLog.puts_msg "path: #{PixbufPix.path_to_s(path)}"
57
+ end_pix = path.last
58
+ if self.a_eql?(end_pix)
59
+ return conn_i
60
+ else
61
+ path = path.reverse[1, path.length-1] << self
62
+ #$PDbgLog.puts_msg "rev_path: #{
63
+ # PixbufPix.path_to_s(path)}"
64
+ rev_conns.each_with_index { |rev_conn, i|
65
+ #$PDbgLog.puts_msg "rev_conn: #{
66
+ # PixbufPix.path_to_s(rev_conn)}"
67
+ if PixbufPix.a_paths_eql?(path, rev_conn)
68
+ return i
69
+ end
70
+ }
71
+ end
72
+ #$PDbgLog.sig_return
73
+ nil
74
+ end
75
+
76
+ def find_shortest_pix_path_to(dest, levs_left=-1, &get_neighbs)
77
+ #$PDbgLog.sig_call(self)
78
+ if dest.kind_of?(Proc)
79
+ dest_proc = dest
80
+ else
81
+ dest_proc = proc { |px| px.y==dest.y && px.x==dest.x }
82
+ end
83
+ path_cache = { self.yx => 0 }
84
+ tail = [[self, 0]]
85
+ #$PDbgLog.print_msg "dest=#{dest}, from #{
86
+ # self.coords_to_s}, levs_left=#{levs_left}: "
87
+ if levs_left == 0
88
+ #$PDbgLog.sig_return("levs_left==0: nil")
89
+ return nil
90
+ end
91
+ while !tail.empty?
92
+ pix, lev = *tail.shift
93
+ #if lev > 100
94
+ #$PDbgLog.print_msg
95
+ #puts "dest=#{dest}, from #{
96
+ # self.coords_to_s}, levs_left=#{levs_left}: #{tail.
97
+ # length},#{pix.coords_to_s},#{lev}; "
98
+ #end
99
+ # $PDbgLog.print_msg "#{tail.length},#{pix.coords_to_s},#{
100
+ # lev}; "
101
+ if dest_proc.call(pix)
102
+ res = []
103
+ i = path_cache[pix.yx]
104
+ while i > 0
105
+ res[i-=1] = pix
106
+ yield(pix).each { |pix|
107
+ break if path_cache[pix.yx] == i
108
+ }
109
+ end
110
+ #$PDbgLog.sig_return(PixbufPix.path_to_s(res))
111
+ return res
112
+ end
113
+ yield(pix).each { |neighb|
114
+ unless (path_cache.include?(neighb.yx) &&
115
+ path_cache[neighb.yx] <= lev+1) ||
116
+ lev+1 == levs_left
117
+ tail.push([neighb, lev+1])
118
+ path_cache[neighb.yx] = lev+1
119
+ end
120
+ }
121
+ end
122
+ #$PDbgLog.sig_return("nil")
123
+ nil
124
+ end
125
+
126
+ def find_shortest_pix_path_into(res, dest, levs_left=-1, path_cache={},
127
+ tail=[], neighbs=[]) # &get_neighbs
128
+ #$PDbgLog.sig_call(self)
129
+ if dest.kind_of?(Proc)
130
+ dest_proc = dest
131
+ else
132
+ dest_proc = proc { |px| px.y==dest.y && px.x==dest.x }
133
+ end
134
+ path_cache.clear; path_cache[self.yx] = 0
135
+ tail.clear; tail << self << 0
136
+ #$PDbgLog.print_msg "dest=#{dest}, from #{
137
+ # self.coords_to_s}, levs_left=#{levs_left}: "
138
+ if levs_left == 0
139
+ #$PDbgLog.sig_return("levs_left==0: nil")
140
+ return nil
141
+ end
142
+ while !tail.empty?
143
+ pix = tail.shift; lev = tail.shift
144
+ #if lev > 100
145
+ #$PDbgLog.print_msg
146
+ #puts "dest=#{dest}, from #{
147
+ # self.coords_to_s}, levs_left=#{levs_left}: #{tail.
148
+ # length},#{pix.coords_to_s},#{lev}; "
149
+ #end
150
+ # $PDbgLog.print_msg "#{tail.length},#{pix.coords_to_s},#{
151
+ # lev}; "
152
+ if dest_proc.call(pix)
153
+ res.clear
154
+ i = path_cache[pix.yx]
155
+ while i > 0
156
+ res[i-=1] = pix
157
+ yield(pix, neighbs).each { |pix|
158
+ break if path_cache[pix.yx] == i
159
+ }
160
+ end
161
+ #$PDbgLog.sig_return(PixbufPix.path_to_s(res))
162
+ return res
163
+ end
164
+ yield(pix, neighbs).each { |neighb|
165
+ unless (path_cache.include?(neighb.yx) &&
166
+ path_cache[neighb.yx] <= lev+1) ||
167
+ lev+1 == levs_left
168
+ tail << neighb << (lev+1)
169
+ path_cache[neighb.yx] = lev+1
170
+ end
171
+ }
172
+ end
173
+ #$PDbgLog.sig_return("nil")
174
+ nil
175
+ end
176
+
177
+ def find_first_path_to(dest, max_lev=1.0/0.0, &get_neighbs_levs)
178
+ $PDbgLog.sig_call(self)
179
+ if dest.kind_of?(Proc)
180
+ dest_proc = dest
181
+ else
182
+ dest_proc = proc { |px| dest.a_eql?(px) }
183
+ end
184
+ path_cache = { self.a_yx => [nil, 0] }
185
+ tail = PMinHeap.new { |frm1,frm2| frm1[1] <=> frm2[1] }
186
+ tail.push([self, 0])
187
+ if max_lev < 1
188
+ $PDbgLog.sig_return("max_lev < 1: nil")
189
+ return nil
190
+ end
191
+ while !tail.empty?
192
+ pix, lev = *tail.pop
193
+ if dest_proc.call(pix, lev)
194
+ frm = path_cache[pix.a_yx]
195
+ res = [pix]
196
+ while frm[0]
197
+ res << frm[0]
198
+ frm = path_cache[frm[0].a_yx]
199
+ end
200
+ $PDbgLog.sig_return(PixbufPix.path_to_s(
201
+ res.reverse))
202
+ return res.reverse!
203
+ end
204
+ yield(pix, lev).each { |args| neighb, neighb_lev = *args
205
+ unless (path_cache.include?(neighb.a_yx) &&
206
+ path_cache[neighb.a_yx][1] <= neighb_lev) ||
207
+ neighb_lev > max_lev
208
+ tail.push([neighb, neighb_lev])
209
+ path_cache[neighb.a_yx]=[pix,neighb_lev]
210
+ end
211
+ }
212
+ end
213
+ $PDbgLog.sig_return("nil")
214
+ nil
215
+ end
216
+
217
+ def inspect
218
+ idmem = self.object_id & ( (1 << (8*self.object_id.size)) - 1 )
219
+ "<#{self.class.name}:0x%x #{self.coords_to_s}" % idmem +
220
+ "#{self.instance_variables.collect { |var| " " + var + "=" +
221
+ self.instance_variable_get(var).inspect }.join(",")}>"
222
+ end
223
+ end
224
+
225
+ class ImageObjectSubpix #< ImageObjectPix
226
+ attr_reader :subpix, :ppix
227
+
228
+ def initialize(subpix)
229
+ @subpix = subpix
230
+ super(subpix.img_pix)
231
+ @ppix = ppix
232
+ end
233
+
234
+ def method_missing(id, *args, &block)
235
+ begin
236
+ @subpix.send(id, *args, &block)
237
+ rescue NoMethodError
238
+ @subpix.img_pix.send(id, *args, &block)
239
+ end
240
+ end
241
+
242
+ def to_s
243
+ @subpix.to_s
244
+ end
245
+
246
+ def inspect
247
+ idmem = self.object_id & ( (1 << (8*self.object_id.size)) - 1 )
248
+ "<#{self.class.name}:0x%x @subpix#{@subpix.to_s}"%idmem +
249
+ "#{self.instance_variables.collect{|var|"#{var}=#{self.
250
+ instance_variable_get(var).inspect}"}.join(",")}>" #"
251
+ end
252
+ end
253
+
254
+ class ImageObject
255
+ @img_obj_meths = []
256
+
257
+ def initialize(times_arr=0, obj_start_i=nil, end_i=nil)
258
+ if end_i
259
+ @__under__ = SubArr.new(times_arr, obj_start_i, end_i)
260
+ elsif obj_start_i
261
+ @__under__ = Array.new(times_arr, obj_start_i)
262
+ else
263
+ @__under__ = Array.new(times_arr)
264
+ end
265
+ self.img_obj_rebuild
266
+ end
267
+
268
+ (Array.instance_methods+SubArr.instance_methods-Object.instance_methods-
269
+ ["[]=", "<<", "push", "+", "-", "*", "concat", "replace"]).
270
+ uniq!.each { |meth|
271
+ if meth[-1,1] == "="
272
+ module_eval <<-"eval_end"
273
+ def #{meth}(val)
274
+ @__under__.#{meth}(val)
275
+ end
276
+ eval_end
277
+ else
278
+ module_eval <<-"eval_end"
279
+ def #{meth}(*args, &block)
280
+ @__under__.#{meth}(*args, &block)
281
+ end
282
+ eval_end
283
+ end
284
+ }
285
+
286
+ def []=(*args, &block)
287
+ @__under__.[]=(*args, &block)
288
+ end
289
+
290
+ def replace(*args, &block)
291
+ @__under__.replace(*args, &block)
292
+ self
293
+ end
294
+
295
+ def concat(*args, &block)
296
+ @__under__.concat(*args, &block)
297
+ self
298
+ end
299
+
300
+ def <<(*args, &block)
301
+ @__under__.<<(*args, &block)
302
+ self
303
+ end
304
+
305
+ def push(*args, &block)
306
+ @__under__.push(*args, &block)
307
+ self
308
+ end
309
+
310
+ def +(*args, &block)
311
+ ImageObject.new.replace(@__under__.+(*args, &block))
312
+ end
313
+
314
+ def -(*args, &block)
315
+ ImageObject.new.replace(@__under__.-(*args, &block))
316
+ end
317
+
318
+ def *(*args, &block)
319
+ ImageObject.new.replace(@__under__.*(*args, &block))
320
+ end
321
+
322
+ def dup
323
+ ImageObject.new(@__under__.dup)
324
+ end
325
+
326
+ def self.img_obj_sub_obj_meths
327
+ @img_obj_sub_obj_meths
328
+ end
329
+
330
+ def self.get_img_obj_sub_obj_meths
331
+ return @img_obj_sub_obj_meths if @img_obj_sub_obj_meths
332
+ begin
333
+ return (@img_obj_sub_obj_meths=@img_obj_sub_obj_meths.dup) if
334
+ (@img_obj_sub_obj_meths =
335
+ self.superclass.get_img_obj_sub_obj_meths)
336
+ rescue NoMethodError
337
+ end
338
+ @img_obj_sub_obj_meths = []
339
+ end
340
+
341
+ def self.img_obj_add_sub_obj(*args)
342
+ self.get_img_obj_sub_obj_meths.concat(args.collect{|m| m.to_s})
343
+ end
344
+
345
+ def self.img_obj_add_to_sub_objs(*args)
346
+ return unless @img_obj_sub_obj_meths
347
+ @img_obj_sub_obj_meths.concat(args.collect{|m| m.to_s})
348
+ end
349
+
350
+ def img_obj_possible_sub_obj_meths
351
+ (self.public_methods - Object.instance_methods -
352
+ Array.instance_methods - SubArr.instance_methods -
353
+ ["rewind", "rebuild", "get_sub_img_objs"]).delete_if { |meth|
354
+ meth.starts_with("_") || meth.starts_with("delete_") ||
355
+ ![-1, 0].include?(self.method(meth).arity)
356
+ }
357
+ end
358
+
359
+ def get_sub_img_objs(excl_set={})
360
+ #$PDbgLog.sig_call(self)
361
+ #$PDbgLog.print_msg self.inspect
362
+ objs = {}
363
+ if (meths = self.class.img_obj_sub_obj_meths)
364
+ meths.each { |meth|
365
+ res = self.send(meth)
366
+ next if excl_set.include?(res.object_id)
367
+ objs[meth] = res
368
+ excl_set[res.object_id] = true
369
+ }
370
+ #$PDbgLog.sig_return
371
+ return objs
372
+ end
373
+ self.img_obj_possible_sub_obj_meths.each { |meth|
374
+ res = self.send(meth)
375
+ #$PDbgLog.print_msg "meth=#{meth}:%x " % res.object_id
376
+ next if excl_set.include?(res.object_id)
377
+ if res.kind_of?(ImageObject)
378
+ objs[meth] = res
379
+ excl_set[res.object_id] = true
380
+ elsif res.kind_of?(Array) && !res.empty? &&
381
+ res.first.kind_of?(ImageObject)
382
+ objs[meth] = res
383
+ excl_set[res.object_id] = true
384
+ elsif res.kind_of?(Hash) && !res.empty?
385
+ flag = true
386
+ res.each_value { |v|
387
+ flag = v.kind_of?(ImageObject)
388
+ break
389
+ }
390
+ if flag
391
+ objs[meth] = res
392
+ excl_set[res.object_id] = true
393
+ end
394
+ end
395
+ }
396
+ #$PDbgLog.sig_return
397
+ objs
398
+ end
399
+
400
+ def img_obj_rebuild
401
+ @img_obj_min_x = @img_obj_max_x = nil
402
+ @img_obj_min_y = @img_obj_max_y = nil
403
+ @img_obj_min_ax = @img_obj_max_ax = nil
404
+ @img_obj_min_ay = @img_obj_max_ay = nil
405
+ @img_obj_yx_set = nil
406
+ @img_obj_ayx_set = nil
407
+ end
408
+
409
+ def img_obj_yx_set
410
+ return @img_obj_yx_set if @img_obj_yx_set
411
+ @img_obj_yx_set = Set.new
412
+ self.each { |pix| @img_obj_yx_set.add(pix.yx) }
413
+ @img_obj_yx_set
414
+ end
415
+
416
+ def img_obj_ayx_set
417
+ return @img_obj_ayx_set if @img_obj_ayx_set
418
+ @img_obj_ayx_set = Set.new
419
+ self.each { |pix| @img_obj_ayx_set.add(pix.a_yx) }
420
+ @img_obj_ayx_set
421
+ end
422
+
423
+ def img_obj_find_xy_rect
424
+ return if self.empty?
425
+ @img_obj_min_x = @img_obj_max_x = self.first.x
426
+ @img_obj_min_y = @img_obj_max_y = self.first.y
427
+ self.each { |pix|
428
+ if pix.x < @img_obj_min_x
429
+ @img_obj_min_x = pix.x
430
+ elsif pix.x > @img_obj_max_x
431
+ @img_obj_max_x = pix.x
432
+ end
433
+ if pix.y < @img_obj_min_y
434
+ @img_obj_min_y = pix.y
435
+ elsif pix.y > @img_obj_max_y
436
+ @img_obj_max_y = pix.y
437
+ end
438
+ }
439
+ end
440
+
441
+ def img_obj_find_axy_rect
442
+ return if self.empty?
443
+ @img_obj_min_ax = @img_obj_max_ax = self.first.ax
444
+ @img_obj_min_ay = @img_obj_max_ay = self.first.ay
445
+ self.each { |pix|
446
+ if pix.ax < @img_obj_min_ax
447
+ @img_obj_min_ax = pix.ax
448
+ elsif pix.ax > @img_obj_max_ax
449
+ @img_obj_max_ax = pix.ax
450
+ end
451
+ if pix.ay < @img_obj_min_ay
452
+ @img_obj_min_ay = pix.ay
453
+ elsif pix.ay > @img_obj_max_ay
454
+ @img_obj_max_ay = pix.ay
455
+ end
456
+ }
457
+ end
458
+
459
+ def img_obj_min_x
460
+ self.img_obj_find_xy_rect unless @img_obj_min_x
461
+ @img_obj_min_x
462
+ end
463
+
464
+ def img_obj_max_x
465
+ self.img_obj_find_xy_rect unless @img_obj_max_x
466
+ @img_obj_max_x
467
+ end
468
+
469
+ def img_obj_min_y
470
+ self.img_obj_find_xy_rect unless @img_obj_min_y
471
+ @img_obj_min_y
472
+ end
473
+
474
+ def img_obj_max_y
475
+ self.img_obj_find_xy_rect unless @img_obj_max_y
476
+ @img_obj_max_y
477
+ end
478
+
479
+ def img_obj_min_ax
480
+ self.img_obj_find_axy_rect unless @img_obj_min_ax
481
+ @img_obj_min_ax
482
+ end
483
+
484
+ def img_obj_max_ax
485
+ self.img_obj_find_axy_rect unless @img_obj_max_ax
486
+ @img_obj_max_ax
487
+ end
488
+
489
+ def img_obj_min_ay
490
+ self.img_obj_find_axy_rect unless @img_obj_min_ay
491
+ @img_obj_min_ay
492
+ end
493
+
494
+ def img_obj_max_ay
495
+ self.img_obj_find_axy_rect unless @img_obj_max_ay
496
+ @img_obj_max_ay
497
+ end
498
+
499
+ def img_obj_freeze
500
+ @__under__.freeze
501
+ end
502
+
503
+ def opt_spanning_tree(min, mk_conn, get_conns)
504
+ return if self.empty?
505
+ # Start from a node pixel:
506
+ return if (conns = get_conns.call(self.first)).empty?
507
+ #$PDbgLog.sig_call(self)
508
+ pix = conns[0].last
509
+ spanned = {pix.yx => true}
510
+ active_conns = min ? PMinHeap.new{|cn1,cn2| cn1[3] <=> cn2[3]} :
511
+ PMinHeap.new { |cn1, cn2| cn2[3] <=> cn1[3] }
512
+ get_conns.call(pix).each_with_index { |conn, conn_i|
513
+ active_conns.push([pix, conn.last, conn_i, conn.length]) }
514
+ cn = nil
515
+ loop do
516
+ # $PDbgLog.print_msg "#{spanned.length}/#{self.length
517
+ # }; spanned: #{PixbufPix.yx_path_to_s(spanned.keys.sort
518
+ # )}; active_conns: #{active_conns.collect{|frm|
519
+ # frm[0].coords_to_s + "--" + frm[1].coords_to_s +
520
+ # ",#{frm[2]}:#{frm[3]}"}.join("; ")}. "
521
+ loop do
522
+ unless (cn = active_conns.pop)
523
+ #$PDbgLog.sig_return
524
+ return
525
+ end
526
+ break unless spanned.include?(cn[1].yx)
527
+ end
528
+ #$PDbgLog.puts_msg "Calling mk_conn(#{cn[0].coords_to_s
529
+ # }, #{cn[2]})"
530
+ mk_conn.call(cn[0], cn[2])
531
+ spanned[cn[1].yx] = true
532
+ get_conns.call(cn[1]).each_with_index { |conn, conn_i|
533
+ next if spanned.include?(conn.last.yx)
534
+ active_conns.push([cn[1], conn.last, conn_i,
535
+ conn.length])
536
+ }
537
+ end
538
+ #$PDbgLog.sig_return
539
+ end
540
+ end
541
+
542
+ class ImageObjectPixCalc
543
+ attr_reader :pix, :path_cache, :first_path_cache, :get_pix_proc
544
+
545
+ def initialize(pix, &get_pix_proc)
546
+ @pix = pix
547
+ @path_cache = {}
548
+ @first_path_cache = {}
549
+ @get_pix_proc = get_pix_proc
550
+ end
551
+
552
+ def find_shortest_pix_path_to_pix(dest, levs_left=-1,
553
+ path_cache=@path_cache, &get_neighbs)
554
+ #$PDbgLog.sig_call(self)
555
+ path_cache = {} unless path_cache
556
+ tail = [[@pix, 0]]
557
+ path_cache[@pix.a_yx]=0 unless path_cache.include?(@pix.a_yx) &&
558
+ path_cache[@pix.a_yx] <= 0
559
+ #$PDbgLog.print_msg "dest=#{dest}, from #{
560
+ # @pix.coords_to_s}, levs_left=#{levs_left}: "
561
+ if levs_left == 0
562
+ #$PDbgLog.sig_return("levs_left==0: nil")
563
+ return nil
564
+ end
565
+ while !tail.empty?
566
+ pix, lev = *tail.shift
567
+ if path_cache.include?(dest.a_yx)
568
+ res = []; pix = dest
569
+ i = path_cache[pix.a_yx]
570
+ while i > 0
571
+ res[i-=1] = pix
572
+ yield(pix).each { |pix|
573
+ break if path_cache[pix.a_yx]==i
574
+ }
575
+ end
576
+ #$PDbgLog.sig_return(PixbufPix.path_to_s(res))
577
+ return res
578
+ end
579
+ yield(pix).each { |neighb|
580
+ unless (path_cache.include?(neighb.a_yx) &&
581
+ path_cache[neighb.a_yx] <= lev+1) ||
582
+ lev+1 == levs_left
583
+ tail.push([neighb, lev+1])
584
+ path_cache[neighb.a_yx] = lev+1
585
+ end
586
+ }
587
+ end
588
+ #$PDbgLog.sig_return("nil")
589
+ nil
590
+ end
591
+
592
+ def find_shortest_path_pix_to(dest, levs_left=-1, &get_neighbs)
593
+ #$PDbgLog.sig_call(self)
594
+ if dest.kind_of?(Proc)
595
+ dest_proc = dest
596
+ else
597
+ #$PDbgLog.sig_return
598
+ return self.find_shortest_pix_path_to_pix(dest,
599
+ levs_left, {}, &get_neighbs)
600
+ end
601
+ path_cache = { @pix.a_yx => 0 }
602
+ tail = [[@pix, 0]]
603
+ #$PDbgLog.print_msg "dest=#{dest}, from #{
604
+ # @pix.coords_to_s}, levs_left=#{levs_left}: "
605
+ if levs_left == 0
606
+ #$PDbgLog.sig_return("levs_left==0: nil")
607
+ return nil
608
+ end
609
+ while !tail.empty?
610
+ pix, lev = *tail.shift
611
+ #if lev > 100
612
+ #$PDbgLog.print_msg
613
+ #puts "dest=#{dest}, from #{
614
+ # @pix.coords_to_s}, levs_left=#{levs_left}: #{tail.
615
+ # length},#{pix.coords_to_s},#{lev}; "
616
+ #end
617
+ # $PDbgLog.print_msg "#{tail.length},#{pix.coords_to_s},#{
618
+ # lev}; "
619
+ if dest_proc.call(pix)
620
+ res = []
621
+ i = path_cache[pix.a_yx]
622
+ while i > 0
623
+ res[i-=1] = pix
624
+ yield(pix).each { |pix|
625
+ break if path_cache[pix.a_yx]==i
626
+ }
627
+ end
628
+ #$PDbgLog.sig_return(PixbufPix.path_to_s(res))
629
+ return res
630
+ end
631
+ yield(pix).each { |neighb|
632
+ unless (path_cache.include?(neighb.a_yx) &&
633
+ path_cache[neighb.a_yx] <= lev+1) ||
634
+ lev+1 == levs_left
635
+ tail.push([neighb, lev+1])
636
+ path_cache[neighb.a_yx] = lev+1
637
+ end
638
+ }
639
+ end
640
+ #$PDbgLog.sig_return("nil")
641
+ nil
642
+ end
643
+
644
+ def self.path_cache_to_s(path_cache)
645
+ "{#{path_cache.keys.to_a.sort.collect{|k| k.inspect + "=>[" +
646
+ (path_cache[k][0] ? path_cache[k][0].coords_to_s : 'nil'
647
+ )+"], #{path_cache[k][1]}"}.join(", ")}}"
648
+ end
649
+
650
+ def self.first_path_cache_get_path(pix, path_cache)
651
+ frm = path_cache[pix.yx]
652
+ res = [pix]
653
+ while frm[0]
654
+ res << frm[0]
655
+ frm = path_cache[frm[0].yx]
656
+ end
657
+ res.reverse!
658
+ end
659
+
660
+ def self.first_path_cache_get_path_to_self(pix, path_cache)
661
+ frm = path_cache[pix.yx]
662
+ res = [pix]
663
+ while frm[0].yx != @pix.yx
664
+ res << frm[0]
665
+ frm = path_cache[frm[0].yx]
666
+ end
667
+ res << frm[0]
668
+ res.reverse!
669
+ end
670
+
671
+ def self.first_path_cache_get_ayx_path(pix, path_cache)
672
+ #$PDbgLog.sig_call(self)
673
+ #$PDbgLog.print_msg "pix#{pix.coords_to_s} path_cache: #{self.
674
+ # path_cache_to_s(path_cache)}: "
675
+ frm = path_cache[pix.a_yx]
676
+ res = [pix]
677
+ while frm[0]
678
+ #$PDbgLog.print_msg "#{frm[0].a_yx.inspect} "
679
+ res << frm[0]
680
+ frm = path_cache[frm[0].a_yx]
681
+ end
682
+ #$PDbgLog.sig_return
683
+ res.reverse!
684
+ end
685
+
686
+ def find_first_path_to(dest, max_lev=1.0/0.0, path_cache=nil,
687
+ &get_neighbs_levs)
688
+ if dest.kind_of?(Proc)
689
+ dest_proc = dest
690
+ else
691
+ dest_proc = proc {|px,lev| dest.a_eql?(px)}
692
+ end
693
+ tail = PMinHeap.new { |frm1,frm2| frm1[1] <=> frm2[1] }
694
+ unless path_cache
695
+ path_cache = @first_path_cache
696
+ unless dest.kind_of?(Proc)
697
+ return ImageObjectPixCalc.
698
+ first_path_cache_get_ayx_path(dest, path_cache) if
699
+ path_cache.include?(dest.a_yx)
700
+ end
701
+ path_cache.each_pair { |pix, frm|
702
+ tail.push([@get_pix_proc.call(pix[1], pix[0]),
703
+ frm[1]])
704
+ }
705
+ end
706
+ #$PDbgLog.sig_call(self)
707
+ path_cache[@pix.a_yx] = [nil, 0]
708
+ tail.push([@pix, 0])
709
+ if max_lev < 1
710
+ #$PDbgLog.sig_return("max_lev < 1: nil")
711
+ return nil
712
+ end
713
+ while !tail.empty?
714
+ #$PDbgLog.puts_msg "tail: " + tail.collect { |frm|
715
+ # (frm[0] ? frm[0].coords_to_s : frm[0].inspect) +
716
+ # ":#{frm[1]}" }.join(" ")
717
+ pix, lev = *tail.pop
718
+ #$PDbgLog.puts_msg "path_cache: #{ImageObjectPixCalc.
719
+ # path_cache_to_s(path_cache)}"
720
+ #$PDbgLog.print_msg pix.coords_to_s + ",#{lev}"
721
+ #$PDbgLog.print_msg "<-#{path_cache[pix.a_yx][0] ?
722
+ # path_cache[pix.a_yx][0].coords_to_s :
723
+ # path_cache[pix.a_yx][0].inspect} "
724
+ next if path_cache.include?(pix.a_yx) &&
725
+ path_cache[pix.a_yx][1] < lev
726
+ if dest_proc.call(pix, lev)
727
+ res = ImageObjectPixCalc.
728
+ first_path_cache_get_ayx_path(pix, path_cache)
729
+ #$PDbgLog.sig_return(PixbufPix.path_to_s(res))
730
+ return res
731
+ end
732
+ yield(pix, lev).each { |args| neighb, neighb_lev = *args
733
+ unless (path_cache.include?(neighb.a_yx) &&
734
+ path_cache[neighb.a_yx][1] <= neighb_lev) ||
735
+ neighb_lev > max_lev
736
+ tail.push([neighb, neighb_lev])
737
+ path_cache[neighb.a_yx]=[pix,neighb_lev]
738
+ end
739
+ }
740
+ end
741
+ #$PDbgLog.sig_return("nil")
742
+ nil
743
+ end
744
+
745
+ def kill_path_cache!
746
+ @path_cache.clear
747
+ @first_path_cache.clear
748
+ end
749
+ end
750
+
751
+ end