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 - 範囲に含まない
        

252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
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
# File 'lib/when_exe/parts/geometric_complex.rb', line 252

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
    super(self.first, self.last, exclude_end?) if self.first && self.last
    return

  when Array
    @node = args[0]
    super(self.first, self.last, exclude_end?) if self.first && self.last
    return

  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, self.last, exclude_end?) if first && last
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) に委譲する

375
376
377
378
379
380
381
382
# File 'lib/when_exe/parts/geometric_complex.rb', line 375

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 - 範囲に含まない
      

45
46
47
# File 'lib/when_exe/parts/geometric_complex.rb', line 45

def node
  @node
end

#reverseBoolean (readonly)

Note:

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

範囲の反転

Returns:

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

28
29
30
# File 'lib/when_exe/parts/geometric_complex.rb', line 28

def reverse
  @reverse
end

Instance Method Details

#[email protected]When::Parts::GeometricComplex

範囲を反転する


115
116
117
# File 'lib/when_exe/parts/geometric_complex.rb', line 115

def [email protected]
  GeometricComplex.new(self, true)
end

#<=>(other) ⇒ Integer

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

Parameters:

  • other (Comparable)

    比較対象

Returns:

  • (Integer)

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


125
126
127
# File 'lib/when_exe/parts/geometric_complex.rb', line 125

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

#_include?(other) ⇒ Boolean

Enumerator._exclude 専用

Returns:

  • (Boolean)

203
204
205
206
207
208
209
210
# File 'lib/when_exe/parts/geometric_complex.rb', line 203

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

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

Parameters:

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

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

Returns:

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

96
97
98
# File 'lib/when_exe/parts/geometric_complex.rb', line 96

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)

    最小の端点


57
58
59
60
61
62
63
64
# File 'lib/when_exe/parts/geometric_complex.rb', line 57

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 - 範囲に含まれない

191
192
193
194
195
196
197
198
# File 'lib/when_exe/parts/geometric_complex.rb', line 191

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)

    最大の端点


77
78
79
80
81
82
83
84
85
# File 'lib/when_exe/parts/geometric_complex.rb', line 77

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)

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


107
108
109
# File 'lib/when_exe/parts/geometric_complex.rb', line 107

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

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

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

Parameters:

Returns:


160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/when_exe/parts/geometric_complex.rb', line 160

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)
end

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

和集合

Parameters:

Returns:


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

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