crystalcell 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,144 +5,144 @@
5
5
  # 原子記号は人間がつけたものだから。
6
6
  #
7
7
  class CrystalCell::Element
8
- # 全データを生成しておく。
9
- def initialize
10
- #原子記号, 原子番号, 周期, 族, 質量数(平均), イオン半径
11
- @symbol = Array.new #; @mass = Array.new @radius = Array.new
12
- #i = 1; @symbol[i], @mass[i], @radius[i] = 'H', 1.008, nil
13
- i = 0; @symbol[i] = nil
14
- i = 1; @symbol[i] = 'H'
15
- i = 2; @symbol[i] = 'He'
16
- i = 3; @symbol[i] = 'Li'
17
- i = 4; @symbol[i] = 'Be'
18
- i = 5; @symbol[i] = 'B'
19
- i = 6; @symbol[i] = 'C'
20
- i = 7; @symbol[i] = 'N'
21
- i = 8; @symbol[i] = 'O'
22
- i = 9; @symbol[i] = 'F'
23
- i = 10; @symbol[i] = 'Ne'
24
- i = 11; @symbol[i] = 'Na'
25
- i = 12; @symbol[i] = 'Mg'
26
- i = 13; @symbol[i] = 'Al'
27
- i = 14; @symbol[i] = 'Si'
28
- i = 15; @symbol[i] = 'P'
29
- i = 16; @symbol[i] = 'S'
30
- i = 17; @symbol[i] = 'Cl'
31
- i = 18; @symbol[i] = 'Ar'
32
- i = 19; @symbol[i] = 'K'
33
- i = 20; @symbol[i] = 'Ca'
34
- i = 21; @symbol[i] = 'Sc'
35
- i = 22; @symbol[i] = 'Ti'
36
- i = 23; @symbol[i] = 'V'
37
- i = 24; @symbol[i] = 'Cr'
38
- i = 25; @symbol[i] = 'Mn'
39
- i = 26; @symbol[i] = 'Fe'
40
- i = 27; @symbol[i] = 'Co'
41
- i = 28; @symbol[i] = 'Ni'
42
- i = 29; @symbol[i] = 'Cu'
43
- i = 30; @symbol[i] = 'Zn'
44
- i = 31; @symbol[i] = 'Ga'
45
- i = 32; @symbol[i] = 'Ge'
46
- i = 33; @symbol[i] = 'As'
47
- i = 34; @symbol[i] = 'Se'
48
- i = 35; @symbol[i] = 'Br'
49
- i = 36; @symbol[i] = 'Kr'
50
- i = 37; @symbol[i] = 'Rb'
51
- i = 38; @symbol[i] = 'Sr'
52
- i = 39; @symbol[i] = 'Y'
53
- i = 40; @symbol[i] = 'Zr'
54
- i = 41; @symbol[i] = 'Nb'
55
- i = 42; @symbol[i] = 'Mo'
56
- i = 43; @symbol[i] = 'Tc'
57
- i = 44; @symbol[i] = 'Ru'
58
- i = 45; @symbol[i] = 'Rh'
59
- i = 46; @symbol[i] = 'Pd'
60
- i = 47; @symbol[i] = 'Ag'
61
- i = 48; @symbol[i] = 'Cd'
62
- i = 49; @symbol[i] = 'In'
63
- i = 50; @symbol[i] = 'Sn'
64
- i = 51; @symbol[i] = 'Sb'
65
- i = 52; @symbol[i] = 'Te'
66
- i = 53; @symbol[i] = 'I'
67
- i = 54; @symbol[i] = 'Xe'
68
- i = 55; @symbol[i] = 'Cs'
69
- i = 56; @symbol[i] = 'Ba'
70
- i = 57; @symbol[i] = 'La'
71
- i = 58; @symbol[i] = 'Ce'
72
- i = 59; @symbol[i] = 'Pr'
73
- i = 60; @symbol[i] = 'Nd'
74
- i = 61; @symbol[i] = 'Pm'
75
- i = 62; @symbol[i] = 'Sm'
76
- i = 63; @symbol[i] = 'Eu'
77
- i = 64; @symbol[i] = 'Gd'
78
- i = 65; @symbol[i] = 'Tb'
79
- i = 66; @symbol[i] = 'Dy'
80
- i = 67; @symbol[i] = 'Ho'
81
- i = 68; @symbol[i] = 'Er'
82
- i = 69; @symbol[i] = 'Tm'
83
- i = 70; @symbol[i] = 'Yb'
84
- i = 71; @symbol[i] = 'Lu'
85
- i = 72; @symbol[i] = 'Hf'
86
- i = 73; @symbol[i] = 'Ta'
87
- i = 74; @symbol[i] = 'W'
88
- i = 75; @symbol[i] = 'Re'
89
- i = 76; @symbol[i] = 'Os'
90
- i = 77; @symbol[i] = 'Ir'
91
- i = 78; @symbol[i] = 'Pt'
92
- i = 79; @symbol[i] = 'Au'
93
- i = 80; @symbol[i] = 'Hg'
94
- i = 81; @symbol[i] = 'Tl'
95
- i = 82; @symbol[i] = 'Pb'
96
- i = 83; @symbol[i] = 'Bi'
97
- i = 84; @symbol[i] = 'Po'
98
- i = 85; @symbol[i] = 'At'
99
- i = 86; @symbol[i] = 'Rn'
100
- i = 87; @symbol[i] = 'Fr'
101
- i = 88; @symbol[i] = 'Ra'
102
- i = 89; @symbol[i] = 'Ac'
103
- i = 90; @symbol[i] = 'Th'
104
- i = 91; @symbol[i] = 'Pa'
105
- i = 92; @symbol[i] = 'U'
106
- i = 93; @symbol[i] = 'Np'
107
- i = 94; @symbol[i] = 'Pu'
108
- i = 95; @symbol[i] = 'Am'
109
- i = 96; @symbol[i] = 'Cm'
110
- i = 97; @symbol[i] = 'Bk'
111
- i = 98; @symbol[i] = 'Cf'
112
- i = 99; @symbol[i] = 'Es'
113
- i = 100; @symbol[i] = 'Fm'
114
- i = 101; @symbol[i] = 'Md'
115
- i = 102; @symbol[i] = 'No'
116
- i = 103; @symbol[i] = 'Lr'
117
- end
8
+ # 全データを生成しておく。
9
+ def initialize
10
+ #原子記号, 原子番号, 周期, 族, 質量数(平均), イオン半径
11
+ @symbol = Array.new #; @mass = Array.new @radius = Array.new
12
+ #i = 1; @symbol[i], @mass[i], @radius[i] = 'H', 1.008, nil
13
+ i = 0; @symbol[i] = nil
14
+ i = 1; @symbol[i] = 'H'
15
+ i = 2; @symbol[i] = 'He'
16
+ i = 3; @symbol[i] = 'Li'
17
+ i = 4; @symbol[i] = 'Be'
18
+ i = 5; @symbol[i] = 'B'
19
+ i = 6; @symbol[i] = 'C'
20
+ i = 7; @symbol[i] = 'N'
21
+ i = 8; @symbol[i] = 'O'
22
+ i = 9; @symbol[i] = 'F'
23
+ i = 10; @symbol[i] = 'Ne'
24
+ i = 11; @symbol[i] = 'Na'
25
+ i = 12; @symbol[i] = 'Mg'
26
+ i = 13; @symbol[i] = 'Al'
27
+ i = 14; @symbol[i] = 'Si'
28
+ i = 15; @symbol[i] = 'P'
29
+ i = 16; @symbol[i] = 'S'
30
+ i = 17; @symbol[i] = 'Cl'
31
+ i = 18; @symbol[i] = 'Ar'
32
+ i = 19; @symbol[i] = 'K'
33
+ i = 20; @symbol[i] = 'Ca'
34
+ i = 21; @symbol[i] = 'Sc'
35
+ i = 22; @symbol[i] = 'Ti'
36
+ i = 23; @symbol[i] = 'V'
37
+ i = 24; @symbol[i] = 'Cr'
38
+ i = 25; @symbol[i] = 'Mn'
39
+ i = 26; @symbol[i] = 'Fe'
40
+ i = 27; @symbol[i] = 'Co'
41
+ i = 28; @symbol[i] = 'Ni'
42
+ i = 29; @symbol[i] = 'Cu'
43
+ i = 30; @symbol[i] = 'Zn'
44
+ i = 31; @symbol[i] = 'Ga'
45
+ i = 32; @symbol[i] = 'Ge'
46
+ i = 33; @symbol[i] = 'As'
47
+ i = 34; @symbol[i] = 'Se'
48
+ i = 35; @symbol[i] = 'Br'
49
+ i = 36; @symbol[i] = 'Kr'
50
+ i = 37; @symbol[i] = 'Rb'
51
+ i = 38; @symbol[i] = 'Sr'
52
+ i = 39; @symbol[i] = 'Y'
53
+ i = 40; @symbol[i] = 'Zr'
54
+ i = 41; @symbol[i] = 'Nb'
55
+ i = 42; @symbol[i] = 'Mo'
56
+ i = 43; @symbol[i] = 'Tc'
57
+ i = 44; @symbol[i] = 'Ru'
58
+ i = 45; @symbol[i] = 'Rh'
59
+ i = 46; @symbol[i] = 'Pd'
60
+ i = 47; @symbol[i] = 'Ag'
61
+ i = 48; @symbol[i] = 'Cd'
62
+ i = 49; @symbol[i] = 'In'
63
+ i = 50; @symbol[i] = 'Sn'
64
+ i = 51; @symbol[i] = 'Sb'
65
+ i = 52; @symbol[i] = 'Te'
66
+ i = 53; @symbol[i] = 'I'
67
+ i = 54; @symbol[i] = 'Xe'
68
+ i = 55; @symbol[i] = 'Cs'
69
+ i = 56; @symbol[i] = 'Ba'
70
+ i = 57; @symbol[i] = 'La'
71
+ i = 58; @symbol[i] = 'Ce'
72
+ i = 59; @symbol[i] = 'Pr'
73
+ i = 60; @symbol[i] = 'Nd'
74
+ i = 61; @symbol[i] = 'Pm'
75
+ i = 62; @symbol[i] = 'Sm'
76
+ i = 63; @symbol[i] = 'Eu'
77
+ i = 64; @symbol[i] = 'Gd'
78
+ i = 65; @symbol[i] = 'Tb'
79
+ i = 66; @symbol[i] = 'Dy'
80
+ i = 67; @symbol[i] = 'Ho'
81
+ i = 68; @symbol[i] = 'Er'
82
+ i = 69; @symbol[i] = 'Tm'
83
+ i = 70; @symbol[i] = 'Yb'
84
+ i = 71; @symbol[i] = 'Lu'
85
+ i = 72; @symbol[i] = 'Hf'
86
+ i = 73; @symbol[i] = 'Ta'
87
+ i = 74; @symbol[i] = 'W'
88
+ i = 75; @symbol[i] = 'Re'
89
+ i = 76; @symbol[i] = 'Os'
90
+ i = 77; @symbol[i] = 'Ir'
91
+ i = 78; @symbol[i] = 'Pt'
92
+ i = 79; @symbol[i] = 'Au'
93
+ i = 80; @symbol[i] = 'Hg'
94
+ i = 81; @symbol[i] = 'Tl'
95
+ i = 82; @symbol[i] = 'Pb'
96
+ i = 83; @symbol[i] = 'Bi'
97
+ i = 84; @symbol[i] = 'Po'
98
+ i = 85; @symbol[i] = 'At'
99
+ i = 86; @symbol[i] = 'Rn'
100
+ i = 87; @symbol[i] = 'Fr'
101
+ i = 88; @symbol[i] = 'Ra'
102
+ i = 89; @symbol[i] = 'Ac'
103
+ i = 90; @symbol[i] = 'Th'
104
+ i = 91; @symbol[i] = 'Pa'
105
+ i = 92; @symbol[i] = 'U'
106
+ i = 93; @symbol[i] = 'Np'
107
+ i = 94; @symbol[i] = 'Pu'
108
+ i = 95; @symbol[i] = 'Am'
109
+ i = 96; @symbol[i] = 'Cm'
110
+ i = 97; @symbol[i] = 'Bk'
111
+ i = 98; @symbol[i] = 'Cf'
112
+ i = 99; @symbol[i] = 'Es'
113
+ i = 100; @symbol[i] = 'Fm'
114
+ i = 101; @symbol[i] = 'Md'
115
+ i = 102; @symbol[i] = 'No'
116
+ i = 103; @symbol[i] = 'Lr'
117
+ end
118
118
 
119
- # 原子記号から原子番号を取得。e.g., H から 1
120
- # 与えられたものが原子番号ならそのまま返す、ようにしたいがまだできてない。
121
- # リストに存在しなければ raise する。
122
- def getAtomicNumber( name )
123
- symbol = @symbol.index( name )
124
- raise "Symbol #{name} not found." if (symbol == nil || symbol == 0)
125
- symbol
126
- end
119
+ # 原子記号から原子番号を取得。e.g., H から 1
120
+ # 与えられたものが原子番号ならそのまま返す、ようにしたいがまだできてない。
121
+ # リストに存在しなければ raise する。
122
+ def getAtomicNumber( name )
123
+ symbol = @symbol.index( name )
124
+ raise "Symbol #{name} not found." if (symbol == nil || symbol == 0)
125
+ symbol
126
+ end
127
127
 
128
- # 原子番号から原子記号を取得。e.g., 1 から H
129
- # 与えられたものが原子記号ならそのまま返す、ようにしたいがまだできてない。
130
- # リストに存在しなければ raise する。
131
- def getSymbol( num )
132
- raise "getSymbol(num) requires Fixnum, but #{num}" if (num.class != Fixnum)
133
- raise "Atomic number is out of range." if (num <= 0 || @symbol.size <= num)
134
- @symbol[num]
135
- end
128
+ # 原子番号から原子記号を取得。e.g., 1 から H
129
+ # 与えられたものが原子記号ならそのまま返す、ようにしたいがまだできてない。
130
+ # リストに存在しなければ raise する。
131
+ def getSymbol( num )
132
+ raise "getSymbol(num) requires Fixnum, but #{num}" if (num.class != Fixnum)
133
+ raise "Atomic number is out of range." if (num <= 0 || @symbol.size <= num)
134
+ @symbol[num]
135
+ end
136
136
 
137
- # 引数 id がリストに含まれているか?
138
- # id は原子番号でも原子記号でも可にしたいが、とりあえず symbol だけ。
139
- def include?( symbol )
140
- return false if symbol == nil
141
- @symbol.include?( symbol )
142
- end
137
+ # 引数 id がリストに含まれているか?
138
+ # id は原子番号でも原子記号でも可にしたいが、とりあえず symbol だけ。
139
+ def include?( symbol )
140
+ return false if symbol == nil
141
+ @symbol.include?( symbol )
142
+ end
143
143
 
144
- ##
145
- #def getRadius
146
- #end
144
+ ##
145
+ #def getRadius
146
+ #end
147
147
 
148
148
  end
@@ -8,200 +8,206 @@ require "malge/simultaneousequations.rb"
8
8
  #
9
9
  # When lattice axes of three vectors are given,
10
10
  # lattice axes are automatically converted as below.
11
- # - c axes in internal axis is along to z axis in cartesian axis.
12
- # - b axes in internal axis is on the b-c plane.
13
- # - a axes in internal axis is set to be a right-hand system.
14
- # E.g.,
15
- # [ [0.5, 0.5, 0.0], [0.5, 0.0, 0.5], [0.0, 0.5, 0.5] ]
16
- # will be converted to
17
- # [ [0.57735, 0.20412, 0.35355],
18
- # [0.00000, 0.61237, 0.35355],
19
- # [0.00000, 0.00000, 0.70710]]
11
+ # - c axes in internal axis is along to z axis in cartesian axis.
12
+ # - b axes in internal axis is on the b-c plane.
13
+ # - a axes in internal axis is set to be a right-hand system.
14
+ # E.g.,
15
+ # [ [0.5, 0.5, 0.0], [0.5, 0.0, 0.5], [0.0, 0.5, 0.5] ]
16
+ # will be converted to
17
+ # [ [0.57735, 0.20412, 0.35355],
18
+ # [0.00000, 0.61237, 0.35355],
19
+ # [0.00000, 0.00000, 0.70710]]
20
20
  class CrystalCell::LatticeAxes < Mageo::Axes
21
21
 
22
- class InitializeError < Exception; end
23
- class ArgumentError < Exception; end
24
- class TypeError < Exception; end
25
-
26
- include Math
27
- include Mageo
28
-
29
- # Argument 'vectors' is three vectors with the order of a, b, c.
30
- # If you want to make LatticeAxes instances from lattice constants,
31
- # you should convert to axes with LatticeAxes.lc_to_axes
32
- # 任意の向きのベクトルを渡しても、必ず triangulate する。
33
- def initialize(vectors)
34
- raise InitializeError, "#{vectors.inspect}" unless vectors.size == 3
35
-
36
- if vectors.class == CrystalCell::LatticeAxes
37
- @axes = vectors
38
- else
39
- begin
40
- vectors = self.class.triangulate(vectors)
41
- rescue Vector3D::RangeError
42
- raise InitializeError, "#{vectors.inspect}"
43
- end
44
-
45
- super(vectors)
22
+ class InitializeError < Exception; end
23
+ class ArgumentError < Exception; end
24
+ class TypeError < Exception; end
25
+
26
+ include Math
27
+ include Mageo
28
+
29
+ # Argument 'vectors' is three vectors with the order of a, b, c.
30
+ # If you want to make LatticeAxes instances from lattice constants,
31
+ # you should convert to axes with LatticeAxes.lc_to_axes
32
+ # 任意の向きのベクトルを渡しても、必ず triangulate する。
33
+ def initialize(vectors)
34
+ raise InitializeError, "#{vectors.inspect}" unless vectors.size == 3
35
+
36
+ if vectors.class == CrystalCell::LatticeAxes
37
+ @axes = vectors
38
+ else
39
+ begin
40
+ vectors = self.class.triangulate(vectors)
41
+ rescue Vector3D::RangeError
42
+ raise InitializeError, "#{vectors.inspect}"
43
+ end
44
+
45
+ super(vectors)
46
+ end
46
47
  end
47
- end
48
-
49
-
50
- ## Class methods
51
-
52
- # Convert six lattice constants to three axes.
53
- # Set true to the argument of 'righthand' if a assumed lattice has righthand axis system.
54
- def self.lc_to_axes(lc, righthand = true)
55
- raise ArgumentError if (lc.size != 6)
56
-
57
- a = lc[0]
58
- b = lc[1]
59
- c = lc[2]
60
- alpha = (2.0*PI) * lc[3] / 360.0 # radian
61
- beta = (2.0*PI) * lc[4] / 360.0 # radian
62
- gamma = (2.0*PI) * lc[5] / 360.0 # radian
63
-
64
- v_c = Vector3D[0.0, 0.0, c]
65
- v_b = Vector3D[0.0, b * Math::sin(alpha), b * Math::cos(alpha)]
66
- v_a_z = a * Math::cos(beta)
67
- v_a_y = (a * (Math::cos(gamma) - Math::cos(alpha) * Math::cos(beta)))/ Math::sin(alpha)
68
- v_a_x = Math::sqrt(a**2 - v_a_y**2 - v_a_z**2)
69
- v_a_x *= -1.0 if righthand == false
70
- v_a = Vector3D[v_a_x, v_a_y, v_a_z]
71
- return [v_a, v_b, v_c]
72
- end
73
-
74
- # Convert three axes to six lattice constants.
75
- def self.axes_to_lc(axes)
76
- axes.collect!{|i| Vector3D[*i] }
77
- a = axes[0].r
78
- b = axes[1].r
79
- c = axes[2].r
80
- alpha = axes[1].angle_degree(axes[2])
81
- beta = axes[2].angle_degree(axes[0])
82
- gamma = axes[0].angle_degree(axes[1])
83
- return [ a, b, c, alpha, beta, gamma ]
84
- end
85
-
86
- # Return true if the relation of vector order is righthand system.
87
- def self.righthand?(axes)
88
- axes.map! { |i| Vector3D[*i] }
89
- return true if Vector3D.scalar_triple_product(*axes) > 0.0
90
- return false
91
- end
92
-
93
- # Return true if the relation of vector order is lefthand system.
94
- def self.lefthand?(axes)
95
- axes.map! { |i| Vector3D[*i] }
96
- return true if Vector3D.scalar_triple_product(*axes) < 0.0
97
- return false
98
- end
99
-
100
- # Convert three axes to three axes with rules below:
101
- # c axis is along z axis in cartesian system.
102
- # b axis is on y-z plane in cartesian system.
103
- # Return an array of three Vector3D instances.
104
- # This class does not convert righthand to lefthand system.
105
- # The name of this method 'triangulate' originates from the
106
- # matrix indicating the vectors being triangular matrix.
107
- #
108
- # クラスメソッドは廃止の方向で。
109
- # vectors の数をチェックするのは initialize でやるべきことだろうし、
110
- # LatticeAxes クラスインスタンス以外で triangulate を使う場面が想像できない。
111
- #
112
- def self.triangulate(vectors)
113
- vectors.map! { |i| Vector3D[*i] }
114
- raise InitializeError if self.dependent?(vectors)
115
- lc = self.axes_to_lc(vectors)
116
- righthand = self.righthand?(vectors)
117
- return self.lc_to_axes(lc, righthand)
118
- end
119
-
120
- ## Instance methods.
121
-
122
- # Get lattice constants in six values.
123
- def get_lattice_constants
124
- return CrystalCell::LatticeAxes.axes_to_lc(@axes)
125
- end
126
-
127
- def righthand?
128
- self.class.righthand?(@axes)
129
- end
130
-
131
- def lefthand?
132
- self.class.lefthand?(@axes)
133
- end
134
-
135
- # This class is obsoleted. [2011-12-22]
136
- ## Convert internal coordinates to cartesian coordinates.
137
- ## Return a Vector3DInternal class instance, which is not a cartesian vector.
138
- #def internal2cartesian(internal_coord)
139
- # Vector3DInternal[ *internal_coord ].to_v3d(axes)
140
- #end
141
-
142
- # This class is obsoleted. [2011-12-22]
143
- ## Convert cartesian coordinates to internal coordinates.
144
- ## Return a Vector3D class instance, which is a cartesian vector.
145
- #def cartesian2internal(cartesian_coord)
146
- # #pp cartesian_coord
147
- # Vector3D[ *cartesian_coord ].to_v3di(axes)
148
- #end
149
-
150
- # Compare <other> CrystalCell::LatticeAxes instance.
151
- # <length_ratio> is tolerance of ratio in length of axes.
152
- # <angle_tolerance> is tolerance of value in angle between axes.
153
- def equal_in_delta?(other, length_ratio, angle_tolerance)
154
- length_a = self .get_lattice_constants[0..2]
155
- length_b = other.get_lattice_constants[0..2]
156
- 3.times do |i|
157
- return false unless ((length_a[i] - length_b[i]).abs <= length_ratio)
48
+
49
+
50
+ ## Class methods
51
+
52
+ # Generate new instance from lattice constants.
53
+ def self.new_lc(lc)
54
+ vec = CrystalCell::LatticeAxes.lc_to_axes(lc)
55
+ CrystalCell::LatticeAxes.new(vec)
56
+ end
57
+
58
+ # Convert six lattice constants to three axes.
59
+ # Set true to the argument of 'righthand' if a assumed lattice has righthand axis system.
60
+ def self.lc_to_axes(lc, righthand = true)
61
+ raise ArgumentError if (lc.size != 6)
62
+
63
+ a = lc[0]
64
+ b = lc[1]
65
+ c = lc[2]
66
+ alpha = (2.0*PI) * lc[3] / 360.0 # radian
67
+ beta = (2.0*PI) * lc[4] / 360.0 # radian
68
+ gamma = (2.0*PI) * lc[5] / 360.0 # radian
69
+
70
+ v_c = Vector3D[0.0, 0.0, c]
71
+ v_b = Vector3D[0.0, b * Math::sin(alpha), b * Math::cos(alpha)]
72
+ v_a_z = a * Math::cos(beta)
73
+ v_a_y = (a * (Math::cos(gamma) - Math::cos(alpha) * Math::cos(beta)))/ Math::sin(alpha)
74
+ v_a_x = Math::sqrt(a**2 - v_a_y**2 - v_a_z**2)
75
+ v_a_x *= -1.0 if righthand == false
76
+ v_a = Vector3D[v_a_x, v_a_y, v_a_z]
77
+ return [v_a, v_b, v_c]
78
+ end
79
+
80
+ # Convert three axes to six lattice constants.
81
+ def self.axes_to_lc(axes)
82
+ axes.collect!{|i| Vector3D[*i] }
83
+ a = axes[0].r
84
+ b = axes[1].r
85
+ c = axes[2].r
86
+ alpha = axes[1].angle_degree(axes[2])
87
+ beta = axes[2].angle_degree(axes[0])
88
+ gamma = axes[0].angle_degree(axes[1])
89
+ return [ a, b, c, alpha, beta, gamma ]
158
90
  end
159
91
 
160
- angle_a = self .get_lattice_constants[3..5]
161
- angle_b = other.get_lattice_constants[3..5]
162
- 3.times do |i|
163
- return false unless ((angle_a[i] - angle_b[i]).abs <= angle_tolerance)
92
+ # Return true if the relation of vector order is righthand system.
93
+ def self.righthand?(axes)
94
+ axes.map! { |i| Vector3D[*i] }
95
+ return true if Vector3D.scalar_triple_product(*axes) > 0.0
96
+ return false
164
97
  end
165
- return true
166
- end
167
-
168
- def ==(other)
169
- 3.times do |i|
170
- 3.times do |j|
171
- return false if self[i][j] != other[i][j]
172
- end
98
+
99
+ # Return true if the relation of vector order is lefthand system.
100
+ def self.lefthand?(axes)
101
+ axes.map! { |i| Vector3D[*i] }
102
+ return true if Vector3D.scalar_triple_product(*axes) < 0.0
103
+ return false
104
+ end
105
+
106
+ # Convert three axes to three axes with rules below:
107
+ # c axis is along z axis in cartesian system.
108
+ # b axis is on y-z plane in cartesian system.
109
+ # Return an array of three Vector3D instances.
110
+ # This class does not convert righthand to lefthand system.
111
+ # The name of this method 'triangulate' originates from the
112
+ # matrix indicating the vectors being triangular matrix.
113
+ #
114
+ # クラスメソッドは廃止の方向で。
115
+ # vectors の数をチェックするのは initialize でやるべきことだろうし、
116
+ # LatticeAxes クラスインスタンス以外で triangulate を使う場面が想像できない。
117
+ #
118
+ def self.triangulate(vectors)
119
+ vectors.map! { |i| Vector3D[*i] }
120
+ raise InitializeError if self.dependent?(vectors)
121
+ lc = self.axes_to_lc(vectors)
122
+ righthand = self.righthand?(vectors)
123
+ return self.lc_to_axes(lc, righthand)
124
+ end
125
+
126
+ ## Instance methods.
127
+
128
+ # Get lattice constants in six values.
129
+ def get_lattice_constants
130
+ return CrystalCell::LatticeAxes.axes_to_lc(@axes)
173
131
  end
174
- return true
175
- end
176
-
177
- private
178
-
179
- def triangulate
180
- #self.class.triangulate(@axes)
181
- # rotate(2, 2, 1)
182
- # rotate(2, 0, 2)
183
- # rotate(1, 2, 1)
184
- end
185
-
186
- #private
187
-
188
- ## 保持する全ての軸を回転する。
189
- ## 以下の index は Axes クラス保持している配列における index。
190
- ## target_index 回転の際の角度を決めるベクトルの
191
- ## self が保持する内部座標軸の index。
192
- ## center_axis_index 回転の中心軸のベクトルの index in x, y, z。
193
- ## plane_axis_index) 回転の目的地となる平面を、中心軸と共に構成するベクトルの index
194
- ## in x, y, z。
195
- #def rotate(target_index, center_axis_index, plane_axis_index)
196
- # theta =
197
-
198
- # axes[target_index]
199
- #
200
- # HERE
201
-
202
- # self.each do |vector|
203
- # vector
204
- # end
205
- #end
132
+
133
+ def righthand?
134
+ self.class.righthand?(@axes)
135
+ end
136
+
137
+ def lefthand?
138
+ self.class.lefthand?(@axes)
139
+ end
140
+
141
+ # This class is obsoleted. [2011-12-22]
142
+ ## Convert internal coordinates to cartesian coordinates.
143
+ ## Return a Vector3DInternal class instance, which is not a cartesian vector.
144
+ #def internal2cartesian(internal_coord)
145
+ # Vector3DInternal[ *internal_coord ].to_v3d(axes)
146
+ #end
147
+
148
+ # This class is obsoleted. [2011-12-22]
149
+ ## Convert cartesian coordinates to internal coordinates.
150
+ ## Return a Vector3D class instance, which is a cartesian vector.
151
+ #def cartesian2internal(cartesian_coord)
152
+ # #pp cartesian_coord
153
+ # Vector3D[ *cartesian_coord ].to_v3di(axes)
154
+ #end
155
+
156
+ # Compare <other> CrystalCell::LatticeAxes instance.
157
+ # <length_ratio> is tolerance of ratio in length of axes.
158
+ # <angle_tolerance> is tolerance of value in angle between axes.
159
+ def equal_in_delta?(other, length_ratio, angle_tolerance)
160
+ length_a = self .get_lattice_constants[0..2]
161
+ length_b = other.get_lattice_constants[0..2]
162
+ 3.times do |i|
163
+ return false unless ((length_a[i] - length_b[i]).abs <= length_ratio)
164
+ end
165
+
166
+ angle_a = self .get_lattice_constants[3..5]
167
+ angle_b = other.get_lattice_constants[3..5]
168
+ 3.times do |i|
169
+ return false unless ((angle_a[i] - angle_b[i]).abs <= angle_tolerance)
170
+ end
171
+ return true
172
+ end
173
+
174
+ def ==(other)
175
+ 3.times do |i|
176
+ 3.times do |j|
177
+ return false if self[i][j] != other[i][j]
178
+ end
179
+ end
180
+ return true
181
+ end
182
+
183
+ private
184
+
185
+ def triangulate
186
+ #self.class.triangulate(@axes)
187
+ # rotate(2, 2, 1)
188
+ # rotate(2, 0, 2)
189
+ # rotate(1, 2, 1)
190
+ end
191
+
192
+ #private
193
+
194
+ ## 保持する全ての軸を回転する。
195
+ ## 以下の index は Axes クラス保持している配列における index。
196
+ ## target_index 回転の際の角度を決めるベクトルの
197
+ ## self が保持する内部座標軸の index。
198
+ ## center_axis_index 回転の中心軸のベクトルの index in x, y, z。
199
+ ## plane_axis_index) 回転の目的地となる平面を、中心軸と共に構成するベクトルの index
200
+ ## in x, y, z。
201
+ #def rotate(target_index, center_axis_index, plane_axis_index)
202
+ # theta =
203
+
204
+ # axes[target_index]
205
+ #
206
+ # HERE
207
+
208
+ # self.each do |vector|
209
+ # vector
210
+ # end
211
+ #end
206
212
 
207
213
  end