1 /**********
2 *
3 * Copyright (c) 2003, Division of Imaging Science and Biomedical Engineering,
4 * University of Manchester, UK. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
8 *
9 * . Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * . Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 *
16 * . Neither the name of the University of Manchester nor the names of its
17 * contributors may be used to endorse or promote products derived from this
18 * software without specific prior written permission.
19 *
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 **********
34 *
35 * Program : TINA
36 * File : $Source: /home/tina/cvs/tina-tools/tinatool/draw/drawPaint_curve.c,v $
37 * Date : $Date: 2003/10/01 16:02:47 $
38 * Version : $Revision: 1.2 $
39 * CVS Id : $Id: drawPaint_curve.c,v 1.2 2003/10/01 16:02:47 tony Exp $
40 *
41 * Author : Legacy TINA
42 *
43 * Notes :
44 *
45 *********
46 */
47
48 #include "drawPaint_curve.h"
49
50 #if HAVE_CONFIG_H
51 #include <config.h>
52 #endif
53
54 #include <math.h>
55 #include <tina/sys/sysDef.h>
56 #include <tina/sys/sysPro.h>
57 #include <tina/math/mathDef.h>
58 #include <tina/math/mathPro.h>
59 #include <tina/geometry/geomDef.h>
60 #include <tina/geometry/geomPro.h>
61 #include <tinatool/draw/draw_TvDef.h>
62 #include <tinatool/draw/draw_TvPro.h>
63 #include <tinatool/draw/draw_PaintDef.h>
64 #include <tinatool/draw/draw_PaintPro.h>
65
66 static int curve_sample = 4; /* sample of 4 pixels */
67 static int min_level = 3; /* minimum level of recursion */
68 static Tv *curve_tv;
69 static Ipos(*curve_func) ();
70 static void *curve_data;
71
72 int curve_draw_sample_get(void)
73 {
74 return (curve_sample);
75 }
76
77 void curve_draw_sample_set(int s)
78 {
79 curve_sample = s;
80 }
81
82 static void curve_section_draw(double t1, double t2, Ipos p1, Ipos p2, int level)
83 {
84 double tm;
85 int space;
86 Ipos pm = {Ipos_id};
87
88 space = (int)ipos_mod(ipos_diff(p1, p2));
89 if (space <= 1 || (level >= min_level && space < curve_sample))
90 {
91 if (level <= min_level || space > 1)
92 tv_line(curve_tv, p1, p2);
93 return;
94 }
95 tm = (t1 + t2) * 0.5;
96 pm = curve_func(curve_tv, curve_data, tm);
97
98 curve_section_draw(t1, tm, p1, pm, level + 1);
99 curve_section_draw(tm, t2, pm, p2, level + 1);
100 }
101
102 void curve_draw(Tv * tv, Ipos(*func) ( /* ??? */ ), void *data, double t1, double t2)
103 {
104 double tm;
105 Ipos p1 = {Ipos_id};
106 Ipos p2 = {Ipos_id};
107 Ipos pm = {Ipos_id};
108
109 if (tv == NULL)
110 return;
111
112 curve_data = data;
113 curve_func = func;
114 curve_tv = tv;
115
116 tm = (t1 + t2) * 0.5;
117 p1 = curve_func(tv, curve_data, t1);
118 p2 = curve_func(tv, curve_data, t2);
119 pm = curve_func(tv, curve_data, tm);
120 curve_section_draw(t1, tm, p1, pm, 1);
121 curve_section_draw(tm, t2, pm, p2, 1);
122 }
123
124 static Ipos conic2_ipos(Tv * tv, Conic * conic, double t)
125 {
126 Vec2 v = {Vec2_id};
127
128 v = conic_point(conic, t);
129 return (tv_proj2(tv, v));
130 }
131
132 void conic2_draw(Tv * tv, Conic * conic)
133 {
134 double t1, t2, tm;
135 Ipos p1 = {Ipos_id};
136 Ipos p2 = {Ipos_id};
137 Ipos pm = {Ipos_id};
138 Conic *conic_im;
139
140 if (tv == NULL || conic == NULL || conic->type == DEGENERATE)
141 return;
142
143 conic_im = (Conic *) prop_get(conic->props, IMPOS);
144 curve_data = (conic_im == NULL) ? (void *) conic : (void *) conic_im;
145 curve_func = conic2_ipos;
146 curve_tv = tv;
147 t1 = ((Conic *) curve_data)->t1;
148 t2 = ((Conic *) curve_data)->t2;
149 tm = (t1 + t2) * 0.5;
150
151 p1 = curve_func(tv, curve_data, t1);
152 p2 = curve_func(tv, curve_data, t2);
153 pm = curve_func(tv, curve_data, tm);
154 curve_section_draw(t1, tm, p1, pm, 1);
155 curve_section_draw(tm, t2, pm, p2, 1);
156 }
157
158 void conic2_draw_axes(Tv * tv, Conic * conic)
159 {
160 Vec2 center_var = {Vec2_id};
161 Vec2 major_var = {Vec2_id};
162 Vec2 minor_var = {Vec2_id};
163 double alpha, beta, theta;
164
165 if (tv == NULL || conic == NULL || conic->type == DEGENERATE)
166 return;
167 center_var = conic->center;
168 alpha = conic->alpha;
169 beta = conic->beta;
170 theta = conic->theta;
171
172 major_var = vec2(alpha * cos(theta), alpha * sin(theta));
173 minor_var = vec2(-beta * sin(theta), beta * cos(theta));
174 tv_line2(tv, vec2_diff(center_var, major_var), vec2_sum(center_var, major_var));
175 tv_line2(tv, vec2_diff(center_var, minor_var), vec2_sum(center_var, minor_var));
176 }
177
178 void conic2_draw_seg(Tv * tv, Conic * conic, double t1, double t2)
179 {
180 double tm;
181 Ipos p1 = {Ipos_id};
182 Ipos p2 = {Ipos_id};
183 Ipos pm = {Ipos_id};
184 Conic *conic_im;
185
186 if (tv == NULL || conic == NULL || conic->type == DEGENERATE)
187 return;
188
189 conic_im = (Conic *) prop_get(conic->props, IMPOS);
190 curve_data = (conic_im == NULL) ? (void *) conic : (void *) conic_im;
191 curve_func = conic2_ipos;
192 curve_tv = tv;
193 tm = (t1 + t2) * 0.5;
194
195 p1 = curve_func(tv, curve_data, t1);
196 p2 = curve_func(tv, curve_data, t2);
197 pm = curve_func(tv, curve_data, tm);
198 curve_section_draw(t1, tm, p1, pm, 1);
199 curve_section_draw(tm, t2, pm, p2, 1);
200 }
201
202 void conic2_draw_col(Tv * tv, Conic * conic)
203 {
204 double t1, t2, tm;
205 Ipos p1 = {Ipos_id};
206 Ipos p2 = {Ipos_id};
207 Ipos pm = {Ipos_id};
208 Conic *conic_im;
209
210 if (tv == NULL || conic == NULL || conic->type == DEGENERATE)
211 return;
212
213 tv_save_draw(tv);
214
215 switch (conic->type)
216 {
217 case ELLIPSE:
218 tv_set_color(tv, yellow);
219 break;
220 case HYPERBOLA:
221 tv_set_color(tv, baby_pink);
222 break;
223 default:
224 tv_set_color(tv, white);
225 }
226
227 conic_im = (Conic *) prop_get(conic->props, IMPOS);
228 curve_data = (conic_im == NULL) ? (void *) conic : (void *) conic_im;
229 curve_func = conic2_ipos;
230 curve_tv = tv;
231 t1 = ((Conic *) curve_data)->t1;
232 t2 = ((Conic *) curve_data)->t2;
233 tm = (t1 + t2) * 0.5;
234
235 p1 = curve_func(tv, curve_data, t1);
236 p2 = curve_func(tv, curve_data, t2);
237 pm = curve_func(tv, curve_data, tm);
238 curve_section_draw(t1, tm, p1, pm, 1);
239 curve_section_draw(tm, t2, pm, p2, 1);
240 tv_set_color(tv, red);
241 tv_point(tv, p1);
242 tv_point(tv, p2);
243
244 tv_reset_draw(tv);
245 }
246
247 static Ipos conic3_ipos(Tv * tv, Conic3 * conic, double t)
248 {
249 Vec3 v = {Vec3_id};
250
251 v = conic3_point(conic, t);
252 return (tv_proj3(tv, v));
253 }
254
255 void conic3_draw(Tv * tv, Conic3 * conic)
256 {
257 double t1, t2, tm;
258 Ipos p1 = {Ipos_id};
259 Ipos p2 = {Ipos_id};
260 Ipos pm = {Ipos_id};
261
262 if (tv == NULL || conic == NULL || conic->type == DEGENERATE)
263 return;
264
265 curve_data = (void *) conic;
266 curve_func = conic3_ipos;
267 curve_tv = tv;
268 t1 = conic->conic->t1;
269 t2 = conic->conic->t2;
270 tm = (t1 + t2) * 0.5;
271 p1 = conic3_ipos(tv, conic, t1);
272 p2 = conic3_ipos(tv, conic, t2);
273 pm = conic3_ipos(tv, conic, tm);
274 curve_section_draw(t1, tm, p1, pm, 1);
275 curve_section_draw(tm, t2, pm, p2, 1);
276 }
277
278 void conic3_draw_col(Tv * tv, Conic3 * conic)
279 {
280 double t1, t2, tm;
281 Ipos p1 = {Ipos_id};
282 Ipos p2 = {Ipos_id};
283 Ipos pm = {Ipos_id};
284
285 if (tv == NULL || conic == NULL || conic->type == DEGENERATE)
286 return;
287
288 switch (conic->type)
289 {
290 case ELLIPSE:
291 tv_set_color(tv, yellow);
292 break;
293 case HYPERBOLA:
294 tv_set_color(tv, baby_pink);
295 break;
296 default:
297 tv_set_color(tv, white);
298 }
299
300 curve_data = (void *) conic;
301 curve_func = conic3_ipos;
302 curve_tv = tv;
303 t1 = conic->conic->t1;
304 t2 = conic->conic->t2;
305 tm = (t1 + t2) * 0.5;
306 p1 = conic3_ipos(tv, conic, t1);
307 p2 = conic3_ipos(tv, conic, t2);
308 pm = conic3_ipos(tv, conic, tm);
309 curve_section_draw(t1, tm, p1, pm, 1);
310 curve_section_draw(tm, t2, pm, p2, 1);
311 tv_set_color(tv, red);
312 tv_point(tv, p1);
313 tv_point(tv, p2);
314 }
315
316 double pick_conic2_dist(Tv * tv, Ipos pos, Conic * conic)
317 {
318 Vec2 p = {Vec2_id};
319 Ipos q = {Ipos_id};
320 double t, t1, t2;
321 Conic *conic_im;
322
323 if ((conic_im = (Conic *) prop_get(conic->props, IMPOS)) != NULL)
324 conic = conic_im;
325
326 p = tv_backproj2(tv, pos);
327 t = conic_param(conic, p);
328
329 t1 = conic->t1;
330 t2 = conic->t2;
331
332 if (t < t1 && t2 > TWOPI)
333 t += TWOPI;
334
335 if (!BETWEEN(t, t1, t2))
336 {
337 double d1, d2;
338
339 q = tv_proj2(tv, conic_point(conic, t1));
340 d1 = ipos_mod(ipos_diff(pos, q));
341 q = tv_proj2(tv, conic_point(conic, t2));
342 d2 = ipos_mod(ipos_diff(pos, q));
343 return (MIN(d1, d2));
344 }
345 q = tv_proj2(tv, conic_point(conic, t));
346 return (ipos_mod(ipos_diff(pos, q)));
347 }
348
349 double pick_conic3_dist(Tv * tv, Ipos pos, Conic3 * con3)
350 {
351 Vec3 q = {Vec3_id};
352 Vec3 v = {Vec3_id};
353 Vec2 p = {Vec2_id};
354 Ipos r = {Ipos_id};
355 double t1, t2, t, d;
356
357 tv_ray3(tv, pos, &q, &v);
358 q = vec3_inter_line_plane(q, v, con3->origin, con3->ez);
359 q = vec3_diff(q, con3->origin);
360 vec2_x(p) = (float)vec3_dot(q, con3->ex);
361 vec2_y(p) = (float)vec3_dot(q, con3->ey);
362 t = conic_param(con3->conic, p);
363
364 t1 = con3->conic->t1;
365 t2 = con3->conic->t2;
366
367 if (t < t1 && t2 > TWOPI)
368 t += TWOPI;
369
370 if (!BETWEEN(t, t1, t2))
371 {
372 double d1, d2;
373
374 r = tv_proj3(tv, conic3_point(con3, t1));
375 d1 = ipos_mod(ipos_diff(pos, r));
376 r = tv_proj3(tv, conic3_point(con3, t2));
377 d2 = ipos_mod(ipos_diff(pos, r));
378 d = MIN(d1, d2);
379 } else
380 {
381 r = tv_proj3(tv, conic3_point(con3, t));
382 d = ipos_mod(ipos_diff(pos, r));
383 }
384 return (d);
385 }
386
387 void conic3_draw_with_arrow(Tv * tv, Conic3 * conic)
388 {
389 double t1, t2, tm,te;
390 Ipos p1 = {Ipos_id};
391 Ipos p2 = {Ipos_id};
392 Ipos pm = {Ipos_id};
393 Ipos pe = {Ipos_id};
394 float ydir, xdir, mag;
395 float hl, hw; /* head length and width */
396
397 if (tv == NULL || conic == NULL || conic->type == DEGENERATE)
398 return;
399
400 curve_data = (void *) conic;
401 curve_func = conic3_ipos;
402 curve_tv = tv;
403 t1 = conic->conic->t1;
404 t2 = conic->conic->t2;
405 tm = (t1 + t2) * 0.5;
406 te = (t1 + t2) * 0.9;
407 p1 = conic3_ipos(tv, conic, t1);
408 p2 = conic3_ipos(tv, conic, t2);
409 pm = conic3_ipos(tv, conic, tm);
410 pe = conic3_ipos(tv, conic, te);
411 curve_section_draw(t1, tm, p1, pm, 1);
412 curve_section_draw(tm, t2, pm, p2, 1);
413
414 xdir = (float)((p2.x - pe.x)*10.0);
415 ydir = (float)((p2.y - pe.y)*10.0);
416 mag = (float)sqrt(SQR(xdir) + SQR(ydir));
417 xdir /= mag;
418 ydir /= mag;
419
420 hl = mag / 10;
421 if (hl > 10)
422 hl = (float)10.0;
423 hw = hl / 3;
424
425 pe.x = (int)(p2.x - hl * xdir);
426 pe.y = (int)(p2.y - hl * ydir);
427 tv_line(tv, ipos((int) (pe.x - ydir * hw), (int) (pe.y + xdir * hw)), p2);
428 tv_line(tv, ipos((int) (pe.x + ydir * hw), (int) (pe.y - xdir * hw)), p2);
429 }
430
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.