1 /**@(#)
2 **/
3 /* pwrte.c
4 *
5 * code to build and manipulate pair wise relation tables for representing
6 * object constraints in matching
7 *
8 */
9
10 #include <math.h>
11 #include <tina/sys.h>
12 #include <tina/sysfuncs.h>
13 #include <tina/math.h>
14 #include <tina/mathfuncs.h>
15 #include <tina/vision.h>
16 #include <tina/visionfuncs.h>
17
18 static double sep_error_ratio = 0.05; /* 5% of separation */
19
20 Pwrte *pwrte_alloc(Ts_id ts_id)
21 {
22 Pwrte *p = ralloc(sizeof(Pwrte));
23
24 *(Ts_id *) p = ts_id;
25
26 return (p);
27 }
28
29 void pwrte_free(Pwrte * p)
30 {
31 rfree((void *) p);
32 }
33
34 void pwtre_table_free(Matrix * tbl)
35 {
36 int i, j;
37 int m, n;
38
39 if (tbl == NULL)
40 return;
41
42 m = tbl->m;
43 n = tbl->n;
44 for (i = 0; i < m; ++i)
45 for (j = 0; j < n; ++j)
46 pwrte_free((Pwrte *) tbl->el.ptr_v[i][j]);
47 matrix_free(tbl);
48 }
49
50 Pwrte *pwrte_point_to_point_make(Point3 * p1, Point3 * p2)
51 {
52 Pwrte *pwrte;
53 Pwrte_point_to_point *p;
54 Iso_error *iso1;
55 Iso_error *iso2;
56 double seperror, poserror, dist;
57
58 if (p1 == NULL || p2 == NULL)
59 return (NULL);
60
61 pwrte = pwrte_alloc(Pwrte_point_to_point_id);
62 p = &(pwrte->p_to_p);
63 p->type1 = POINT3;
64 p->type2 = POINT3;
65 p->p1 = (void *) p1;
66 p->p2 = (void *) p2;
67
68 dist = vec3_mod(vec3_diff(p2->p, p1->p));
69
70 iso1 = (Iso_error *) prop_get(p1->props, ISO_ERROR);
71 iso2 = (Iso_error *) prop_get(p2->props, ISO_ERROR);
72 poserror = iso1->pos + iso2->pos;
73 seperror = sep_error_ratio * dist;
74
75 if (seperror > poserror)
76 poserror = seperror;
77
78 p->lowdist = (float)((dist < poserror) ? 0 : dist - poserror);
79 p->hidist = (float)(dist + poserror);
80 return (pwrte);
81 }
82
83 Pwrte *pwrte_point_to_line_make(void *p1, int type1, void *p2, int type2)
84 {
85 Pwrte *pwrte;
86 Pwrte_point_to_vec *p;
87 Point3 *point;
88 Line3 *line;
89 Iso_error *iso1;
90 Iso_error *iso2;
91 double poserror, rot_lever, mind, d1, d2;
92 Vec3 closest = {Vec3_id};
93
94 if (p1 == NULL || p2 == NULL)
95 return (NULL);
96
97 pwrte = pwrte_alloc(Pwrte_point_to_vec_id);
98 p = &(pwrte->p_to_v);
99 p->type1 = type1;
100 p->type2 = type2;
101 p->p1 = p1;
102 p->p2 = p2;
103
104 line = (type1 == LINE3) ? (Line3 *) p1 : (Line3 *) p2;
105 point = (type1 == POINT3) ? (Point3 *) p1 : (Point3 *) p2;
106
107 iso1 = (Iso_error *) prop_get(point->props, ISO_ERROR);
108 iso2 = (Iso_error *) prop_get(line->props, ISO_ERROR);
109
110 poserror = iso1->pos + iso2->pos;
111
112 closest = vec3_proj_on_line(point->p, line->p, line->v);
113
114 mind = vec3_mod(vec3_diff(point->p, closest));
115 d1 = vec3_dot(line->v, vec3_diff(closest, line->p1));/* signed value */
116 d2 = vec3_dot(line->v, vec3_diff(closest, line->p2));
117
118 ORDER(double, d1, d2);
119 p->lowvecd = (float)(d1 - poserror - mind * iso2->rot);/* small angle sine
120 * assump */
121 p->hivecd = (float)(d2 + poserror + mind * iso2->rot);
122
123 rot_lever = (BETWEEN(0, d1, d2)) ? 0 : fmin(fabs(d1), fabs(d2));
124 poserror += atan(iso2->rot) * rot_lever;
125
126 p->lowmind = (float)((mind < poserror) ? 0.0 : mind - poserror);
127 p->himind = (float)(mind + poserror);
128 return (pwrte);
129 }
130
131 Pwrte *pwrte_point_to_conic_make(void *p1, int type1, void *p2, int type2)
132 {
133 Pwrte *pwrte;
134 Pwrte_point_to_vec *p;
135 Point3 *point;
136 Conic3 *conic;
137 Iso_error *iso1;
138 Iso_error *iso2;
139 double poserror, seperror, dist;
140 Vec3 closest = {Vec3_id};
141
142 if (p1 == NULL || p2 == NULL)
143 return (NULL);
144
145 pwrte = pwrte_alloc(Pwrte_point_to_vec_id);
146 p = &(pwrte->p_to_v);
147 p->type1 = type1;
148 p->type2 = type2;
149 p->p1 = p1;
150 p->p2 = p2;
151
152 conic = (type1 == CONIC3) ? (Conic3 *) p1 : (Conic3 *) p2;
153 point = (type1 == POINT3) ? (Point3 *) p1 : (Point3 *) p2;
154
155 dist = vec3_mod(vec3_diff(conic->origin, point->p));
156
157 iso1 = (Iso_error *) prop_get(conic->conic->props, ISO_ERROR);
158 iso2 = (Iso_error *) prop_get(point->props, ISO_ERROR);
159 poserror = iso1->pos + iso2->pos;
160 seperror = sep_error_ratio * dist;
161
162 if (seperror > poserror)
163 poserror = seperror;
164
165 p->lowmind = (float)((dist < poserror) ? 0 : dist - poserror);
166 p->himind = (float)(dist + poserror);
167
168 closest = vec3_proj_on_line(point->p, conic->origin, conic->ez);
169 dist = vec3_mod(vec3_diff(point->p, closest));
170 poserror += dist * iso1->rot; /* small angle sine assumption */
171 dist = vec3_dot(conic->ez, vec3_diff(closest, conic->origin));
172 p->lowvecd = (float)(dist - poserror);
173 p->hivecd = (float)(dist + poserror);
174
175 return (pwrte);
176 }
177
178 Pwrte *pwrte_line_to_line_make(Line3 * l1, Line3 * l2)
179 {
180 Pwrte *pwrte;
181 Pwrte_vec_to_vec *p;
182 Iso_error *iso1;
183 Iso_error *iso2;
184 double roterror, poserror;
185 double dp, angle;
186
187 if (l1 == NULL || l2 == NULL)
188 return (NULL);
189
190 pwrte = pwrte_alloc(Pwrte_vec_to_vec_id);
191 p = &(pwrte->v_to_v);
192 p->type1 = LINE3;
193 p->type2 = LINE3;
194 p->p1 = (void *) l1;
195 p->p2 = (void *) l2;
196
197 iso1 = (Iso_error *) prop_get(l1->props, ISO_ERROR);
198 iso2 = (Iso_error *) prop_get(l2->props, ISO_ERROR);
199
200 roterror = iso1->rot + iso2->rot;
201 poserror = iso1->pos + iso2->pos;
202
203 p->parallel = smm_geom_parallel((void *) l1, LINE3, (void *) l2, LINE3);
204
205 dp = vec3_dot(l1->v, l2->v);
206 angle = tina_acos(dp);
207
208 p->lowang = (float)((angle < roterror) ? 0.0 : angle - roterror);
209 p->hiang = (float)((angle + roterror > PI) ? PI : angle + roterror);
210
211 if (p->parallel == false)
212 {
213 Vec3 c1 = {Vec3_id};
214 Vec3 c2 = {Vec3_id};
215 double a1, b1, a2, b2, m1, m2;
216 double tanrot, angscale;
217 double mind, minderror;
218
219 tanrot = atan(roterror);
220 angscale = tanrot / sin(fabs(angle));
221
222 mind = vec3_closest_app(l1->p1, l1->v, l2->p1, l2->v, &c1, &c2);
223 a1 = vec3_dot(l1->v, vec3_diff(c1, l1->p1)); /* directed */
224 b1 = vec3_dot(l1->v, vec3_diff(c1, l1->p2));
225 a2 = vec3_dot(l2->v, vec3_diff(c2, l2->p1));
226 b2 = vec3_dot(l2->v, vec3_diff(c2, l2->p2));
227 m1 = (BETWEEN(0, a1, b1)) ? 0 : fmin(fabs(a1), fabs(b1));
228 m2 = (BETWEEN(0, a2, b2)) ? 0 : fmin(fabs(a2), fabs(b2));
229 ORDER(double, a1, b1);
230 ORDER(double, a2, b2);
231
232 p->lowvec1 = (float)(a1 - poserror - m2 * angscale);
233 p->hivec1 = (float)(b1 + poserror + m2 * angscale);
234 p->lowvec2 = (float)(a2 - poserror - m1 * angscale);
235 p->hivec2 = (float)(b2 + poserror + m1 * angscale);
236
237 minderror = (m1 + m2) * tanrot + poserror;
238
239 p->lowmind = (float)(mind - minderror);
240 p->himind = (float)(mind + minderror);
241 } else
242 {
243 /* towards parallel */
244 double d1, d2;
245
246 if (l1->length > l2->length)
247 {
248 d1 = vec3_dist_point_line(l1->p1, l2->p1, l2->v);
249 d2 = vec3_dist_point_line(l1->p2, l2->p1, l2->v);
250 } else
251 {
252 d1 = vec3_dist_point_line(l2->p1, l1->p1, l1->v);
253 d2 = vec3_dist_point_line(l2->p2, l1->p1, l1->v);
254 }
255 ORDER(double, d1, d2);
256 p->lowmind = (float)((d1 < poserror) ? 0.0 : d1 - poserror);
257 p->himind = (float)(d2 + poserror);
258 }
259 return (pwrte);
260 }
261
262 Pwrte *pwrte_conic_to_line_make(Conic3 * conic, Line3 * line)
263 {
264 Pwrte *pwrte;
265 Pwrte_vec_to_vec *p;
266 Iso_error *iso1;
267 Iso_error *iso2;
268 double roterror, poserror;
269 double dp, angle, dist, d1, d2, minderror, rot_lever;
270 Vec3 closest = {Vec3_id};
271
272 if (conic == NULL || line == NULL)
273 return (NULL);
274
275 pwrte = pwrte_alloc(Pwrte_vec_to_vec_id);
276 p = &(pwrte->v_to_v);
277 p->type1 = CONIC3;
278 p->type2 = LINE3;
279 p->p1 = (void *) conic;
280 p->p2 = (void *) line;
281
282 iso1 = (Iso_error *) prop_get(conic->conic->props, ISO_ERROR);
283 iso2 = (Iso_error *) prop_get(line->props, ISO_ERROR);
284
285 roterror = iso1->rot + iso2->rot;
286 poserror = iso1->pos + iso2->pos;
287
288 p->parallel = smm_geom_parallel((void *) conic, CONIC3, (void *) line, LINE3);
289
290 dp = vec3_dot(conic->ez, line->v);
291 angle = tina_acos(dp);
292
293 p->lowang = (float)((angle < roterror) ? 0.0 : angle - roterror);
294 p->hiang = (float)((angle + roterror > PI) ? PI : angle + roterror);
295
296 closest = vec3_proj_on_line(conic->origin, line->p, line->v);
297
298 dist = vec3_mod(vec3_diff(conic->origin, closest));
299 d1 = vec3_dot(line->v, vec3_diff(closest, line->p1)); /* signed value */
300 d2 = vec3_dot(line->v, vec3_diff(closest, line->p2));
301
302 ORDER(double, d1, d2);
303 p->lowvec2 = (float)(d1 - poserror - dist * iso2->rot);
304 p->hivec2 = (float)(d2 + poserror + dist * iso2->rot);
305
306 rot_lever = (BETWEEN(0, d1, d2)) ? 0 : fmin(fabs(d1), fabs(d2));
307 minderror = poserror + atan(iso2->rot) * rot_lever;
308
309 p->lowmind = (float)((dist < minderror) ? 0.0 : dist - minderror);
310 p->himind = (float)(dist + minderror);
311
312 if (p->parallel == false)
313 {
314 Vec3 c1 = {Vec3_id};
315 Vec3 c2 = {Vec3_id};
316 double tanrot, angscale;
317
318 tanrot = atan(roterror);
319 angscale = tanrot / sin(fabs(angle));
320
321 (void) vec3_closest_app(conic->origin, conic->ez, line->p1, line->v, &c1, &c2);
322 dist = vec3_dot(conic->ez, vec3_diff(c1, conic->origin));
323 d1 = vec3_dot(line->v, vec3_diff(c1, line->p1));
324 d2 = vec3_dot(line->v, vec3_diff(c1, line->p2));
325 angscale *= (BETWEEN(0, d1, d2)) ? 0 : fmin(fabs(d1), fabs(d2));
326
327 p->lowvec1 = (float)(dist - poserror - angscale);
328 p->hivec1 = (float)(dist + poserror + angscale);
329 }
330 return (pwrte);
331 }
332
333 Pwrte *pwrte_line_to_conic_make(Line3 * line, Conic3 * conic)
334 {
335 Pwrte *pwrte;
336 Pwrte_vec_to_vec *p;
337 Iso_error *iso1;
338 Iso_error *iso2;
339 double roterror, poserror;
340 double dp, angle, dist, d1, d2, minderror, rot_lever;
341 Vec3 closest = {Vec3_id};
342
343 if (conic == NULL || line == NULL)
344 return (NULL);
345
346 pwrte = pwrte_alloc(Pwrte_vec_to_vec_id);
347 p = &(pwrte->v_to_v);
348 p->type1 = LINE3;
349 p->type2 = CONIC3;
350 p->p1 = (void *) line;
351 p->p2 = (void *) conic;
352
353 iso1 = (Iso_error *) prop_get(line->props, ISO_ERROR);
354 iso2 = (Iso_error *) prop_get(conic->conic->props, ISO_ERROR);
355
356 roterror = iso1->rot + iso2->rot;
357 poserror = iso1->pos + iso2->pos;
358
359 p->parallel = smm_geom_parallel((void *) conic, CONIC3, (void *) line, LINE3);
360
361 dp = vec3_dot(conic->ez, line->v);
362 angle = tina_acos(dp);
363
364 p->lowang = (float)((angle < roterror) ? 0.0 : angle - roterror);
365 p->hiang = (float)((angle + roterror > PI) ? PI : angle + roterror);
366
367 closest = vec3_proj_on_line(conic->origin, line->p, line->v);
368
369 dist = vec3_mod(vec3_diff(conic->origin, closest));
370 d1 = vec3_dot(line->v, vec3_diff(closest, line->p1)); /* signed value */
371 d2 = vec3_dot(line->v, vec3_diff(closest, line->p2));
372
373 ORDER(double, d1, d2);
374 p->lowvec1 = (float)(d1 - poserror - dist * iso2->rot);
375 p->hivec1 = (float)(d2 + poserror + dist * iso2->rot);
376
377 rot_lever = (BETWEEN(0, d1, d2)) ? 0 : fmin(fabs(d1), fabs(d2));
378 minderror = poserror + atan(iso2->rot) * rot_lever;
379
380 p->lowmind = (float)((dist < minderror) ? 0.0 : dist - minderror);
381 p->himind = (float)(dist + minderror);
382
383 if (p->parallel == false)
384 {
385 Vec3 c1 = {Vec3_id};
386 Vec3 c2 = {Vec3_id};
387 double tanrot, angscale;
388
389 tanrot = atan(roterror);
390 angscale = tanrot / sin(fabs(angle));
391
392 (void) vec3_closest_app(conic->origin, conic->ez, line->p1, line->v, &c1, &c2);
393 dist = vec3_dot(conic->ez, vec3_diff(c1, conic->origin));
394 d1 = vec3_dot(line->v, vec3_diff(c1, line->p1));
395 d2 = vec3_dot(line->v, vec3_diff(c1, line->p2));
396 angscale *= (BETWEEN(0, d1, d2)) ? 0 : fmin(fabs(d1), fabs(d2));
397
398 p->lowvec2 = (float)(dist - poserror - angscale);
399 p->hivec2 = (float)(dist + poserror + angscale);
400 }
401 return (pwrte);
402 }
403
404 Pwrte *pwrte_conic_to_conic_make(Conic3 * c1, Conic3 * c2)
405 {
406 Pwrte *pwrte;
407 Pwrte_vec_to_vec *p;
408 Iso_error *iso1;
409 Iso_error *iso2;
410 double roterror, poserror, seperror;
411 double dp, angle, dist;
412 Vec3 closest = {Vec3_id};
413
414 if (c1 == NULL || c2 == NULL)
415 return (NULL);
416
417 pwrte = pwrte_alloc(Pwrte_vec_to_vec_id);
418 p = &(pwrte->v_to_v);
419 p->type1 = CONIC3;
420 p->type2 = CONIC3;
421 p->p1 = (void *) c1;
422 p->p2 = (void *) c2;
423
424 dist = vec3_mod(vec3_diff(c1->origin, c2->origin));
425
426 iso1 = (Iso_error *) prop_get(c1->conic->props, ISO_ERROR);
427 iso2 = (Iso_error *) prop_get(c2->conic->props, ISO_ERROR);
428
429 roterror = iso1->rot + iso2->rot;
430 poserror = iso1->pos + iso2->pos;
431 seperror = sep_error_ratio * dist;
432
433 if (seperror > poserror)
434 poserror = seperror;
435
436 p->parallel = false;
437
438 dp = vec3_dot(c1->ez, c2->ez);
439 angle = tina_acos(dp);
440
441 p->lowang = (float)((angle < roterror) ? 0.0 : angle - roterror);
442 p->hiang = (float)((angle + roterror > PI) ? PI : angle + roterror);
443
444 p->lowmind = (float)((dist < poserror) ? 0 : dist - poserror);
445 p->himind = (float)(dist + poserror);
446
447 closest = vec3_proj_on_line(c2->origin, c1->origin, c1->ez);
448 roterror = vec3_mod(vec3_diff(closest, c2->origin)) * iso1->rot;
449 dist = vec3_dot(c1->ez, vec3_diff(closest, c1->origin));
450 p->lowvec1 = (float)(dist - poserror - roterror);
451 p->hivec1 = (float)(dist + poserror + roterror);
452
453 closest = vec3_proj_on_line(c1->origin, c2->origin, c2->ez);
454 roterror = vec3_mod(vec3_diff(closest, c1->origin)) * iso2->rot;
455 dist = vec3_dot(c2->ez, vec3_diff(closest, c2->origin));
456 p->lowvec2 = (float)(dist - poserror - roterror);
457 p->hivec2 = (float)(dist + poserror + roterror);
458
459 return (pwrte);
460 }
461
462 Pwrte *pwrte_make(void *p1, int type1, void *p2, int type2)
463 {
464 switch (PAIR(type1, type2))
465 {
466 case PAIR(POINT3, POINT3):
467 return (pwrte_point_to_point_make((Point3 *) p1, (Point3 *) p2));
468 case PAIR(POINT3, LINE3):
469 return (pwrte_point_to_line_make(p1, type1, p2, type2));
470 case PAIR(POINT3, CONIC3):
471 return (pwrte_point_to_conic_make(p1, type1, p2, type2));
472 case PAIR(LINE3, LINE3):
473 return (pwrte_line_to_line_make((Line3 *) p1, (Line3 *) p2));
474 case PAIR(LINE3, CONIC3):
475 switch (OPAIR(type1, type2))
476 {
477 case OPAIR(LINE3, CONIC3):
478 return (pwrte_line_to_conic_make((Line3 *) p1, (Conic3 *) p2));
479 case OPAIR(CONIC3, LINE3):
480 return (pwrte_conic_to_line_make((Conic3 *) p1, (Line3 *) p2));
481 }
482 case PAIR(CONIC3, CONIC3):
483 return (pwrte_conic_to_conic_make((Conic3 *) p1, (Conic3 *) p2));
484 default:
485 return (NULL);
486 }
487 }
488
489 Bool point_to_point_pwrte_compatible(Pwrte_point_to_point * p1, Pwrte_point_to_point * p2)
490 {
491 if (p1 == NULL || p2 == NULL)
492 return (false);
493
494 if (!OVERLAPPED(p1->lowdist, p1->hidist, p2->lowdist, p2->hidist))
495 return (false);
496 return (true);
497 }
498
499 Bool point_to_vec_pwrte_compatible(Pwrte_point_to_vec * p1, Pwrte_point_to_vec * p2)
500 {
501 if (p1 == NULL || p2 == NULL)
502 return (false);
503
504 if (!OVERLAPPED(p1->lowmind, p1->himind, p2->lowmind, p2->himind))
505 return (false);
506
507 if (!OVERLAPPED(p1->lowvecd, p1->hivecd, p2->lowvecd, p2->hivecd))
508 return (false);
509
510 return (true);
511 }
512
513 Bool line_to_line_pwrte_compatible(Pwrte_vec_to_vec * p1, Pwrte_vec_to_vec * p2)
514 {
515 if (p1 == NULL || p2 == NULL)
516 return (false);
517
518 if (!OVERLAPPED(p1->lowang, p1->hiang, p2->lowang, p2->hiang))
519 return (false);
520
521 if (p1->parallel == false && p2->parallel == false)
522 {
523 if (!OVERLAPPED(p1->lowmind, p1->himind, p2->lowmind, p2->himind))
524 return (false);
525
526 if (!OVERLAPPED(p1->lowvec1, p1->hivec1, p2->lowvec1, p2->hivec1))
527 return (false);
528
529 if (!OVERLAPPED(p1->lowvec2, p1->hivec2, p2->lowvec2, p2->hivec2))
530 return (false);
531
532 return (true);
533 }
534 if (p1->parallel == p2->parallel) /* both parallel */
535 {
536 if (OVERLAPPED(p1->lowmind, p1->himind, p2->lowmind, p2->himind))
537 return (true);
538 else
539 return (false);
540 }
541 if (p1->parallel == true)
542 {
543 double d1, d2;
544 Line3 *l1 = (Line3 *) p2->p1;
545 Line3 *l2 = (Line3 *) p2->p2;
546
547 if (l1->length > l2->length)
548 {
549 d1 = vec3_dist_point_line(l1->p1, l2->p1, l2->v);
550 d2 = vec3_dist_point_line(l1->p2, l2->p1, l2->v);
551 } else
552 {
553 d1 = vec3_dist_point_line(l2->p1, l1->p1, l1->v);
554 d2 = vec3_dist_point_line(l2->p2, l1->p1, l1->v);
555 }
556 ORDER(double, d1, d2);
557 return (OVERLAPPED(p1->lowmind, p1->himind, d1, d2) ? true : false);
558 } else
559 {
560 /* p2 parallel */
561 double d1, d2;
562 Line3 *l1 = (Line3 *) p1->p1;
563 Line3 *l2 = (Line3 *) p1->p2;
564
565 if (l1->length > l2->length)
566 {
567 d1 = vec3_dist_point_line(l1->p1, l2->p1, l2->v);
568 d2 = vec3_dist_point_line(l1->p2, l2->p1, l2->v);
569 } else
570 {
571 d1 = vec3_dist_point_line(l2->p1, l1->p1, l1->v);
572 d2 = vec3_dist_point_line(l2->p2, l1->p1, l1->v);
573 }
574 ORDER(double, d1, d2);
575 return (OVERLAPPED(p2->lowmind, p2->himind, d1, d2) ? true : false);
576 }
577 }
578
579 Bool line_to_conic_pwrte_compatible(Pwrte_vec_to_vec * p1, Pwrte_vec_to_vec * p2)
580 {
581 Bool parallel;
582
583 if (p1 == NULL || p2 == NULL)
584 return (false);
585
586 if (!OVERLAPPED(p1->lowang, p1->hiang, p2->lowang, p2->hiang))
587 return (false);
588
589 if (!OVERLAPPED(p1->lowmind, p1->himind, p2->lowmind, p2->himind))
590 return (false);
591
592 parallel = (Bool) (p1->parallel == true || p2->parallel == true);
593
594 if ((parallel == false || p1->type1 == LINE3) && /* if // only test line */
595 !OVERLAPPED(p1->lowvec1, p1->hivec1, p2->lowvec1, p2->hivec1))
596 return (false);
597
598 if ((parallel == false || p1->type2 == LINE3) && /* if // only test line */
599 !OVERLAPPED(p1->lowvec2, p1->hivec2, p2->lowvec2, p2->hivec2))
600 return (false);
601
602 return (true);
603 }
604
605 Bool conic_to_conic_pwrte_compatible(Pwrte_vec_to_vec * p1, Pwrte_vec_to_vec * p2)
606 {
607 if (p1 == NULL || p2 == NULL)
608 return (false);
609
610 if (!OVERLAPPED(p1->lowang, p1->hiang, p2->lowang, p2->hiang))
611 return (false);
612
613 if (!OVERLAPPED(p1->lowmind, p1->himind, p2->lowmind, p2->himind))
614 return (false);
615
616 if (!OVERLAPPED(p1->lowvec1, p1->hivec1, p2->lowvec1, p2->hivec1))
617 return (false);
618
619 if (!OVERLAPPED(p1->lowvec2, p1->hivec2, p2->lowvec2, p2->hivec2))
620 return (false);
621
622 return (true);
623 }
624
625 Bool pwrte_compatible(Pwrte * p1, Pwrte * p2)
626 {
627 if (p1 == NULL || p2 == NULL)
628 return (false);
629
630 if (OPAIR(p1->gen.type1, p1->gen.type2) != OPAIR(p2->gen.type1, p2->gen.type2))
631 return (false);
632
633 switch (PAIR(p1->gen.type1, p1->gen.type2))
634 {
635 case PAIR(POINT3, POINT3):
636 return (point_to_point_pwrte_compatible(&(p1->p_to_p), &(p2->p_to_p)));
637 case PAIR(POINT3, LINE3):
638 case PAIR(POINT3, CONIC3):
639 return (point_to_vec_pwrte_compatible(&(p1->p_to_v), &(p2->p_to_v)));
640 case PAIR(LINE3, LINE3):
641 return (line_to_line_pwrte_compatible(&(p1->v_to_v), &(p2->v_to_v)));
642 case PAIR(LINE3, CONIC3):
643 return (line_to_conic_pwrte_compatible(&(p1->v_to_v), &(p2->v_to_v)));
644 case PAIR(CONIC3, CONIC3):
645 return (conic_to_conic_pwrte_compatible(&(p1->v_to_v), &(p2->v_to_v)));
646 }
647 return (false);
648 }
649
650 void pwrte_set_entry(Matrix * table, void *p1, int type1, void *p2, int type2)
651 /* of shape full; type ptr_v */
652
653
654 {
655 int i, j;
656
657 i = (int) geom_prop_get(p1, type1, PWR);
658 j = (int) geom_prop_get(p2, type2, PWR);
659
660 if (table->el.ptr_v[i][j] == NULL)
661 table->el.ptr_v[i][j] = (void *) pwrte_make(p1, type1, p2, type2);
662 if (i != j && table->el.ptr_v[j][i] == NULL)
663 table->el.ptr_v[j][i] = (void *) pwrte_make(p2, type2, p1, type1);
664 }
665
666 Matrix *pwrte_build_full_table(List * list)
667 /* list of geom primitives */
668 {
669 List *l1;
670 List *l2;
671 Matrix *table;
672 int n;
673
674 if (list == NULL)
675 return (NULL);
676
677 for (n = 0, l1 = list; l1 != NULL; l1 = l1->next, n++)
678 geom_prop_addifnp(l1->to, l1->type, (void *) n, PWR, (void (*) ()) NULL, false);
679
680 table = matrix_alloc(n, n, matrix_full, ptr_v);
681
682 if (list->next == NULL)
683 return (table);
684
685 for (l1 = list; l1->next != NULL; l1 = l1->next)
686 for (l2 = l1->next; l2 != NULL; l2 = l2->next)
687 pwrte_set_entry(table, l1->to, l1->type, l2->to, l2->type);
688
689 return (table);
690 }
691
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.