您的位置:首页 > 其它

点到线段直线的距离, 直线与直线的关系 直线与线段的关系

2016-03-24 18:29 567 查看
//代码参考与kuangbin的模板

#include<bits/stdc++.h>
using namespace std;

const double eps = 1e-8;
const double inf = 1e20;
const double pi = acos(-1.0);
const int maxp = 1010;

int sgn(double x) { //判断
if(fabs(x) < eps) return 0;
if(x < 0) return -1;
return 1;
}
//
inline double sqr(double x) {
return x*x;
}
//
struct point {
double x, y;
point() {};
//
point(double _x, double _y) {
x = _x;
y = _y;
}
//
void input() {
scanf("%lf %lf", &x, &y);
}
void output() {
printf("%.2f %.2f\n", x, y);
}
//
bool operator == (point b) const {
return sgn(x - b.x) && sgn(y - b.y) == 0;
}
//操作符重载
bool operator < (point b) const {
return sgn(x - b.x) == 0 ? sgn(y - b.y) < 0 : x < b.x;
}
//点积
double operator *(const point &b)const {
return x * b.x + y * b.y;
}
//叉积
double operator ^(const point &b) const {
return x*b.y - y * b.x;
}
//重载减号
point operator -(const point &b) const {
return point(x - b.x, y - b.y);
}
//重载加号
point operator +(const point &b) const {
return point(x + b.x, y + b.y);
}
//
point operator *(const double k) const {
return point(x * k, y * k);
}
//
point operator /(const double k) const {
return point(x / k, y / k);
}

//
double distance(point b) {
return hypot(x-b.x, y-b.y);
}

double len() {
return hypot(x, y);
}
//
double len2() {
return x*x + y*y;
}
};

struct line {
point s, e;
line() {};
line(point _s, point _e) {
s = _s;
e = _e;
}
//
bool operator == (line v) {
return (s == v.s) && (e == v.e);
}
//根据一个点和倾斜角 angle 确定直线, 0 《= angle 《 pi
line(point p, double angle) {
s = p;
if(sgn(angle - pi/2) == 0) {
e = (s + point (0, 1));
} else {
e = (s + point(1, tan(angle)));
}
}
//ax + by + c = 0
line (double a, double b, double c) {
if(sgn(a) == 0) {
s = point(0, -c/b);
e = point(1, -c/b);
} else if(sgn(b) == 0) {
s = point(-c/a, 0);
e = point(-c/a, 1);
} else {
s = point(0, -c/b);
e = point(1, (-c-a)/b);
}
}
void input() {
s.input();
e.input();
}
void adjust() {
if(e < s) swap(s,e);
}
//求线段长度
double length() {
return s.distance(e);
}
//返回线段倾斜角0《= angle 《=pi
double angle() {
double k = atan2(e.y - s.y, e.x - s.x);
if(sgn(k) < 0 ) k += pi;
if(sgn(k - pi) == 0) k -= pi;
return k;
}
//点和直线的关系  1, 在左侧, 2.在右侧 3.在直线上
int relation(point p) {
int c = sgn((p-s)^(e-s));
if(c < 0) return 1;
if(c > 0) return 2;
if(c == 0) return 3;
}
//点在线段上的判断
bool point_on_seg(point p) {
return sgn((p - s)^(e - s)) == 0 && sgn((p - s) * (p - e)) <= 0;
}
//两向量平行 (对应直线平行或者重合
bool parallel(line v) {   //差集为0
return sgn((e - s)^(v.e - v.s)) == 0;
}
//两线段相交的判断 0, 不相交 1.非规范相交  2.规范相交
int seg_cross_seg(line v) {
int d1 = sgn((e - s) ^ (v.s - s));
int d2 = sgn((e - s) ^ (v.e - s));
int d3 = sgn((v.e - v.s) ^ (s-v.s));
int d4 = sgn((v.e - v.s) ^ (e-v.s));
if((d1 ^ d2) == -2 &&(d3 ^ d4) == -2) return 2;
return (d1 == 0 && sgn((v.s - s) * (v.s - e)) <= 0) ||
(d2 == 0 && sgn((v.e - s) * (v.e - e)) <= 0) ||
(d3 == 0 && sgn((s - v.s) * (s - v.e)) <= 0) ||
(d4 == 0 && sgn((s - v.e) * (e - v.e)) <= 0);
}
//直线和线段判断相交  0。 不相交 1.非规范相交  2.规范相交
int line_cross_seg(line v){
int d1 = sgn((e-s)^(v.s-s));
int d2 = sgn((e-s)^(v.e-s));
if( (d1^d2) == -2) return 2;
return (d1 == 0 || d2 == 0);
}

//两直线关系  0 平行 1 重合 2 相交
int line_cross_line(line v){
if((*this).parallel(v))
return v.relation(s) == 3;
return 2;
}

//求两条直线的焦点 前提应该保证两条直线不平行或者重合

point cross_point(line v){
double a1 = (v.e - v.s) ^ (s - v.s);
double a2 = (v.e - v.s) ^ (e - v.s);
return point((s.x*a2 - e.x*a1)/(a2-a1), (s.y*a2-e.y*a1) / (a2 - a1));
}
//点到直线的距离
double dis_point_to_line(point p) {
return fabs((p - s) ^ (e - s)) / length();
}
//点到线段的距离
double dis_point_to_seg(point p) {
if(sgn((p - s) * (e - s)) < 0 || ((p - e) * (s - e)) < 0)
{
return min(p.distance(s), p.distance(e));
}
return dis_point_to_line(p);
}
//返回线段到线段的距离,  前提两线段不相交 相交距离就是0了。
double dis_seg_to_seg(line v){
return min(min(dis_point_to_seg(v.s), dis_point_to_seg(v.e)), min(v.dis_point_to_seg(s), v.dis_point_to_seg(e)));
}
//返回点p在直线上的投影
point line_prog(point p){
return s + (((e-s)*((e-s)*(p-s)))/((e-s).len2()));
}
//返回点p在直线上的对称点
point symmetry_point(point p){
point q = line_prog(p);
return point(2 * q.x - p.x, 2 * q.y - p.y);
}

};

int main() {
// freopen("in.txt", "r",stdin);
point A,B,C,D;
int n;
scanf("%d", &n);
A.input();
double maxx = -1;
double minn = 1e9;
B.input();
D = B;
line x;
maxx = max(maxx, A.distance(B));
for(int i = 0; i < n - 1; i++) {
C.input();
maxx = max(maxx, A.distance(C));
x.s = C;
x.e = B;
minn = min(minn, x.dis_point_to_seg(A));
B = C;
}
x.s = C;
x.e = D;
minn = min(minn, x.dis_point_to_seg(A));
printf("%.7f\n", (maxx * maxx - minn * minn) * pi);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: