crystalcell 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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