Code

make rotations, scales and flips work with the object's rotation axis
[inkscape.git] / src / livarot / MySeg.cpp
1 /*
2  *  MySeg.cpp
3  *  nlivarot
4  *
5  *  Created by fred on Wed Nov 12 2003.
6  *  Copyright (c) 2003 __MyCompanyName__. All rights reserved.
7  *
8  */
10 #include "MySeg.h"
11 #include <math.h>
13 void
14 L_SEG::Distance (L_SEG & is, double &di, int mode)
15 {
16   if (mode == inters_seg_seg)
17     {
18       double ms, me, os, oe;
20       vec2d en = is.p;
21       L_VEC_Add (en, is.d, en);
23       Distance (is.p, os, inters_seg_pt);
24       Distance (en, oe, inters_seg_pt);
26       en = p;
27       L_VEC_Add (en, d, en);
29       is.Distance (p, ms, inters_orseg_pt);
30       is.Distance (en, me, inters_orseg_pt);
31       if (L_VAL_Zero (ms) < 0 || L_VAL_Zero (me) < 0)
32         {
33           di = 1000000;
34           return;
35         }
36       if (L_VAL_Cmp (oe, os) < 0)
37         os = oe;
38       if (L_VAL_Cmp (me, ms) < 0)
39         ms = me;
40       if (L_VAL_Cmp (ms, os) < 0)
41         os = ms;
42       di = os;
43     }
44   else if (mode == inters_seg_dmd)
45     {
46     }
47   else if (mode == inters_seg_dr)
48     {
49     }
50 }
52 void
53 L_SEG::Distance (vec2d & iv, double &di, int mode)
54 {
55   if (L_VAL_Zero (d.x) == 0 && L_VAL_Zero (d.y) == 0)
56     {
57       L_VEC_Distance (p, iv, di);
58       return;
59     }
60   double dd, sqd;
61   vec2d nd = d;
62   L_VEC_RotCW (nd);
63   L_VEC_Cross (nd, nd, dd);
64   sqd = sqrt (dd);
65   vec2d diff = iv;
66   L_VEC_Sub (diff, p, diff);
67   if (mode == inters_dr_pt)
68     {
69       double cp;
70       L_VEC_Cross (diff, nd, cp);
71       di = cp / sqd;
72       if (di < 0)
73         di = -di;
74     }
75   else if (mode == inters_dmd_pt)
76     {
77       double cp;
78       L_VEC_Cross (diff, d, cp);
79       if (cp < 0)
80         {
81           L_VEC_Distance (p, iv, di);
82           return;
83         }
84       L_VEC_Cross (diff, nd, cp);
85       di = cp / sqd;
86       if (di < 0)
87         di = -di;
88     }
89   else if (mode == inters_seg_pt)
90     {
91       double cp;
92       L_VEC_Cross (diff, d, cp);
93       if (cp < 0)
94         {
95           L_VEC_Distance (p, iv, di);
96           return;
97         }
98       if (cp > dd)
99         {
100           vec2d se = p;
101           L_VEC_Add (se, d, se);
102           L_VEC_Distance (se, iv, di);
103           return;
104         }
105       L_VEC_Cross (diff, nd, cp);
106       di = cp / sqd;
107       if (di < 0)
108         di = -di;
109     }
110   else if (mode == inters_orseg_pt)
111     {
112       double cp;
113       L_VEC_Cross (diff, d, cp);
114       if (cp < 0)
115         {
116           L_VEC_Distance (p, iv, di);
117           L_VEC_Dot (diff, d, cp);
118           if (L_VAL_Zero (cp) < 0)
119             di = -di;
120           return;
121         }
122       if (cp > dd)
123         {
124           vec2d se = p;
125           L_VEC_Add (se, d, se);
126           L_VEC_Distance (se, iv, di);
128           L_VEC_Dot (diff, d, cp);
129           if (cp < 0)
130             di = -di;
131           return;
132         }
133       L_VEC_Cross (diff, nd, cp);
134       di = cp / sqd;
135 //              if ( diL_VAL_Zero() < 0 ) di.Neg();
136     }
139 int
140 L_SEG::Intersect (L_SEG & iu, L_SEG & iv, int mode)
142   double iudd, ivdd;
143   L_VEC_Cross (iu.d, iu.d, iudd);
144   L_VEC_Cross (iv.d, iv.d, ivdd);
145   if (L_VAL_Zero (iudd) <= 0)
146     return 0;                   // cas illicite
147   if (L_VAL_Zero (ivdd) <= 0)
148     return 0;                   // cas illicite
150   vec2d usvs, uevs, usve, ueve;
151   L_VEC_Sub (iv.p, iu.p, usvs);
152   L_VEC_Sub (usvs, iu.d, uevs);
153   L_VEC_Add (usvs, iv.d, usve);
154   L_VEC_Sub (usve, iu.d, ueve);
155   double usvsl, uevsl, usvel, uevel;
156   L_VEC_Cross (usvs, usvs, usvsl);
157   L_VEC_Cross (uevs, uevs, uevsl);
158   L_VEC_Cross (usve, usve, usvel);
159   L_VEC_Cross (ueve, ueve, uevel);
161   double dd;
162   L_VEC_Cross (iu.d, iv.d, dd);
164   if (L_VAL_Zero (usvsl) <= 0)
165     {
166       if (mode == inters_dr_dr || mode == inters_dmd_dr
167           || mode == inters_seg_dr)
168         {
169           return inters_colinear + inters_a_st + inters_b_st;
170         }
171       else if (mode == inters_dmd_dmd || mode == inters_seg_dmd
172                || mode == inters_seg_seg)
173         {
174           if (L_VAL_Zero (dd) > 0)
175             {
176               return inters_colinear + inters_a_st + inters_b_st;
177             }
178           else
179             {
180               return inters_a_st + inters_b_st;
181             }
182         }
183       return 0;
184     }
185   if (L_VAL_Zero (uevsl) <= 0)
186     {
187       if (mode == inters_dr_dr || mode == inters_dmd_dr
188           || mode == inters_seg_dr)
189         {
190           return inters_colinear + inters_a_en + inters_b_st;
191         }
192       else if (mode == inters_dmd_dmd)
193         {
194           return inters_colinear + inters_a_en + inters_b_st;
195         }
196       else if (mode == inters_seg_dmd || mode == inters_seg_seg)
197         {
198           if (L_VAL_Zero (dd) > 0)
199             {
200               return inters_a_en + inters_b_st;
201             }
202           else
203             {
204               return inters_colinear + inters_a_en + inters_b_st;
205             }
206         }
207       return 0;
208     }
209   if (L_VAL_Zero (usvel) <= 0)
210     {
211       if (mode == inters_dr_dr || mode == inters_dmd_dr
212           || mode == inters_seg_dr)
213         {
214           return inters_colinear + inters_a_st + inters_b_en;
215         }
216       else if (mode == inters_dmd_dmd || mode == inters_seg_dmd)
217         {
218           return inters_colinear + inters_a_st + inters_b_en;
219         }
220       else if (mode == inters_seg_seg)
221         {
222           if (L_VAL_Zero (dd) > 0)
223             {
224               return inters_a_st + inters_b_en;
225             }
226           else
227             {
228               return inters_colinear + inters_a_st + inters_b_en;
229             }
230         }
231       return 0;
232     }
233   if (L_VAL_Zero (uevel) <= 0)
234     {
235       if (mode == inters_dr_dr || mode == inters_dmd_dr
236           || mode == inters_seg_dr)
237         {
238           return inters_colinear + inters_a_en + inters_b_en;
239         }
240       else if (mode == inters_dmd_dmd || mode == inters_seg_dmd)
241         {
242           return inters_colinear + inters_a_en + inters_b_en;
243         }
244       else if (mode == inters_seg_seg)
245         {
246           if (L_VAL_Zero (dd) > 0)
247             {
248               return inters_colinear + inters_a_en + inters_b_en;
249             }
250           else
251             {
252               return inters_a_en + inters_b_en;
253             }
254         }
255       return 0;
256     }
258   // plus d'extremites en commun a partir de ce point
260   mat2d m;
261   L_MAT_SetC (m, iu.d, iv.d);
262   double det;
263   L_MAT_Det (m, det);
265   if (L_VAL_Zero (det) == 0)
266     {                           // ces couillons de vecteurs sont colineaires
267       vec2d iudp;
268       iudp.x = iu.d.y;
269       iudp.y = -iu.d.x;
270       double dist;
271       L_VEC_Cross (iudp, usvs, dist);
272       if (L_VAL_Zero (dist) == 0)
273         {
274           if (mode == inters_dr_dr || mode == inters_dmd_dr
275               || mode == inters_seg_dr)
276             {
277               return inters_colinear;
278             }
279           else if (mode == inters_dmd_dmd)
280             {
281               if (L_VAL_Zero (dd) > 0)
282                 return inters_colinear;
283               double ts;
284               L_VEC_Cross (iu.d, usvs, ts);
285               if (L_VAL_Zero (ts) > 0)
286                 return inters_colinear;
287               return 0;
288             }
289           else if (mode == inters_seg_dmd)
290             {
291               if (L_VAL_Zero (dd) > 0)
292                 {
293                   double ts;
294                   L_VEC_Cross (iv.d, uevs, ts);
295                   if (L_VAL_Zero (ts) < 0)
296                     return inters_colinear;
297                   return 0;
298                 }
299               else
300                 {
301                   double ts;
302                   L_VEC_Cross (iv.d, usvs, ts);
303                   if (L_VAL_Zero (ts) < 0)
304                     return inters_colinear;
305                   return 0;
306                 }
307             }
308           else if (mode == inters_seg_seg)
309             {
310               double ts, te;
311               L_VEC_Cross (iu.d, usvs, ts);
312               L_VEC_Cross (iu.d, uevs, te);
313               if (L_VAL_Zero (ts) > 0 && L_VAL_Zero (te) < 0)
314                 return inters_colinear;
315               L_VEC_Cross (iu.d, usve, ts);
316               L_VEC_Cross (iu.d, ueve, te);
317               if (L_VAL_Zero (ts) > 0 && L_VAL_Zero (te) < 0)
318                 return inters_colinear;
319               L_VEC_Cross (iv.d, usvs, ts);
320               L_VEC_Cross (iv.d, usve, te);
321               if (L_VAL_Zero (ts) < 0 && L_VAL_Zero (te) > 0)
322                 return inters_colinear;
323               L_VEC_Cross (iv.d, uevs, ts);
324               L_VEC_Cross (iv.d, ueve, te);
325               if (L_VAL_Zero (ts) < 0 && L_VAL_Zero (te) > 0)
326                 return inters_colinear;
327               return 0;
328             }
329         }
330       else
331         {
332           return 0;             // paralleles
333         }
334     }
336   // plus de colinearite ni d'extremites en commun
337   L_MAT_Inv (m);
338   vec2d res;
339   L_MAT_MulV (m, usvs, res);
341   if (mode == inters_dr_dr)
342     {
343       return inters_a_mi + inters_b_mi;
344     }
345   else if (mode == inters_dmd_dr)
346     {
347       int i = L_VAL_Zero (res.x);
348       if (i == 0)
349         return inters_a_st + inters_b_mi;
350       if (i > 0)
351         return inters_a_mi + inters_b_mi;
352       return 0;
353     }
354   else if (mode == inters_seg_dr)
355     {
356       int i = L_VAL_Zero (res.x);
357       int j = L_VAL_Cmp (res.x, 1);
358       if (i == 0)
359         return inters_a_st + inters_b_mi;
360       if (j == 0)
361         return inters_a_en + inters_b_mi;
362       if (i > 0 && j < 0)
363         return inters_a_mi + inters_b_mi;
364       return 0;
365     }
366   else if (mode == inters_dmd_dmd)
367     {
368       int i = L_VAL_Zero (res.x);
369       int j = -(L_VAL_Zero (res.y));
370       // nota : i=0 et j=0 a ete elimine au debut
371       if (i == 0 && j > 0)
372         return inters_a_st + inters_b_mi;
373       if (j == 0 && i > 0)
374         return inters_a_mi + inters_b_st;
375       if (i > 0 && j > 0)
376         return inters_a_mi + inters_b_mi;
377       return 0;
378     }
379   else if (mode == inters_seg_dmd)
380     {
381       int i = L_VAL_Zero (res.x);
382       int j = L_VAL_Cmp (res.x, 1);
383       int k = -(L_VAL_Zero (res.y));
384       // nota : i=0 et j=0 a ete elimine au debut
385       if (i == 0 && k > 0)
386         return inters_a_st + inters_b_mi;
387       if (j == 0 && k > 0)
388         return inters_a_en + inters_b_mi;
389       if (i > 0 && j < 0 && k == 0)
390         return inters_a_mi + inters_b_st;
391       if (i > 0 && j < 0 && k > 0)
392         return inters_a_mi + inters_b_mi;
393       return 0;
394     }
395   else if (mode == inters_seg_seg)
396     {
397       int i = L_VAL_Zero (res.x);
398       int j = L_VAL_Cmp (res.x, 1);
399       int k = -(L_VAL_Zero (res.y));
400       int l = -(L_VAL_Cmp (res.y, 1));
401       // nota : i=0 et j=0 a ete elimine au debut
402       if (i == 0 && k > 0 && l < 0)
403         return inters_a_st + inters_b_mi;
404       if (j == 0 && k > 0 && l < 0)
405         return inters_a_en + inters_b_mi;
406       if (k == 0 && i > 0 && j < 0)
407         return inters_a_mi + inters_b_st;
408       if (l == 0 && i > 0 && j < 0)
409         return inters_a_mi + inters_b_en;
410       if (k > 0 && l < 0 && i > 0 && j < 0)
411         return inters_a_mi + inters_b_mi;
412       return 0;
413     }
415   return 0;
418 int
419 L_SEG::Intersect (L_SEG & iu, L_SEG & iv, vec2d & at, int mode)
421   double iudd, ivdd;
422   L_VEC_Cross (iu.d, iu.d, iudd);
423   L_VEC_Cross (iv.d, iv.d, ivdd);
424   if (L_VAL_Zero (iudd) <= 0)
425     return 0;                   // cas illicite
426   if (L_VAL_Zero (ivdd) <= 0)
427     return 0;                   // cas illicite
429   vec2d usvs, uevs, usve, ueve;
430   L_VEC_Sub (iv.p, iu.p, usvs);
431   L_VEC_Sub (usvs, iu.d, uevs);
432   L_VEC_Add (usvs, iv.d, usve);
433   L_VEC_Sub (usve, iu.d, ueve);
434   double usvsl, uevsl, usvel, uevel;
435   L_VEC_Cross (usvs, usvs, usvsl);
436   L_VEC_Cross (uevs, uevs, uevsl);
437   L_VEC_Cross (usve, usve, usvel);
438   L_VEC_Cross (ueve, ueve, uevel);
440   double dd;
441   L_VEC_Cross (iu.d, iv.d, dd);
443   if (L_VAL_Zero (usvsl) <= 0)
444     {
445       at = iu.p;
446       if (mode == inters_dr_dr || mode == inters_dmd_dr
447           || mode == inters_seg_dr)
448         {
449           return inters_colinear + inters_a_st + inters_b_st;
450         }
451       else if (mode == inters_dmd_dmd || mode == inters_seg_dmd
452                || mode == inters_seg_seg)
453         {
454           if (L_VAL_Zero (dd) > 0)
455             {
456               return inters_colinear + inters_a_st + inters_b_st;
457             }
458           else
459             {
460               return inters_a_st + inters_b_st;
461             }
462         }
463       return 0;
464     }
465   if (L_VAL_Zero (uevsl) <= 0)
466     {
467       at = iv.p;
468       if (mode == inters_dr_dr || mode == inters_dmd_dr
469           || mode == inters_seg_dr)
470         {
471           return inters_colinear + inters_a_en + inters_b_st;
472         }
473       else if (mode == inters_dmd_dmd)
474         {
475           return inters_colinear + inters_a_en + inters_b_st;
476         }
477       else if (mode == inters_seg_dmd || mode == inters_seg_seg)
478         {
479           if (L_VAL_Zero (dd) > 0)
480             {
481               return inters_a_en + inters_b_st;
482             }
483           else
484             {
485               return inters_colinear + inters_a_en + inters_b_st;
486             }
487         }
488       return 0;
489     }
490   if (L_VAL_Zero (usvel) <= 0)
491     {
492       at = iu.p;
493       if (mode == inters_dr_dr || mode == inters_dmd_dr
494           || mode == inters_seg_dr)
495         {
496           return inters_colinear + inters_a_st + inters_b_en;
497         }
498       else if (mode == inters_dmd_dmd || mode == inters_seg_dmd)
499         {
500           return inters_colinear + inters_a_st + inters_b_en;
501         }
502       else if (mode == inters_seg_seg)
503         {
504           if (L_VAL_Zero (dd) > 0)
505             {
506               return inters_a_st + inters_b_en;
507             }
508           else
509             {
510               return inters_colinear + inters_a_st + inters_b_en;
511             }
512         }
513       return 0;
514     }
515   if (L_VAL_Zero (uevel) <= 0)
516     {
517       at = iu.p;
518       L_VEC_Add (at, iu.d, at);
519       if (mode == inters_dr_dr || mode == inters_dmd_dr
520           || mode == inters_seg_dr)
521         {
522           return inters_colinear + inters_a_en + inters_b_en;
523         }
524       else if (mode == inters_dmd_dmd || mode == inters_seg_dmd)
525         {
526           return inters_colinear + inters_a_en + inters_b_en;
527         }
528       else if (mode == inters_seg_seg)
529         {
530           if (L_VAL_Zero (dd) > 0)
531             {
532               return inters_colinear + inters_a_en + inters_b_en;
533             }
534           else
535             {
536               return inters_a_en + inters_b_en;
537             }
538         }
539       return 0;
540     }
542   // plus d'extremites en commun a partir de ce point
544   mat2d m;
545   L_MAT_SetC (m, iu.d, iv.d);
546   double det;
547   L_MAT_Det (m, det);
549   if (L_VAL_Zero (det) == 0)
550     {                           // ces couillons de vecteurs sont colineaires
551       vec2d iudp;
552       iudp.x = iu.d.y;
553       iudp.y = -iu.d.x;
554       double dist;
555       L_VEC_Cross (iudp, usvs, dist);
556       if (L_VAL_Zero (dist) == 0)
557         {
558           if (mode == inters_dr_dr || mode == inters_dmd_dr
559               || mode == inters_seg_dr)
560             {
561               return inters_colinear;
562             }
563           else if (mode == inters_dmd_dmd)
564             {
565               if (L_VAL_Zero (dd) > 0)
566                 return inters_colinear;
567               double ts;
568               L_VEC_Cross (iu.d, usvs, ts);
569               if (L_VAL_Zero (ts) > 0)
570                 return inters_colinear;
571               return 0;
572             }
573           else if (mode == inters_seg_dmd)
574             {
575               if (L_VAL_Zero (dd) > 0)
576                 {
577                   double ts;
578                   L_VEC_Cross (iv.d, uevs, ts);
579                   if (L_VAL_Zero (ts) < 0)
580                     return inters_colinear;
581                   return 0;
582                 }
583               else
584                 {
585                   double ts;
586                   L_VEC_Cross (iv.d, usvs, ts);
587                   if (L_VAL_Zero (ts) < 0)
588                     return inters_colinear;
589                   return 0;
590                 }
591             }
592           else if (mode == inters_seg_seg)
593             {
594               double ts, te;
595               L_VEC_Cross (iu.d, usvs, ts);
596               L_VEC_Cross (iu.d, uevs, te);
597               if (L_VAL_Zero (ts) > 0 && L_VAL_Zero (te) < 0)
598                 return inters_colinear;
599               L_VEC_Cross (iu.d, usve, ts);
600               L_VEC_Cross (iu.d, ueve, te);
601               if (L_VAL_Zero (ts) > 0 && L_VAL_Zero (te) < 0)
602                 return inters_colinear;
603               L_VEC_Cross (iv.d, usvs, ts);
604               L_VEC_Cross (iv.d, usve, te);
605               if (L_VAL_Zero (ts) < 0 && L_VAL_Zero (te) > 0)
606                 return inters_colinear;
607               L_VEC_Cross (iv.d, uevs, ts);
608               L_VEC_Cross (iv.d, ueve, te);
609               if (L_VAL_Zero (ts) < 0 && L_VAL_Zero (te) > 0)
610                 return inters_colinear;
611               return 0;
612             }
613         }
614       else
615         {
616           return 0;             // paralleles
617         }
618     }
620   // plus de colinearite ni d'extremites en commun
621   L_MAT_Inv (m);
622   vec2d res;
623   L_MAT_MulV (m, usvs, res);
625   // l'intersection
626   L_VEC_MulC (iu.d, res.x, at);
627   L_VEC_Add (at, iu.p, at);
629   if (mode == inters_dr_dr)
630     {
631       return inters_a_mi + inters_b_mi;
632     }
633   else if (mode == inters_dmd_dr)
634     {
635       int i = L_VAL_Zero (res.x);
636       if (i == 0)
637         return inters_a_st + inters_b_mi;
638       if (i > 0)
639         return inters_a_mi + inters_b_mi;
640       return 0;
641     }
642   else if (mode == inters_seg_dr)
643     {
644       int i = L_VAL_Zero (res.x);
645       int j = L_VAL_Cmp (res.x, 1);
646       if (i == 0)
647         return inters_a_st + inters_b_mi;
648       if (j == 0)
649         return inters_a_en + inters_b_mi;
650       if (i > 0 && j < 0)
651         return inters_a_mi + inters_b_mi;
652       return 0;
653     }
654   else if (mode == inters_dmd_dmd)
655     {
656       int i = L_VAL_Zero (res.x);
657       int j = -(L_VAL_Zero (res.y));
658       // nota : i=0 et j=0 a ete elimine au debut
659       if (i == 0 && j > 0)
660         return inters_a_st + inters_b_mi;
661       if (j == 0 && i > 0)
662         return inters_a_mi + inters_b_st;
663       if (i > 0 && j > 0)
664         return inters_a_mi + inters_b_mi;
665       return 0;
666     }
667   else if (mode == inters_seg_dmd)
668     {
669       int i = L_VAL_Zero (res.x);
670       int j = L_VAL_Cmp (res.x, 1);
671       int k = -(L_VAL_Zero (res.y));
672       // nota : i=0 et j=0 a ete elimine au debut
673       if (i == 0 && k > 0)
674         return inters_a_st + inters_b_mi;
675       if (j == 0 && k > 0)
676         return inters_a_en + inters_b_mi;
677       if (i > 0 && j < 0 && k == 0)
678         return inters_a_mi + inters_b_st;
679       if (i > 0 && j < 0 && k > 0)
680         return inters_a_mi + inters_b_mi;
681       return 0;
682     }
683   else if (mode == inters_seg_seg)
684     {
685       int i = L_VAL_Zero (res.x);
686       int j = L_VAL_Cmp (res.x, 1);
687       int k = -(L_VAL_Zero (res.y));    // la coordonnée sur iv est inversee
688       int l = -(L_VAL_Cmp (res.y, -1));
689       // nota : i=0 et j=0 a ete elimine au debut
690       if (i == 0 && k > 0 && l < 0)
691         return inters_a_st + inters_b_mi;
692       if (j == 0 && k > 0 && l < 0)
693         return inters_a_en + inters_b_mi;
694       if (k == 0 && i > 0 && j < 0)
695         return inters_a_mi + inters_b_st;
696       if (l == 0 && i > 0 && j < 0)
697         return inters_a_mi + inters_b_en;
698       if (k > 0 && l < 0 && i > 0 && j < 0)
699         return inters_a_mi + inters_b_mi;
700       return 0;
701     }
703   return 0;
706 int
707 L_SEG::IntersectGeneral (L_SEG & iu, L_SEG & iv, vec2d & at, int mode)
710   vec2d usvs;
711   L_VEC_Sub (iv.p, iu.p, usvs);
713   double dd;
714   L_VEC_Cross (iu.d, iv.d, dd);
717   mat2d m;
718   L_MAT_SetC (m, iu.d, iv.d);
719   double det;
720   L_MAT_Det (m, det);
722   if (L_VAL_Zero (det))
723     {                           // ces couillons de vecteurs sont colineaires
724       return 0;                 // paralleles
725     }
727   // plus de colinearite ni d'extremites en commun
728   L_MAT_Inv (m);
729   vec2d res;
730   L_MAT_MulV (m, usvs, res);
732   // l'intersection
733   L_VEC_MulC (iu.d, res.x, at);
734   L_VEC_Add (at, iu.p, at);
736   if (mode == inters_dr_dr)
737     {
738       return inters_a_mi + inters_b_mi;
739     }
740   else if (mode == inters_dmd_dr)
741     {
742       int i = L_VAL_Zero (res.x);
743       if (i == 0)
744         return inters_a_st + inters_b_mi;
745       if (i > 0)
746         return inters_a_mi + inters_b_mi;
747       return 0;
748     }
749   else if (mode == inters_seg_dr)
750     {
751       int i = L_VAL_Zero (res.x);
752       int j = L_VAL_Cmp (res.x, 1);
753       if (i == 0)
754         return inters_a_st + inters_b_mi;
755       if (j == 0)
756         return inters_a_en + inters_b_mi;
757       if (i > 0 && j < 0)
758         return inters_a_mi + inters_b_mi;
759       return 0;
760     }
761   else if (mode == inters_dmd_dmd)
762     {
763       int i = L_VAL_Zero (res.x);
764       int j = -(L_VAL_Zero (res.y));
765       // nota : i=0 et j=0 a ete elimine au debut
766       if (i == 0 && j > 0)
767         return inters_a_st + inters_b_mi;
768       if (j == 0 && i > 0)
769         return inters_a_mi + inters_b_st;
770       if (i > 0 && j > 0)
771         return inters_a_mi + inters_b_mi;
772       return 0;
773     }
774   else if (mode == inters_seg_dmd)
775     {
776       int i = L_VAL_Zero (res.x);
777       int j = L_VAL_Cmp (res.x, 1);
778       int k = -(L_VAL_Zero (res.y));
779       // nota : i=0 et j=0 a ete elimine au debut
780       if (i == 0 && k > 0)
781         return inters_a_st + inters_b_mi;
782       if (j == 0 && k > 0)
783         return inters_a_en + inters_b_mi;
784       if (i > 0 && j < 0 && k == 0)
785         return inters_a_mi + inters_b_st;
786       if (i > 0 && j < 0 && k > 0)
787         return inters_a_mi + inters_b_mi;
788       return 0;
789     }
790   else if (mode == inters_seg_seg)
791     {
792       int i = L_VAL_Zero (res.x);
793       int j = L_VAL_Cmp (res.x, 1);
794       int k = -(L_VAL_Zero (res.y));    // la coordonnée sur iv est inversee
795       int l = -(L_VAL_Cmp (res.y, -1));
796       // nota : i=0 et j=0 a ete elimine au debut
797       if (i == 0 && k > 0 && l < 0)
798         return inters_a_st + inters_b_mi;
799       if (j == 0 && k > 0 && l < 0)
800         return inters_a_en + inters_b_mi;
801       if (k == 0 && i > 0 && j < 0)
802         return inters_a_mi + inters_b_st;
803       if (l == 0 && i > 0 && j < 0)
804         return inters_a_mi + inters_b_en;
805       if (k > 0 && l < 0 && i > 0 && j < 0)
806         return inters_a_mi + inters_b_mi;
807       return 0;
808     }
810   return 0;
813 int
814 L_SEG::Contains (vec2d & pos, int mode)
816   vec2d sp, ep;
817   L_VEC_Sub (pos, p, sp);
818   L_VEC_Sub (sp, d, ep);
819   double spl, epl;
820   L_VEC_Cross (sp, sp, spl);
821   L_VEC_Cross (ep, ep, epl);
822   if (L_VAL_Zero (spl) == 0)
823     {
824       if (mode == inters_dr_pt)
825         return inters_a_mi;
826       return inters_a_st;
827     }
828   if (L_VAL_Zero (epl) == 0)
829     {
830       if (mode == inters_dr_pt || mode == inters_dmd_pt)
831         return inters_a_mi;
832       return inters_a_en;
833     }
835   vec2d perp = d;
836   L_VEC_RotCW (perp);
838   double dd, ps;
839   L_VEC_Cross (d, d, dd);
840   L_VEC_Cross (perp, sp, ps);
841   if (L_VAL_Zero (ps) == 0)
842     {                           // sur la droite
843       if (mode == inters_dr_pt)
844         return inters_a_mi;
845       L_VEC_Cross (d, sp, ps);
846       // ps != 0 car le cas est traité avant
847       if (mode == inters_dmd_pt)
848         {
849           if (L_VAL_Zero (ps) > 0)
850             {
851               return inters_a_mi;
852             }
853         }
854       else
855         {
856           if (L_VAL_Zero (ps) > 0)
857             {
858               if (L_VAL_Cmp (ps, dd) < 0)
859                 {
860                   return inters_a_mi;
861                 }
862             }
863         }
864     }
866   return 0;