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,853 @@
1
+ require 'set'
2
+ require 'pav/pix'
3
+ require 'pav/pix/node'
4
+ require 'pav/pix/aapix'
5
+ require 'pav/attr_cache'
6
+ require 'pav/pix/img_obj'
7
+
8
+ module PPix
9
+
10
+ class GrpNodeConnProxyToExterior < NodeConn
11
+ def reverse(conn_0)
12
+ link = self.path.last
13
+ link.conn.reverse(link.node)
14
+ end
15
+ end
16
+
17
+ class NodeGrp < Set
18
+ def initialize(*args)
19
+ super(*args)
20
+ @cache_get_node_paths_to_exterior = {}
21
+ @cache_get_node_shortest_paths_to_exterior = {}
22
+ @cache_get_node_paths_to_entries = {}
23
+ @link_filter = proc { |link| self.include?(link.exit) }
24
+ end
25
+
26
+ alias_method :includes_node?, :include?
27
+ alias_method :nodes_to_a, :to_a
28
+ alias_method :node_cnt, :length
29
+ alias_method :each_node, :each
30
+
31
+ cache_get_lm! :get_node_paths_to_exterior,
32
+ :get_node_shortest_paths_to_exterior, :get_node_paths_to_entries
33
+
34
+ def get_all_links_to(node)
35
+ res = []
36
+ self.each { |m| m.conns.each_with_index { |cn,cn_i|
37
+ res << NodeLink.new(m,cn_i) if node.node_eql?(cn.exit)}}
38
+ res
39
+ end
40
+
41
+ def get_entries_grp
42
+ res = NodeGrp.new
43
+ self.each { |m|
44
+ if m.conns.detect { |conn| !self.include?(conn.exit) }
45
+ res << m
46
+ end
47
+ }
48
+ res
49
+ end
50
+
51
+ def get_terminals
52
+ known = {}
53
+ self.each { |m| known[m] = true }
54
+ terminals = []
55
+ self.each { |m| m.conns.each { |cn|
56
+ unless known.include?(cn.exit)
57
+ terminals << cn.exit
58
+ known[cn.exit] = true
59
+ end
60
+ }}
61
+ terminals
62
+ end
63
+
64
+ def get_vicinity_grp(max_distc)
65
+ res = NodeGrp.new(self)
66
+ tail = []
67
+ self.each { |m| tail.push([m, 0]) }
68
+ while !tail.empty?
69
+ nd, lev = *tail.pop
70
+ nd.conns.each { |cn|
71
+ if (n_lev = lev + cn.length) <= max_distc &&
72
+ !res.include?(cn.exit)
73
+ res << cn.exit
74
+ tail.push([cn.exit, n_lev])
75
+ end
76
+ }
77
+ end
78
+ res
79
+ end
80
+
81
+ def get_vicinity_grp_in_set(max_distc, incl_set)
82
+ res = NodeGrp.new(self)
83
+ tail = []
84
+ self.each { |m| tail.push([m, 0]) if incl_set.include?(m) }
85
+ while !tail.empty?
86
+ nd, lev = *tail.pop
87
+ nd.conns.each { |cn|
88
+ if (n_lev = lev + cn.length) <= max_distc &&
89
+ !res.include?(cn.exit) && incl_set.include?(cn.exit)
90
+ res << cn.exit
91
+ tail.push([cn.exit, n_lev])
92
+ end
93
+ }
94
+ end
95
+ res
96
+ end
97
+
98
+ cache_get! :get_entries_grp, :get_terminals
99
+
100
+ def get_node_paths_to_exterior(node, node_calc=nil)
101
+ node_calc = NodeCalc.new(node) unless node_calc
102
+ node_calc.link_filter = @link_filter
103
+ paths = []
104
+ self.each { |m|
105
+ path = node_calc.find_shortest_path_to_node(m)
106
+ m.conns.each_with_index { |conn, conn_i|
107
+ next if self.include?(conn.exit)
108
+ paths << path + [NodeLink.new(m, conn_i)]
109
+ }
110
+ }
111
+ paths
112
+ end
113
+
114
+ def get_node_shortest_paths_to_exterior(node, node_calc=nil)
115
+ #$PDbgLog.sig_call(self)
116
+ node_calc = NodeCalc.new(node) unless node_calc
117
+ node_calc.link_filter = @link_filter
118
+ paths = {}
119
+ self.each { |m|
120
+ path = node_calc.find_shortest_path_to_node(m)
121
+ path_len = path.get_length
122
+ m.conns.each_with_index { |conn, conn_i|
123
+ next if self.include?(conn.exit)
124
+ len = path_len + conn.length
125
+ next if paths.include?(conn.exit) &&
126
+ paths[conn.exit][1] <= len
127
+ paths[conn.exit] =
128
+ [path+[NodeLink.new(m,conn_i)], len]
129
+ }
130
+ }
131
+ res = []
132
+ paths.each_value { |p_spec| res << p_spec[0] }
133
+ #$PDbgLog.sig_return(res.inspect)
134
+ res
135
+ end
136
+
137
+ def get_node_paths_to_entries(node, node_calc=nil)
138
+ #$PDbgLog.sig_call(self)
139
+ node_calc = NodeCalc.new(node) unless node_calc
140
+ node_calc.link_filter = @link_filter
141
+ paths = []
142
+ self.each { |m| next if m.node_eql?(node)
143
+ if m.conns.detect { |conn| !self.include?(conn.exit) }
144
+ #$PDbgLog.print_msg "Entry #{m.coords_to_s}: "
145
+ paths << node_calc.find_shortest_path_to_node(m)
146
+ #$PDbgLog.puts_msg paths.last.to_s + '.'
147
+ end
148
+ }
149
+ #$PDbgLog.sig_return
150
+ paths
151
+ end
152
+
153
+ def self.get_node_vicinity_grp(node, max_distc)
154
+ res = NodeGrp.new
155
+ res << node
156
+ tail = [node, 0]
157
+ while !tail.empty?
158
+ nd, lev = *tail.pop
159
+ nd.conns.each { |cn|
160
+ if (n_lev = lev + cn.length) <= max_distc &&
161
+ !res.include?(cn.exit)
162
+ res << cn.exit
163
+ tail.push([cn.exit, n_lev])
164
+ end
165
+ }
166
+ end
167
+ res
168
+ end
169
+
170
+ def get_a_longest_path
171
+ #$PDbgLog.sig_call(self)
172
+ max_path = nil
173
+ max_path_len = -1
174
+ self.each { |m_0|
175
+ node_calc = NodeCalc.new(m_0)
176
+ node_calc.link_filter = @link_filter
177
+ self.each { |m_end| next if m_end.a_eql?(m_0)
178
+ # $PDbgLog.print_msg "m_0#{m_0.coords_to_s}, m_end#{m_end.
179
+ # coords_to_s}: "
180
+ path = node_calc.find_shortest_path_to_node(m_end)
181
+ #$PDbgLog.puts_msg path.to_s
182
+ if (len = path.get_length) > max_path_len
183
+ max_path = path; max_path_len = len
184
+ end
185
+ }
186
+ }
187
+ #$PDbgLog.sig_return
188
+ max_path
189
+ end
190
+
191
+ cache_get! :get_a_longest_path
192
+
193
+ def get_node_islands(dyke_set)
194
+ assigned = Set.new(dyke_set)
195
+ islands = []
196
+ dyke_set.each { |m| m.conns.each { |conn|
197
+ if self.include?(conn.exit) &&
198
+ !assigned.include?(conn.exit)
199
+ island = NodeGrp.new; island << conn.exit
200
+ tail = [conn.exit]
201
+ while !tail.empty?
202
+ node = tail.pop
203
+ node.conns.each { |cn|
204
+ if self.include?(cn.exit) &&
205
+ !assigned.include?(cn.exit)
206
+ island << cn.exit
207
+ assigned << cn.exit
208
+ tail.push(cn.exit)
209
+ end
210
+ }
211
+ end
212
+ end
213
+ } }
214
+ islands
215
+ end
216
+
217
+ def find_first_path_to(dest, max_distc=1.0/0.0)
218
+ return nil if max_distc < 0
219
+ if dest.kind_of?(Proc)
220
+ dest_proc = dest
221
+ else
222
+ dest_proc = proc { |nd| dest.node_eql?(nd) }
223
+ end
224
+ c_paths = {}
225
+ tail = PMinHeap.new { |a,b| a[1] <=> b[1] }
226
+ self.each { |m| c_paths[m] = [0, nil]; tail.push([m, 0]) }
227
+ while !tail.empty?
228
+ node, lev = *tail.pop
229
+ if dest_proc.call(node)
230
+ return NodeCalc.path_cache_get_path(node, c_paths)
231
+ end
232
+ next if c_paths.include?(node) && c_paths[node][0] <=lev
233
+ node.conns.each_with_index { |conn, conn_i|
234
+ if (c_lev = lev + conn.length) <= max_distc &&
235
+ !c_paths.include?(conn.exit) ||
236
+ c_paths[conn.exit][0] > c_lev
237
+ c_paths[conn.exit] = [c_lev, NodeLink.
238
+ new(node, conn_i)]
239
+ tail.push([conn.exit, c_lev])
240
+ end
241
+ }
242
+ end
243
+ nil
244
+ end
245
+
246
+ def get_islands_min_span_grp(islands)
247
+ return nil if islands.empty?
248
+ node2grp = {}
249
+ islands.each { |isl| isl.each { |m| node2grp[m] = isl } }
250
+ res = NodeGrp.new(islands.first)
251
+ tail = PMinHeap.new { |a,b| a[1] <=> b[1] }
252
+ c_paths = {}
253
+ res.each { |m| tail.push([m, 0]); c_paths[m] = [0, nil] }
254
+ grps_left = islands.length - 1
255
+ while grps_left > 0
256
+ lev, node = *tail.pop
257
+ node.conns.each_with_index { |conn, conn_i|
258
+ c_lev = lev + conn.length
259
+ if !c_paths.include?(conn.exit) ||
260
+ c_paths[conn.exit][0] > c_lev
261
+ if (grp = node2grp[conn.exit]) &&
262
+ grp.object_id != res.object_id
263
+ grp.each{|m| res << m; node2grp[m]=res
264
+ c_paths[m] = [0, nil]
265
+ tail.push([m, 0])
266
+ }
267
+ grps_left -= 1
268
+ to_link = c_paths[node][1]
269
+ while to_link
270
+ res << to_link.node
271
+ node2grp[to_link.node] = res
272
+ to_link=c_paths[to_link.node][1]
273
+ end
274
+ end
275
+ else
276
+ c_paths[conn.exit] =
277
+ [c_lev, NodeLink.new(node, conn_i)]
278
+ tail.push([c_lev, conn.exit])
279
+ end
280
+ }
281
+ end
282
+ res
283
+ end
284
+
285
+ def get_islands_min_span_paths(islands)
286
+ res = []
287
+ return res if islands.empty?
288
+ node2grp = {}
289
+ islands.each { |isl| isl.each { |m| node2grp[m] = isl } }
290
+ grp0 = NodeGrp.new(islands.first)
291
+ tail = PMinHeap.new { |a,b| a[1] <=> b[1] }
292
+ c_paths = {}
293
+ grp0.each { |m| tail.push([m, 0]); c_paths[m] = [0, nil] }
294
+ grps_left = islands.length - 1
295
+ while grps_left > 0
296
+ lev, node = *tail.pop
297
+ node.conns.each_with_index { |conn, conn_i|
298
+ next unless self.include?(conn.exit)
299
+ c_lev = lev + conn.length
300
+ if !c_paths.include?(conn.exit) ||
301
+ c_paths[conn.exit][0] > c_lev
302
+ if (grp = node2grp[conn.exit]) &&
303
+ grp.object_id != res.object_id
304
+ grp.each{|m| node2grp[m]=grp0
305
+ c_paths[m] = [0, nil]
306
+ tail.push([m, 0])
307
+ }
308
+ grps_left -= 1
309
+ path = NodePath.new
310
+ to_link = c_paths[node][1]
311
+ while to_link
312
+ path << to_link
313
+ node2grp[to_link.node] = grp0
314
+ to_link=c_paths[to_link.node][1]
315
+ end
316
+ path.reverse_links!
317
+ res << path
318
+ end
319
+ else
320
+ c_paths[conn.exit] =
321
+ [c_lev, NodeLink.new(node, conn_i)]
322
+ tail.push([c_lev, conn.exit])
323
+ end
324
+ }
325
+ end
326
+ res
327
+ end
328
+
329
+ def to_s
330
+ arr = self.to_a; arr.sort!
331
+ '{' + arr.join(', ') + '}'
332
+ end
333
+ end
334
+
335
+ class LinkGrpAsNodeSet
336
+ attr_reader :link_grp
337
+
338
+ def initialize(link_grp)
339
+ @link_grp = link_grp
340
+ end
341
+
342
+ def include?(node)
343
+ @link_grp.includes_node?(node)
344
+ end
345
+ end
346
+
347
+ class LinkGrp
348
+ def initialize
349
+ super()
350
+ @cache_get_node_paths_to_exterior = {}
351
+ @cache_get_node_paths_to_external_nodes = {}
352
+ @cache_get_node_shortest_paths_to_exterior = {}
353
+ @cache_get_node_shortest_paths_to_external_nodes = {}
354
+ @cache_get_node_paths_to_border = {}
355
+ @cache_get_node_paths_to_entries = {}
356
+ @node2links = {}
357
+ @link_filter = self.method('include?').to_proc
358
+ end
359
+
360
+ def add(link)
361
+ unless (links = @node2links[link.node])
362
+ links = @node2links[link.node] = []
363
+ end
364
+ links[link.conn_i] = link
365
+ end
366
+
367
+ def <<(link)
368
+ unless (links = @node2links[link.node])
369
+ links = @node2links[link.node] = []
370
+ end
371
+ links[link.conn_i] = link
372
+ self
373
+ end
374
+
375
+ def include?(link)
376
+ (links = @node2links[link.node]) && links[link.conn_i]
377
+ end
378
+
379
+ alias_method :member?, :include?
380
+
381
+ def includes_node?(node)
382
+ @node2links.include?(node)
383
+ end
384
+
385
+ alias_method :include_node?, :includes_node?
386
+
387
+ def each
388
+ @node2links.each_pair { |node, links|
389
+ links.each { |link| yield(link) if link } }
390
+ end
391
+
392
+ def each_node(&block)
393
+ @node2links.each_key(&block)
394
+ end
395
+
396
+ def to_a
397
+ res = []
398
+ self.each { |link| res << link }
399
+ res
400
+ end
401
+
402
+ def nodes_to_a
403
+ @node2links.keys
404
+ end
405
+
406
+ def nodes_to_node_grp
407
+ res = NodeGrp.new
408
+ self.each_node { |node| res << node }
409
+ res
410
+ end
411
+
412
+ def as_node_set
413
+ LinkGrpAsNodeSet.new(self)
414
+ end
415
+
416
+ def to_s
417
+ nodes = @node2links.keys; nodes.sort!
418
+ res = '{'
419
+ nodes.each { |node| res << node.to_s << ':'
420
+ @node2links[node].each_with_index { |link,link_i|
421
+ res << " #{link_i}" if link }
422
+ res << '; '
423
+ }
424
+ res[-2] ? res[-2,2] = '}' : res << '}'
425
+ res
426
+ end
427
+
428
+ def node_cnt
429
+ @node2links.length
430
+ end
431
+
432
+ def add_undir_path!(path)
433
+ path.each { |link| self << link
434
+ begin
435
+ self << link.reverse
436
+ rescue NoReverseLinkError
437
+ end
438
+ }
439
+ end
440
+
441
+ alias_method :add_undir_path, :add_undir_path!
442
+
443
+ cache_get_lm! :get_node_paths_to_exterior,
444
+ :get_node_paths_to_external_nodes,
445
+ :get_node_shortest_paths_to_exterior,
446
+ :get_node_shortest_paths_to_external_nodes,
447
+ :get_node_paths_to_border, :get_node_paths_to_entries
448
+
449
+ def get_all_links_to(node)
450
+ res = []
451
+ self.each { |m| res << m if node.node_eql?(node) }
452
+ res
453
+ end
454
+
455
+ def get_entries_grp
456
+ res = NodeGrp.new
457
+ @node2links.each_pair { |node, links|
458
+ node.conns.each_index { |conn_i|
459
+ unless links[conn_i]
460
+ res << node; break
461
+ end
462
+ }
463
+ }
464
+ res
465
+ end
466
+
467
+ def get_border_grp
468
+ res = NodeGrp.new
469
+ self.each_node { |node|
470
+ res << node if node.conns.detect { |conn|
471
+ !self.includes_node?(conn.exit) }
472
+ }
473
+ res
474
+ end
475
+
476
+ def get_terminals
477
+ known = {}
478
+ self.each_node { |node| known[node] = true }
479
+ terminals = []
480
+ self.each_node { |node| node.conns.each { |cn|
481
+ unless known.include?(cn.exit)
482
+ terminals << cn.exit
483
+ known[cn.exit] = true
484
+ end
485
+ }}
486
+ terminals
487
+ end
488
+
489
+ def get_vicinity_grp(max_distc)
490
+ res = NodeGrp.new(self)
491
+ tail = []
492
+ self.each_node { |node| tail.push([node, 0]) }
493
+ while !tail.empty?
494
+ nd, lev = *tail.pop
495
+ nd.conns.each { |cn|
496
+ if (n_lev = lev + cn.length) <= max_distc &&
497
+ !res.include?(cn.exit)
498
+ res << cn.exit
499
+ tail.push([cn.exit, n_lev])
500
+ end
501
+ }
502
+ end
503
+ res
504
+ end
505
+
506
+ cache_get! :get_entries_grp, :get_border_grp, :get_terminals
507
+
508
+ def get_node_paths_to_external_nodes(node, node_calc=nil)
509
+ node_calc = NodeCalc.new(node) unless node_calc
510
+ node_calc.link_filter = @link_filter
511
+ paths = []
512
+ self.each_node { |node|
513
+ path = node_calc.find_shortest_path_to_node(node)
514
+ node.conns.each_with_index { |conn, conn_i|
515
+ next if self.includes_node?(conn.exit)
516
+ paths << path + [NodeLink.new(node, conn_i)]
517
+ }
518
+ }
519
+ paths
520
+ end
521
+
522
+ def get_node_paths_to_exterior(node, node_calc=nil)
523
+ node_calc = NodeCalc.new(node) unless node_calc
524
+ node_calc.link_filter = @link_filter
525
+ paths = []
526
+ self.each_node { |node|
527
+ path = node_calc.find_shortest_path_to_node(node)
528
+ links = @node2links[node]
529
+ node.conns.each_with_index { |conn, conn_i|
530
+ next if links[conn_i]
531
+ paths << path + [NodeLink.new(node, conn_i)]
532
+ }
533
+ }
534
+ paths
535
+ end
536
+
537
+ def get_node_shortest_paths_to_external_nodes(node, node_calc=nil)
538
+ #$PDbgLog.sig_call(self)
539
+ node_calc = NodeCalc.new(node) unless node_calc
540
+ node_calc.link_filter = @link_filter
541
+ paths = {}
542
+ self.each_node { |node|
543
+ path = node_calc.find_shortest_path_to_node(node)
544
+ path_len = path.get_length
545
+ node.conns.each_with_index { |conn, conn_i|
546
+ next if self.includes_node?(conn.exit)
547
+ len = path_len + conn.length
548
+ next if paths.include?(conn.exit) &&
549
+ paths[conn.exit][1] <= len
550
+ paths[conn.exit] =
551
+ [path+[NodeLink.new(node,conn_i)], len]
552
+ }
553
+ }
554
+ res = []
555
+ paths.each_value { |p_spec| res << p_spec[0] }
556
+ #$PDbgLog.sig_return(res.inspect)
557
+ res
558
+ end
559
+
560
+ def get_node_shortest_paths_to_exterior(node, node_calc=nil)
561
+ #$PDbgLog.sig_call(self)
562
+ node_calc = NodeCalc.new(node) unless node_calc
563
+ node_calc.link_filter = @link_filter
564
+ paths = {}
565
+ self.each_node { |node|
566
+ path = node_calc.find_shortest_path_to_node(node)
567
+ path_len = path.get_length
568
+ links = @node2links[node]
569
+ node.conns.each_with_index { |conn, conn_i|
570
+ next if links[conn_i]
571
+ len = path_len + conn.length
572
+ link = NodeLink.new(node, conn_i)
573
+ next if paths.include?(link) &&
574
+ paths[link][1] <= len
575
+ paths[link] = [path + [link], len]
576
+ }
577
+ }
578
+ res = []
579
+ paths.each_value { |p_spec| res << p_spec[0] }
580
+ #$PDbgLog.sig_return(res.inspect)
581
+ res
582
+ end
583
+
584
+ def get_node_paths_to_border(node, node_calc=nil)
585
+ node_calc = NodeCalc.new(node) unless node_calc
586
+ node_calc.link_filter = @link_filter
587
+ paths = []
588
+ self.each_node { |nd| next if nd.node_eql?(node)
589
+ if nd.conns.detect { |conn| !self.includes_node?(conn.exit) }
590
+ path = node_calc.find_shortest_path_to_node(nd)
591
+ paths << path
592
+ end
593
+ }
594
+ paths
595
+ end
596
+
597
+ def get_node_paths_to_entries(node, node_calc=nil)
598
+ node_calc = NodeCalc.new(node) unless node_calc
599
+ node_calc.link_filter = @link_filter
600
+ paths = []
601
+ self.each_node { |nd| next if nd.node_eql?(node)
602
+ links = @node2links[nd]
603
+ nd.conns.each_index { |conn_i|
604
+ unless links[conn_i]
605
+ path = node_calc.find_shortest_path_to_node(nd)
606
+ paths << path
607
+ break
608
+ end
609
+ }
610
+ }
611
+ paths
612
+ end
613
+
614
+ def get_a_longest_path
615
+ #$PDbgLog.sig_call(self)
616
+ max_path = nil
617
+ max_path_len = 0
618
+ node_grp = self.nodes_to_node_grp
619
+ end_nodes = {}
620
+ self.each_node { |node| nd_end_nodes = node_grp.dup
621
+ nd_end_nodes.delete(node); end_nodes[node]=nd_end_nodes}
622
+ self.each_node { |start_node|
623
+ node_calc = NodeCalc.new(start_node)
624
+ node_calc.link_filter = @link_filter
625
+ end_nodes[start_node].each_node { |end_node|
626
+ #$PDbgLog.puts_msg "start_node#{start_node},end_node#{
627
+ # end_node}"
628
+ path = node_calc.find_shortest_path_to_node(end_node)
629
+ if (len = path.get_length) > max_path_len
630
+ max_path = path; max_path_len = len
631
+ end
632
+ node_calc.path_cache_each_path { |iter|
633
+ if (nd1 = iter.pop)
634
+ nd1 = nd1.node
635
+ while (nd2 = iter.pop)
636
+ end_nodes[nd1].delete(nd2=nd2.node)
637
+ end_nodes[nd2].delete(nd1)
638
+ end
639
+ end
640
+ }
641
+ }
642
+ }
643
+ #$PDbgLog.sig_return("max_path(#{max_path_len.inspect}): #{
644
+ # max_path ? max_path.to_s(1) : max_path.inspect}")
645
+ max_path
646
+ end
647
+
648
+ cache_get! :get_a_longest_path
649
+
650
+ def get_node_islands(dyke_set)
651
+ #$PDbgLog.sig_call(self)
652
+ #$PDbgLog.puts_msg self.to_s
653
+ #$PDbgLog.puts_msg 'Dyke set: ' + dyke_set.to_s
654
+ assigned = Set.new(dyke_set)
655
+ islands = []
656
+ dyke_set.each { |m|
657
+ #$PDbgLog.print_msg "m#{m} "
658
+ links = @node2links[m]
659
+ m.conns.each_with_index { |conn, conn_i|
660
+ if links[conn_i] && !assigned.include?(conn.exit)
661
+ island = NodeGrp.new; island << conn.exit
662
+ tail = [conn.exit]
663
+ while !tail.empty?
664
+ node = tail.pop
665
+ lks = @node2links[node]
666
+ node.conns.each_with_index { |cn, cn_i|
667
+ if lks[cn_i] && !assigned.include?(cn.exit)
668
+ island << cn.exit
669
+ assigned << cn.exit
670
+ tail.push(cn.exit)
671
+ end
672
+ }
673
+ end
674
+ end
675
+ }
676
+ }
677
+ #$PDbgLog.sig_return
678
+ islands
679
+ end
680
+
681
+ def get_link_islands(dyke_set)
682
+ #$PDbgLog.sig_call(self)
683
+ #$PDbgLog.puts_msg self.to_s
684
+ #$PDbgLog.puts_msg 'Dyke set: ' + dyke_set.to_s
685
+ assigned = Set.new(dyke_set)
686
+ islands = []
687
+ dyke_set.each { |m|
688
+ #$PDbgLog.print_msg "m#{m} "
689
+ links = @node2links[m]
690
+ m.conns.each_with_index { |conn, conn_i|
691
+ if links[conn_i] && !assigned.include?(conn.exit)
692
+ island = LinkGrp.new
693
+ tail = [conn.exit]
694
+ while !tail.empty?
695
+ node = tail.pop
696
+ lks = @node2links[node]
697
+ node.conns.each_with_index { |cn, cn_i|
698
+ if lks[cn_i] && !dyke_set.include?(cn.exit)
699
+ islands << NodeLink.new(node, cn_i)
700
+ tail.push(cn.exit) unless
701
+ assigned.include?(cn.exit)
702
+ end
703
+ }
704
+ assigned << node
705
+ end
706
+ end
707
+ }
708
+ }
709
+ #$PDbgLog.sig_return
710
+ islands
711
+ end
712
+
713
+ def find_first_path_to(dest, max_distc=1.0/0.0)
714
+ return nil if max_distc < 0
715
+ if dest.kind_of?(Proc)
716
+ dest_proc = dest
717
+ else
718
+ dest_proc = proc { |nd| dest.node_eql?(nd) }
719
+ end
720
+ c_paths = {}
721
+ tail = PMinHeap.new { |a,b| a[1] <=> b[1] }
722
+ self.each_node { |m| c_paths[m] = [0, nil]; tail.push([m, 0]) }
723
+ while !tail.empty?
724
+ node, lev = *tail.pop
725
+ if dest_proc.call(node)
726
+ return NodeCalc.path_cache_get_path(node, c_paths)
727
+ end
728
+ next if c_paths.include?(node) && c_paths[node][0] <=lev
729
+ node.conns.each_with_index { |conn, conn_i|
730
+ if (c_lev = lev + conn.length) <= max_distc &&
731
+ !c_paths.include?(conn.exit) ||
732
+ c_paths[conn.exit][0] > c_lev
733
+ c_paths[conn.exit] = [c_lev, NodeLink.
734
+ new(node, conn_i)]
735
+ tail.push([conn.exit, c_lev])
736
+ end
737
+ }
738
+ end
739
+ nil
740
+ end
741
+
742
+ def get_islands_min_span_grp(islands)
743
+ return nil if islands.empty?
744
+ node2grp = {}
745
+ islands.each { |isl| isl.each { |m| node2grp[m] = isl } }
746
+ res = NodeGrp.new(islands.first)
747
+ tail = PMinHeap.new { |a,b| a[1] <=> b[1] }
748
+ c_paths = {}
749
+ res.each { |m| tail.push([m, 0]); c_paths[m] = [0, nil] }
750
+ grps_left = islands.length - 1
751
+ while grps_left > 0
752
+ lev, node = *tail.pop
753
+ node.conns.each_with_index { |conn, conn_i|
754
+ c_lev = lev + conn.length
755
+ if !c_paths.include?(conn.exit) ||
756
+ c_paths[conn.exit][0] > c_lev
757
+ if (grp = node2grp[conn.exit]) &&
758
+ grp.object_id != res.object_id
759
+ grp.each{|m| res << m; node2grp[m]=res
760
+ c_paths[m] = [0, nil]
761
+ tail.push([m, 0])
762
+ }
763
+ grps_left -= 1
764
+ to_link = c_paths[node][1]
765
+ while to_link
766
+ res << to_link.node
767
+ node2grp[to_link.node] = res
768
+ to_link=c_paths[to_link.node][1]
769
+ end
770
+ end
771
+ else
772
+ c_paths[conn.exit] =
773
+ [c_lev, NodeLink.new(node, conn_i)]
774
+ tail.push([c_lev, conn.exit])
775
+ end
776
+ }
777
+ end
778
+ res
779
+ end
780
+
781
+ def get_islands_min_span_paths(islands)
782
+ res = []
783
+ return res if islands.empty?
784
+ node2grp = {}
785
+ islands.each { |isl| isl.each_node { |m| node2grp[m] = isl } }
786
+ grp0 = NodeGrp.new(islands.first)
787
+ tail = PMinHeap.new { |a,b| a[1] <=> b[1] }
788
+ c_paths = {}
789
+ grp0.each_node { |m| tail.push([m, 0]); c_paths[m] = [0, nil] }
790
+ grps_left = islands.length - 1
791
+ while grps_left > 0
792
+ lev, node = *tail.pop
793
+ links = @node2links[node]
794
+ node.conns.each_with_index { |conn, conn_i|
795
+ next unless links[conn_i]
796
+ c_lev = lev + conn.length
797
+ if !c_paths.include?(conn.exit) ||
798
+ c_paths[conn.exit][0] > c_lev
799
+ if (grp = node2grp[conn.exit]) &&
800
+ grp.object_id != res.object_id
801
+ grp.each{|m| node2grp[m]=grp0
802
+ c_paths[m] = [0, nil]
803
+ tail.push([m, 0])
804
+ }
805
+ grps_left -= 1
806
+ path = NodePath.new
807
+ to_link = c_paths[node][1]
808
+ while to_link
809
+ path << to_link
810
+ node2grp[to_link.node] = grp0
811
+ to_link=c_paths[to_link.node][1]
812
+ end
813
+ path.reverse_links!
814
+ res << path
815
+ end
816
+ else
817
+ c_paths[conn.exit] =
818
+ [c_lev, NodeLink.new(node, conn_i)]
819
+ tail.push([c_lev, conn.exit])
820
+ end
821
+ }
822
+ end
823
+ res
824
+ end
825
+ end
826
+
827
+ class NodePath
828
+ def to_node_grp
829
+ res = NodeGrp.new
830
+ self.each { |link| res << link.node }
831
+ res << self.exit
832
+ res
833
+ end
834
+
835
+ def to_link_grp
836
+ res = LinkGrp.new
837
+ self.each { |link| res << link }
838
+ res
839
+ end
840
+
841
+ def undir_to_link_grp
842
+ res = LinkGrp.new
843
+ self.each { |link| res << link
844
+ begin
845
+ res << link.reverse
846
+ rescue NoReverseLinkError
847
+ end
848
+ }
849
+ res
850
+ end
851
+ end
852
+
853
+ end