OSDN Git Service

[TAG]NyARToolkit-2.0.0
[nyartoolkit-and/nyartoolkit-and.git] / tags / 2.0.0 / src / jp / nyatla / nyartoolkit / core / transmat / NyARTransMat.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 version ARToolkit class library.\r
11  * Copyright (C)2008 R.Iizuka\r
12  *\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
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 framework; if not, write to the Free Software\r
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
26  * \r
27  * For further information please contact.\r
28  *      http://nyatla.jp/nyatoolkit/\r
29  *      <airmail(at)ebony.plala.or.jp>\r
30  * \r
31  */\r
32 package jp.nyatla.nyartoolkit.core.transmat;\r
33 \r
34 import jp.nyatla.nyartoolkit.NyARException;\r
35 import jp.nyatla.nyartoolkit.core.NyARSquare;\r
36 import jp.nyatla.nyartoolkit.core.param.*;\r
37 import jp.nyatla.nyartoolkit.core.transmat.fitveccalc.NyARFitVecCalculator;\r
38 import jp.nyatla.nyartoolkit.core.transmat.optimize.NyARRotTransOptimize;\r
39 import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.NyARRotMatrix;\r
40 import jp.nyatla.nyartoolkit.core.types.*;\r
41 \r
42 \r
43 /**\r
44  * This class calculates ARMatrix from square information and holds it. --\r
45  * 変換行列を計算して、結果を保持するクラス。\r
46  * \r
47  */\r
48 public class NyARTransMat implements INyARTransMat\r
49 {\r
50         private final static double AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR = 1.0;\r
51 \r
52         private final NyARRotMatrix _rotmatrix;\r
53         private final NyARDoublePoint2d _center=new NyARDoublePoint2d(0,0);\r
54         private final NyARFitVecCalculator _calculator;\r
55         private final NyARTransOffset _offset=new NyARTransOffset();\r
56         private final NyARRotTransOptimize _mat_optimize;\r
57 \r
58 \r
59         public NyARTransMat(NyARParam i_param) throws NyARException\r
60         {\r
61                 final NyARCameraDistortionFactor dist=i_param.getDistortionFactor();\r
62                 final NyARPerspectiveProjectionMatrix pmat=i_param.getPerspectiveProjectionMatrix();\r
63                 this._calculator=new NyARFitVecCalculator(pmat,dist);\r
64                 this._rotmatrix = new NyARRotMatrix(pmat);\r
65                 this._mat_optimize=new NyARRotTransOptimize(pmat);\r
66         }\r
67 \r
68         public void setCenter(double i_x, double i_y)\r
69         {\r
70                 this._center.x= i_x;\r
71                 this._center.y= i_y;\r
72         }\r
73 \r
74 \r
75 \r
76 \r
77         /**\r
78          * 頂点順序をi_directionに対応して並べ替えます。\r
79          * @param i_square\r
80          * @param i_direction\r
81          * @param o_sqvertex_ref\r
82          * @param o_liner_ref\r
83          */\r
84         private final void initVertexOrder(NyARSquare i_square, int i_direction, NyARDoublePoint2d[] o_sqvertex_ref, NyARLinear[] o_liner_ref)\r
85         {\r
86                 //頂点順序を考慮した矩形の頂点情報\r
87                 o_sqvertex_ref[0]= i_square.sqvertex[(4 - i_direction) % 4];\r
88                 o_sqvertex_ref[1]= i_square.sqvertex[(5 - i_direction) % 4];\r
89                 o_sqvertex_ref[2]= i_square.sqvertex[(6 - i_direction) % 4];\r
90                 o_sqvertex_ref[3]= i_square.sqvertex[(7 - i_direction) % 4];    \r
91                 o_liner_ref[0]=i_square.line[(4 - i_direction) % 4];\r
92                 o_liner_ref[1]=i_square.line[(5 - i_direction) % 4];\r
93                 o_liner_ref[2]=i_square.line[(6 - i_direction) % 4];\r
94                 o_liner_ref[3]=i_square.line[(7 - i_direction) % 4];\r
95                 return;\r
96         }\r
97 \r
98 \r
99         private final NyARDoublePoint2d[] __transMat_sqvertex_ref = new NyARDoublePoint2d[4];\r
100         private final NyARLinear[] __transMat_linear_ref=new NyARLinear[4];\r
101         private final NyARDoublePoint3d __transMat_trans=new NyARDoublePoint3d();\r
102         /**\r
103          * double arGetTransMat( ARMarkerInfo *marker_info,double center[2], double width, double conv[3][4] )\r
104          * \r
105          * @param i_square\r
106          * 計算対象のNyARSquareオブジェクト\r
107          * @param i_direction\r
108          * @param i_width\r
109          * @return\r
110          * @throws NyARException\r
111          */\r
112         public void transMat(final NyARSquare i_square, int i_direction, double i_width, NyARTransMatResult o_result_conv) throws NyARException\r
113         {\r
114                 final NyARDoublePoint2d[] sqvertex_ref = __transMat_sqvertex_ref;\r
115                 final NyARLinear[] linear_ref=__transMat_linear_ref;\r
116                 final NyARDoublePoint3d trans=this.__transMat_trans;\r
117                 \r
118                 //計算用に頂点情報を初期化(順番調整)\r
119                 initVertexOrder(i_square, i_direction, sqvertex_ref,linear_ref);\r
120                 \r
121                 //基準矩形を設定\r
122                 this._offset.setSquare(i_width,this._center);\r
123 \r
124                 // rotationを矩形情報から計算\r
125                 this._rotmatrix.initRotBySquare(linear_ref,sqvertex_ref);\r
126 \r
127                 //平行移動量計算機にオフセット頂点をセット\r
128                 this._calculator.setOffsetSquare(this._offset);\r
129                 \r
130                 //平行移動量計算機に適応先矩形の情報をセット\r
131                 this._calculator.setFittedSquare(sqvertex_ref); \r
132 \r
133                 //回転行列の平行移動量の計算\r
134                 this._calculator.calculateTransfer(this._rotmatrix,trans);\r
135                 \r
136                 //計算結果の最適化(this._rotmatrix,trans)\r
137                 this._mat_optimize.optimize(this._rotmatrix,trans,this._calculator);\r
138                 \r
139                 // マトリクスの保存\r
140                 o_result_conv.updateMatrixValue(this._rotmatrix, this._offset.point, trans);\r
141                 return;\r
142         }\r
143         /**\r
144          * double arGetTransMatCont( ARMarkerInfo *marker_info, double prev_conv[3][4],double center[2], double width, double conv[3][4] )\r
145          * \r
146          * @param i_square\r
147          * @param i_direction\r
148          * マーカーの方位を指定する。\r
149          * @param i_width\r
150          * @param io_result_conv\r
151          * 計算履歴を持つNyARTransMatResultオブジェクトを指定する。 履歴を持たない場合は、transMatと同じ処理を行う。\r
152          * @return\r
153          * @throws NyARException\r
154          */\r
155         public void transMatContinue(NyARSquare i_square, int i_direction, double i_width, NyARTransMatResult io_result_conv) throws NyARException\r
156         {\r
157                 final NyARDoublePoint2d[] sqvertex_ref = __transMat_sqvertex_ref;\r
158                 final NyARLinear[] linear_ref=__transMat_linear_ref;\r
159                 final NyARDoublePoint3d trans=this.__transMat_trans;\r
160 \r
161                 // io_result_convが初期値なら、transMatで計算する。\r
162                 if (!io_result_conv.hasValue()) {\r
163                         this.transMat(i_square, i_direction, i_width, io_result_conv);\r
164                         return;\r
165                 }\r
166                 \r
167                 //基準矩形を設定\r
168                 this._offset.setSquare(i_width,this._center);\r
169 \r
170                 // rotationを矩形情報を一つ前の変換行列で初期化\r
171                 this._rotmatrix.initRotByPrevResult(io_result_conv);\r
172 \r
173                 //平行移動量計算機に、オフセット頂点をセット\r
174                 this._calculator.setOffsetSquare(this._offset);\r
175                 \r
176                 //平行移動量計算機に、適応先矩形の情報をセット\r
177                 this._calculator.setFittedSquare(sqvertex_ref); \r
178                                 \r
179                 //回転行列の平行移動量の計算\r
180                 this._calculator.calculateTransfer(this._rotmatrix,trans);\r
181                 \r
182                 //計算結果の最適化(this._rotmatrix,trans)\r
183                 final double err=this._mat_optimize.optimize(this._rotmatrix,trans,this._calculator);\r
184                 \r
185                 //計算結果を保存\r
186                 io_result_conv.updateMatrixValue(this._rotmatrix, this._offset.point, trans);\r
187 \r
188                 // エラー値が許容範囲でなければTransMatをやり直し\r
189                 if (err > AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR) {\r
190                         // rotationを矩形情報で初期化\r
191                         this._rotmatrix.initRotBySquare(linear_ref,sqvertex_ref);\r
192                         //回転行列の平行移動量の計算\r
193                         this._calculator.calculateTransfer(this._rotmatrix,trans);\r
194                         //計算結果の最適化(this._rotmatrix,trans)\r
195                         final double err2=this._mat_optimize.optimize(this._rotmatrix,trans,this._calculator);\r
196                         //エラー値が低かったら値を差換え\r
197                         if (err2 < err) {\r
198                                 // 良い値が取れたら、差換え\r
199                                 io_result_conv.updateMatrixValue(this._rotmatrix, this._offset.point, trans);\r
200                         }\r
201                 }\r
202                 return;\r
203         }\r
204 }\r