Subversion Repositories AndroidProjects

Rev

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