2 * PROJECT: NyARToolkit(Extension)
\r
3 * --------------------------------------------------------------------------------
\r
4 * The NyARToolkit is Java version ARToolkit class library.
\r
5 * Copyright (C)2008 R.Iizuka
\r
7 * This program is free software; you can redistribute it and/or
\r
8 * modify it under the terms of the GNU General Public License
\r
9 * as published by the Free Software Foundation; either version 2
\r
10 * of the License, or (at your option) any later version.
\r
12 * This program is distributed in the hope that it will be useful,
\r
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
15 * GNU General Public License for more details.
\r
17 * You should have received a copy of the GNU General Public License
\r
18 * along with this framework; if not, write to the Free Software
\r
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
21 * For further information please contact.
\r
22 * http://nyatla.jp/nyatoolkit/
\r
23 * <airmail(at)ebony.plala.or.jp>
\r
26 package jp.nyatla.nyartoolkit.core.utils;
\r
29 * 連立方程式を解くためのプロセッサクラスです。
\r
32 public class NyARSystemOfLinearEquationsProcessor
\r
35 * i_reftとi_rightの整合性を確認します。
\r
40 private static boolean isValid2dArray(double[][] i_left,double[] i_right)
\r
42 final int sm=i_left.length;
\r
43 final int sn=i_left[0].length;
\r
44 if(i_left.length!=sm){
\r
47 if(i_right.length!=sm){
\r
50 for(int i=1;i<sm;i++){
\r
51 if(i_left[i].length!=sn){
\r
58 * [i_left_src]=[i_right_src]の式にガウスの消去法を実行して、[x][x]の要素が1になるように基本変形します。
\r
59 * i_mとi_nが等しくない時は、最終行までの[x][x]要素までを1になるように変形します。
\r
61 * 連立方程式の左辺値を指定します。[i_m][i_n]の配列を指定してください。
\r
63 * 連立方程式の右辺値を指定します。[i_m][i_n]の配列を指定してください。
\r
69 * 最終行まで基本変形ができてばtrueを返します。
\r
71 public static boolean doGaussianElimination(double[][] i_left,double[] i_right,int i_n,int i_m)
\r
74 assert isValid2dArray(i_left,i_right);
\r
78 for(int solve_row=0;solve_row<i_m;solve_row++)
\r
81 int pivod=solve_row;
\r
82 double pivod_value=Math.abs(i_left[pivod][pivod]);
\r
83 for(int i=solve_row+1;i<i_m;i++){
\r
84 final double pivod_2=Math.abs(i_left[i][pivod]);
\r
85 if(pivod_value<Math.abs(pivod_2)){
\r
87 pivod_value=pivod_2;
\r
90 if(solve_row!=pivod){
\r
91 //行の入れ替え(Cの時はポインタテーブル使って!)
\r
92 final double[] t=i_left[solve_row];
\r
93 i_left[solve_row]=i_left[pivod];
\r
95 final double t2=i_right[solve_row];
\r
96 i_right[solve_row]=i_right[pivod];
\r
100 final double[] dest_l_n=i_left[solve_row];
\r
101 final double dest_l_nn=i_left[solve_row][solve_row];
\r
102 if(dest_l_nn==0.0){
\r
103 //選択後の対角要素が0になってしまったら失敗する。
\r
107 //消去計算(0 - solve_row-1項までの消去)
\r
108 for(int i=0;i<solve_row;i++){
\r
109 double s=dest_l_n[i];
\r
110 for(int i2=0;i2<i_n;i2++)
\r
112 final double p=i_left[i][i2]*s;
\r
113 dest_l_n[i2]=dest_l_n[i2]-p;
\r
115 final double k=i_right[i]*s;
\r
116 i_right[solve_row]=i_right[solve_row]-k;
\r
120 final double d=dest_l_n[solve_row];
\r
121 for(int i2=0;i2<solve_row;i2++){
\r
125 dest_l_n[solve_row]=1.0;
\r
126 for(int i=solve_row+1;i<i_n;i++){
\r
129 i_right[solve_row]/=d;
\r
135 * i_leftとi_rightの連立方程式を解いて、i_left,i_right内容を更新します。
\r
136 * i_right[n]の内容が、i_left[x][n]番目の係数の解になります。
\r
138 * 方程式が解ければtrueを返します。
\r
140 public static boolean solve(double[][] i_left,double[] i_right,int i_number_of_system)
\r
142 return doGaussianElimination(i_left,i_right,i_number_of_system,i_number_of_system);
\r