Class: When::Parts::GeometricComplex

Inherits:
Range
  • Object
show all
Includes:
Comparable
Defined in:
lib/when_exe/parts/geometric_complex.rb

Overview

任意個の端点から構成する [Range] の subclass

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(range, reverse = false) ⇒ GeometricComplex #initialize(point, reverse = false) ⇒ GeometricComplex #initialize(first, last, reverse = false) ⇒ GeometricComplex #initialize(first, duration, reverse = false) ⇒ GeometricComplex #initialize(other, reverse = false) ⇒ GeometricComplex #initialize(node, reverse = false) ⇒ GeometricComplex

Note:

すべての呼び出しパターンに共通の最終引数 reverse を付けることができる

reverse [Boolean]
  true  - 

オブジェクトの生成

Overloads:

  • #initialize(point, reverse = false) ⇒ GeometricComplex

    range = Range(point..point) と同じ

  • #initialize(first, last, reverse = false) ⇒ GeometricComplex

    range = Range(first…last) と同じ

  • #initialize(first, duration, reverse = false) ⇒ GeometricComplex

    range = Range(first…(first+duration)) と同じ

  • #initialize(other, reverse = false) ⇒ GeometricComplex

    もとの When::Parts::GeometricComplex のコピー

  • #initialize(node, reverse = false) ⇒ GeometricComplex

    指定した node 構造の When::Parts::GeometricComplex を生成



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/when_exe/parts/geometric_complex.rb', line 267

def initialize(*args)

  @reverse = (args[-1]==true || args[-1]==false) ? args.pop : false

  case args[0]
  when GeometricComplex
    @node     = args[0].node
    @reverse ^= args[0].reverse
    return super(self.first||-Float::INFINITY, self.last||+Float::INFINITY, exclude_end?)

  when Array
    @node = args[0]
    return super(self.first||-Float::INFINITY, self.last||+Float::INFINITY, exclude_end?)

  when Range
    first = [args[0].first, true]
    last  = [args[0].last, !args[0].exclude_end?]

  when Comparable
    first, last, rest = args
    raise ArgumentError, "Too many argument: #{rest}" if rest
    first = [first, true]
    case last
    when Comparable         ; last = [last, false]
    when When::TM::Duration ; last = [first[0] + last, false]
    when nil                ; last = first
    else ; raise TypeError, "Irregal GeometricComplex Type for last element: #{last.class}"
    end

  when nil ;
  else ; raise TypeError, "Irregal GeometricComplex Type: #{first.class}"
  end

  first, last = last, first if (first && last && first[0] > last[0])
  @node = []
  @node << first if first
  @node << last  if last
  super(self.first||-Float::INFINITY, self.last||+Float::INFINITY, exclude_end?)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object (private)

その他のメソッド

When::Parts::GeometricComplex 


388
389
390
391
392
393
394
395
# File 'lib/when_exe/parts/geometric_complex.rb', line 388

def method_missing(name, *args, &block)
  self.class.module_eval %Q{
    def #{name}(*args, &block)
      first.send("#{name}", *args, &block)
    end
  } unless When::Parts::MethodCash.escape(name)
  first.send(name, *args, &block)
end

Instance Attribute Details

#nodeArray<Array<Comparable, Boolean>> (readonly)

When::Parts::GeometricComplex を構成する端点の Array

Examples:

[[3,true],] は Range(3…4)に対応する




48
49
50
# File 'lib/when_exe/parts/geometric_complex.rb', line 48

def node
  @node
end

#reverseBoolean (readonly)

Note:

無限の過去(-Infinity)を範囲に含むか否かと同値である

範囲の反転



31
32
33
# File 'lib/when_exe/parts/geometric_complex.rb', line 31

def reverse
  @reverse
end

Instance Method Details

#&(other) ⇒ When::Parts::GeometricComplex

共通集合



162
163
164
# File 'lib/when_exe/parts/geometric_complex.rb', line 162

def &(other)
  -(-self | -other)
end

#-@When::Parts::GeometricComplex

範囲を反転する



118
119
120
# File 'lib/when_exe/parts/geometric_complex.rb', line 118

def -@
  GeometricComplex.new(self, true)
end

#<=>(other) ⇒ Integer

最小の端点と other を比較する



128
129
130
# File 'lib/when_exe/parts/geometric_complex.rb', line 128

def <=>(other)
  first <=> other
end

#_include?(other) ⇒ Boolean

Enumerator._exclude 専用



218
219
220
221
222
223
224
225
# File 'lib/when_exe/parts/geometric_complex.rb', line 218

def _include?(other)
  if (other.kind_of?(Comparable) && !other.kind_of?(GeometricComplex))
    return _include_point?(other)
  else
    other = GeometricComplex.new(other) unless other.kind_of?(GeometricComplex)
    return _include_range?(other) && _include_point?(other.first)
  end
end

#exclude_end?(index = -1)) ⇒ Boolean

端点が範囲に含まれるか?



99
100
101
# File 'lib/when_exe/parts/geometric_complex.rb', line 99

def exclude_end?(index=-1)
  (@node.length==0) ? nil : !@node[index][1] ^ @reverse
end

#first(default = nil) ⇒ Comparable Also known as: begin

Note:

含むか否かに関わらず、最小の端点を返す。default が指定されているが有効な区間がない場合、nil を返す。

最小の端点



60
61
62
63
64
65
66
67
# File 'lib/when_exe/parts/geometric_complex.rb', line 60

def first(default=nil)
  return (@node.length==0) ? nil : @node[0][0] unless default # 互換性
  if reverse
    return default
  else
    (@node.length==0) ? nil : @node[0][0]
  end
end

#include?(other) ⇒ Boolean Also known as: ===

Note:

制限事項When::TM::TopologicalComplex どうしの包含判定は、和集合がもとの範囲と等しいかで判断している。分解能が When::SYSTEM でない場合、論理的には等しいものが、内部表現が異なるために等しくないとみなされる事があり、その場合 true であるべきものを false と誤判断する。実行速度上の制約もあり、現時点では対策しない。

範囲に含まれるか?



206
207
208
209
210
211
212
213
# File 'lib/when_exe/parts/geometric_complex.rb', line 206

def include?(other)
  if (other.kind_of?(Comparable) && !other.kind_of?(GeometricComplex))
    return (_include_point?(other) != false)
  else
    other = GeometricComplex.new(other) unless other.kind_of?(GeometricComplex)
    return _include_range?(other)
  end
end

#last(default = nil) ⇒ Comparable Also known as: end

Note:

含むか否かに関わらず、最大の端点を返すdefault が指定されているが有効な区間がない場合、nil を返す

最大の端点



80
81
82
83
84
85
86
87
88
# File 'lib/when_exe/parts/geometric_complex.rb', line 80

def last(default=nil)
  return (@node.length==0) ? nil : @node[-1][0] unless default # 互換性
  if reverse
    return (@node.length[0]==0) ? default : @node[-1][0]
  else
    return nil if (@node.length==0)
    return (@node.length[0]==1) ? default : @node[-1][0]
  end
end

#precisionInteger

Note:

分解能がない場合は、When::SYSTEM を返す

分解能



110
111
112
# File 'lib/when_exe/parts/geometric_complex.rb', line 110

def precision
  @node[0] && @node[0][0].respond_to?(:precision) ? @node[0][0].precision : When::SYSTEM
end

#to_tm_object(options = {}) ⇒ When::TM::Node, ...

ISO19108 の TM オブジェクトに変換する



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/when_exe/parts/geometric_complex.rb', line 173

def to_tm_object(options={})
  return nil unless !@reverse && @node.length>0 && @node.length[0]==0
  objects    = []
  primitives = @node.dup
  while (primitives) do
    first, last, primitives = primitives
    if (first[0].eql?(last[0]))
      objects = When::TM::Node.new(When::TM::Instant.new(When.when?(first[0],options)))
    else
      objects = When::TM::Edge.new(When::TM::Node.new(When::TM::Instant.new(When.when?(first[0],options))),
                                   When::TM::Node.new(When::TM::Instant.new(When.when?(last[0],options))))
    end
  end
  return objects[0] if objects.length==1
  return When::TM::TopologicalComplex.new(objects)
rescue NameError
  raise NameError, "Please require 'when_exe' to use Temporal Objects Package"
end

#|(other) ⇒ When::Parts::GeometricComplex

和集合



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/when_exe/parts/geometric_complex.rb', line 138

def |(other)
  other = GeometricComplex.new(other) unless other.kind_of?(GeometricComplex)
  return self if self.reverse && self.node.length==0
  return other | self if !self.reverse && other.reverse
  copy = self.node.dup
  ref  = other.node.dup
  max  = _max(copy.shift.dup, ref.shift.dup) if (other.reverse)
  rev  = max ? false : @reverse
  while (ref.length > 0) do
    first, last, *ref = ref
    updated  = _upper(copy, first, rev)
    updated += _lower(copy, last, rev) if last
    copy = updated
  end
  copy = _lower(copy, max, true) if max
  return GeometricComplex.new(copy, self.reverse)
end