OSDN Git Service

[Backup]NyARToolkit for Java
[nyartoolkit-and/nyartoolkit-and.git] / src / jp / nyatla / nyartoolkit / core / transmat / optimize / artoolkit / NyARRotMatrixOptimize_O2.java
1 /* \r
2  * PROJECT: NyARToolkit\r
3  * --------------------------------------------------------------------------------\r
4  * This work is based on the original ARToolKit developed by\r
5  *   Hirokazu Kato\r
6  *   Mark Billinghurst\r
7  *   HITLab, University of Washington, Seattle\r
8  * http://www.hitl.washington.edu/artoolkit/\r
9  *\r
10  * The NyARToolkit is Java edition ARToolKit class library.\r
11  * Copyright (C)2008-2009 Ryo Iizuka\r
12  *\r
13  * This program is free software: you can redistribute it and/or modify\r
14  * it under the terms of the GNU General Public License as published by\r
15  * the Free Software Foundation, either version 3 of the License, or\r
16  * (at your option) any later version.\r
17  * \r
18  * This program is distributed in the hope that it will be useful,\r
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
21  * GNU General Public License for more details.\r
22  *\r
23  * You should have received a copy of the GNU General Public License\r
24  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
25  * \r
26  * For further information please contact.\r
27  *      http://nyatla.jp/nyatoolkit/\r
28  *      <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
29  * \r
30  */\r
31 package jp.nyatla.nyartoolkit.core.transmat.optimize.artoolkit;\r
32 \r
33 \r
34 import jp.nyatla.nyartoolkit.NyARException;\r
35 import jp.nyatla.nyartoolkit.core.param.*;\r
36 import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
37 import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
38 import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;\r
39 /**\r
40  * 基本姿勢と実画像を一致するように、角度を微調整→平行移動量を再計算\r
41  * を繰り返して、変換行列を最適化する。\r
42  *\r
43  */\r
44 public class NyARRotMatrixOptimize_O2 implements INyARRotMatrixOptimize\r
45 {\r
46         private final NyARPerspectiveProjectionMatrix _projection_mat_ref;\r
47         public NyARRotMatrixOptimize_O2(NyARPerspectiveProjectionMatrix i_projection_mat_ref)\r
48         {\r
49                 this._projection_mat_ref=i_projection_mat_ref;\r
50                 return;\r
51         }\r
52         private final double[][] __modifyMatrix_double1D = new double[8][3];\r
53         /**\r
54          * arGetRot計算を階層化したModifyMatrix 896\r
55          * \r
56          * @param trans\r
57          * @param i_vertex3d\r
58          * [m][3]\r
59          * @param i_vertex2d\r
60          * [n][2]\r
61          * @return\r
62          * @throws NyARException\r
63          */\r
64         public double modifyMatrix(NyARRotMatrix_ARToolKit io_rot,NyARDoublePoint3d trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d) throws NyARException\r
65         {\r
66                 double factor;\r
67                 double a2, b2, c2;\r
68                 double h, x, y;\r
69                 double err, minerr = 0;\r
70                 int t1, t2, t3;\r
71                 int best_idx=0;\r
72 \r
73                 factor = 10.0 * Math.PI / 180.0;\r
74                 double rot0, rot1, rot2;\r
75                 double combo00, combo01, combo02, combo03, combo10, combo11, combo12, combo13, combo20, combo21, combo22, combo23;\r
76                 double combo02_2, combo02_5, combo02_8, combo02_11;\r
77                 double combo22_2, combo22_5, combo22_8, combo22_11;\r
78                 double combo12_2, combo12_5, combo12_8, combo12_11;\r
79                 // vertex展開\r
80                 final double VX00, VX01, VX02, VX10, VX11, VX12, VX20, VX21, VX22, VX30, VX31, VX32;\r
81                 VX00 = i_vertex3d[0].x;\r
82                 VX01 = i_vertex3d[0].y;\r
83                 VX02 = i_vertex3d[0].z;\r
84                 VX10 = i_vertex3d[1].x;\r
85                 VX11 = i_vertex3d[1].y;\r
86                 VX12 = i_vertex3d[1].z;\r
87                 VX20 = i_vertex3d[2].x;\r
88                 VX21 = i_vertex3d[2].y;\r
89                 VX22 = i_vertex3d[2].z;\r
90                 VX30 = i_vertex3d[3].x;\r
91                 VX31 = i_vertex3d[3].y;\r
92                 VX32 = i_vertex3d[3].z;\r
93                 final double P2D00, P2D01, P2D10, P2D11, P2D20, P2D21, P2D30, P2D31;\r
94                 P2D00 = i_vertex2d[0].x;\r
95                 P2D01 = i_vertex2d[0].y;\r
96                 P2D10 = i_vertex2d[1].x;\r
97                 P2D11 = i_vertex2d[1].y;\r
98                 P2D20 = i_vertex2d[2].x;\r
99                 P2D21 = i_vertex2d[2].y;\r
100                 P2D30 = i_vertex2d[3].x;\r
101                 P2D31 = i_vertex2d[3].y;\r
102                 final NyARPerspectiveProjectionMatrix prjmat = this._projection_mat_ref;\r
103                 final double CP0 = prjmat.m00,CP1 = prjmat.m01,CP2 = prjmat.m02,CP4 = prjmat.m10,CP5 = prjmat.m11,CP6 = prjmat.m12,CP8 = prjmat.m20,CP9 = prjmat.m21,CP10 = prjmat.m22;\r
104                 combo03 = CP0 * trans.x + CP1 * trans.y + CP2 * trans.z + prjmat.m03;\r
105                 combo13 = CP4 * trans.x + CP5 * trans.y + CP6 * trans.z + prjmat.m13;\r
106                 combo23 = CP8 * trans.x + CP9 * trans.y + CP10 * trans.z + prjmat.m23;\r
107                 double CACA, SASA, SACA, CA, SA;\r
108                 double CACACB, SACACB, SASACB, CASB, SASB;\r
109                 double SACASC, SACACBSC, SACACBCC, SACACC;\r
110                 final double[][] double1D = this.__modifyMatrix_double1D;\r
111 \r
112                 final double[] a_factor = double1D[1];\r
113                 final double[] sinb = double1D[2];\r
114                 final double[] cosb = double1D[3];\r
115                 final double[] b_factor = double1D[4];\r
116                 final double[] sinc = double1D[5];\r
117                 final double[] cosc = double1D[6];\r
118                 final double[] c_factor = double1D[7];\r
119                 double w, w2;\r
120                 double wsin, wcos;\r
121                 \r
122                 final NyARDoublePoint3d angle = io_rot.refAngle();\r
123                 a2 = angle.x;\r
124                 b2 = angle.y;\r
125                 c2 = angle.z;\r
126 \r
127                 // comboの3行目を先に計算\r
128                 for (int i = 0; i < 10; i++) {\r
129                         minerr = 1000000000.0;\r
130                         // sin-cosテーブルを計算(これが外に出せるとは…。)\r
131                         for (int j = 0; j < 3; j++) {\r
132                                 w2 = factor * (j - 1);\r
133                                 w = a2 + w2;\r
134                                 a_factor[j] = w;\r
135                                 w = b2 + w2;\r
136                                 b_factor[j] = w;\r
137                                 sinb[j] = Math.sin(w);\r
138                                 cosb[j] = Math.cos(w);\r
139                                 w = c2 + w2;\r
140                                 c_factor[j] = w;\r
141                                 sinc[j] = Math.sin(w);\r
142                                 cosc[j] = Math.cos(w);\r
143                         }\r
144                         //\r
145                         for (t1 = 0; t1 < 3; t1++) {\r
146                                 SA = Math.sin(a_factor[t1]);\r
147                                 CA = Math.cos(a_factor[t1]);\r
148                                 // Optimize\r
149                                 CACA = CA * CA;\r
150                                 SASA = SA * SA;\r
151                                 SACA = SA * CA;\r
152                                 for (t2 = 0; t2 < 3; t2++) {\r
153                                         wsin = sinb[t2];\r
154                                         wcos = cosb[t2];\r
155                                         CACACB = CACA * wcos;\r
156                                         SACACB = SACA * wcos;\r
157                                         SASACB = SASA * wcos;\r
158                                         CASB = CA * wsin;\r
159                                         SASB = SA * wsin;\r
160                                         // comboの計算1\r
161                                         combo02 = CP0 * CASB + CP1 * SASB + CP2 * wcos;\r
162                                         combo12 = CP4 * CASB + CP5 * SASB + CP6 * wcos;\r
163                                         combo22 = CP8 * CASB + CP9 * SASB + CP10 * wcos;\r
164 \r
165                                         combo02_2 = combo02 * VX02 + combo03;\r
166                                         combo02_5 = combo02 * VX12 + combo03;\r
167                                         combo02_8 = combo02 * VX22 + combo03;\r
168                                         combo02_11 = combo02 * VX32 + combo03;\r
169                                         combo12_2 = combo12 * VX02 + combo13;\r
170                                         combo12_5 = combo12 * VX12 + combo13;\r
171                                         combo12_8 = combo12 * VX22 + combo13;\r
172                                         combo12_11 = combo12 * VX32 + combo13;\r
173                                         combo22_2 = combo22 * VX02 + combo23;\r
174                                         combo22_5 = combo22 * VX12 + combo23;\r
175                                         combo22_8 = combo22 * VX22 + combo23;\r
176                                         combo22_11 = combo22 * VX32 + combo23;\r
177                                         for (t3 = 0; t3 < 3; t3++) {\r
178                                                 wsin = sinc[t3];\r
179                                                 wcos = cosc[t3];\r
180                                                 SACASC = SACA * wsin;\r
181                                                 SACACC = SACA * wcos;\r
182                                                 SACACBSC = SACACB * wsin;\r
183                                                 SACACBCC = SACACB * wcos;\r
184 \r
185                                                 rot0 = CACACB * wcos + SASA * wcos + SACACBSC - SACASC;\r
186                                                 rot1 = SACACBCC - SACACC + SASACB * wsin + CACA * wsin;\r
187                                                 rot2 = -CASB * wcos - SASB * wsin;\r
188                                                 combo00 = CP0 * rot0 + CP1 * rot1 + CP2 * rot2;\r
189                                                 combo10 = CP4 * rot0 + CP5 * rot1 + CP6 * rot2;\r
190                                                 combo20 = CP8 * rot0 + CP9 * rot1 + CP10 * rot2;\r
191 \r
192                                                 rot0 = -CACACB * wsin - SASA * wsin + SACACBCC - SACACC;\r
193                                                 rot1 = -SACACBSC + SACASC + SASACB * wcos + CACA * wcos;\r
194                                                 rot2 = CASB * wsin - SASB * wcos;\r
195                                                 combo01 = CP0 * rot0 + CP1 * rot1 + CP2 * rot2;\r
196                                                 combo11 = CP4 * rot0 + CP5 * rot1 + CP6 * rot2;\r
197                                                 combo21 = CP8 * rot0 + CP9 * rot1 + CP10 * rot2;\r
198                                                 //\r
199                                                 err = 0.0;\r
200                                                 h = combo20 * VX00 + combo21 * VX01 + combo22_2;\r
201                                                 x = P2D00 - (combo00 * VX00 + combo01 * VX01 + combo02_2) / h;\r
202                                                 y = P2D01 - (combo10 * VX00 + combo11 * VX01 + combo12_2) / h;\r
203                                                 err += x * x + y * y;\r
204                                                 h = combo20 * VX10 + combo21 * VX11 + combo22_5;\r
205                                                 x = P2D10 - (combo00 * VX10 + combo01 * VX11 + combo02_5) / h;\r
206                                                 y = P2D11 - (combo10 * VX10 + combo11 * VX11 + combo12_5) / h;\r
207                                                 err += x * x + y * y;\r
208                                                 h = combo20 * VX20 + combo21 * VX21 + combo22_8;\r
209                                                 x = P2D20 - (combo00 * VX20 + combo01 * VX21 + combo02_8) / h;\r
210                                                 y = P2D21 - (combo10 * VX20 + combo11 * VX21 + combo12_8) / h;\r
211                                                 err += x * x + y * y;\r
212                                                 h = combo20 * VX30 + combo21 * VX31 + combo22_11;\r
213                                                 x = P2D30 - (combo00 * VX30 + combo01 * VX31 + combo02_11) / h;\r
214                                                 y = P2D31 - (combo10 * VX30 + combo11 * VX31 + combo12_11) / h;\r
215                                                 err += x * x + y * y;\r
216                                                 if (err < minerr) {\r
217                                                         minerr = err;\r
218                                                         a2 = a_factor[t1];\r
219                                                         b2 = b_factor[t2];\r
220                                                         c2 = c_factor[t3];\r
221                                                         best_idx=t1+t2*3+t3*9;\r
222                                                 }\r
223                                         }\r
224                                 }\r
225                         }\r
226                         if (best_idx==(1+3+9)) {\r
227                                 factor *= 0.5;\r
228                         }\r
229                 }\r
230                 io_rot.setAngle(a2, b2, c2);\r
231                 /* printf("factor = %10.5f\n", factor*180.0/MD_PI); */\r
232                 return minerr /4;\r
233         }       \r
234         \r
235         \r
236 }\r