summaryrefslogtreecommitdiffstats
path: root/src/livarot/MySeg.h
blob: 8183b7d46f34af4b1f8822c4580b99c8bdf89299 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
 *  MySeg.h
 *  nlivarot
 *
 *  Created by fred on Wed Nov 12 2003.
 *
 */

#ifndef my_math_seg
#define my_math_seg

#include "MyMath.h"

// codes for the intersections computations
//  pt = point
//  seg = segment
//  dmd = half line
//  dr = infinite line
enum
{
  inters_seg_seg,		// intersection between 2 segments
  inters_seg_dmd,		// intersection between one segment (parameter no 1) and one half-line (parameter no 2)
  inters_seg_dr,		// ....
  inters_dmd_dmd,
  inters_dmd_dr,
  inters_dr_dr,

  inters_seg_pt,		// "intersection" between segment and point=  "does the segment contain the point?"
  inters_dmd_pt,
  inters_dr_pt,

  inters_orseg_pt		// don't use
};

// return codes for the intersection computations; build as a concatenation of
// _a = first parameter
// _b = second parameter
// _st = start of the segment/half-line (lines don't have starts)
// _en = end of thz segment (half-lines and lines don't have ends)
// _mi = inside of the segment/half-line/line
// _colinear = this flag is set if the intersection of the 2 parameter is more than a point
// the first 2 bits of the return code contain the position of the intersection on the first parameter (_st, _mi or _en)
// the next 2 bits of the return code contain the position of the intersection on the second parameter (_st, _mi or _en)
// the 5th bit is set if the parameters are colinear
enum
{
  inters_a_st = 1,
  inters_a_mi = 2,
  inters_a_en = 3,
  inters_b_st = 4,
  inters_b_mi = 8,
  inters_b_en = 12,
  inters_colinear = 16
};


//
// a class to describe a segment: defined by its startpoint p and its direction d
// if the object is considered as a segment: p+xd, where x ranges from 0 to 1
// if the object is considered as an half-line, the length of the direction vector doesn't matter:
// p+xd, where x ranges from 0 to +infinity
// if the object is considered as a line: p+xd, where x ranges from -infinity to +infinity
//
class L_SEG
{
public:
  vec2d p, d;

  // constructors
  L_SEG (vec2d & st, vec2d & dir):p (st), d (dir)
  {
  };				// by default, you give one startpoint and one direction
  L_SEG (void)
  {
  };
  ~L_SEG (void)
  {
  };

  // assignations
  void Set (L_SEG * s)
  {
    p = s->p;
    d = s->d;
  };
  void Set (L_SEG & s)
  {
    p = s.p;
    d = s.d;
  };
  // 2 specific assignations:
  // assignation where you give the startpoint and the direction (like in the constructor):
  void SetSD (vec2d & st, vec2d & dir)
  {
    p = st;
    d = dir;
  };
  // assignation where you give the startpoint and the endpoint:
  void SetSE (vec2d & st, vec2d & en)
  {
    p = st;
    d.x = en.x - st.x;
    d.y = en.y - st.y;
  };

  // reverses the segment
  void Rev (void)
  {
    p.x += d.x;
    p.y += d.y;
    d.x = -d.x;
    d.y = -d.y;
  };
  // transitibve version: the reversed segment is stored in s
  void Rev (L_SEG & s)
  {
    s.p.x = p.x + d.x;
    s.p.y = p.y + d.y;
    s.d.x = -d.x;
    s.d.y = -d.y;
  };

  // distance of the point iv to the segment/half-line/line
  // the mode parameter specifies how the caller instance should be handled:
  // inters_seg_pt : segment
  // inters_dmd_pt : half-line
  // inters_dr_pt : line
  void Distance (vec2d & iv, double &d, int mode = inters_dr_pt);
  // distance between 2 segments
  // mode parameter specifies how the segments have to be treated (just like above)
  void Distance (L_SEG & is, double &d, int mode = inters_seg_seg);

  // tests if the segment contains the point pos
  // mode is as in the Distance function
  int Contains (vec2d & pos, int mode);

  // intersection between 2 lines/half-lines/segments
  // mode specifies how the L_SEG instances have to be considered; codes at the beginning of this file
  // the "at" parameter stores the intersection point, if it exists and is unique
  static int Intersect (L_SEG & iu, L_SEG & iv, int mode);
  static int Intersect (L_SEG & iu, L_SEG & iv, vec2d & at, int mode);
  // specific version, when you can garantuee the colinearity case won't occur
  static int IntersectGeneral (L_SEG & iu, L_SEG & iv, vec2d & at, int mode);
};


#endif