65,184
社区成员




//重新适当化简后的
//r >= 0
//a*a+b*b > 0
Line solve(Line l, Pt p, Ct r)
{
if (dbcmp(l.online(p)) == 0 || dbcmp(r) == 0) return l;//点在直线上或者平移距离为零
/*
|l.c - c| = r * sqrt(a*a+b*b)
=> c = l.c - r * sqrt(a*a+b*b)或者 l.c + r * sqrt(a*a+b*b)
*/
double delta = sqrt(l.a * l.a + l.b * l.b);
double dist = r * delta;
Line ans1(l.a, l.b, l.c + dist), ans2(l.a, l.b, l.c - dist);
//距离近的为所求:分上有delta,忽略掉。
double x1 = fabs(ans1.online(p)), x2 = fabs(ans2.online(p));
return x1 < x2 ? ans1 : ans2;
}
//p到目标直线的距离近
double dist1 = p2l(p, ans1);
return dist1 > r ? ans2 : ans1;
//这里写错老,应该是把dist1, dist2都求出来,返回较小的对应的直线。
typedef double Ct;
struct Pt
{
Pt(Ct _x = 0, Ct _y = 0) : x(_x), y(_y){}
Ct x, y;
};
struct Line
{
Line(Ct _a = 0, Ct _b = 0, Ct _c = 0) : a(_a), b(_b), c(_c){}
Ct online(const Pt& p) const {return a * p.x + b * p.y + c;}
Ct a, b, c;
};
const double pi = acos(-1);
typedef Pt Vec;
#define SQ(x) ((x)*(x))
inline int dbcmp(double x)
{
if (fabs(x) < 1e-8) return 0;
return x > 0 ? 1 : -1;
}
inline Pt operator - (const Pt& a, const Pt& b)
{
return Pt(a.x-b.x, a.y-b.y);
}
inline Pt operator + (const Pt& a, const Pt& b)
{
return Pt(a.x+b.x, a.y+b.y);
}
inline Ct dot(const Pt& a, const Pt& b)
{
return a.x*b.x + a.y*b.y;
}
inline Ct dot(const Pt& a, const Pt& b, const Pt& c)
{
return dot(b-a, c-a);
}
inline Ct cross(const Pt& a, const Pt& b)
{
return a.x * b.y - a.y * b.x;
}
inline Ct cross(const Pt& a, const Pt& b, const Pt& c)
{
return cross(b-a, c-a);
}
inline double norm(const Pt& a)
{
return sqrt(dot(a, a));
}
inline Ct norm2(const Pt& a)
{
return dot(a, a);
}
inline double p2l(const Pt& a, const Line& l)
{
return fabs(l.online(a))/norm(Pt(l.a, l.b));
}
inline Line make_line(const Pt& a, const Pt& b)
{
Line ret;
ret.a = b.y-a.y;
ret.b = -(b.x-a.x);
ret.c = cross(b-a, a);
return ret;
}
inline Pt get_symmetry(const Pt& a, const Line& l)
{
Pt x(l.a, l.b), y(dot(x, a)+2*l.c, cross(x, a));
double t = norm2(x);
return Pt(-dot(y, x)/t, -cross(y, x)/t);
}
inline Vec rotate(const Vec& v, double sita)
{
Pt r(cos(sita), -sin(sita));
return Pt(dot(v, r), -cross(v, r));
}
ostream& operator << (ostream& o, const Pt& p)
{
return o << "(" << p.x << "," << p.y << ")";
}
Line solve(Line l, Pt p, Ct r)
{
if (dbcmp(l.online(p)) == 0 || dbcmp(r) == 0) return l;//点在直线上或者平移距离为零
double delta = sqrt(l.a * l.a + l.b * l.b);
double dist = r * delta;
Line ans1(l.a, l.b, l.c + dist), ans2(l.a, l.b, l.c - dist);//求出两点可能的直线
int x1 = dbcmp(ans1.online(p)), x2 = dbcmp(ans2.online(p));//p就在其中一条直线上
if (x1 == 0) return ans1;
if (x2 == 0) return ans2;
//p到目标直线的距离近
double dist1 = p2l(p, ans1);
return dist1 > r ? ans2 : ans1;
}