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

Linux Cross Reference
Tina6/tina-libs/tina/geometry/geomEdge_2dstring.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/geomEdge_2dstring.c,v $
 27  * Date    :  $Date: 2005/02/07 23:27:41 $
 28  * Version :  $Revision: 1.3 $
 29  * CVS Id  :  $Id: geomEdge_2dstring.c,v 1.3 2005/02/07 23:27:41 paul Exp $
 30  *
 31  * Author  : Legacy TINA
 32  *
 33  * Notes : Utilities for dealing with strings of 2D points (Edgels or VEC2's)
 34  *
 35  *********
 36 */
 37 
 38 #include "geomEdge_2dstring.h"
 39 
 40 #if HAVE_CONFIG_H
 41   #include <config.h>
 42 #endif
 43 
 44 #include <math.h>
 45 #include <tina/sys/sysDef.h>
 46 #include <tina/sys/sysPro.h>
 47 #include <tina/math/mathDef.h>
 48 #include <tina/math/mathPro.h>
 49 #include <tina/geometry/geomDef.h>
 50 #include <tina/geometry/geom_CurvePro.h>
 51 
 52 
 53 /*
 54 Return centroid of points on 2D string.
 55 */
 56 Vec2 str2_centroid(Tstring * str)
 57 {
 58     Vec2 sum = vec2_zero(), p;
 59     List *ptr;
 60     int n = 0;
 61     if (str == NULL)
 62         return (sum);
 63     for (ptr = str->start;  ;  ptr=ptr->next)
 64     {
 65         DD_GET_POS2(ptr, p);
 66         sum = vec2_sum(sum, p);
 67         n++;
 68         if(ptr == str->end)
 69           break;
 70     }
 71     return (vec2_times(1.0 / n, sum));
 72 }
 73 
 74 /*
 75 Translate a 2d string by vector v.
 76 */
 77 void str2_translate(Tstring * str, Vec2 v)
 78 {
 79     List *ptr;
 80 
 81     if (str == NULL)
 82         return;
 83     for (ptr = str->start; ; ptr = ptr->next)
 84     {
 85         Vec2 p;
 86 
 87         DD_GET_POS2(ptr, p);
 88         p = vec2_sum(p, v);
 89         DD_SET_POS2(ptr, p);
 90         if (ptr == str->end)
 91             break;
 92     }
 93 }
 94 
 95 /*
 96 Rotate, translate, and scale a 2d string about centre c.
 97 x->t+c+sr(x-c).
 98 */
 99 void str2_rts(Tstring * str, Vec2 c, Mat2 r, Vec2 t, double s)
100 {
101     List *ptr;
102 
103     if (str == NULL)
104         return;
105     for (ptr = str->start; ; ptr = ptr->next)
106     {
107         Vec2 p;
108 
109         DD_GET_POS2(ptr, p);
110         p = vec2_diff(p, c);
111         p = vec2_times(s, p);
112         p = mat2_vprod(r, p);
113         p = vec2_sum3(c, t, p);
114         DD_SET_POS2(ptr, p);
115         if (ptr == str->end)
116             break;
117     }
118 }
119 
120 /*
121 Return area enclosed by 2D string (0 for type STRING).
122 */
123 double str2_area(Tstring * str) /* Newcode */
124 {
125     List *ptr;
126     double a = 0.0;
127     if (str == NULL)
128          return(0.0);
129     if (str->type == STRING)
130     {
131         error("str2_area: passed open contour", non_fatal);
132         return (0.0);
133     }
134     for (ptr = str->start; ; ptr = ptr->next)
135     {
136         Vec2 p1, p2;
137         DD_GET_POS2(ptr, p1);
138         DD_GET_POS2(ptr->next, p2);
139         a += vec2_cross(p1, p2);
140         if (ptr == str->end)
141             break;
142     }
143     a *= 0.5;
144     return (a);
145 }
146 
147 /*
148 Find major and minor axes (a, b) and angle of principle direction
149 theta of 2D-string.
150 */
151 void str2_eigen(Tstring * str, double *a, double *b, double *theta)
152 {
153     List *ptr;
154     Mat2 m = mat2_zero();
155     Vec2 c = str2_centroid(str);
156     if (str == NULL)
157         return;
158     for (ptr = str->start; ; ptr = ptr->next)
159     {
160         Vec2 p;
161         DD_GET_POS2(ptr, p);
162         p = vec2_diff(p, c);
163         m = mat2_sum(m, mat2_tensor(p, p));
164         if (ptr == str->end)
165             break;
166     }
167     mat2_sym_eigen(m, theta, a, b);
168 }
169 
170 /*
171 Return angle of major axis of 2D string.
172 */
173 double str2_orientation(Tstring * str)
174 {
175     double a, b, theta;
176     str2_eigen(str, &a, &b, &theta);
177     return (theta);
178 }
179 
180 /*
181 Allocates Vec2 at same position as Edgel or Vec2 pointer.
182 Function no longer used PAB 30/1/2005
183 
184 static Vec2 *make_vec2_from_edge(void *e, int *type)
185 {
186     Vec2 v;
187 
188     GET_POS2(e, *type, v);
189     *type = VEC2;
190     return (vec2_make(v));
191 }
192 */
193 
194 /*
195 Return copy of 2D string (with Vec2 entries).
196 */
197 Tstring *str2_copy(Tstring * str)
198 {
199     return(str_copy(str, (void *(*) ()) vec2_copy, NULL));
200 }
201 
202 /*
203 Return total arc (chord) length of Ddstring, running from
204 start past nextoend.
205 */
206 double dd2_arc_length(List *start, List *nextoend)
207 {
208     List *ptr;
209     double s;
210     if (start == NULL || nextoend == NULL || nextoend->next == NULL)
211         return (0.0);
212     for (s = 0.0, ptr = start;; ptr = ptr->next)
213     {
214         Vec2 p1, p2;
215         DD_GET_POS2(ptr, p1);
216         DD_GET_POS2(ptr->next, p2);
217         s += vec2_dist(p1, p2);
218         if (ptr == nextoend)
219             break;
220     }
221     return (s);
222 }
223 
224 /*
225 Return total arc (chord) length of 2D string.
226 */
227 double str2_arc_length(Tstring * str)
228 {
229     if (str == NULL || str->count < 2)
230         return (0.0);
231     switch(str->type)
232     {
233         case LOOP:
234             return(dd2_arc_length(str->start, str->end));
235         case STRING:
236             return(dd2_arc_length(str->start, str->end->last));
237         default:
238             return(-1.0);
239     }
240 }
241 
242 /*
243 Return total absolute angle turned through by 2D List,
244 summing angles at nextostart up to nextoend.
245 */
246 double dd2_ang_length(List *nextostart, List *nextoend)
247 {
248     List *ptr;
249     double s;
250     if (nextostart == NULL || nextoend == NULL)
251         return (0.0);
252     for (s = 0.0, ptr = nextostart;; ptr = ptr->next)
253     {
254         Vec2 p1, p2, p3;
255         DD_GET_POS2(ptr->last, p1);
256         DD_GET_POS2(ptr,       p2);
257         DD_GET_POS2(ptr->next, p3);
258         s += fabs(vec2_angle(vec2_diff(p3, p2), vec2_diff(p2, p1)));
259         if (ptr == nextoend)
260             break;
261     }
262     return (s);
263 }
264 
265 /*
266 Return total absolute angle turned through by 2D string.
267 */
268 double str2_ang_length(Tstring * str)
269 {
270     if (str == NULL ||
271         (str->type == LOOP && str->count < 2) ||
272         (str->type == STRING && str->count < 3))
273         return (0.0);
274     switch(str->type)
275     {
276         case LOOP:
277             return(dd2_ang_length(str->start, str->end));
278         case STRING:
279             return(dd2_ang_length(str->start->next, str->end->last));
280         default:
281             return(-1.0);
282     }
283 }
284 
285 /*
286 Put n equally spaced points from 2D string in Vec2 array
287 p[0],i...,p[n-1]. (Note points are always on string, to get
288 interpolated points see str2_get_interp_vec2_knots below)
289 */
290 void str2_get_vec2_knots(Tstring * str, int n, Vec2 * p)
291 {
292     List *ptr;
293     int i, j;
294     double s, ds;
295 
296     s = str->count;
297     switch (str->type)
298     {
299       case STRING:
300         ds = (s-1) / (n - 1);
301         break;
302       case LOOP:
303         ds = s / (n-1);
304         break;
305       default:
306         return;
307     }
308     for (i = 0, j = 0, ptr = str->start; j < n; i++, ptr = ptr->next)
309     {
310         if (i >= j * ds || (str->type == STRING && ptr == str->end))
311         {
312             DD_GET_POS2(ptr, p[j]);
313             j++;
314         }
315     }
316 }
317 
318 /*
319 Get point given arc-length along 2D string.
320 */
321 Vec2 str2_point(Tstring *str, double t)
322 {
323     List *ptr=NULL, *end=NULL;
324     double s;
325     if(str == NULL)
326         return(vec2_zero());
327     if(str->count == 1 || t <= 0)
328     {
329         Vec2 p;
330         DD_GET_POS2(str->start, p);
331         return(p);
332     }
333     switch(str->type)
334     {
335         case LOOP:
336             end = str->start;
337             break;
338         case STRING:
339             end = str->end;
340             break;
341     }
342     for(s = 0, ptr = str->start; ; ptr = ptr->next)
343     {
344         Vec2 p1, p2;
345         double ds;
346         DD_GET_POS2(ptr, p1);
347         DD_GET_POS2(ptr->next, p2);
348         ds = vec2_dist(p1, p2);
349         if(ds != 0.0 && s+ds >= t)
350             return(vec2_interp((t-s) / ds, p1, p2));
351         s += ds;
352         if(ptr->next == end)
353             return(p2);
354     }
355 }
356 
357 /*
358 Put n equally spaced points interpolated from 2D string
359 in Vec2 array p[0],i...,p[n-1].
360 */
361 void str2_get_interp_vec2_knots(Tstring * str, int n, Vec2 * p)
362 {
363     double s;
364     int i, m;
365     if(str == NULL)
366         return;
367     switch(str->type)
368     {
369         case STRING:
370             m = n-1;
371             break;
372         case LOOP:
373             m = n;
374             break;
375         default:
376             return;
377     }
378     /* get str length */
379     s = str2_arc_length(str);
380     for(i = 0; i < n; i++)
381     {
382         double t = (i*s)/m;
383         p[i] = str2_point(str, t);
384     }
385 }
386 
387 /*
388 Return an 8-neighbour connected string linearly interpolating str.
389 */
390 Tstring *str2_fill(Tstring *str)
391 {
392     double s = str2_arc_length(str);
393     return (str2_of_curve2(str2_point, str, 0, s, (void *) NULL));
394 }
395 
396 /*
397 Free a 2D string.
398 */
399 void str2_free(Tstring *str)
400 {
401     str_free(str, rfree);
402 }
403 

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