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

Linux Cross Reference
Tina4/src/draw/paint/tv_curve.c

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

  1 /**@(#)
  2 **/
  3 #include <math.h>
  4 #include <tina/sys.h>
  5 #include <tina/sysfuncs.h>
  6 #include <tina/math.h>
  7 #include <tina/mathfuncs.h>
  8 #include <tina/vision.h>
  9 #include <tina/visionfuncs.h>
 10 #include <tina/tv.h>
 11 #include <tina/draw.h>
 12 #include <tina/drawfuncs.h>
 13 #include <tina/tvfuncs.h>
 14 
 15 static int curve_sample = 4;    /* sample of 4 pixels */
 16 static int min_level = 3;       /* minimum level of recursion */
 17 static Tv *curve_tv;
 18 static  Ipos(*curve_func) ();
 19 static void *curve_data;
 20 
 21 int     curve_draw_sample_get(void)
 22 {
 23     return (curve_sample);
 24 }
 25 
 26 void    curve_draw_sample_set(int s)
 27 {
 28     curve_sample = s;
 29 }
 30 
 31 static void curve_section_draw(double t1, double t2, Ipos p1, Ipos p2, int level)
 32 {
 33     double  tm;
 34     int     space;
 35     Ipos    pm = {Ipos_id};
 36 
 37     space = (int)ipos_mod(ipos_diff(p1, p2));
 38     if (space <= 1 || (level >= min_level && space < curve_sample))
 39     {
 40         if (level <= min_level || space > 1)
 41             tv_line(curve_tv, p1, p2);
 42         return;
 43     }
 44     tm = (t1 + t2) * 0.5;
 45     pm = curve_func(curve_tv, curve_data, tm);
 46 
 47     curve_section_draw(t1, tm, p1, pm, level + 1);
 48     curve_section_draw(tm, t2, pm, p2, level + 1);
 49 }
 50 
 51 void    curve_draw(Tv * tv, Ipos(*func) ( /* ??? */ ), void *data, double t1, double t2)
 52 {
 53     double  tm;
 54     Ipos    p1 = {Ipos_id};
 55     Ipos    p2 = {Ipos_id};
 56     Ipos    pm = {Ipos_id};
 57 
 58     if (tv == NULL)
 59         return;
 60 
 61     curve_data = data;
 62     curve_func = func;
 63     curve_tv = tv;
 64 
 65     tm = (t1 + t2) * 0.5;
 66     p1 = curve_func(tv, curve_data, t1);
 67     p2 = curve_func(tv, curve_data, t2);
 68     pm = curve_func(tv, curve_data, tm);
 69     curve_section_draw(t1, tm, p1, pm, 1);
 70     curve_section_draw(tm, t2, pm, p2, 1);
 71 }
 72 
 73 static Ipos conic2_ipos(Tv * tv, Conic * conic, double t)
 74 {
 75     Vec2    v = {Vec2_id};
 76 
 77     v = conic_point(conic, t);
 78     return (tv_proj2(tv, v));
 79 }
 80 
 81 void    conic2_draw(Tv * tv, Conic * conic)
 82 {
 83     double  t1, t2, tm;
 84     Ipos    p1 = {Ipos_id};
 85     Ipos    p2 = {Ipos_id};
 86     Ipos    pm = {Ipos_id};
 87     Conic  *conic_im;
 88 
 89     if (tv == NULL || conic == NULL || conic->type == DEGENERATE)
 90         return;
 91 
 92     conic_im = (Conic *) prop_get(conic->props, IMPOS);
 93     curve_data = (conic_im == NULL) ? (void *) conic : (void *) conic_im;
 94     curve_func = conic2_ipos;
 95     curve_tv = tv;
 96     t1 = ((Conic *) curve_data)->t1;
 97     t2 = ((Conic *) curve_data)->t2;
 98     tm = (t1 + t2) * 0.5;
 99 
100     p1 = curve_func(tv, curve_data, t1);
101     p2 = curve_func(tv, curve_data, t2);
102     pm = curve_func(tv, curve_data, tm);
103     curve_section_draw(t1, tm, p1, pm, 1);
104     curve_section_draw(tm, t2, pm, p2, 1);
105 }
106 
107 void    conic2_draw_axes(Tv * tv, Conic * conic)
108 {
109     Vec2    center_var = {Vec2_id};
110     Vec2    major_var = {Vec2_id};
111     Vec2    minor_var = {Vec2_id};
112     double  alpha, beta, theta;
113 
114     if (tv == NULL || conic == NULL || conic->type == DEGENERATE)
115         return;
116     center_var = conic->center;
117     alpha = conic->alpha;
118     beta = conic->beta;
119     theta = conic->theta;
120 
121     major_var = vec2(alpha * cos(theta), alpha * sin(theta));
122     minor_var = vec2(-beta * sin(theta), beta * cos(theta));
123     tv_line2(tv, vec2_diff(center_var, major_var), vec2_sum(center_var, major_var));
124     tv_line2(tv, vec2_diff(center_var, minor_var), vec2_sum(center_var, minor_var));
125 }
126 
127 void    conic2_draw_seg(Tv * tv, Conic * conic, double t1, double t2)
128 {
129     double  tm;
130     Ipos    p1 = {Ipos_id};
131     Ipos    p2 = {Ipos_id};
132     Ipos    pm = {Ipos_id};
133     Conic  *conic_im;
134 
135     if (tv == NULL || conic == NULL || conic->type == DEGENERATE)
136         return;
137 
138     conic_im = (Conic *) prop_get(conic->props, IMPOS);
139     curve_data = (conic_im == NULL) ? (void *) conic : (void *) conic_im;
140     curve_func = conic2_ipos;
141     curve_tv = tv;
142     tm = (t1 + t2) * 0.5;
143 
144     p1 = curve_func(tv, curve_data, t1);
145     p2 = curve_func(tv, curve_data, t2);
146     pm = curve_func(tv, curve_data, tm);
147     curve_section_draw(t1, tm, p1, pm, 1);
148     curve_section_draw(tm, t2, pm, p2, 1);
149 }
150 
151 void    conic2_draw_col(Tv * tv, Conic * conic)
152 {
153     double  t1, t2, tm;
154     Ipos    p1 = {Ipos_id};
155     Ipos    p2 = {Ipos_id};
156     Ipos    pm = {Ipos_id};
157     Conic  *conic_im;
158 
159     if (tv == NULL || conic == NULL || conic->type == DEGENERATE)
160         return;
161 
162     tv_save_draw(tv);
163 
164     switch (conic->type)
165     {
166     case ELLIPSE:
167         tv_set_color(tv, yellow);
168         break;
169     case HYPERBOLA:
170         tv_set_color(tv, baby_pink);
171         break;
172     default:
173         tv_set_color(tv, white);
174     }
175 
176     conic_im = (Conic *) prop_get(conic->props, IMPOS);
177     curve_data = (conic_im == NULL) ? (void *) conic : (void *) conic_im;
178     curve_func = conic2_ipos;
179     curve_tv = tv;
180     t1 = ((Conic *) curve_data)->t1;
181     t2 = ((Conic *) curve_data)->t2;
182     tm = (t1 + t2) * 0.5;
183 
184     p1 = curve_func(tv, curve_data, t1);
185     p2 = curve_func(tv, curve_data, t2);
186     pm = curve_func(tv, curve_data, tm);
187     curve_section_draw(t1, tm, p1, pm, 1);
188     curve_section_draw(tm, t2, pm, p2, 1);
189     tv_set_color(tv, red);
190     tv_point(tv, p1);
191     tv_point(tv, p2);
192 
193     tv_reset_draw(tv);
194 }
195 
196 static Ipos conic3_ipos(Tv * tv, Conic3 * conic, double t)
197 {
198     Vec3    v = {Vec3_id};
199 
200     v = conic3_point(conic, t);
201     return (tv_proj3(tv, v));
202 }
203 
204 void    conic3_draw(Tv * tv, Conic3 * conic)
205 {
206     double  t1, t2, tm;
207     Ipos    p1 = {Ipos_id};
208     Ipos    p2 = {Ipos_id};
209     Ipos    pm = {Ipos_id};
210 
211     if (tv == NULL || conic == NULL || conic->type == DEGENERATE)
212         return;
213 
214     curve_data = (void *) conic;
215     curve_func = conic3_ipos;
216     curve_tv = tv;
217     t1 = conic->conic->t1;
218     t2 = conic->conic->t2;
219     tm = (t1 + t2) * 0.5;
220     p1 = conic3_ipos(tv, conic, t1);
221     p2 = conic3_ipos(tv, conic, t2);
222     pm = conic3_ipos(tv, conic, tm);
223     curve_section_draw(t1, tm, p1, pm, 1);
224     curve_section_draw(tm, t2, pm, p2, 1);
225 }
226 
227 void    conic3_draw_col(Tv * tv, Conic3 * conic)
228 {
229     double  t1, t2, tm;
230     Ipos    p1 = {Ipos_id};
231     Ipos    p2 = {Ipos_id};
232     Ipos    pm = {Ipos_id};
233 
234     if (tv == NULL || conic == NULL || conic->type == DEGENERATE)
235         return;
236 
237     switch (conic->type)
238     {
239     case ELLIPSE:
240         tv_set_color(tv, yellow);
241         break;
242     case HYPERBOLA:
243         tv_set_color(tv, baby_pink);
244         break;
245     default:
246         tv_set_color(tv, white);
247     }
248 
249     curve_data = (void *) conic;
250     curve_func = conic3_ipos;
251     curve_tv = tv;
252     t1 = conic->conic->t1;
253     t2 = conic->conic->t2;
254     tm = (t1 + t2) * 0.5;
255     p1 = conic3_ipos(tv, conic, t1);
256     p2 = conic3_ipos(tv, conic, t2);
257     pm = conic3_ipos(tv, conic, tm);
258     curve_section_draw(t1, tm, p1, pm, 1);
259     curve_section_draw(tm, t2, pm, p2, 1);
260     tv_set_color(tv, red);
261     tv_point(tv, p1);
262     tv_point(tv, p2);
263 }
264 
265 double  pick_conic2_dist(Tv * tv, Ipos pos, Conic * conic)
266 {
267     Vec2    p = {Vec2_id};
268     Ipos    q = {Ipos_id};
269     double  t, t1, t2;
270     Conic  *conic_im;
271 
272     if ((conic_im = (Conic *) prop_get(conic->props, IMPOS)) != NULL)
273         conic = conic_im;
274 
275     p = tv_backproj2(tv, pos);
276     t = conic_param(conic, p);
277 
278     t1 = conic->t1;
279     t2 = conic->t2;
280 
281     if (t < t1 && t2 > TWOPI)
282         t += TWOPI;
283 
284     if (!BETWEEN(t, t1, t2))
285     {
286         double  d1, d2;
287 
288         q = tv_proj2(tv, conic_point(conic, t1));
289         d1 = ipos_mod(ipos_diff(pos, q));
290         q = tv_proj2(tv, conic_point(conic, t2));
291         d2 = ipos_mod(ipos_diff(pos, q));
292         return (MIN(d1, d2));
293     }
294     q = tv_proj2(tv, conic_point(conic, t));
295     return (ipos_mod(ipos_diff(pos, q)));
296 }
297 
298 double  pick_conic3_dist(Tv * tv, Ipos pos, Conic3 * con3)
299 {
300     Vec3    q = {Vec3_id};
301     Vec3    v = {Vec3_id};
302     Vec2    p = {Vec2_id};
303     Ipos    r = {Ipos_id};
304     double  t1, t2, t, d;
305 
306     tv_ray3(tv, pos, &q, &v);
307     q = vec3_inter_line_plane(q, v, con3->origin, con3->ez);
308     q = vec3_diff(q, con3->origin);
309     vec2_x(p) = (float)vec3_dot(q, con3->ex);
310     vec2_y(p) = (float)vec3_dot(q, con3->ey);
311     t = conic_param(con3->conic, p);
312 
313     t1 = con3->conic->t1;
314     t2 = con3->conic->t2;
315 
316     if (t < t1 && t2 > TWOPI)
317         t += TWOPI;
318 
319     if (!BETWEEN(t, t1, t2))
320     {
321         double  d1, d2;
322 
323         r = tv_proj3(tv, conic3_point(con3, t1));
324         d1 = ipos_mod(ipos_diff(pos, r));
325         r = tv_proj3(tv, conic3_point(con3, t2));
326         d2 = ipos_mod(ipos_diff(pos, r));
327         d = MIN(d1, d2);
328     } else
329     {
330         r = tv_proj3(tv, conic3_point(con3, t));
331         d = ipos_mod(ipos_diff(pos, r));
332     }
333     return (d);
334 }
335 
336 void    conic3_draw_with_arrow(Tv * tv, Conic3 * conic)
337 {
338     double  t1, t2, tm,te;
339     Ipos    p1 = {Ipos_id};
340     Ipos    p2 = {Ipos_id};
341     Ipos    pm = {Ipos_id};
342     Ipos    pe = {Ipos_id};
343     float   ydir, xdir, mag;
344     float   hl, hw;             /* head length and width */
345 
346     if (tv == NULL || conic == NULL || conic->type == DEGENERATE)
347         return;
348 
349     curve_data = (void *) conic;
350     curve_func = conic3_ipos;
351     curve_tv = tv;
352     t1 = conic->conic->t1;
353     t2 = conic->conic->t2;
354     tm = (t1 + t2) * 0.5;
355     te = (t1 + t2) * 0.9;
356     p1 = conic3_ipos(tv, conic, t1);
357     p2 = conic3_ipos(tv, conic, t2);
358     pm = conic3_ipos(tv, conic, tm);
359     pe = conic3_ipos(tv, conic, te);
360     curve_section_draw(t1, tm, p1, pm, 1);
361     curve_section_draw(tm, t2, pm, p2, 1);
362 
363     xdir = (float)((p2.x - pe.x)*10.0);
364     ydir = (float)((p2.y - pe.y)*10.0);
365     mag = (float)sqrt(SQR(xdir) + SQR(ydir));
366     xdir /= mag;
367     ydir /= mag;
368 
369     hl = mag / 10;
370     if (hl > 10)
371         hl = (float)10.0;
372     hw = hl / 3;
373 
374     pe.x = (int)(p2.x - hl * xdir);
375     pe.y = (int)(p2.y - hl * ydir);
376     tv_line(tv, ipos((int) (pe.x - ydir * hw), (int) (pe.y + xdir * hw)), p2);
377     tv_line(tv, ipos((int) (pe.x + ydir * hw), (int) (pe.y - xdir * hw)), p2);
378 }
379 

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