extract_curves 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) 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/cstr.c +82 -0
  18. data/ruby_ext/pav/cstr.h +17 -0
  19. data/ruby_ext/pav/extconf.rb +22 -0
  20. data/ruby_ext/pav/pav.c +162 -0
  21. data/ruby_ext/pav/pgtk.c +40 -0
  22. data/ruby_ext/pav/pgtk.h +14 -0
  23. data/ruby_ext/pav/pix.c +806 -0
  24. data/ruby_ext/pav/pix.h +236 -0
  25. data/ruby_ext/pav/t.rb +35 -0
  26. data/ruby_ext/pav/t1.rb +35 -0
  27. data/ruby_libs/CVS/Entries +1 -0
  28. data/ruby_libs/CVS/Repository +1 -0
  29. data/ruby_libs/CVS/Root +1 -0
  30. data/ruby_libs/pav/CVS/Entries +20 -0
  31. data/ruby_libs/pav/CVS/Repository +1 -0
  32. data/ruby_libs/pav/CVS/Root +1 -0
  33. data/ruby_libs/pav/attr_cache.rb +211 -0
  34. data/ruby_libs/pav/attr_cache.t1.rb +32 -0
  35. data/ruby_libs/pav/cache.rb +31 -0
  36. data/ruby_libs/pav/dbg_log.rb +458 -0
  37. data/ruby_libs/pav/floatsio.rb +53 -0
  38. data/ruby_libs/pav/generator_cache.rb +165 -0
  39. data/ruby_libs/pav/gtk/CVS/Entries +4 -0
  40. data/ruby_libs/pav/gtk/CVS/Repository +1 -0
  41. data/ruby_libs/pav/gtk/CVS/Root +1 -0
  42. data/ruby_libs/pav/gtk/button.rb +130 -0
  43. data/ruby_libs/pav/gtk/icons.rb +87 -0
  44. data/ruby_libs/pav/gtk/toolbar.rb +192 -0
  45. data/ruby_libs/pav/heap.rb +54 -0
  46. data/ruby_libs/pav/icons/CVS/Entries +17 -0
  47. data/ruby_libs/pav/icons/CVS/Repository +1 -0
  48. data/ruby_libs/pav/icons/CVS/Root +1 -0
  49. data/ruby_libs/pav/icons/alt_handle.xcf +0 -0
  50. data/ruby_libs/pav/icons/alt_handle.xpm +3832 -0
  51. data/ruby_libs/pav/icons/alt_handle_hover.xcf +0 -0
  52. data/ruby_libs/pav/icons/alt_handle_hover.xpm +3368 -0
  53. data/ruby_libs/pav/icons/alt_handle_pressed.xcf +0 -0
  54. data/ruby_libs/pav/icons/alt_handle_pressed.xpm +3828 -0
  55. data/ruby_libs/pav/icons/extract_curves/CVS/Entries +6 -0
  56. data/ruby_libs/pav/icons/extract_curves/CVS/Repository +1 -0
  57. data/ruby_libs/pav/icons/extract_curves/CVS/Root +1 -0
  58. data/ruby_libs/pav/icons/extract_curves/extract_curves-icon-rgb.ppm +14 -0
  59. data/ruby_libs/pav/icons/extract_curves/extract_curves-logo-rgb.gif +0 -0
  60. data/ruby_libs/pav/icons/extract_curves/extract_curves-logo-rgb.xcf +0 -0
  61. data/ruby_libs/pav/icons/extract_curves/trace_mark.xcf +0 -0
  62. data/ruby_libs/pav/icons/extract_curves/trace_mark.xpm +38 -0
  63. data/ruby_libs/pav/icons/handle.xcf +0 -0
  64. data/ruby_libs/pav/icons/handle.xpm +213 -0
  65. data/ruby_libs/pav/icons/next.xpm +29 -0
  66. data/ruby_libs/pav/icons/next_hover.xpm +315 -0
  67. data/ruby_libs/pav/icons/next_pressed.xpm +144 -0
  68. data/ruby_libs/pav/icons/prev.xpm +29 -0
  69. data/ruby_libs/pav/icons/prev_hover.xpm +315 -0
  70. data/ruby_libs/pav/icons/prev_pressed.xpm +144 -0
  71. data/ruby_libs/pav/icons/vnext.xpm +29 -0
  72. data/ruby_libs/pav/icons/vprev.xpm +29 -0
  73. data/ruby_libs/pav/numeric/CVS/Entries +2 -0
  74. data/ruby_libs/pav/numeric/CVS/Repository +1 -0
  75. data/ruby_libs/pav/numeric/CVS/Root +1 -0
  76. data/ruby_libs/pav/numeric/ext.rb +13 -0
  77. data/ruby_libs/pav/pav_find.rb +90 -0
  78. data/ruby_libs/pav/pix.rb +402 -0
  79. data/ruby_libs/pav/pix/CVS/Entries +11 -0
  80. data/ruby_libs/pav/pix/CVS/Repository +1 -0
  81. data/ruby_libs/pav/pix/CVS/Root +1 -0
  82. data/ruby_libs/pav/pix/aapix.rb +378 -0
  83. data/ruby_libs/pav/pix/blob.rb +543 -0
  84. data/ruby_libs/pav/pix/circle.rb +73 -0
  85. data/ruby_libs/pav/pix/contour.rb +644 -0
  86. data/ruby_libs/pav/pix/contour/CVS/Entries +5 -0
  87. data/ruby_libs/pav/pix/contour/CVS/Repository +1 -0
  88. data/ruby_libs/pav/pix/contour/CVS/Root +1 -0
  89. data/ruby_libs/pav/pix/contour/calc_situations.rb +9 -0
  90. data/ruby_libs/pav/pix/contour/carp_calc.rb +212 -0
  91. data/ruby_libs/pav/pix/contour/situations.dmp +0 -0
  92. data/ruby_libs/pav/pix/contour/situations.rb +21 -0
  93. data/ruby_libs/pav/pix/curve.rb +1508 -0
  94. data/ruby_libs/pav/pix/img_obj.rb +751 -0
  95. data/ruby_libs/pav/pix/node.rb +712 -0
  96. data/ruby_libs/pav/pix/node_grp.rb +853 -0
  97. data/ruby_libs/pav/pix/shaved_core.rb +534 -0
  98. data/ruby_libs/pav/pix/subpix.rb +212 -0
  99. data/ruby_libs/pav/rand_accessible.rb +16 -0
  100. data/ruby_libs/pav/rangeset.rb +63 -0
  101. data/ruby_libs/pav/search.rb +210 -0
  102. data/ruby_libs/pav/set.rb +20 -0
  103. data/ruby_libs/pav/string/CVS/Entries +6 -0
  104. data/ruby_libs/pav/string/CVS/Repository +1 -0
  105. data/ruby_libs/pav/string/CVS/Root +1 -0
  106. data/ruby_libs/pav/string/bits.rb +523 -0
  107. data/ruby_libs/pav/string/ext.rb +58 -0
  108. data/ruby_libs/pav/string/observable.rb +155 -0
  109. data/ruby_libs/pav/string/text.rb +79 -0
  110. data/ruby_libs/pav/string/words.rb +42 -0
  111. data/ruby_libs/pav/sub_arr.rb +55 -0
  112. data/ruby_libs/pav/traced_obj.rb +79 -0
  113. metadata +161 -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