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

Linux Cross Reference
Tina4/src/vision/edge/str2.c

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

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

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