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

Linux Cross Reference
Tina6/tina-libs/tina/geometry/geomCurve_circprox.c

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

  1 /**********
  2  * 
  3  * This file is part of the TINA Open Source Image Analysis Environment
  4  * henceforth known as TINA
  5  *
  6  * TINA is free software; you can redistribute it and/or modify
  7  * it under the terms of the GNU General Public License as 
  8  * published by the Free Software Foundation.
  9  *
 10  * TINA is distributed in the hope that it will be useful,
 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13  * GNU General Public License for more details.
 14  *
 15  * You should have received a copy of the GNU General Public License
 16  * along with TINA; if not, write to the Free Software Foundation, Inc., 
 17  * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 18  *
 19  * ANY users of TINA who require exemption from the existing licence must
 20  * negotiate a new licence with Dr. Neil.A.Thacker, the sole agent for
 21  * the University of Manchester.
 22  *
 23  **********
 24  * 
 25  * Program :    TINA
 26  * File    :  $Source: /home/tina/cvs/tina-libs/tina/geometry/geomCurve_circprox.c,v $
 27  * Date    :  $Date: 2003/09/09 16:02:21 $
 28  * Version :  $Revision: 1.2 $
 29  * CVS Id  :  $Id: geomCurve_circprox.c,v 1.2 2003/09/09 16:02:21 ipoole Exp $
 30  *
 31  * Author  : Legacy TINA
 32  *
 33  * Notes :
 34  *
 35  * fitting a string of 2D pos data with circles the circles are
 36  * represented using the conic data structure
 37  * 
 38  *********
 39 */
 40 
 41 #include "geomCurve_circprox.h"
 42 
 43 #if HAVE_CONFIG_H
 44   #include <config.h>
 45 #endif
 46 
 47 #include <math.h>
 48 #include <tina/sys/sysDef.h>
 49 #include <tina/sys/sysPro.h>
 50 #include <tina/math/mathDef.h>
 51 #include <tina/math/mathPro.h>
 52 #include <tina/geometry/geomDef.h>
 53 #include <tina/geometry/geom_CurveDef.h>
 54 #include <tina/geometry/geomLine_linearprox.h>
 55 #include <tina/geometry/geomCurve_conicprox.h>
 56 #include <tina/geometry/geomCurve_conic.h>
 57 #include <tina/geometry/geomCurve_conic_5pt.h>
 58 
 59 
 60 static int init_sample = 12;            /* static data! */
 61 
 62 /* grow the original circle "conic" along the implicit string between
 63  * start and end from original p1 and p2 starting and
 64  * 
 65  * ending points (these positions are updated) */
 66 Conic  *conic_circ_grow(Conic * conic, List * start, List * end, List ** p1, List ** p2, double lo_th, double hi_th, int max_div)
 67 {
 68     Bool    updated;
 69     List *m1 = *p1;
 70     List *m2 = *p2;
 71 
 72     do
 73     {
 74         Bool    string_grown;
 75 
 76         /** grow start and end along conic **/
 77         string_grown = conic_grow_string(conic, start, end, &m1, &m2,
 78                                          lo_th, hi_th, max_div);
 79 
 80         if (string_grown)       /** fit a new circ and see if still good **/
 81         {
 82             Conic  *new_conic = ddstr_conic_circ_3pt(m1, m2);
 83 
 84             if (new_conic != NULL &&
 85                 conic_check(new_conic, m1, m2, lo_th, hi_th, max_div))
 86             {
 87                 updated = true;
 88                 conic_free(conic);
 89                 conic = new_conic;
 90             } else
 91             {
 92                 updated = false;
 93                 if (new_conic != NULL)
 94                     conic_free(new_conic);
 95             }
 96         } else
 97             updated = false;
 98     } while (updated);
 99 
100     *p1 = m1;
101     *p2 = m2;
102 
103     return (conic);
104 }
105 
106 /* perform a recursive approximation between start and end use the
107  * conic version of a circle as primitive failing to fit a circle use
108  * straight line approximation */
109 static List *conic_circ_prox(List * start, List * end, int sample, double lo_th, double hi_th, int max_div)
110 {
111     List *p1;
112     List *p2;
113     List *m1;
114     List *m2;
115     List *list1 = NULL;
116     List *list2 = NULL;
117     Conic  *conic = NULL;
118     double  lo_sqth = lo_th * lo_th;
119     double  hi_sqth = hi_th * hi_th;
120     int     i, maxcount = 0;
121 
122     if (start == NULL || end == NULL || start == end)
123         return (NULL);
124 
125     p1 = start;
126     p2 = ddstr_nth_point(start, end, 2 * sample + 1);
127     if (p2 == NULL)
128         p2 = end;
129 
130     while (1)
131     {
132         conic = ddstr_conic_circ_3pt(p1, p2);
133         if (conic != NULL &&
134             conic_check(conic, p1, p2, lo_sqth, hi_sqth, max_div))
135         {
136             int     count = conic_count(conic, start, end, sample / 2, lo_sqth);
137 
138             if (count > maxcount)
139             {
140                 maxcount = count;
141                 m1 = p1;
142                 m2 = p2;
143             }
144         }
145         conic_free(conic);
146         conic = NULL;
147 
148         if (p2 == end)
149             break;
150 
151         for (i = 0; i < sample; ++i)
152         {
153             p1 = p1->next;
154             p2 = p2->next;
155             if (p2 == end)
156                 break;
157         }
158     }
159 
160     if (maxcount >= 5)
161     {
162         conic = ddstr_conic_circ_3pt(m1, m2);
163         conic = conic_circ_grow(conic, start, end, &m1, &m2,
164                                 lo_sqth, hi_sqth, max_div);
165     }
166     if (conic == NULL)          /* failed */
167     {
168         sample = (int)(sample*0.75);            /* increase sample frequency */
169         if (sample > 1)
170             return (conic_circ_prox(start, end, sample, lo_th, hi_th, max_div));
171         return (linear_prox(start, end, (float)lo_th, init_sample));
172     }
173     if (m1 != start)
174         list1 = conic_circ_prox(start, m1, sample, lo_th, hi_th, max_div);
175     if (m2 != end)
176         list2 = conic_circ_prox(m2, end, sample, lo_th, hi_th, max_div);
177 
178     return (dd_append(list1, dd_append(dd_link_alloc((void *) conic, CONIC2), list2)));
179 }
180 
181 /* approximate given string by circular sections represented as conics
182  * straight lines are used for sections that can not be fit as a circle
183  * return a new string of conics and straight line sections */
184 Tstring *conic_circ_string(Tstring * string, int init_smpl, double lo_th, double hi_th, int max_div)
185 {
186     List *conic_list;
187 
188     if (string == NULL)
189         return (NULL);
190 
191     init_sample = init_smpl;
192 
193     conic_list = conic_circ_prox(string->start, string->end, init_sample,
194                                  lo_th, hi_th, max_div);
195 
196     if (conic_list == NULL)
197         return (NULL);
198 
199     return (str_make(STRING, conic_list, dd_get_end(conic_list)));
200 }
201 
202 List   *conic_circ_strings(List * strings, int init_smpl, double lo_th, double hi_th, int max_div)
203 {
204     List   *sptr;
205     List   *splist = NULL;
206 
207     for (sptr = strings; sptr != NULL; sptr = sptr->next)
208     {
209         Tstring *string = (Tstring *) sptr->to;
210 
211         string = conic_circ_string(string, init_smpl, lo_th, hi_th, max_div);
212         splist = ref_addtostart(splist, (void *) string, STRING);
213     }
214     return (splist);
215 }
216 

~ [ 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.