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

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

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