int main(int argc, char** argv) { GSList *l1, *l2; GList *tri1, *tri2; int np1 = 0, np2 = 0; struct point *pt1, *pt2; //struct triangle_pair *t; int i; double width, height, e1, e2; int discarded; GList *tp, *tmp; int np, nm; l1 = read_star_list ((argc > 1) ? argv[1] : "starf1.list", &width, &height); e1 = POS_EPSILON * MAX(width, height); l2 = read_star_list ((argc > 2) ? argv[2] : "starf2.list", &width, &height); e2 = POS_EPSILON * MAX(width, height); //printf("e1 %lf, e2 %lf\n", e1, e2); /* a) select points to be matched */ pt1 = filter_point_list (l1, &np1, e1); pt2 = filter_point_list (l2, &np2, e2); //printf("got %d, %d points\n", np1, np2); /* b) generate triangle lists */ tri1 = generate_triangles (pt1, np1, e1); tri2 = generate_triangles (pt2, np2, e2); printf("got %d, %d triangles\n", g_list_length(tri1), g_list_length(tri2)); /* c) triangle match */ /* sort in increasing order of ratio and determine max ratio tolerance */ double rtol1 = 0.0, rtol2 = 0.0, maxtol; tri1 = g_list_sort_with_data (tri1, (GCompareDataFunc) ratio_compare, &rtol1); tri2 = g_list_sort_with_data (tri2, (GCompareDataFunc) ratio_compare, &rtol2); maxtol = rtol1 + rtol2; //print_triangle_list(pt1, tri1); //print_triangle_list(pt2, tri2); /* match the triangles */ GList *tripairs = match_triangles(tri1, tri2); printf("got %d tripairs\n", g_list_length(tripairs)); //print_triangle_pairs(pt1, pt2, tripairs); i = 0; discarded = 1; while (discarded && i < MAX_LOGM_ITER) { double avg, stdev, f = 0; np = 0; nm = 0; avg = 0.0; for (tp = tripairs; tp; tp = g_list_next(tp)) { struct triangle_pair *t = tp->data; //printf("delta log P %lf\n", t->t1->logP - t->t2->logP); avg += t->t1->logP - t->t2->logP; if (t->t1->clockwise == t->t2->clockwise) np++; else nm++; } avg /= (nm + np); stdev = 0.0; for (tp = tripairs; tp; tp = g_list_next(tp)) { struct triangle_pair *t = tp->data; stdev += sqr(t->t1->logP - t->t2->logP - avg); } stdev = sqrt(stdev / (nm + np)); int mt = abs(np - nm); int mf = np + nm - mt; if (mf > mt) f = 1.0; else if (0.1 * mt > 1.0 * mf) f = 3.0; else f = 2.0; printf("iter %3d, avg %lf, stdev %lf, n+ %5d, n- %5d, factor %lf\n", i, avg, stdev, np, nm, f); discarded = 0; for (tp = tripairs; tp; ) { struct triangle_pair *t = tp->data; if (fabs(t->t1->logP - t->t2->logP - avg) > f * stdev) { discarded = 1; tmp = tp->next; tripairs = g_list_delete_link (tripairs, tp); tp = tmp; continue; } tp = g_list_next(tp); } i++; } if (discarded) { printf("failed\n"); } for (tp = tripairs; tp; ) { struct triangle_pair *t = tp->data; if ((np > nm && t->t1->clockwise != t->t2->clockwise) || (nm > np && t->t1->clockwise == t->t2->clockwise)) { tmp = tp->next; tripairs = g_list_delete_link (tripairs, tp); tp = tmp; continue; } tp = g_list_next(tp); } #if 0 for (tp = tripairs; tp; tp = g_list_next(tp)) { struct triangle_pair *t = tp->data; printf("%d %d\n", pt1[t->t1->v[0]].id, pt2[t->t2->v[0]].id); printf("%d %d\n", pt1[t->t1->v[1]].id, pt2[t->t2->v[1]].id); printf("%d %d\n", pt1[t->t1->v[2]].id, pt2[t->t2->v[2]].id); } #endif print_triangle_pairs(pt1, pt2, tripairs); printf("rtol1 = %lf, rtol2 = %lf, %d matches\n", rtol1, rtol2, g_list_length(tripairs)); return 0; }
/* read a star file frame (one s-expression) from the given file pointer, and return the stf of the root node */ struct stf *stf_read_frame(FILE *fp) { GScanner *scan; GTokenType tok; int level = 0; int minus = 0; GList *sl; struct stf *ret = NULL; struct stf *lstf[STF_MAX_DEPTH]; struct stf *stf=NULL, *nstf = NULL; lstf[0] = NULL; scan = init_scanner(); g_scanner_input_file(scan, fileno(fp)); do { tok = g_scanner_get_next_token(scan); // d3_printf("level %d ", level); // print_token(scan, tok); if (level == 0 && tok != '(') continue; if (level == 1 && tok == ')') { ret = lstf[0]; break; } if (minus) minus --; switch(tok) { case '(': if (level >= STF_MAX_DEPTH - 1) break; nstf = stf_new(); lstf[level] = nstf; if (level > 0) { stf->next = nstf; STF_SET_LIST(nstf, stf_new()); stf = STF_LIST(nstf); } else { stf = nstf; } level ++; break; case ')': stf = lstf[level-1]; level --; break; case G_TOKEN_SYMBOL: if (!STF_IS_NIL(stf)) { nstf = stf_new(); stf->next = nstf; stf = nstf; } STF_SET_SYMBOL(stf, intval(scan)); if (intval(scan) == SYM_STARS) { sl = read_star_list(scan); if (sl == NULL) break; nstf = stf_new(); stf->next = nstf; stf = nstf; STF_SET_GLIST(stf, sl); } break; case '-': minus = 2; break; case G_TOKEN_FLOAT: if (!STF_IS_NIL(stf)) { nstf = stf_new(); stf->next = nstf; stf = nstf; } STF_SET_DOUBLE(stf, minus?-floatval(scan):floatval(scan)); break; case G_TOKEN_STRING: if (!STF_IS_NIL(stf)) { nstf = stf_new(); stf->next = nstf; stf = nstf; } STF_SET_STRING(stf, strdup(stringval(scan))); break; case G_TOKEN_IDENTIFIER: err_printf("unexpected identifier: %s\n", stringval(scan)); // if (!STF_IS_NIL(stf)) { // nstf = stf_new(); // stf->next = nstf; // stf = nstf; // } // STF_SET_IDENT(stf, strdup(stringval(scan))); // break; default: err_printf("unexected token %d\n", tok); break; } } while (tok != G_TOKEN_EOF); g_scanner_sync_file_offset(scan); g_scanner_destroy(scan); return ret; }