Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 203 | chris | 1 | /* |
| 2 | * PROJECT: NyARToolkit |
||
| 3 | * -------------------------------------------------------------------------------- |
||
| 4 | * This work is based on the original ARToolKit developed by |
||
| 5 | * Hirokazu Kato |
||
| 6 | * Mark Billinghurst |
||
| 7 | * HITLab, University of Washington, Seattle |
||
| 8 | * http://www.hitl.washington.edu/artoolkit/ |
||
| 9 | * |
||
| 10 | * The NyARToolkit is Java version ARToolkit class library. |
||
| 11 | * Copyright (C)2008 R.Iizuka |
||
| 12 | * |
||
| 13 | * This program is free software; you can redistribute it and/or |
||
| 14 | * modify it under the terms of the GNU General Public License |
||
| 15 | * as published by the Free Software Foundation; either version 2 |
||
| 16 | * of the License, or (at your option) any later version. |
||
| 17 | * |
||
| 18 | * This program is distributed in the hope that it will be useful, |
||
| 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
| 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
| 21 | * GNU General Public License for more details. |
||
| 22 | * |
||
| 23 | * You should have received a copy of the GNU General Public License |
||
| 24 | * along with this framework; if not, write to the Free Software |
||
| 25 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||
| 26 | * |
||
| 27 | * For further information please contact. |
||
| 28 | * http://nyatla.jp/nyatoolkit/ |
||
| 29 | * <airmail(at)ebony.plala.or.jp> |
||
| 30 | * |
||
| 31 | */ |
||
| 32 | package jp.nyatla.nyartoolkit.core; |
||
| 33 | |||
| 34 | |||
| 35 | |||
| 36 | |||
| 37 | |||
| 38 | |||
| 39 | |||
| 40 | /** |
||
| 41 | * typedef struct { |
||
| 42 | * int area; |
||
| 43 | * double pos[2]; |
||
| 44 | * int coord_num; |
||
| 45 | * int x_coord[AR_CHAIN_MAX]; |
||
| 46 | * int y_coord[AR_CHAIN_MAX]; |
||
| 47 | * int vertex[5]; |
||
| 48 | * } ARMarkerInfo2; |
||
| 49 | * |
||
| 50 | */ |
||
| 51 | class NyARMarker |
||
| 52 | { |
||
| 53 | /** |
||
| 54 | * メモリブロックのサイズ(32*4=128kb) |
||
| 55 | */ |
||
| 56 | private static final int ALLOCATE_PAGE_SIZE=256; |
||
| 57 | /** |
||
| 58 | * メモリブロックの初期サイズ |
||
| 59 | */ |
||
| 60 | private static final int INITIAL_SIZE=1; |
||
| 61 | int[] x_coord=new int[INITIAL_SIZE]; |
||
| 62 | int[] y_coord=new int[INITIAL_SIZE]; |
||
| 63 | int coord_num; |
||
| 64 | int area; |
||
| 65 | final double[] pos=new double[2]; |
||
| 66 | final int[] mkvertex=new int[5]; |
||
| 67 | /** |
||
| 68 | * coordバッファをi_chain_num以上のサイズに再アロケートする。 |
||
| 69 | * 内容の引継ぎは行われない。 |
||
| 70 | * @param i_chain_num |
||
| 71 | */ |
||
| 72 | private void reallocCoordArray(int i_chain_num) |
||
| 73 | { |
||
| 74 | if(x_coord.length<i_chain_num){ |
||
| 75 | //ALLOCATE_PAGE_SIZE単位で確保する。 |
||
| 76 | int new_size=((i_chain_num+ALLOCATE_PAGE_SIZE-1)/ALLOCATE_PAGE_SIZE)*ALLOCATE_PAGE_SIZE; |
||
| 77 | x_coord=new int[new_size]; |
||
| 78 | y_coord=new int[new_size]; |
||
| 79 | coord_num=0; |
||
| 80 | } |
||
| 81 | } |
||
| 82 | public void setCoordXY(int i_v1,int i_coord_num,int[] i_xcoord,int[] i_ycoord) |
||
| 83 | { |
||
| 84 | //メモリの割り当て保障 |
||
| 85 | reallocCoordArray(i_coord_num+1); |
||
| 86 | //[A B C]を[B C A]に並べなおす。 |
||
| 87 | System.arraycopy(i_xcoord,i_v1,x_coord,0,i_coord_num-i_v1); |
||
| 88 | System.arraycopy(i_xcoord,0,x_coord,i_coord_num-i_v1, i_v1); |
||
| 89 | x_coord[i_coord_num]=x_coord[0]; |
||
| 90 | System.arraycopy(i_ycoord,i_v1,y_coord,0,i_coord_num-i_v1); |
||
| 91 | System.arraycopy(i_ycoord,0,y_coord,i_coord_num-i_v1, i_v1); |
||
| 92 | y_coord[i_coord_num]=y_coord[0]; |
||
| 93 | coord_num=i_coord_num+1; |
||
| 94 | return; |
||
| 95 | //arGetContour関数から取り外した部分 |
||
| 96 | // int[] wx=new int[v1];//new int[Config.AR_CHAIN_MAX]; |
||
| 97 | // int[] wy=new int[v1]; //new int[Config.AR_CHAIN_MAX]; |
||
| 98 | // for(i=0;i<v1;i++) { |
||
| 99 | // wx[i] = marker_ref.x_coord[i];//wx[i] = marker_info2->x_coord[i]; |
||
| 100 | // wy[i] = marker_ref.y_coord[i];//wy[i] = marker_info2->y_coord[i]; |
||
| 101 | // } |
||
| 102 | // for(i=0;i<marker_ref.coord_num-v1;i++) {//for(i=v1;i<marker_info2->coord_num;i++) { |
||
| 103 | // marker_ref.x_coord[i] = marker_ref.x_coord[i+v1];//marker_info2->x_coord[i-v1] = marker_info2->x_coord[i]; |
||
| 104 | // marker_ref.y_coord[i] = marker_ref.y_coord[i+v1];//marker_info2->y_coord[i-v1] = marker_info2->y_coord[i]; |
||
| 105 | // } |
||
| 106 | // for(i=0;i<v1;i++) { |
||
| 107 | // marker_ref.x_coord[i-v1+marker_ref.coord_num] = wx[i];//marker_info2->x_coord[i-v1+marker_info2->coord_num] = wx[i]; |
||
| 108 | // marker_ref.y_coord[i-v1+marker_ref.coord_num] = wy[i];//marker_info2->y_coord[i-v1+marker_info2->coord_num] = wy[i]; |
||
| 109 | // } |
||
| 110 | // marker_ref.x_coord[marker_ref.coord_num] = marker_ref.x_coord[0];//marker_info2->x_coord[marker_info2->coord_num] = marker_info2->x_coord[0]; |
||
| 111 | // marker_ref.y_coord[marker_ref.coord_num] = marker_ref.y_coord[0];//marker_info2->y_coord[marker_info2->coord_num] = marker_info2->y_coord[0]; |
||
| 112 | // marker_ref.coord_num++;//marker_info2->coord_num++; |
||
| 113 | } |
||
| 114 | private final NyARVertexCounter wk_checkSquare_wv1=new NyARVertexCounter(); |
||
| 115 | private final NyARVertexCounter wk_checkSquare_wv2=new NyARVertexCounter(); |
||
| 116 | /** |
||
| 117 | * static int arDetectMarker2_check_square( int area, ARMarkerInfo2 *marker_info2, double factor ) |
||
| 118 | * 関数の代替関数 |
||
| 119 | * OPTIMIZED STEP [450->415] |
||
| 120 | * @param i_area |
||
| 121 | * @param i_factor |
||
| 122 | * @return |
||
| 123 | */ |
||
| 124 | public boolean checkSquare(int i_area,double i_factor,double i_pos_x,double i_pos_y) |
||
| 125 | { |
||
| 126 | final int[] l_vertex=mkvertex; |
||
| 127 | final int[] l_x_coord=x_coord; |
||
| 128 | final int[] l_y_coord=y_coord; |
||
| 129 | final NyARVertexCounter wv1=wk_checkSquare_wv1; |
||
| 130 | final NyARVertexCounter wv2=wk_checkSquare_wv2; |
||
| 131 | int sx,sy; |
||
| 132 | int dmax,d,v1; |
||
| 133 | |||
| 134 | int v2;// int wvnum1,wvnum2,v2; |
||
| 135 | int i; |
||
| 136 | |||
| 137 | final int L_coord_num_m1=this.coord_num-1; |
||
| 138 | dmax = 0; |
||
| 139 | v1 = 0; |
||
| 140 | sx = l_x_coord[0];//sx = marker_info2->x_coord[0]; |
||
| 141 | sy = l_y_coord[0];//sy = marker_info2->y_coord[0]; |
||
| 142 | for(i=1;i<L_coord_num_m1;i++){//for(i=1;i<marker_info2->coord_num-1;i++) { |
||
| 143 | d = (l_x_coord[i]-sx)*(l_x_coord[i]-sx)+ (l_y_coord[i]-sy)*(l_y_coord[i]-sy); |
||
| 144 | if( d > dmax ) { |
||
| 145 | dmax = d; |
||
| 146 | v1 = i; |
||
| 147 | } |
||
| 148 | } |
||
| 149 | |||
| 150 | final double thresh = (i_area/0.75) * 0.01 * i_factor; |
||
| 151 | |||
| 152 | l_vertex[0] = 0; |
||
| 153 | |||
| 154 | if(!wv1.getVertex(l_x_coord,l_y_coord, 0, v1,thresh)){ //if( get_vertex(marker_info2->x_coord, marker_info2->y_coord, 0, v1,thresh, wv1, &wvnum1) < 0 ) { |
||
| 155 | return false; |
||
| 156 | } |
||
| 157 | if(!wv2.getVertex(l_x_coord,l_y_coord,v1,L_coord_num_m1, thresh)) {//if(get_vertex(marker_info2->x_coord, marker_info2->y_coord,v1, marker_info2->coord_num-1, thresh, wv2, &wvnum2) < 0 ) { |
||
| 158 | return false; |
||
| 159 | } |
||
| 160 | |||
| 161 | if(wv1.number_of_vertex==1 && wv2.number_of_vertex==1) {//if( wvnum1 == 1 && wvnum2 == 1 ) { |
||
| 162 | l_vertex[1] = wv1.vertex[0]; |
||
| 163 | l_vertex[2] = v1; |
||
| 164 | l_vertex[3] = wv2.vertex[0]; |
||
| 165 | }else if( wv1.number_of_vertex>1 && wv2.number_of_vertex==0 ) {//}else if( wvnum1 > 1 && wvnum2 == 0 ) { |
||
| 166 | v2 = v1 / 2; |
||
| 167 | if(!wv1.getVertex(l_x_coord,l_y_coord,0, v2, thresh)) { |
||
| 168 | return false; |
||
| 169 | } |
||
| 170 | if(!wv2.getVertex(l_x_coord,l_y_coord,v2, v1, thresh)) { |
||
| 171 | return false; |
||
| 172 | } |
||
| 173 | if(wv1.number_of_vertex==1 && wv2.number_of_vertex==1 ) { |
||
| 174 | l_vertex[1] = wv1.vertex[0]; |
||
| 175 | l_vertex[2] = wv2.vertex[0]; |
||
| 176 | l_vertex[3] = v1; |
||
| 177 | }else{ |
||
| 178 | return false; |
||
| 179 | } |
||
| 180 | }else if(wv1.number_of_vertex==0 && wv2.number_of_vertex> 1 ) { |
||
| 181 | v2 = (v1 + this.coord_num-1) / 2; |
||
| 182 | |||
| 183 | if(!wv1.getVertex(l_x_coord,l_y_coord,v1, v2, thresh)) { |
||
| 184 | return false; |
||
| 185 | } |
||
| 186 | if(!wv2.getVertex(l_x_coord,l_y_coord,v2,L_coord_num_m1, thresh)) { |
||
| 187 | return false; |
||
| 188 | } |
||
| 189 | if( wv1.number_of_vertex==1 && wv2.number_of_vertex==1 ) { |
||
| 190 | l_vertex[1] = v1; |
||
| 191 | l_vertex[2] = wv1.vertex[0]; |
||
| 192 | l_vertex[3] = wv2.vertex[0]; |
||
| 193 | } |
||
| 194 | else { |
||
| 195 | return false; |
||
| 196 | } |
||
| 197 | } |
||
| 198 | else { |
||
| 199 | return false; |
||
| 200 | } |
||
| 201 | l_vertex[4] =L_coord_num_m1;//この値使ってるの? |
||
| 202 | // |
||
| 203 | area = i_area; |
||
| 204 | pos[0] = i_pos_x; |
||
| 205 | pos[1] = i_pos_y; |
||
| 206 | // marker_holder[marker_num2].pos[1] = wpos[i*2+1]; |
||
| 207 | return true; |
||
| 208 | } |
||
| 209 | } |
||
| 210 | |||
| 211 | |||
| 212 | |||
| 213 | /** |
||
| 214 | * get_vertex関数を切り離すためのクラス |
||
| 215 | * |
||
| 216 | */ |
||
| 217 | final class NyARVertexCounter |
||
| 218 | { |
||
| 219 | public final int[] vertex=new int[10];//5まで削れる |
||
| 220 | public int number_of_vertex; |
||
| 221 | private double thresh; |
||
| 222 | private int[] x_coord; |
||
| 223 | private int[] y_coord; |
||
| 224 | |||
| 225 | public boolean getVertex(int[] i_x_coord, int[] i_y_coord, int st, int ed,double i_thresh) |
||
| 226 | { |
||
| 227 | this.number_of_vertex=0; |
||
| 228 | this.thresh=i_thresh; |
||
| 229 | this.x_coord=i_x_coord; |
||
| 230 | this.y_coord=i_y_coord; |
||
| 231 | return get_vertex(st,ed); |
||
| 232 | } |
||
| 233 | /** |
||
| 234 | * static int get_vertex( int x_coord[], int y_coord[], int st, int ed,double thresh, int vertex[], int *vnum) |
||
| 235 | * 関数の代替関数 |
||
| 236 | * @param x_coord |
||
| 237 | * @param y_coord |
||
| 238 | * @param st |
||
| 239 | * @param ed |
||
| 240 | * @param thresh |
||
| 241 | * @return |
||
| 242 | */ |
||
| 243 | private boolean get_vertex(int st, int ed) |
||
| 244 | { |
||
| 245 | double d, dmax; |
||
| 246 | double a, b, c; |
||
| 247 | int i, v1=0; |
||
| 248 | final int[] lx_coord=this.x_coord; |
||
| 249 | final int[] ly_coord=this.y_coord; |
||
| 250 | a = ly_coord[ed] - ly_coord[st]; |
||
| 251 | b = lx_coord[st] - lx_coord[ed]; |
||
| 252 | c = lx_coord[ed]*ly_coord[st] - ly_coord[ed]*lx_coord[st]; |
||
| 253 | dmax = 0; |
||
| 254 | for(i=st+1;i<ed;i++) { |
||
| 255 | d = a*lx_coord[i] + b*ly_coord[i] + c; |
||
| 256 | if( d*d > dmax ) { |
||
| 257 | dmax = d*d; |
||
| 258 | v1 = i; |
||
| 259 | } |
||
| 260 | } |
||
| 261 | if( dmax/(a*a+b*b) > thresh ) { |
||
| 262 | if(!get_vertex(st, v1)){ |
||
| 263 | return false; |
||
| 264 | } |
||
| 265 | if(number_of_vertex > 5 ){ |
||
| 266 | return false; |
||
| 267 | } |
||
| 268 | vertex[number_of_vertex] = v1;//vertex[(*vnum)] = v1; |
||
| 269 | number_of_vertex++;//(*vnum)++; |
||
| 270 | |||
| 271 | if(!get_vertex(v1, ed)){ |
||
| 272 | return false; |
||
| 273 | } |
||
| 274 | } |
||
| 275 | return true; |
||
| 276 | } |
||
| 277 | } |
||
| 278 |