line.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #ifndef _LINE_HPP_
  2. #define _LINE_HPP_
  3. #include "point.h"
  4. struct line
  5. {
  6. double a,b,c;
  7. line()
  8. :a(0)
  9. ,b(0)
  10. ,c(0)
  11. {
  12. }
  13. line(double k,double b_)
  14. :a(k)
  15. ,b(-1)
  16. ,c(b_)
  17. {
  18. }
  19. line(double a_,double b_,double c_)
  20. :a(a_)
  21. ,b(b_)
  22. ,c(c_)
  23. {
  24. }
  25. line(const point&p0,const point&p1)
  26. {
  27. set(p0,p1);
  28. }
  29. void clear()
  30. {
  31. a=b=c=0;
  32. }
  33. bool empty() const
  34. {
  35. return a==0 && b==0 && c==0;
  36. }
  37. void set(const point&p0,const point&p1)
  38. {
  39. auto abc=p0.get_abc(p1);
  40. a=std::get<0>(abc);
  41. b=std::get<1>(abc);
  42. c=std::get<2>(abc);
  43. }
  44. std::string to_string()const
  45. {
  46. char buf[256];
  47. int len=sprintf(buf,"a=%.3lf,b=%.3lf,c=%.3lf",a,b,c);
  48. return std::string(buf,len);
  49. }
  50. double cos_k()const
  51. {
  52. if(b==0)
  53. return 0;
  54. double k=-a/b;
  55. return 1/sqrt(1+k*k);
  56. }
  57. double sin_k()const
  58. {
  59. if(b==0)
  60. return 1;
  61. double k=-a/b;
  62. return k/sqrt(1+k*k);
  63. }
  64. double arg()const
  65. {
  66. return acos(cos_k())*(sin_k()>0?1:-1);
  67. }
  68. static bool eq(double a,double b,double e)
  69. {
  70. return fabs(a-b)<e;
  71. }
  72. point projection(const point&lv)const
  73. {
  74. line pp(-b,a,b*lv.x-a*lv.y);
  75. return crossing(pp);
  76. }
  77. double dist(const point&v)const
  78. {
  79. return v.dist(projection(v));
  80. }
  81. bool parallel(const line&l2)const
  82. {
  83. return eq(cos_k(),l2.cos_k(),0.0001) && eq(sin_k(),l2.sin_k(),0.0001);
  84. }
  85. point crossing(const line&l)const
  86. {
  87. if(parallel(l))
  88. return point();
  89. return point ( (c*l.b-l.c*b) /(l.a*b-a*l.b) ,
  90. (c*l.a-l.c*a) /(l.b*a-b*l.a) );
  91. }
  92. bool contain(const point&p,double e)const
  93. {
  94. return contain(p.x,p.y,e);
  95. }
  96. bool contain(double x,double y,double e)const
  97. {
  98. return fabs(a*x+b*y+c)<e;
  99. }
  100. };
  101. struct line_v:line//线段
  102. {
  103. std::array<point,2> v;
  104. line_v()
  105. {
  106. v[0].set(0,0);
  107. v[1].set(0,0);
  108. }
  109. line_v(const point&p0,const point&p1)
  110. :line(p0,p1)
  111. {
  112. v[0]=p0;
  113. v[1]=p1;
  114. }
  115. point&operator[](int i) { return v[i]; }
  116. const point&operator[](int i)const { return v[i]; }
  117. std::string to_string()const
  118. {
  119. char buf[256];
  120. int len=sprintf(buf,"[(%.3lf,%.3lf),(%.3lf,%.3lf)]",v[0].x,v[0].y,v[1].x,v[1].y);
  121. return std::string(buf,len);
  122. }
  123. point crossing(const line&l)const
  124. {
  125. point pt=line::crossing(l);
  126. return contain(pt)?pt:point();
  127. }
  128. point crossing(const line_v&l)const
  129. {
  130. point pt=line::crossing(l);
  131. return contain(pt)&&l.contain(pt)?pt:point();
  132. }
  133. bool is_same(const line_v&l,double e=0.0001)const
  134. {
  135. return line::contain(l[0],e) && line::contain(l[1],e);
  136. }
  137. point projection(const point&p)const
  138. {
  139. point pt=line::projection(p);
  140. return contain(pt)?pt:point();
  141. }
  142. line_v projection(const line_v&lv)const
  143. {
  144. std::array<point,2> o,t;
  145. o[0]=line::projection(lv[0]);
  146. o[1]=line::projection(lv[1]);
  147. if(o[1]<o[0]) o[0].swap(o[1]);
  148. t[0]=v[0];
  149. t[1]=v[1];
  150. if(t[1]<t[0]) t[0].swap(t[1]);
  151. if(o[1] < t[0] || t[1] < o[0])
  152. return line_v(point(0,0),point(0,0));
  153. return line_v(point::max(t[0],o[0]),point::min(t[1],o[1]));
  154. }
  155. bool empty()const
  156. {
  157. return length()<0.01;
  158. }
  159. double length()const
  160. {
  161. return v[0].dist(v[1]);
  162. }
  163. bool contain(const point&p,double e=0.0001)const
  164. {
  165. return contain(p.x,p.y,e);
  166. }
  167. bool contain(double x,double y,double e=0.0001)const
  168. {
  169. return eq(v[0].dist(v[1]),v[0].dist(x,y)+v[1].dist(x,y),0.0001);
  170. }
  171. double dist(const point&v)const
  172. {
  173. point p=projection(v);
  174. if(p.empty())
  175. return -1;
  176. return v.dist(p);
  177. }
  178. };
  179. #endif