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  - 反転する
  false - 反転しない

オブジェクトの生成

Overloads:

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

    Parameters:

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

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

    Parameters:

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

    range = Range(first…last) と同じ

    Parameters:

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

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

    Parameters:

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

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

    Parameters:

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

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

    Parameters:

    • note (Array<Array<Comparable, Boolean>>)
      • Comparable - 端点

      • Boolean

        @reverse == true の場合
          true  - 範囲に含まない
          false - 範囲に含む
        @reverse == false の場合
          true  - 範囲に含む
          false - 範囲に含まない
        


317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
# File 'lib/when_exe/parts/geometric_complex.rb', line 317

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, last]
    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 で定義されていないメソッドは
処理を first (type: When::TM::(Temporal)Position) に委譲する


438
439
440
441
442
443
444
445
# File 'lib/when_exe/parts/geometric_complex.rb', line 438

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)に対応する

Returns:

  • (Array<Array<Comparable, Boolean>>)
    • Comparable - 端点

    • Boolean

      @reverse == true の場合
        true  - 範囲に含まない
        false - 範囲に含む
      @reverse == false の場合
        true  - 範囲に含む
        false - 範囲に含まない
      


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

def node
  @node
end

#reverseBoolean (readonly)

Note:

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

範囲の反転

Returns:

  • (Boolean)
    true - 反転する
    false - 反転しない


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

def reverse
  @reverse
end

Instance Method Details

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

共通集合

Parameters:

Returns:



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

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

#+(duration) ⇒ When::Parts::GeometricComplex

平行移動(加算)

Parameters:

Returns:



255
256
257
258
259
260
261
# File 'lib/when_exe/parts/geometric_complex.rb', line 255

def +(duration)
  self.class.new(@node.map {|node|
    new_node     = node.dup
    new_node[0] += duration
    new_node
  }, @reverse)
end

#-(duration) ⇒ When::Parts::GeometricComplex

平行移動(減算)

Parameters:

Returns:



269
270
271
272
273
274
275
# File 'lib/when_exe/parts/geometric_complex.rb', line 269

def -(duration)
  self.class.new(@node.map {|node|
    new_node     = node.dup
    new_node[0] -= duration
    new_node
  }, @reverse)
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 を比較する

Parameters:

  • other (Comparable)

    比較対象

Returns:

  • (Integer)

    比較結果を 負, 0, 正の値で返す



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

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

#_include?(other) ⇒ Boolean

Enumerator._exclude 専用

Returns:

  • (Boolean)


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

#apply_delayed_options(options) ⇒ When::Parts::GeometricComplex

オブジェクト変換オプションの遅延適用

Parameters:

  • options (Hash)

    以下の通り

Options Hash (options):

Returns:



236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/when_exe/parts/geometric_complex.rb', line 236

def apply_delayed_options(options)
  last_node = nil
  self.class.new(@node.map {|node|
    point, flag, range = node
    if range && last_node
      [last_node + range, flag, range]
    else
       last_node = point.apply_delayed_options(options)
      [last_node, flag]
    end
  }, @reverse)
end

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

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

Parameters:

  • index (Integer) (defaults to: -1))

    端点の番号(デフォルト : -1 - 最大の端点)

Returns:

  • (Boolean)
    true - 含まれる
    false - 含まれない


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 を返す。

最小の端点

Parameters:

  • default (Comparable) (defaults to: nil)

    端点が-∞の場合に返すべき値(指定がなければ nil)

Returns:

  • (Comparable)

    最小の端点



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 と誤判断する。実行速度上の制約もあり、現時点では対策しない。

範囲に含まれるか?

Parameters:

  • other (Comparable)

    判断する Comparable

Returns:

  • (Boolean)
    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 を返す

最大の端点

Parameters:

  • default (Comparable) (defaults to: nil)

    端点が+∞場合に返すべき値(指定がなければ nil)

Returns:

  • (Comparable)

    最大の端点



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 を返す

分解能

Returns:

  • (Integer)

    最小の端点の分解能を返す



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 オブジェクトに変換する

Parameters:

Returns:



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

和集合

Parameters:

Returns:



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