EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHBBox.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHBBox.h
1 // Tell emacs that this is a C++ source
2 // -*- C++ -*-.
3 #ifndef G4MAIN_PHBBOX_H
4 #define G4MAIN_PHBBOX_H
5 
6 #include <iostream>
7 #include <iomanip>
8 #include <bitset>
9 
10 // Clip a line using the Cohen-Southerland algorithm
11 
12 class PHBBox
13 {
14 public:
15 
17  PHBBox(const double x0, const double y0, const double x1, const double y1) :
18  _x0(x0), _y0(y0), _x1(x1), _y1(y1)
19  {}
20 
23  bool ClipLine(double& x0, double& y0, double& x1, double& y1) const
24  {
25  int clipCode0 = ClipCode(x0,y0); // clipping code for end point 0
26  int clipCode1 = ClipCode(x1,y1); // clipping code for end point 1
27 
28  while ( clipCode0 || clipCode1 )
29  {
30  //std::cout << "clipCode0 = " << std::bitset<4>(clipCode0).to_string() << std::endl;
31  //std::cout << "clipCode1 = " << std::bitset<4>(clipCode1).to_string() << std::endl;
32 
33  if ( clipCode0 & clipCode1 ) return false;
34 
35  int code = 0;
36  if ( clipCode0 > 0 ) code = clipCode0; // clip the first point
37  else code = clipCode1; // clip the last point
38 
39  double x = 0, y = 0;
40 
41  if ( (code & BOTTOM) == BOTTOM )
42  {
43  // Clip the line to the bottom of the box
44  //std::cout << "Clip the line to the bottom of the box" << std::endl;
45  y = _y0;
46  x = x0 + (x1-x0)*(y-y0)/(y1-y0);
47  }
48  else if ( (code & TOP) == TOP )
49  {
50  // Clip the line to the top of the box
51  //std::cout << "Clip the line to the top of the box" << std::endl;
52  y = _y1;
53  x = x0 + (x1-x0)*(y-y0)/(y1-y0);
54  }
55  else if ( (code & LEFT) == LEFT )
56  {
57  //std::cout << "Clip the line to the left of the box" << std::endl;
58  x = _x0;
59  y = y0 + (y1-y0)*(x-x0)/(x1-x0);
60  }
61  else if ( (code & RIGHT) == RIGHT )
62  {
63  //std::cout << "Clip the line to the right of the box" << std::endl;
64  x = _x1;
65  y = y0 + (y1-y0)*(x-x0)/(x1-x0);
66  }
67 
68  //std::cout << "x = " << x << ", y = " << y << std::endl;
69 
70  if ( code == clipCode0 )
71  {
72  // modify the first coord
73  //std::cout << "modify the first coord" << std::endl;
74  x0 = x;
75  y0 = y;
76  clipCode0 = ClipCode(x0,y0);
77  }
78  else
79  {
80  // modify the second coord
81  //std::cout << "modify the second coord" << std::endl;
82  x1 = x;
83  y1 = y;
84  clipCode1 = ClipCode(x1,y1);
85  }
86  }
87 
88  return true;
89  }
90 
91  void Print(std::ostream& os = std::cout)
92  {
93  os << _x0 << " " << _y0 << ", " << _x1 << " " << _y1 << std::endl;
94  }
95 
96 private:
97  enum { RIGHT=1, BOTTOM=2, LEFT=4, TOP=8 };
98 
99  int ClipCode(const double x, const double y) const
100  {
101  int code = 0;
102  if ( x > _x1 ) code |= RIGHT;
103  else if ( x < _x0 ) code |= LEFT;
104  if ( y > _y1 ) code |= TOP;
105  else if ( y < _y0 ) code |= BOTTOM;
106  return code;
107  }
108 
109  double _x0;
110  double _y0;
111  double _x1;
112  double _y1;
113 };
114 
115 #endif // __PHBBOX_H__