2 * PROJECT: NyARToolkit(Extension)
\r
3 * --------------------------------------------------------------------------------
\r
5 * The NyARToolkit is Java edition ARToolKit class library.
\r
6 * Copyright (C)2008-2009 Ryo Iizuka
\r
8 * This program is free software: you can redistribute it and/or modify
\r
9 * it under the terms of the GNU General Public License as published by
\r
10 * the Free Software Foundation, either version 3 of the License, or
\r
11 * (at your option) any later version.
\r
13 * This program is distributed in the hope that it will be useful,
\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
16 * GNU General Public License for more details.
\r
18 * You should have received a copy of the GNU General Public License
\r
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
\r
21 * For further information please contact.
\r
22 * http://nyatla.jp/nyatoolkit/
\r
23 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
\r
26 package jp.nyatla.nyartoolkit.core.transmat.solver;
\r
28 import jp.nyatla.nyartoolkit.NyARException;
\r
29 import jp.nyatla.nyartoolkit.core.param.NyARPerspectiveProjectionMatrix;
\r
30 import jp.nyatla.nyartoolkit.core.types.*;
\r
33 * このクラスは、ARToolKitと同じアルゴリズムを、異なる演算手順で処理して、並進ベクトルを求めます。
\r
34 * アルゴリズムは、ARToolKit 拡張現実プログラミング入門 の、P207のものです。
\r
37 * [A]*[T]=bを、[A]T*[A]*[T]=[A]T*[b]にする。
\r
38 * set2dVertexで[A]T*[A]=[M]を計算して、Aの3列目の情報だけ保存しておく。
\r
39 * getTransportVectorで[M]*[T]=[A]T*[b]を連立方程式で解いて、[T]を得る。
\r
43 public class NyARTransportVectorSolver implements INyARTransportVectorSolver
\r
45 private double[] _cx;
\r
46 private double[] _cy;
\r
47 private final NyARPerspectiveProjectionMatrix _projection_mat;
\r
48 private int _nmber_of_vertex;
\r
51 * 射影変換オブジェクトの参照値と、取り扱う頂点の最大数を指定して、インスタンスを生成します。
\r
52 * @param i_projection_mat_ref
\r
54 * @param i_max_vertex
\r
57 public NyARTransportVectorSolver(NyARPerspectiveProjectionMatrix i_projection_mat_ref,int i_max_vertex)
\r
59 this._projection_mat=i_projection_mat_ref;
\r
60 this._cx=new double[i_max_vertex];
\r
61 this._cy=new double[i_max_vertex];
\r
64 private double _a00,_a01_10,_a02_20,_a11,_a12_21,_a22;
\r
66 * この関数は、射影変換後の2次元頂点座標をセットします。
\r
67 * i_number_of_vertexは、コンストラクタで指定した最大数以下である必要があります。
\r
69 public void set2dVertex(NyARDoublePoint2d[] i_ref_vertex_2d,int i_number_of_vertex) throws NyARException
\r
71 //3x2nと2n*3の行列から、最小二乗法計算するために3x3マトリクスを作る。
\r
73 final double[] cx=this._cx;
\r
74 final double[] cy=this._cy;
\r
77 double p00=this._projection_mat.m00;
\r
78 double p01=this._projection_mat.m01;
\r
79 double p11=this._projection_mat.m11;
\r
80 double p12=this._projection_mat.m12;
\r
81 double p02=this._projection_mat.m02;
\r
84 this._a00=i_number_of_vertex*p00*p00;
\r
85 this._a01_10=i_number_of_vertex*p00*p01;
\r
86 this._a11=i_number_of_vertex*(p01*p01+p11*p11);
\r
91 for(int i=0;i<i_number_of_vertex;i++){
\r
93 w3=p02-(cx[i]=i_ref_vertex_2d[i].x);
\r
94 w4=p12-(cy[i]=i_ref_vertex_2d[i].y);
\r
99 this._a02_20=w1*p00;
\r
100 this._a12_21=p01*w1+p11*w2;
\r
103 this._nmber_of_vertex=i_number_of_vertex;
\r
108 * 画面座標群と3次元座標群から、平行移動量を計算します。
\r
109 * 2d座標系は、直前に実行した{@link #set2dVertex}のものを使用します。
\r
111 public void solveTransportVector(NyARDoublePoint3d[] i_vertex3d,NyARDoublePoint3d o_transfer) throws NyARException
\r
113 final int number_of_vertex=this._nmber_of_vertex;
\r
114 final double p00=this._projection_mat.m00;
\r
115 final double p01=this._projection_mat.m01;
\r
116 final double p02=this._projection_mat.m02;
\r
117 final double p11=this._projection_mat.m11;
\r
118 final double p12=this._projection_mat.m12;
\r
120 final double[] cx=this._cx;
\r
121 final double[] cy=this._cy;
\r
125 double b1=0,b2=0,b3=0;
\r
126 for(int i=0;i<number_of_vertex;i++)
\r
128 double w1=i_vertex3d[i].z*cx[i]-p00*i_vertex3d[i].x-p01*i_vertex3d[i].y-p02*i_vertex3d[i].z;
\r
129 double w2=i_vertex3d[i].z*cy[i]-p11*i_vertex3d[i].y-p12*i_vertex3d[i].z;
\r
132 b3+=cx[i]*w1+cy[i]*w2;
\r
135 b3=p02*b1+p12*b2-b3;//順番変えたらダメよ
\r
138 //([A]T*[A])*[T]=[A]T*[b]を方程式で解く。
\r
139 //a01とa10を0と仮定しても良いんじゃないかな?
\r
140 double a00=this._a00;
\r
141 double a01=this._a01_10;
\r
142 double a02=this._a02_20;
\r
143 double a11=this._a11;
\r
144 double a12=this._a12_21;
\r
145 double a22=this._a22;
\r
147 double t1=a22*b2-a12*b3;
\r
148 double t2=a12*b2-a11*b3;
\r
149 double t3=a01*b3-a02*b2;
\r
150 double t4=a12*a12-a11*a22;
\r
151 double t5=a02*a12-a01*a22;
\r
152 double t6=a02*a11-a01*a12;
\r
153 double det=a00*t4-a01*t5 + a02*t6;
\r
154 o_transfer.x= (a01*t1 - a02*t2 +b1*t4)/det;
\r
155 o_transfer.y=-(a00*t1 + a02*t3 +b1*t5)/det;
\r
156 o_transfer.z= (a00*t2 + a01*t3 +b1*t6)/det;
\r