~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Tina4/src/vision/curve2/circprox.c

Version: ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /**@(#)
  2 **/
  3 /* circprox.c
  4  * 
  5  * fitting a string of 2D pos data with circles the circles are
  6  * represented using the conic data structure
  7  * 
  8  */
  9 
 10 #include <math.h>
 11 #include <tina/sys.h>
 12 #include <tina/sysfuncs.h>
 13 #include <tina/math.h>
 14 #include <tina/mathfuncs.h>
 15 #include <tina/vision.h>
 16 #include <tina/visionfuncs.h>
 17 
 18 static int init_sample = 12;
 19 
 20 /* grow the original circle "conic" along the implicit string between
 21  * start and end from original p1 and p2 starting and
 22  * 
 23  * ending points (these positions are updated) */
 24 Conic  *conic_circ_grow(Conic * conic, List * start, List * end, List ** p1, List ** p2, double lo_th, double hi_th, int max_div)
 25 {
 26     Bool    updated;
 27     List *m1 = *p1;
 28     List *m2 = *p2;
 29 
 30     do
 31     {
 32         Bool    string_grown;
 33 
 34         /** grow start and end along conic **/
 35         string_grown = conic_grow_string(conic, start, end, &m1, &m2,
 36                                          lo_th, hi_th, max_div);
 37 
 38         if (string_grown)       /** fit a new circ and see if still good **/
 39         {
 40             Conic  *new_conic = ddstr_conic_circ_3pt(m1, m2);
 41 
 42             if (new_conic != NULL &&
 43                 conic_check(new_conic, m1, m2, lo_th, hi_th, max_div))
 44             {
 45                 updated = true;
 46                 conic_free(conic);
 47                 conic = new_conic;
 48             } else
 49             {
 50                 updated = false;
 51                 if (new_conic != NULL)
 52                     conic_free(new_conic);
 53             }
 54         } else
 55             updated = false;
 56     } while (updated);
 57 
 58     *p1 = m1;
 59     *p2 = m2;
 60 
 61     return (conic);
 62 }
 63 
 64 /* perform a recursive approximation between start and end use the
 65  * conic version of a circle as primitive failing to fit a circle use
 66  * straight line approximation */
 67 static List *conic_circ_prox(List * start, List * end, int sample, double lo_th, double hi_th, int max_div)
 68 {
 69     List *p1;
 70     List *p2;
 71     List *m1;
 72     List *m2;
 73     List *list1 = NULL;
 74     List *list2 = NULL;
 75     Conic  *conic = NULL;
 76     double  lo_sqth = lo_th * lo_th;
 77     double  hi_sqth = hi_th * hi_th;
 78     int     i, maxcount = 0;
 79 
 80     if (start == NULL || end == NULL || start == end)
 81         return (NULL);
 82 
 83     p1 = start;
 84     p2 = ddstr_nth_point(start, end, 2 * sample + 1);
 85     if (p2 == NULL)
 86         p2 = end;
 87 
 88     while (1)
 89     {
 90         conic = ddstr_conic_circ_3pt(p1, p2);
 91         if (conic != NULL &&
 92             conic_check(conic, p1, p2, lo_sqth, hi_sqth, max_div))
 93         {
 94             int     count = conic_count(conic, start, end, sample / 2, lo_sqth);
 95 
 96             if (count > maxcount)
 97             {
 98                 maxcount = count;
 99                 m1 = p1;
100                 m2 = p2;
101             }
102         }
103         conic_free(conic);
104         conic = NULL;
105 
106         if (p2 == end)
107             break;
108 
109         for (i = 0; i < sample; ++i)
110         {
111             p1 = p1->next;
112             p2 = p2->next;
113             if (p2 == end)
114                 break;
115         }
116     }
117 
118     if (maxcount >= 5)
119     {
120         conic = ddstr_conic_circ_3pt(m1, m2);
121         conic = conic_circ_grow(conic, start, end, &m1, &m2,
122                                 lo_sqth, hi_sqth, max_div);
123     }
124     if (conic == NULL)          /* failed */
125     {
126         sample = (int)(sample*0.75);            /* increase sample frequency */
127         if (sample > 1)
128             return (conic_circ_prox(start, end, sample, lo_th, hi_th, max_div));
129         return (linear_prox(start, end, (float)lo_th, init_sample));
130     }
131     if (m1 != start)
132         list1 = conic_circ_prox(start, m1, sample, lo_th, hi_th, max_div);
133     if (m2 != end)
134         list2 = conic_circ_prox(m2, end, sample, lo_th, hi_th, max_div);
135 
136     return (dd_append(list1, dd_append(dd_link_alloc((void *) conic, CONIC2), list2)));
137 }
138 
139 /* approximate given string by circular sections represented as conics
140  * straight lines are used for sections that can not be fit as a circle
141  * return a new string of conics and straight line sections */
142 Tstring *conic_circ_string(Tstring * string, int init_smpl, double lo_th, double hi_th, int max_div)
143 {
144     List *conic_list;
145 
146     if (string == NULL)
147         return (NULL);
148 
149     init_sample = init_smpl;
150 
151     conic_list = conic_circ_prox(string->start, string->end, init_sample,
152                                  lo_th, hi_th, max_div);
153 
154     if (conic_list == NULL)
155         return (NULL);
156 
157     return (str_make(STRING, conic_list, dd_get_end(conic_list)));
158 }
159 
160 List   *conic_circ_strings(List * strings, int init_smpl, double lo_th, double hi_th, int max_div)
161 {
162     List   *sptr;
163     List   *splist = NULL;
164 
165     for (sptr = strings; sptr != NULL; sptr = sptr->next)
166     {
167         Tstring *string = (Tstring *) sptr->to;
168 
169         string = conic_circ_string(string, init_smpl, lo_th, hi_th, max_div);
170         splist = ref_addtostart(splist, (void *) string, STRING);
171     }
172     return (splist);
173 }
174 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.