OSDN Git Service

git-svn-id: http://svn.sourceforge.jp/svnroot/nyartoolkit/NyARToolkit/trunk@802 7cac0...
[nyartoolkit-and/nyartoolkit-and.git] / lib / src.rpf / jp / nyatla / nyartoolkit / rpf / utils / VecLinearCoordinates.java
1 package jp.nyatla.nyartoolkit.rpf.utils;\r
2 \r
3 import jp.nyatla.nyartoolkit.core.types.NyARVecLinear2d;\r
4 \r
5 /**\r
6  * このクラスは、RFFパッケージが使う輪郭データのリストです。\r
7  * リスト要素に対する計算機能と、リストの操作機能を提供します。\r
8  *\r
9  */\r
10 public class VecLinearCoordinates\r
11 {       \r
12         /**\r
13          * データ型です。\r
14          * {@link NyARVecLinear2d}に輪郭強度値を追加したものです。\r
15          */\r
16         public static class VecLinearCoordinatePoint extends NyARVecLinear2d\r
17         {\r
18                 /**\r
19                  * ベクトルの2乗値です。輪郭の強度値にもなります。\r
20                  */\r
21                 public double scalar;\r
22                 public static VecLinearCoordinatePoint[] createArray(int i_length)\r
23                 {\r
24                         VecLinearCoordinatePoint[] r=new VecLinearCoordinatePoint[i_length];\r
25                         for(int i=0;i<i_length;i++){\r
26                                 r[i]=new VecLinearCoordinatePoint();\r
27                         }\r
28                         return r;\r
29                 }\r
30         }\r
31         /**\r
32          * [read only] リストの有効な長さです。\r
33          */\r
34         public int length;\r
35         /**\r
36          * リスト要素を格納する配列です。\r
37          * この長さは、有効なデータの長さで無いことに注意してください。有効な長さは、{@link #length}から得られます。\r
38          */\r
39         public VecLinearCoordinatePoint[] items;\r
40         /**\r
41          * コンストラクタです。\r
42          * @param i_length\r
43          * リストの最大数を指定します。\r
44          */\r
45 \r
46         public VecLinearCoordinates(int i_length)\r
47         {\r
48                 this.length = 0;\r
49                 this.items = VecLinearCoordinatePoint.createArray(i_length);\r
50         }\r
51         /**\r
52          * この関数は、要素のベクトルを、1,2象限方向に制限します。\r
53          */\r
54         public final void limitQuadrantTo12()\r
55         {\r
56                 for (int i = this.length - 1; i >= 0; i--) {\r
57                         VecLinearCoordinates.VecLinearCoordinatePoint target1 = this.items[i];\r
58                         if (target1.dy < 0) {\r
59                                 target1.dy *= -1;\r
60                                 target1.dx *= -1;\r
61                         }\r
62                 }\r
63         }\r
64         /**\r
65          * この関数は、輪郭配列からキーのベクトル(絶対値の大きいベクトル)を抽出して、そのインデクスを配列に返します。\r
66          * 抽出したベクトルの順序は、元の配列と同じです。\r
67          * @param o_index\r
68          * インデクス番号を受け取る配列。受け取るインデックスの個数は、この配列の数と同じになります。\r
69          */\r
70         public void getOrderdKeyCoordIndexes(int[] o_index)\r
71         {\r
72                 getKeyCoordIndexes(o_index);\r
73                 // idxでソート\r
74                 int out_len_1 = o_index.length - 1;\r
75                 for (int i = 0; i < out_len_1;) {\r
76                         if (o_index[i] > o_index[i + 1]) {\r
77                                 int t = o_index[i];\r
78                                 o_index[i] = o_index[i + 1];\r
79                                 o_index[i + 1] = t;\r
80                                 i = 0;\r
81                                 continue;\r
82                         }\r
83                         i++;\r
84                 }\r
85                 return;\r
86         }\r
87         /**\r
88          * この関数は、輪郭配列からキーのベクトル(絶対値の大きいベクトル)を抽出して、そのインデクスを配列に返します。\r
89          * 抽出したベクトルの順序は、元の配列と異なります。そのかわり、{@link #getOrderdKeyCoordIndexes}より若干高速です。\r
90          * @param o_index\r
91          * インデクス番号を受け取る配列。受け取るインデックスの個数は、この配列の数と同じになります。\r
92          */\r
93         public void getKeyCoordIndexes(int[] o_index)\r
94         {\r
95                 VecLinearCoordinatePoint[] vp = this.items;\r
96                 assert (o_index.length <= this.length);\r
97                 int i;\r
98                 int out_len = o_index.length;\r
99                 int out_len_1 = out_len - 1;\r
100                 for (i = out_len - 1; i >= 0; i--) {\r
101                         o_index[i] = i;\r
102                 }\r
103                 // sqdistでソートする(B->S)\r
104                 for (i = 0; i < out_len_1;) {\r
105                         if (vp[o_index[i]].scalar < vp[o_index[i + 1]].scalar) {\r
106                                 int t = o_index[i];\r
107                                 o_index[i] = o_index[i + 1];\r
108                                 o_index[i + 1] = t;\r
109                                 i = 0;\r
110                                 continue;\r
111                         }\r
112                         i++;\r
113                 }\r
114                 // 先に4個をsq_distでソートしながら格納\r
115                 for (i = out_len; i < this.length; i++) {\r
116                         // 配列の値と比較\r
117                         for (int i2 = 0; i2 < out_len; i2++) {\r
118                                 if (vp[i].scalar > vp[o_index[i2]].scalar) {\r
119                                         // 値挿入の為のシフト\r
120                                         for (int i3 = out_len - 1; i3 > i2; i3--) {\r
121                                                 o_index[i3] = o_index[i3 - 1];\r
122                                         }\r
123                                         // 設定\r
124                                         o_index[i2] = i;\r
125                                         break;\r
126                                 }\r
127                         }\r
128                 }\r
129                 return;\r
130         }\r
131         /**\r
132          * この関数は、輪郭配列からキーのベクトル(絶対値の大きいベクトル)を抽出して、そのオブジェクトの参照値を配列に返します。\r
133          * 抽出したベクトルの順序は、元の配列と異なります。\r
134          * @param o_index\r
135          * オブジェクトの参照値を受け取る配列。受け取るオブジェクトの個数は、この配列の数と同じになります。\r
136          */\r
137         public void getKeyCoord(VecLinearCoordinatePoint[] o_index)\r
138         {\r
139                 VecLinearCoordinatePoint[] vp = this.items;\r
140                 assert (o_index.length <= this.length);\r
141                 int i;\r
142                 int out_len = o_index.length;\r
143                 int out_len_1 = out_len - 1;\r
144                 for (i = out_len - 1; i >= 0; i--) {\r
145                         o_index[i] = vp[i];\r
146                 }\r
147                 // sqdistでソートする(B->S)\r
148                 for (i = 0; i < out_len_1;) {\r
149                         if (o_index[i].scalar < o_index[i + 1].scalar) {\r
150                                 VecLinearCoordinatePoint t = o_index[i];\r
151                                 o_index[i] = o_index[i + 1];\r
152                                 o_index[i + 1] = t;\r
153                                 i = 0;\r
154                                 continue;\r
155                         }\r
156                         i++;\r
157                 }\r
158                 // 先に4個をsq_distでソートしながら格納\r
159                 for (i = out_len; i < this.length; i++) {\r
160                         // 配列の値と比較\r
161                         for (int i2 = 0; i2 < out_len; i2++) {\r
162                                 if (vp[i].scalar > o_index[i2].scalar) {\r
163                                         // 値挿入の為のシフト\r
164                                         for (int i3 = out_len - 1; i3 > i2; i3--) {\r
165                                                 o_index[i3] = o_index[i3 - 1];\r
166                                         }\r
167                                         // 設定\r
168                                         o_index[i2] = vp[i];\r
169                                         break;\r
170                                 }\r
171                         }\r
172                 }\r
173                 return;\r
174         }       \r
175         \r
176         /**\r
177          * この関数は、最も大きいベクトル成分のインデクスを返します。\r
178          * @return\r
179          * ベクトルのインデクス。\r
180          */\r
181         public final int getMaxCoordIndex()\r
182         {\r
183                 VecLinearCoordinatePoint[] vp = this.items;\r
184                 int index = 0;\r
185                 double max_dist = vp[0].scalar;\r
186                 for (int i = this.length - 1; i > 0; i--) {\r
187                         if (max_dist < vp[i].scalar) {\r
188                                 max_dist = vp[i].scalar;\r
189                                 index = i;\r
190                         }\r
191                 }\r
192                 return index;\r
193         }\r
194 \r
195 \r
196 \r
197         /**\r
198          * この関数は、リストから大きさ(sq_dist)が0のベクトルを削除して、要素を前方に詰めます。\r
199          */\r
200         public void removeZeroDistItem()\r
201         {\r
202                 //前方詰め\r
203                 int idx=0;\r
204                 final int len=this.length;\r
205                 for(int i=0;i<len;i++){\r
206                         if(this.items[i].scalar!=0){\r
207                                 idx++;\r
208                                 continue;\r
209                         }\r
210                         for(i=i+1;i<len;i++){\r
211                                 if(this.items[i].scalar!=0){\r
212                                         VecLinearCoordinatePoint temp = this.items[i];\r
213                                         this.items[i]=this.items[idx];\r
214                                         this.items[idx]=temp;\r
215                                         idx++;\r
216                                         i--;\r
217                                         break;\r
218                                 }\r
219                         }\r
220                 }\r
221                 this.length=idx;\r
222                 return;\r
223         }\r
224 }\r