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

Linux Cross Reference
Tina4/src/covira/snake.c

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

  1 /*
  2 *
  3 * snake.c
  4 *
  5 * Kass-Witkin (edge seeking) Snake utility functions
  6 *
  7 */
  8 
  9 #include <tina/all_tina.h>
 10 #include <tina/brain.h>
 11 #include <tina/brainfuncs.h>
 12 
 13 /*
 14 Allocate and return a snake with n vertices.
 15 */
 16 Snake *snake_make(int n)
 17 {
 18     Snake *snake = talloc(Snake);
 19     snake->n = n;
 20     snake->p = tvector_alloc(0, n, Vec2); /* snake vertices */
 21     snake->f = tvector_alloc(0, n, Vec2); /* workspace for forces */
 22     snake->forcelaw = snake_gradient_forces; /* default force law */
 23     return (snake);
 24 }
 25 
 26 /*
 27 Allocate and return a copy of a snake.
 28 */
 29 Snake *snake_copy(Snake * snake)
 30 {
 31     Snake *new;
 32 
 33     if (snake == NULL)
 34         return (NULL);
 35     new = snake_make(snake->n);
 36     tvector_copy_inplace((char *) new->p, (char *) snake->p, 0, snake->n, Vec2);
 37     tvector_copy_inplace((char *) new->f, (char *) snake->f, 0, snake->n, Vec2);
 38     new->forcelaw = snake->forcelaw;
 39     return (new);
 40 }
 41 
 42 /*
 43 Free a snake and associated memory.
 44 */
 45 void snake_free(Snake * snake)
 46 {
 47     if (snake == NULL)
 48         return;
 49     tvector_free(snake->p, 0, Vec2);
 50     tvector_free(snake->f, 0, Vec2);
 51     rfree((void *) snake);
 52 }
 53 
 54 /*
 55 Return unit vector approx orthogonal to snake at ith knot.
 56 */
 57 Vec2 snake_perp(Snake * snake, int i)
 58 {
 59     int n = snake->n;
 60     Vec2 *p = snake->p;
 61     Vec2 v;
 62 
 63     if (i == 0)
 64         v = vec2_diff(p[1], p[n - 1]);
 65     else if (i == n - 1)
 66         v = vec2_diff(p[n - 1], p[1]);
 67     else
 68         v = vec2_diff(p[i + 1], p[i - 1]);
 69     return (vec2_perp(vec2_unit(v)));
 70 }
 71 
 72 /*
 73 Allocate and return snake with with given list of Vec2's as knots.
 74 */
 75 Snake *snake_from_list(List * points)
 76 {
 77     List *ptr;
 78     int i, n;
 79     Snake *snake = snake_make(n = list_length(points));
 80     for (i = 0, ptr = points; i < n; i++, ptr = ptr->next)
 81     {
 82         Vec2 *v = (Vec2 *) ptr->to;
 83         snake->p[i] = *v;
 84     }
 85     return (snake);
 86 }
 87 
 88 /*
 89 Alocate and return snake interpolating edge string with averaging
 90 turning angle asnake, min knot number   = 4 knots, min chord = 3 pixels.
 91 */
 92 Snake *snake_of_str2(Tstring * str, double asnake)
 93 {
 94     Snake *snake;
 95     int na = str2_ang_length(str)/asnake;
 96     int nl = str2_arc_length(str)/3, n;
 97     n = MAX(4, na);
 98     n = MIN(nl, na);
 99     if (str == NULL)
100         return (NULL);
101     snake = snake_make(n);
102     str2_get_interp_vec2_knots(str, n, snake->p);
103     return (snake);
104 }
105 
106 /*
107 Evaluate snake at non-integer parameter value  by linear interpolation.
108 */
109 Vec2 snake_eval(Snake * snake, double t)
110 {
111     int i, i1, n = snake->n;
112     Vec2 *p = snake->p;
113     double dt, dt1;
114 
115     i = floor(t);
116     dt = t - i;
117     dt1 = 1.0 - dt;
118     while (i < 0)
119         i += n;
120     i %= n;
121     i1 = (i + 1) % n;
122     return (vec2_sum(vec2_times(dt1, p[i]), vec2_times(dt, p[i1])));
123 }
124 
125 /*
126 Allocate and return 8-connected edge string occupied by snake.
127 Edge points have sub-pixel accuracy.
128 */
129 Tstring *str2_of_snake(Snake * snake)
130 {
131     double t1 = 0.0, t2;
132 
133     if (snake == NULL)
134         return (NULL);
135     t2 = snake->n;
136     return (str2_of_curve2(snake_eval, (void *) snake, t1, t2, (void *) NULL));
137 }
138 
139 /*
140 Return length of chord (i, i+1) of snake.
141 */
142 double snake_chord(Snake *snake, int i)
143 {
144     int n = snake->n;
145     while(i < 0)
146         i += n;
147     while(i >= n)
148         i -= n;
149     if(i == n-1)
150         return(vec2_dist(snake->p[0], snake->p[i]));
151     else
152         return(vec2_dist(snake->p[i+1], snake->p[i]));
153 }
154 
155 /*
156 Return total chord length of snake.
157 */
158 double snake_length(Snake * snake)
159 {
160     double l = 0.0;
161     int i;
162     if (snake == NULL)
163         return (-1.0);
164     for (i = 0; i < snake->n; i++)
165         l += snake_chord(snake, i);
166     return (l);
167 }
168 
169 /*
170 Return centroid of snake.
171 */
172 Vec2 snake_centroid(Snake * snake)
173 {
174     Vec2 c, *p;
175     int i, n;
176 
177     if (snake == NULL)
178         return vec2_zero();
179     n = snake->n;
180     p = snake->p;
181     c = vec2_zero();
182     for (i = 0; i < n; ++i)
183         c = vec2_sum(c, p[i]);
184     return (vec2_times(1.0 / n, c));
185 }
186 
187 /*
188 Translate snake by vector dp.
189 */
190 void snake_shift(Snake * snake, Vec2 dp)
191 {
192     int i, n;
193     n = snake->n;
194     for (i = 0; i < n; ++i)
195         snake->p[i] = vec2_sum(snake->p[i], dp);
196 }
197 

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