home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / diverses / leda / src / plane / _segment.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-15  |  4.6 KB  |  207 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  2.1.1                                                 11-15-1991
  4. +
  5. +
  6. +  _segment.c
  7. +
  8. +
  9. +  Copyright (c) 1991  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15.  
  16. #include <LEDA/plane.h>
  17. #include <math.h>
  18. #include <ctype.h>
  19.  
  20. static const double eps = 1e-10;
  21.  
  22.  
  23. //------------------------------------------------------------------------------
  24. // segments 
  25. //------------------------------------------------------------------------------
  26.  
  27. segment_rep::segment_rep()  { count = 1; }
  28.  
  29. segment_rep::segment_rep(point p, point q) 
  30. { start = p;
  31.   end   = q;
  32.   count = 1; 
  33. }
  34.  
  35. segment::segment()                 { ptr = new segment_rep; }
  36. segment::segment(int)              { ptr = new segment_rep; }
  37. segment::segment(ent x)            { ptr = (segment_rep*)x; ptr->count++; }
  38. segment::segment(point x, point y) { ptr = new segment_rep(x,y); }
  39. segment::segment(double x1, double y1, double x2, double y2) 
  40.                           { ptr = new segment_rep(point(x1,y1), point(x2,y2)); }
  41.  
  42. segment::segment(point p, double alpha, double length)
  43. { point q = p.translate(alpha,length);
  44.   ptr  = new segment_rep(p,q); 
  45.  }
  46.   
  47. segment::segment(segment& s)       { ptr = s.ptr; ptr->count++; }
  48. void segment::clear()              { if (--(ptr->count)==0) delete ptr; }
  49.  
  50.  
  51. segment segment::translate(double alpha, double d)
  52. { point p = ptr->start.translate(alpha,d);
  53.   point q = ptr->end.translate(alpha,d);
  54.   return segment(p,q);
  55.  }
  56.  
  57. segment segment::translate(const vector& v)
  58. { point p = ptr->start.translate(v);
  59.   point q = ptr->end.translate(v);
  60.   return segment(p,q);
  61.  }
  62.  
  63.  
  64. segment& segment::operator=(const segment& s)
  65. { s.ptr->count++;
  66.   if (--ptr->count == 0)  delete ptr;
  67.   ptr = s.ptr;
  68.   return *this;
  69. }
  70.  
  71.  
  72. ostream& operator<<(ostream& out, const segment& s) 
  73. { out << "[" << s.start() << "===" << s.end() << "]"; 
  74.   return out;
  75.  } 
  76.  
  77. /*
  78. istream& operator>>(istream& in, segment& s) 
  79. { double x1,x2,y1,y2; 
  80.   in >> x1 >> y1 >> x2 >> y2; 
  81.   s = segment(x1,y1,x2,y2); 
  82.   return in; 
  83.  } 
  84. */
  85.  
  86. istream& operator>>(istream& in, segment& s) 
  87. { // syntax: {[} p {===} q {]}
  88.  
  89.   point p,q; 
  90.   char c;
  91.  
  92.   do in.get(c); while (isspace(c));
  93.   if (c != '[') in.putback(c);
  94.  
  95.   in >> p;
  96.  
  97.   do in.get(c); while (isspace(c));
  98.   while (c== '=') in.get(c);
  99.   while (isspace(c)) in.get(c);
  100.   in.putback(c);
  101.  
  102.   in >> q; 
  103.  
  104.   do in.get(c); while (c == ' ');
  105.   if (c != ']') in.putback(c);
  106.  
  107.   s = segment(p,q); 
  108.   return in; 
  109.  
  110.  } 
  111.  
  112.  
  113.  
  114. bool  segment::vertical()            
  115. { return ptr->start.ptr->x == ptr->end.ptr->x; }
  116.  
  117. bool  segment::horizontal()            
  118. { return ptr->start.ptr->y == ptr->end.ptr->y; }
  119.  
  120. double  segment::length()            
  121. { return ptr->start.distance(ptr->end); }
  122.  
  123. double segment::angle()
  124. {  return -angle(segment(0,0,1,0)); }
  125.  
  126.  
  127. double segment::angle(segment s)
  128. {
  129.   double cosfi,fi,norm;
  130.   
  131.   double dx  = ptr->end.ptr->x - ptr->start.ptr->x; 
  132.   double dy  = ptr->end.ptr->y - ptr->start.ptr->y; 
  133.  
  134.   double dxs = s.ptr->end.ptr->x - s.ptr->start.ptr->x; 
  135.   double dys = s.ptr->end.ptr->y - s.ptr->start.ptr->y; 
  136.   
  137.   cosfi=dx*dxs+dy*dys;
  138.   
  139.   norm=(dx*dx+dy*dy)*(dxs*dxs+dys*dys);
  140.  
  141.   cosfi /= sqrt( norm );
  142.  
  143.   if (cosfi >=  1.0 ) return 0;
  144.   if (cosfi <= -1.0 ) return M_PI;
  145.   
  146.   fi=acos(cosfi);
  147.  
  148.   if (dx*dys-dy*dxs>0) return fi;
  149.  
  150.   return -fi;
  151. }
  152.   
  153. double segment::distance(segment s)
  154. { if (angle(s)!=0) return 0;
  155.   return distance(s.ptr->start);
  156.  }
  157.  
  158. double  segment::distance()          
  159. { return distance(point(0,0)); }
  160.  
  161. double segment::distance(point p)
  162. { segment s(ptr->start,p);
  163.   double l = s.length();
  164.   if (l==0) return 0;
  165.   else return l*sin(angle(s));
  166.  }
  167.  
  168. double  segment::slope()  
  169. { double dx = (ptr->end.ptr->x - ptr->start.ptr->x); 
  170.   if (dx==0) 
  171.   { cout << *this << "\n";
  172.     cout.flush();
  173.     error_handler(1,"segment::slope() : vertical segment");
  174.    }
  175.   return   (ptr->end.ptr->y - ptr->start.ptr->y)/dx; 
  176. }
  177.  
  178. double  segment::y_abs() 
  179. { return  ptr->start.ptr->y - (ptr->start.ptr->x * slope()); }
  180.  
  181. bool segment::intersection(segment s, point& inter)
  182. { line l(s);
  183.   if (l.intersection(*this,inter))
  184.   { double d1  = inter.distance(s.ptr->start);
  185.     double d2  = inter.distance(s.ptr->end);
  186.     double l   = s.length()+eps;
  187.     if ( d1 < l && d2 < l) return true;
  188.    }
  189.    return false;
  190. }
  191.  
  192. segment segment::rotate(double alpha)
  193. {  double  l = length();
  194.    point p = start();
  195.    double beta = alpha + angle();
  196.    return segment(p,beta,l);
  197. }
  198.  
  199. segment segment::rotate(point origin, double alpha)
  200. {  point p = start().rotate(origin,alpha);
  201.    point q = end().rotate(origin,alpha);
  202.    return segment(p,q);
  203. }
  204.  
  205.  
  206.