segment.h
Upload User: gzelex
Upload Date: 2007-01-07
Package Size: 707k
Code Size: 8k
Development Platform:

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  segment.h
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. #ifndef LEDA_SEGMENT_H
  12. #define LEDA_SEGMENT_H
  13. #include <LEDA/point.h>
  14. //------------------------------------------------------------------------------
  15. // segments
  16. //------------------------------------------------------------------------------
  17. class segment_rep : public handle_rep {
  18. friend class segment;
  19. friend class line;
  20. friend class circle;
  21. static unsigned long id_counter;
  22.    
  23.    point start;
  24.    point end;
  25.    double dx;
  26.    double dy;
  27.    double slope;
  28.    double y_abs;
  29.    double angle;
  30.    unsigned long id;
  31. public:
  32.    
  33.    segment_rep(const point&, const point&);
  34.    segment_rep();  
  35.   ~segment_rep() {}
  36. };
  37. /*{Manpage {segment} {} {Segments}}*/
  38. class segment  : public handle_base 
  39. {
  40. /*{Mdefinition
  41.     An instance $s$ of the data type $segment$ is a directed straight line
  42.     segment in the two-dimensional plane, i.e., a straight line segment $[p,q]$
  43.     connecting two points $p,q in real^2$. $p$ is called the start point
  44.     and $q$ is called the end point of $s$. The length of $s$ is the Euclidean
  45.     distance between $p$ and $q$. The angle between a right oriented horizontal
  46.     ray and $s$ is called the direction of $s$. The segment $[(0,0),(0,0)]$
  47.     is said to be empty.}*/
  48. friend class line;
  49. friend class circle;
  50. segment_rep* ptr() const { return (segment_rep*)PTR; }
  51. public:
  52. /*{Mcreation s }*/
  53. segment(const point& p, const point& q); 
  54. /*{Mcreate introduces a variable var of type name. var is initialized 
  55.             to the segment $(p,q)$ }*/
  56. segment(const point& p, const vector& v); 
  57. /*{Mcreate introduces a variable var of type name. var is initialized 
  58.             to the segment $(p,p+v)$. precond $v.dim() = 2$. }*/
  59. segment(double x1, double y1, double x2, double y2) ;
  60. /*{Mcreate introduces a variable var of type name. var is initialized 
  61.             to the segment $[(x_1,y_1),(x_2,y_2)]$.}*/ 
  62. segment(const point& p, double dir, double length);
  63. /*{Mcreate introduces a variable var of type name. var is initialized 
  64.             to the segment with start point $p$, direction $dir$, and
  65.             length $length$.}*/
  66. segment();                 
  67. /*{Mcreate introduces a variable var of type name. var is initialized 
  68.             to the empty segment.}*/
  69.  segment(const segment& s) : handle_base(s) {}     
  70. ~segment() {}
  71.  segment& operator=(const segment& s) 
  72.  { handle_base::operator=(s); return *this;}
  73. /*{Moperations 2 3.5}*/
  74. operator vector()  { return vector(xcoord2()-xcoord1(), ycoord2()-ycoord1()); }
  75. point start()  const      { return ptr()->start; }
  76. point source() const      { return ptr()->start; }
  77. /*{Mop       returns the source point of segment var.}*/
  78. point end()    const      { return ptr()->end; }
  79. point target() const      { return ptr()->end; }
  80. /*{Mop       returns the target point of segment var.}*/
  81. double xcoord1() const    { return ptr()->start.ptr()->x; }
  82. /*{Mop       returns the x-coordinate of var.start().}*/
  83. double xcoord2() const    { return ptr()->end.ptr()->x;   }
  84. /*{Mop       returns the x-coordinate of var.end().}*/
  85. double ycoord1() const    { return ptr()->start.ptr()->y; }
  86. /*{Mop       returns the y-coordinate of var.start().}*/
  87. double ycoord2() const    { return ptr()->end.ptr()->y;   }
  88. /*{Mop       returns the y-coordinate of var.end().}*/
  89. double dx() const    { return ptr()->dx;   }
  90. /*{Mop       returns the $xcoord2 - xcoord1$.}*/
  91. double dy() const    { return ptr()->dy;   }
  92. /*{Mop       returns the $ycoord2 - ycoord1$.}*/
  93. double length() const { return start().distance(end()); }
  94. /*{Mop       returns the length of var.}*/
  95. double direction() const { return angle(); }
  96. /*{Mop       returns the direction of var as an angle in 
  97.       the intervall $(-pi,pi]$.}*/
  98. double angle()     const { return ptr()->angle; }
  99. /*{Mop       returns var.direction().}*/
  100. double  angle(const segment& t) const;
  101. /*{Mop       returns the angle between var and $t$, i.e., 
  102.               $t$.direction() - var.direction().}*/
  103. bool vertical()   const { return xcoord1() == xcoord2(); }
  104. /*{Mop       returns true iff var is vertical.}*/
  105. bool horizontal() const { return ycoord1() == ycoord2(); }
  106. /*{Mop       returns true iff var is horizontal.}*/
  107. double slope() const { return ptr()->slope; }
  108. /*{Mop       returns the slope of $s$.\
  109.       precond  var  is not vertical.}*/
  110. double y_abs() const { return ptr()->y_abs; }
  111. bool intersection(const segment& t, point& p) const;
  112. /*{Mopl    if var and $t$ are not collinear and intersect the 
  113.     intersection point is assigned to $p$ and true is 
  114.     returned, otherwise false is returned.}*/
  115. bool intersection_of_lines(const segment& t, point& p) const;
  116. /*{Mopl    if var and $t$ are not collinear and the underlying
  117.     lines intersect the point of intersection is assigned 
  118.             to $p$ and true is returned, otherwise false is returned.}*/
  119. segment translate(double a, double d) const;
  120. /*{Mopl    returns the segment created by a translation of
  121.     $s$ in direction $a$ by distance $d$.}*/
  122. segment translate(const vector& v) const;
  123. /*{Mop     returns $s+v$, i.e., the segment created by 
  124.     translating $s$ by vector $v$.\
  125.     precond $v$.dim() = 2.}*/ 
  126. double  distance(const segment&) const;
  127. double  distance(const point&) const;
  128. double  distance() const;
  129. double  x_proj(double) const;
  130. double  y_proj(double) const;
  131. double operator()(double x) { return y_proj(x); }
  132. segment rotate(const point& q, double a) const;
  133. /*{Mopl    returns the segment created by a rotation of $s$ 
  134.     about point $q$ by angle $a$.}*/
  135. segment rotate(double a) const;
  136. /*{Mop     returns $s$.rotate($s$.start(), $a$).}*/
  137. segment rotate90(const point& q) const;
  138. /*{Mopl    returns the segment created by a rotation of $s$ 
  139.     about point $q$ by an angle of 90 degrees.}*/
  140. segment rotate90() const;
  141. /*{Mop     returns $s$.rotate90($s$.start(), $a$).}*/
  142. bool  right()  const     { return ptr()->start.ptr()->x < ptr()->end.ptr()->x; }
  143. bool  left()   const     { return ptr()->start.ptr()->x > ptr()->end.ptr()->x; }
  144. bool  up()     const     { return ptr()->start.ptr()->y < ptr()->end.ptr()->y; }
  145. bool  down()   const     { return ptr()->start.ptr()->y > ptr()->end.ptr()->y; }
  146. int operator==(const segment& t) const
  147. { return (ptr()->start == t.ptr()->start && ptr()->end == t.ptr()->end); }
  148. /*{Mbinop       Test for equality.}*/
  149. int operator!=(const segment& t) const { return !operator==(t);}
  150. /*{Mbinop       Test for inequality.}*/
  151. segment operator+(const vector& v) const { return translate(v); }
  152. /*{Mbinop       Translation by vector $v$.}*/
  153. friend ostream& operator<<(ostream& O, const segment& s);
  154. /*{Mbinopfunc     writes var to output stream $O$.}*/
  155. friend istream& operator>>(istream& I, segment& s);
  156. /*{Mbinopfunc     reads the coordinates of var (four $double$ numbers)
  157.            from input stream $I$.}*/
  158. friend inline bool identical(const segment& s1, const segment& s2);
  159. };
  160. inline void Print(const segment& s, ostream& out) { out << s; } 
  161. inline void Read(segment& s,  istream& in)        { in >> s; }
  162. /*{Mtext
  163. {bf Non-Member Functions}
  164. smallskip
  165. }*/
  166. inline bool identical(const segment& s1, const segment& s2)
  167. { return s1.ptr() == s2.ptr(); }
  168. /*{Mfuncl Test for identity.}*/
  169. inline int orientation(const segment& s, const point& p)
  170. /*{Mfuncl      computes orientation($a$, $b$, $p$), where $a not= b$
  171. and $a$ and $b$ appear in this order on segment $s$. }*/
  172. { return compare(s.dy()*(s.xcoord1()-p.xcoord()), 
  173.                  s.dx()*(s.ycoord1()-p.ycoord())); 
  174.  }
  175. inline int cmp_slopes(const segment& s1, const segment& s2)
  176. /*{Mfuncl      returns compare(slope($s_1$), slope($s_2$)).}*/
  177. { return compare(s1.slope(), s2.slope()); }
  178. inline bool parallel(const segment& s1, const segment& s2)
  179. /*{Mfuncl      returns (cmp_slopes($s_1$, $s_2$) == 0).}*/
  180. { return cmp_slopes(s1,s2) == 0; }
  181. #endif