00001
00002
00003
00004
00005 extern "C" {
00006 #include <stdarg.h>
00007 #include <float.h>
00008 };
00009
00010
00011 #include "tags.h"
00012 #include "random.h"
00013 #include <string.h>
00014
00015
00016 #define MAX_P1 10
00017 #define MAX_P2 10
00018
00019
00020
00021
00022 static class TagDbaseClass:public TclClass
00023 {
00024 public:
00025 TagDbaseClass ():TclClass ("TagDbase")
00026 {
00027 }
00028 TclObject *create (int, const char *const *)
00029 {
00030 return (new tags_database ());
00031 }
00032 } class_tags_database;
00033
00034
00035
00036
00037 void tags_database::
00038 trace (char *fmt,...)
00039 {
00040 va_list ap;
00041
00042 if (!tracetarget_)
00043 return;
00044
00045
00046 va_start (ap, fmt);
00047
00048 vsprintf (tracetarget_->buffer (), fmt, ap);
00049 tracetarget_->dump ();
00050
00051 va_end (ap);
00052 }
00053
00054
00055
00056
00057 int
00058 tags_database::command (int argc, const char *const *argv)
00059 {
00060 if (argc == 7)
00061 {
00062 if (strcmp (argv[1], "create_database") == 0)
00063 {
00064 double x_min = atof(argv[2]);
00065 double x_max = atof(argv[3]);
00066 double y_min = atof(argv[4]);
00067 double y_max = atof(argv[5]);
00068 int num_tags = atoi(argv[6]);
00069
00070 num_tags_ = num_tags;
00071 sensed_tag_list_ = new int[num_tags];
00072 freq_qry_tag_list_ = new int[num_tags];
00073 create_tags_database(x_min,x_max,y_min,y_max,num_tags);
00074 return (TCL_OK);
00075 }
00076 }
00077 else if (argc == 3)
00078 {
00079 if (strcasecmp (argv[1], "tracetarget") == 0)
00080 {
00081 TclObject *obj;
00082 if ((obj = TclObject::lookup (argv[2])) == 0)
00083 {
00084 fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__, argv[1],
00085 argv[2]);
00086 return TCL_ERROR;
00087 }
00088 tracetarget_ = (Trace *) obj;
00089 return TCL_OK;
00090 }
00091 }
00092
00093 return (TclObject::command(argc, argv));
00094 }
00095
00096
00097
00098
00099 void
00100 tags_database::create_tags_database(double x_min, double x_max, double y_min, double y_max, int num_tags)
00101 {
00102 dbase_node *dbnode;
00103 int i;
00104
00105 assert((x_min <= x_max) && (y_min <= y_max));
00106
00107
00108 tags_db_ = new dbase_node(x_min, x_max, y_min, y_max);
00109
00110
00111 add_level(x_min, x_max, y_min, y_max, tags_db_);
00112
00113
00114 for(i = 0; i < NUM_RECTANGLES; ++i) {
00115 dbnode = tags_db_->list_node_[i];
00116 assert((dbnode->x_min_ <= dbnode->x_max_) && (dbnode->y_min_ <= dbnode->y_max_));
00117 add_level(dbnode->x_min_, dbnode->x_max_, dbnode->y_min_, dbnode->y_max_, dbnode);
00118 }
00119
00120
00121 tag *newtag = new tag();
00122 i = 0;
00123 int p1 = 1, p2 = 1, p3 = 1;
00124 int max_p1 = MAX_P1, max_p2 = MAX_P2;
00125 int max_p3 = num_tags/(MAX_P1 * MAX_P2);
00126
00127 while(i < num_tags) {
00128 newtag->x_ = x_min + rn_->uniform(x_max-x_min);
00129 newtag->y_ = y_min + rn_->uniform(y_max-y_min);
00130 newtag->obj_name_ = (int)((p1 * pow(2,24)) + (p2 * pow(2,16)) + p3) ;
00131 ++p3;
00132
00133 if(p3 == max_p3) {
00134 p3 = 1;
00135 ++p2;
00136 if(p2 == max_p2) {
00137 p2 = 1;
00138 ++p1;
00139 if(p1 == max_p1) {
00140 break;
00141 }
00142 }
00143 }
00144
00145 Addtag(newtag);
00146
00147
00148 ++i;
00149 }
00150 delete newtag;
00151 }
00152
00153
00154
00155 void
00156 tags_database::add_level(double x_min, double x_max, double y_min, double y_max, dbase_node *dbnode)
00157 {
00158 double x1, x2, y1, y2, x_partition_size;
00159 int i;
00160
00161
00162 x_partition_size = (x_max-x_min)/NUM_RECTANGLES;
00163 x2 = x_min;
00164 y1 = y_min;
00165 y2 = y_max;
00166 for(i = 0; i < NUM_RECTANGLES; ++i) {
00167 x1 = x2;
00168 x2 = x1 + x_partition_size;
00169
00170
00171 if (i == (NUM_RECTANGLES - 1)) {
00172 x2 = x_max;
00173 }
00174 dbnode->list_node_[i] = new dbase_node(x1,x2,y1,y2);
00175 }
00176 }
00177
00178
00179
00180 void
00181 tags_database::Addtag(const tag* tag_)
00182 {
00183 dbase_node *dbnode = tags_db_;
00184 int i, found = FALSE;
00185 tag *new_tag;
00186
00187 while(dbnode->list_node_[0] != NULL) {
00188 for(i = 0; i < NUM_RECTANGLES; ++i) {
00189 if(((dbnode->list_node_[i])->x_min_ <= tag_->x_) && ((dbnode->list_node_[i])->x_max_ >= tag_->x_)) {
00190 found = TRUE;
00191 break;
00192 }
00193 }
00194 assert(found);
00195 dbnode = dbnode->list_node_[i];
00196 }
00197
00198 if(dbnode->tags_list_ == NULL) {
00199 dbnode->tags_list_ = new tag;
00200 new_tag = dbnode->tags_list_;
00201 }
00202 else {
00203 new_tag = dbnode->tags_list_;
00204 while(new_tag->next_ != NULL) {
00205 new_tag = new_tag->next_;
00206 }
00207 new_tag->next_ = new tag;
00208 new_tag = new_tag->next_;
00209 }
00210
00211
00212 new_tag->x_ = tag_->x_;
00213 new_tag->y_ = tag_->y_;
00214 new_tag->obj_name_ = tag_->obj_name_;
00215 }
00216
00217
00218
00219 void
00220 tags_database::Deletetag(const tag *tag_)
00221 {
00222 dbase_node *dbnode = tags_db_;
00223 int i, found = FALSE;
00224 tag *old_tag;
00225
00226 while(dbnode->list_node_[0] != NULL) {
00227 for(i = 0; i < NUM_RECTANGLES; ++i) {
00228 if(((dbnode->list_node_[i])->x_min_ <= tag_->x_) && ((dbnode->list_node_[i])->x_max_ >= tag_->x_)) {
00229 found = TRUE;
00230 break;
00231 }
00232 }
00233 assert(found);
00234 dbnode = dbnode->list_node_[i];
00235 }
00236
00237 assert(dbnode->tags_list_ != NULL);
00238
00239
00240 found = FALSE;
00241 old_tag = dbnode->tags_list_;
00242 tag *prev_tag = old_tag;
00243 while(old_tag != NULL) {
00244 if ((old_tag->x_== tag_->x_) && (old_tag->y_ == tag_->y_) && (old_tag->obj_name_ == tag_->obj_name_)) {
00245 found = TRUE;
00246 break;
00247 }
00248 prev_tag = old_tag;
00249 old_tag = old_tag->next_;
00250 }
00251
00252 assert(found);
00253 prev_tag->next_ = old_tag->next_;
00254 delete old_tag;
00255 }
00256
00257
00258
00259 compr_taglist *
00260 tags_database::Gettags(double x, double y, double r)
00261 {
00262 dbase_node *dbnode = tags_db_;
00263 compr_taglist *tptr;
00264 int i, found = FALSE;
00265 vtags_ = NULL;
00266
00267
00268
00269 search_tags_dbase(x,y,r,dbnode);
00270
00271 tptr = vtags_;
00272 while(tptr) {
00273 found = FALSE;
00274 for(i = 0; i < num_sensed_tags_; ++i) {
00275 if(tptr->obj_name_ == sensed_tag_list_[i]) {
00276 found = TRUE;
00277 break;
00278 }
00279 }
00280 if(!found) {
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 sensed_tag_list_[num_sensed_tags_] = tptr->obj_name_;
00291 ++num_sensed_tags_;
00292
00293 }
00294 tptr = tptr->next_;
00295 }
00296 assert(num_sensed_tags_ <= num_tags_);
00297 return(vtags_);
00298 }
00299
00300
00301 int
00302 tags_database::get_random_tag()
00303 {
00304
00305
00306
00307
00308
00309 int i = rn_->uniform(num_sensed_tags_);
00310 return(sensed_tag_list_[i]);
00311
00312
00313
00314
00315
00316 }
00317
00318
00319
00320
00321 void
00322 tags_database::search_tags_dbase(double x, double y, double r, dbase_node *dbnode)
00323 {
00324 int i, found = FALSE, removed_tag = 0;
00325 compr_taglist **apt_tags;
00326 tag *prev_tag, *next_tag;
00327 tag *dbase_tags;
00328 dbase_node *child_dbnode;
00329
00330
00331 if(dbnode->list_node_[0] == NULL) {
00332
00333 apt_tags = &vtags_;
00334 while((*apt_tags) != NULL)
00335 apt_tags = &((*apt_tags)->next_);
00336
00337 dbase_tags = dbnode->tags_list_;
00338 prev_tag = dbase_tags;
00339 while(dbase_tags) {
00340 removed_tag = 0;
00341 double xpos = (dbase_tags->x_ - x) * (dbase_tags->x_ - x);
00342 double ypos = (dbase_tags->y_ - y) * (dbase_tags->y_ - y);
00343
00344 if((xpos + ypos) < (r*r)) {
00345 *apt_tags = new compr_taglist;
00346 (*apt_tags)->obj_name_ = dbase_tags->obj_name_;
00347 apt_tags = &((*apt_tags)->next_);
00348
00349
00350
00351 removed_tag = 1;
00352 if(prev_tag == dbase_tags) {
00353 dbnode->tags_list_ = dbase_tags->next_;
00354 prev_tag = dbase_tags->next_;
00355 }
00356 else
00357 prev_tag->next_ = dbase_tags->next_;
00358
00359 next_tag = dbase_tags->next_;
00360 delete dbase_tags;
00361 }
00362 if(!removed_tag) {
00363 prev_tag = dbase_tags;
00364 dbase_tags = dbase_tags->next_;
00365 }
00366 else {
00367 dbase_tags = next_tag;
00368 }
00369 }
00370 return;
00371 }
00372
00373 for(i = 0; i < NUM_RECTANGLES; ++i) {
00374 found = FALSE;
00375
00376
00377 if(((dbnode->list_node_[i])->x_min_ <= (x - r)) && ((dbnode->list_node_[i])->x_max_ >= (x - r)))
00378 found = TRUE;
00379
00380
00381 if(((dbnode->list_node_[i])->x_min_ <= (x + r)) && ((dbnode->list_node_[i])->x_max_ >= (x + r)))
00382 found = TRUE;
00383
00384
00385 if(((dbnode->list_node_[i])->x_min_ >= (x - r)) && ((dbnode->list_node_[i])->x_max_ <= (x + r)))
00386 found = TRUE;
00387 if(found) {
00388 child_dbnode = dbnode->list_node_[i];
00389 search_tags_dbase(x,y,r,child_dbnode);
00390 }
00391 }
00392 }
00393
00394
00395
00396