Class: Mageo::Polyhedron

Inherits:
Object
  • Object
show all
Defined in:
lib/mageo/polyhedron.rb

Overview

多面体を表現する抽象クラス。 面は必ず三角形で、たとえば四角形も2つの三角形であると考える。 initialize メソッドは subclass で再定義する。 subclass の注意点。

- 凸包であることを前提とする。
  チェック機構は Mageo::Polyhedron クラスで持っているべきだが、面倒なので後回し。
  3次元凸包判定の方法をぐぐったが、これといったものが見つからない。
- 定義された面同士の間に隙間がないことを前提とする。
  チェック機構は Mageo::Polyhedron クラスで持っているべきだが、面倒なので後回し。
- 頂点リスト @vertices と、面リスト @vertex_indices_of_triangles を持つ。
  ただし、@vertex_indices_of_triangles は Mageo::Triangle クラスインスタンスではなく、
  @vertices 内の index。
  see Mageo::Tetrahedron.rb
- メインのテストは 四面体 Mageo::Tetrahedron クラスで行っている。

Direct Known Subclasses

Octahedron, Tetrahedron

Defined Under Namespace

Classes: TypeError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePolyhedron

initialize で例外を返すことでインスタンスを生成できない抽象クラスを表現。 subclass で再定義する。

Raises:

  • (NotImplementedError)


29
30
31
# File 'lib/mageo/polyhedron.rb', line 29

def initialize()
  raise NotImplementedError, "need to define `initialize'"
end

Instance Attribute Details

#verticesObject (readonly)

Returns the value of attribute vertices.



23
24
25
# File 'lib/mageo/polyhedron.rb', line 23

def vertices
  @vertices
end

Instance Method Details

#centerObject

各頂点の座標の平均値を返す。



86
87
88
89
90
91
92
# File 'lib/mageo/polyhedron.rb', line 86

def center
  tmp = Mageo::Vector3D[ 0.0, 0.0, 0.0 ]
  @vertices.each do |vertex|
    tmp += vertex
  end
  return tmp * ( 1.0 / @vertices.size.to_f ) # 座標の平均の算出
end

#edgesObject



33
34
35
36
37
38
39
40
41
# File 'lib/mageo/polyhedron.rb', line 33

def edges
  results = []
  edges = triangles.each do |triangle|
    triangle.edges.each do |edge|
      results << edge unless results.include_eql?(edge)
    end
  end
  return results
end

#include?(pos, tolerance = 0.0) ⇒ Boolean

Returns:

  • (Boolean)

Raises:



61
62
63
64
65
66
67
68
69
70
71
# File 'lib/mageo/polyhedron.rb', line 61

def include?(pos, tolerance = 0.0)
  raise TypeError if pos.class == Mageo::Vector3DInternal

  return true if inside?( pos )
  triangles.each do |triangle|
    #pp pos
    #pp triangle
    return true if triangle.include?(pos.to_v3d, tolerance)
  end
  return false
end

#inside?(pos) ⇒ Boolean

面で囲まれた空間の中にあれば true を返す。

Returns:

  • (Boolean)

Raises:



51
52
53
54
55
56
57
58
59
# File 'lib/mageo/polyhedron.rb', line 51

def inside?( pos )
  raise TypeError if pos.class == Mageo::Vector3DInternal

  result = true
  triangles.each do |triangle|
    result = false unless triangle.same_side?( center, pos.to_v3d )
  end
  return result
end

#shared_vertices(other, tolerance = 0.0) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
# File 'lib/mageo/polyhedron.rb', line 106

def shared_vertices(other, tolerance = 0.0)
  results = []
  @vertices.each do |sv|
    flag = false
    other.vertices.each do |ov|
      flag = true if (ov - sv).r <= tolerance
    end
    results << sv if flag
  end
  results
end

#translate(vector) ⇒ Object



100
101
102
103
104
# File 'lib/mageo/polyhedron.rb', line 100

def translate(vector)
  result = Marshal.load(Marshal.dump(self))
  result.translate! vector
  result
end

#translate!(vector) ⇒ Object



94
95
96
97
98
# File 'lib/mageo/polyhedron.rb', line 94

def translate!(vector)
  @vertices.map! do |pos|
    pos + vector
  end
end

#trianglesObject



43
44
45
46
47
48
# File 'lib/mageo/polyhedron.rb', line 43

def triangles
  results = @vertex_indices_of_triangles.map do |indices|
    Mageo::Triangle.new( indices.map{|i| @vertices[i] } )
  end
  return results
end

#volumeObject

体積を返す。



74
75
76
77
78
79
80
81
82
83
# File 'lib/mageo/polyhedron.rb', line 74

def volume
  result = 0.0
  @vertex_indices_of_triangles.each do |tri_vertices|
    vectors =  tri_vertices.map { |i| @vertices[i] - center }
    volume = Mageo::Vector3D.scalar_triple_product( *vectors ).abs
    volume /= 6.0
    result += volume
  end
  return result
end