#ifndef _LINE_HPP_ #define _LINE_HPP_ #include "point.h" NAMESPACE_POINT_BEGIN (NAMESPACE_POINT) struct line { double a,b,c; line() :a(0) ,b(0) ,c(0) { } line(double k,double b_) :a(k) ,b(-1) ,c(b_) { } line(double a_,double b_,double c_) :a(a_) ,b(b_) ,c(c_) { } line(const point&p0,const point&p1) { set(p0,p1); } void clear() { a=b=c=0; } bool empty() const { return a==0 && b==0 && c==0; } void set(const point&p0,const point&p1) { auto abc=p0.get_abc(p1); a=std::get<0>(abc); b=std::get<1>(abc); c=std::get<2>(abc); } std::string to_string()const { char buf[256]; int len=sprintf(buf,"a=%.3lf,b=%.3lf,c=%.3lf",a,b,c); return std::string(buf,len); } double cos_k()const { if(b==0) return 0; double k=-a/b; return 1/sqrt(1+k*k); } double sin_k()const { if(b==0) return 1; double k=-a/b; return k/sqrt(1+k*k); } double arg()const { return acos(cos_k())*(sin_k()>0?1:-1); } static bool eq(double a,double b,double e) { return fabs(a-b) v; line_v() { v[0].set(0,0); v[1].set(0,0); } line_v(const point&p0,const point&p1) :line(p0,p1) { v[0]=p0; v[1]=p1; } point&operator[](int i) { return v[i]; } const point&operator[](int i)const { return v[i]; } std::string to_string()const { char buf[256]; int len=sprintf(buf,"[(%.3lf,%.3lf),(%.3lf,%.3lf)]",v[0].x,v[0].y,v[1].x,v[1].y); return std::string(buf,len); } point crossing(const line&l)const { point pt=line::crossing(l); return contain(pt)?pt:point(); } point crossing(const line_v&l)const { point pt=line::crossing(l); return contain(pt)&&l.contain(pt)?pt:point(); } bool is_same(const line_v&l,double e=0.0001)const { return line::contain(l[0],e) && line::contain(l[1],e); } point projection(const point&p)const { point pt=line::projection(p); return contain(pt)?pt:point(); } line_v projection(const line_v&lv)const { std::array o,t; o[0]=line::projection(lv[0]); o[1]=line::projection(lv[1]); if(o[1]