2 * PROJECT: NyARToolkit
\r
3 * --------------------------------------------------------------------------------
\r
4 * This work is based on the original ARToolKit developed by
\r
7 * HITLab, University of Washington, Seattle
\r
8 * http://www.hitl.washington.edu/artoolkit/
\r
10 * The NyARToolkit is Java version ARToolkit class library.
\r
11 * Copyright (C)2008 R.Iizuka
\r
13 * This program is free software; you can redistribute it and/or
\r
14 * modify it under the terms of the GNU General Public License
\r
15 * as published by the Free Software Foundation; either version 2
\r
16 * of the License, or (at your option) any later version.
\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
23 * You should have received a copy of the GNU General Public License
\r
24 * along with this framework; if not, write to the Free Software
\r
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
27 * For further information please contact.
\r
28 * http://nyatla.jp/nyatoolkit/
\r
29 * <airmail(at)ebony.plala.or.jp>
\r
32 package jp.nyatla.nyartoolkit.toys.x2;
\r
35 import jp.nyatla.nyartoolkit.NyARException;
\r
36 import jp.nyatla.nyartoolkit.core.param.*;
\r
37 import jp.nyatla.nyartoolkit.core.transmat.fitveccalc.*;
\r
38 import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;
\r
39 import jp.nyatla.nyartoolkit.core.types.*;
\r
40 import jp.nyatla.nyartoolkit.core.transmat.optimize.*;
\r
41 import jp.nyatla.nyartoolkit.toys.x2.NyARSinTable;
\r
44 * 基本姿勢と実画像を一致するように、角度を微調整→平行移動量を再計算
\r
45 * を繰り返して、変換行列を最適化する。
\r
48 public class NyARRotTransOptimize_X2 implements INyARRotTransOptimize
\r
50 private NyARSinTable _sin_table_ref;
\r
51 private final static int AR_GET_TRANS_MAT_MAX_LOOP_COUNT = 5;// #define AR_GET_TRANS_MAT_MAX_LOOP_COUNT 5
\r
52 private final static double AR_GET_TRANS_MAT_MAX_FIT_ERROR = 1.0;// #define AR_GET_TRANS_MAT_MAX_FIT_ERROR 1.0
\r
53 private final NyARPerspectiveProjectionMatrix _projection_mat_ref;
\r
54 public NyARRotTransOptimize_X2(NyARPerspectiveProjectionMatrix i_projection_mat_ref,NyARSinTable _sin_table_ref)
\r
56 this._sin_table_ref=_sin_table_ref;
\r
57 this._projection_mat_ref=i_projection_mat_ref;
\r
61 final public double optimize(NyARRotMatrix io_rotmat,NyARDoublePoint3d io_transvec,NyARFitVecCalculator i_calculator) throws NyARException
\r
63 final NyARDoublePoint2d[] fit_vertex=i_calculator.getFitSquare();
\r
64 final NyARDoublePoint3d[] offset_square=i_calculator.getOffsetVertex().vertex;
\r
68 /*ループを抜けるタイミングをARToolKitと合わせるために変なことしてます。*/
\r
69 for (int i = 0;; i++) {
\r
71 err = modifyMatrix(io_rotmat,io_transvec,offset_square,fit_vertex);
\r
72 i_calculator.calculateTransfer(io_rotmat, io_transvec);
\r
73 err = modifyMatrix(io_rotmat,io_transvec,offset_square,fit_vertex);
\r
74 // //</arGetTransMat3>
\r
75 if (err < AR_GET_TRANS_MAT_MAX_FIT_ERROR || i == AR_GET_TRANS_MAT_MAX_LOOP_COUNT-1) {
\r
78 i_calculator.calculateTransfer(io_rotmat, io_transvec);
\r
83 private final double[][] __modifyMatrix_double1D = new double[8][3];
\r
84 private final NyARDoublePoint3d __modifyMatrix_angle = new NyARDoublePoint3d();
\r
86 * arGetRot計算を階層化したModifyMatrix 896
\r
95 * @throws NyARException
\r
97 private double modifyMatrix(NyARRotMatrix io_rot,NyARDoublePoint3d trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d) throws NyARException
\r
101 double ma = 0.0, mb = 0.0, mc = 0.0;
\r
103 double err, minerr = 0;
\r
105 int s1 = 0, s2 = 0, s3 = 0;
\r
107 factor = 10.0 * Math.PI / 180.0;
\r
108 double rot0, rot1, rot3, rot4, rot6, rot7;
\r
109 double combo00, combo01, combo02, combo03, combo10, combo11, combo12, combo13, combo20, combo21, combo22, combo23;
\r
110 double combo02_2, combo02_5, combo02_8, combo02_11;
\r
111 double combo22_2, combo22_5, combo22_8, combo22_11;
\r
112 double combo12_2, combo12_5, combo12_8, combo12_11;
\r
114 final double VX00, VX01, VX02, VX10, VX11, VX12, VX20, VX21, VX22, VX30, VX31, VX32;
\r
115 NyARDoublePoint3d d_pt;
\r
116 d_pt = i_vertex3d[0];
\r
120 d_pt = i_vertex3d[1];
\r
124 d_pt = i_vertex3d[2];
\r
128 d_pt = i_vertex3d[3];
\r
132 final double P2D00, P2D01, P2D10, P2D11, P2D20, P2D21, P2D30, P2D31;
\r
133 NyARDoublePoint2d d_pt2;
\r
134 d_pt2 = i_vertex2d[0];
\r
137 d_pt2 = i_vertex2d[1];
\r
140 d_pt2 = i_vertex2d[2];
\r
143 d_pt2 = i_vertex2d[3];
\r
146 final NyARPerspectiveProjectionMatrix prjmat = this._projection_mat_ref;
\r
147 final double CP0, CP1, CP2, CP4, CP5, CP6, CP8, CP9, CP10;
\r
157 combo03 = CP0 * trans.x + CP1 * trans.y + CP2 * trans.z + prjmat.m03;
\r
158 combo13 = CP4 * trans.x + CP5 * trans.y + CP6 * trans.z + prjmat.m13;
\r
159 combo23 = CP8 * trans.x + CP9 * trans.y + CP10 * trans.z + prjmat.m23;
\r
160 double CACA, SASA, SACA, CA, SA;
\r
161 double CACACB, SACACB, SASACB, CASB, SASB;
\r
162 double SACASC, SACACBSC, SACACBCC, SACACC;
\r
163 final double[][] double1D = this.__modifyMatrix_double1D;
\r
165 final NyARDoublePoint3d angle = this.__modifyMatrix_angle;
\r
167 final double[] a_factor = double1D[1];
\r
168 final double[] sinb = double1D[2];
\r
169 final double[] cosb = double1D[3];
\r
170 final double[] b_factor = double1D[4];
\r
171 final double[] sinc = double1D[5];
\r
172 final double[] cosc = double1D[6];
\r
173 final double[] c_factor = double1D[7];
\r
177 io_rot.getAngle(angle);// arGetAngle( rot, &a, &b, &c );
\r
183 for (int i = 0; i < 10; i++) {
\r
184 minerr = 1000000000.0;
\r
185 // sin-cosテーブルを計算(これが外に出せるとは…。)
\r
186 for (int j = 0; j < 3; j++) {
\r
187 w2 = factor * (j - 1);
\r
192 sinb[j] = this._sin_table_ref.sin(w);
\r
193 cosb[j] = this._sin_table_ref.cos(w);
\r
196 sinc[j] = this._sin_table_ref.sin(w);
\r
197 cosc[j] = this._sin_table_ref.cos(w);
\r
200 for (t1 = 0; t1 < 3; t1++) {
\r
201 SA = this._sin_table_ref.sin(a_factor[t1]);
\r
202 CA = this._sin_table_ref.cos(a_factor[t1]);
\r
207 for (t2 = 0; t2 < 3; t2++) {
\r
210 CACACB = CACA * wcos;
\r
211 SACACB = SACA * wcos;
\r
212 SASACB = SASA * wcos;
\r
216 combo02 = CP0 * CASB + CP1 * SASB + CP2 * wcos;
\r
217 combo12 = CP4 * CASB + CP5 * SASB + CP6 * wcos;
\r
218 combo22 = CP8 * CASB + CP9 * SASB + CP10 * wcos;
\r
220 combo02_2 = combo02 * VX02 + combo03;
\r
221 combo02_5 = combo02 * VX12 + combo03;
\r
222 combo02_8 = combo02 * VX22 + combo03;
\r
223 combo02_11 = combo02 * VX32 + combo03;
\r
224 combo12_2 = combo12 * VX02 + combo13;
\r
225 combo12_5 = combo12 * VX12 + combo13;
\r
226 combo12_8 = combo12 * VX22 + combo13;
\r
227 combo12_11 = combo12 * VX32 + combo13;
\r
228 combo22_2 = combo22 * VX02 + combo23;
\r
229 combo22_5 = combo22 * VX12 + combo23;
\r
230 combo22_8 = combo22 * VX22 + combo23;
\r
231 combo22_11 = combo22 * VX32 + combo23;
\r
232 for (t3 = 0; t3 < 3; t3++) {
\r
235 SACASC = SACA * wsin;
\r
236 SACACC = SACA * wcos;
\r
237 SACACBSC = SACACB * wsin;
\r
238 SACACBCC = SACACB * wcos;
\r
240 rot0 = CACACB * wcos + SASA * wcos + SACACBSC - SACASC;
\r
241 rot3 = SACACBCC - SACACC + SASACB * wsin + CACA * wsin;
\r
242 rot6 = -CASB * wcos - SASB * wsin;
\r
244 combo00 = CP0 * rot0 + CP1 * rot3 + CP2 * rot6;
\r
245 combo10 = CP4 * rot0 + CP5 * rot3 + CP6 * rot6;
\r
246 combo20 = CP8 * rot0 + CP9 * rot3 + CP10 * rot6;
\r
248 rot1 = -CACACB * wsin - SASA * wsin + SACACBCC - SACACC;
\r
249 rot4 = -SACACBSC + SACASC + SASACB * wcos + CACA * wcos;
\r
250 rot7 = CASB * wsin - SASB * wcos;
\r
251 combo01 = CP0 * rot1 + CP1 * rot4 + CP2 * rot7;
\r
252 combo11 = CP4 * rot1 + CP5 * rot4 + CP6 * rot7;
\r
253 combo21 = CP8 * rot1 + CP9 * rot4 + CP10 * rot7;
\r
256 h = combo20 * VX00 + combo21 * VX01 + combo22_2;
\r
257 x = P2D00 - (combo00 * VX00 + combo01 * VX01 + combo02_2) / h;
\r
258 y = P2D01 - (combo10 * VX00 + combo11 * VX01 + combo12_2) / h;
\r
259 err += x * x + y * y;
\r
260 h = combo20 * VX10 + combo21 * VX11 + combo22_5;
\r
261 x = P2D10 - (combo00 * VX10 + combo01 * VX11 + combo02_5) / h;
\r
262 y = P2D11 - (combo10 * VX10 + combo11 * VX11 + combo12_5) / h;
\r
263 err += x * x + y * y;
\r
264 h = combo20 * VX20 + combo21 * VX21 + combo22_8;
\r
265 x = P2D20 - (combo00 * VX20 + combo01 * VX21 + combo02_8) / h;
\r
266 y = P2D21 - (combo10 * VX20 + combo11 * VX21 + combo12_8) / h;
\r
267 err += x * x + y * y;
\r
268 h = combo20 * VX30 + combo21 * VX31 + combo22_11;
\r
269 x = P2D30 - (combo00 * VX30 + combo01 * VX31 + combo02_11) / h;
\r
270 y = P2D31 - (combo10 * VX30 + combo11 * VX31 + combo12_11) / h;
\r
271 err += x * x + y * y;
\r
272 if (err < minerr) {
\r
284 if (s1 == 0 && s2 == 0 && s3 == 0) {
\r
291 io_rot.setAngle(ma, mb, mc);
\r
292 /* printf("factor = %10.5f\n", factor*180.0/MD_PI); */
\r