#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<queue>
#include<vector>
#include<map>
#include<stack>
#include<set>
#define e exp(1.0); //2.718281828
#define mod 1000000007
#define INF 0x7fffffff
#define inf 0x3f3f3f3f
typedef long long LL;
using namespace std;
#define zero(x) (((x)>0?(x):(-x))<eps)
const double eps=1e-8;
const double pi=acos(-1.0);
int cmp(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 a,double b):x(a),y(b){};
void input(){
scanf("%lf %lf",&x,&y);
}
friend point operator + (const point &a,const point &b){
return point(a.x+b.x,a.y+b.y);
}
friend point operator - (const point &a,const point &b){
return point(a.x-b.x,a.y-b.y);
}
friend bool operator == (const point &a,const point &b){
return cmp(a.x-b.x)==0&&cmp(a.y-b.y)==0;
}
friend point operator * (const point &a,const double &b){
return point(a.x*b,a.y*b);
}
friend point operator * (const double &a,const point &b){
return point(a*b.x,a*b.y);
}
friend point operator / (const point &a,const double &b){
return point(a.x/b,a.y/b);
}
double norm(){
return sqrt(sqr(x)+sqr(y));
}
};
//计算两个向量的叉积
double det(const point &a,const point &b){
return a.x*b.y-a.y*b.x;
}
//计算两个点的点积
double dot(const point &a,const point &b){
return a.x*b.x+a.y*b.y;
}
//计算两个点的距离
double dist(const point &a,const point &b){
return (a-b).norm();
}
//op沿远点逆时针旋转角度A
point rotate_point(const point &p,double A){
double tx=p.x,ty=p.y;
return point(tx*cos(A)-ty*sin(A),tx*sin(A)+ty*cos(A));
}
//判断数k的符号 -1负数 1正数 0零
int dcmp(double k){
return k<-eps?-1:k>eps?1:0;
}
double cross(const point &a,const point &b){
return a.x*b.y-a.y*b.x;
}
double abs(const point &o){
return sqrt(dot(o,o));
}
struct line{
point a,b;
line(){};
line(point x,point y):a(x),b(y){};
};
//两个点生成一个线段/直线
line point_make_pair(const point a,const point b){
return line(a,b);
}
//p点到线段st的垂足,保存在cp里
void PointProjLine(const point p,const point s,const point t,point &cp){
double r=dot((t-s),(p-s))/dot(t-s,t-s);
cp=s+r*(t-s);
}
//判断p点是否在线段st上(包括端点)
bool PointOnSegment(point p,point s,point t){
return cmp(det(p-s,t-s))==0 && cmp(dot(p-s,p-t))<=0;
}
//判断线段a,b是否平行
bool parallel(line a,line b){
return !cmp(det(a.a-a.b,b.a-b.b));
}
//判断a,b是否相交,交点保存在res
bool line_make_point(line a,line b,point &res){
if(parallel(a,b)) return false;
double s1=det(a.a-b.a,b.b-b.a);
double s2=det(a.b-b.a,b.b-b.a);
res=(s1*a.b-s2*a.a)/(s1-s2);
return true;
}
//将线段a沿法向量平移len的线段
line move_d(line a,const double &len){
point d=a.b-a.a;
d=d/d.norm();
d=rotate_point(d,pi/2);
return line(a.a+d*len,a.b+d*len);
}
//p0p1 X p0p2
double xmult(point p0,point p1,point p2) {
return det((p1-p0),(p2-p0));
}
double xmult(double x1,double y1,double x2,double y2,double x0,double y0){
return (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);
}
//dot(p1-p0).(p2-p0)
double dmult(point p1,point p2,point p0){
return (p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
}
double dmult(double x1,double y1,double x2,double y2,double x0,double y0){
return (x1-x0)*(x2-x0)+(y1-y0)*(y2-y0);
}
//判断3点是否共线
bool dots_inline(point p1,point p2,point p3){
return zero(xmult(p1,p2,p3));
}
//判断点是否在线段上,包括端点
bool dot_online_in(point p,line l){
return zero(xmult(p,l.a,l.b))&&(l.a.x-p.x)*(l.b.x-p.x)<eps&&(l.a.y-p.y)*(l.b.y-p.y)<eps;
}
//判断点是否在线段上,不包括端点
bool dot_online_ex(point p,line l){
return dot_online_in(p,l)&&(!zero(p.x-l.a.x)||!zero(p.y-l.a.y))&&(!zero(p.x-l.b.x)||!zero(p.y-l.b.y));
}
//判断两点是否在线段同一侧(点在直线上时为0)
bool same_side(point p1,point p2,line l){
return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)>eps;
}
//判断两点是否在线段异侧(点在直线上时为0)
bool opposite_side(point p1,point p2,line l){
return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)<-eps;
}
//点关于直线的对称点
point symmetric_point(point p1,point l1,point l2){
point ret;
if(l1.x>l2.x-eps&&l1.x<l2.x+eps){
ret.x=(2*l1.x-p1.x);
ret.y=p1.y;
}
else{
double k=(l1.y-l2.y)/(l1.x-l2.x);
ret.x=(2*k*k*l1.x+2*k*p1.y-2*k*l1.y-k*k*p1.x+p1.x)/(1+k*k);
ret.y=p1.y-(ret.x-p1.x)/k;
}
return ret;
}
//判断两线段相交,包括端点和部分重合
bool intersect_in(line u,line v){
if(!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))
return !same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);
return dot_online_in(u.a,v)||dot_online_in(u.b,v)||dot_online_in(v.a,u)||dot_online_in(v.b,u);
}
//判断两线段相交,不包括端点和部分重合
bool intersect_ex(line u,line v){
return opposite_side(u.a,u.b,v)&&opposite_side(v.a,v.b,u);
}
//判断直线l1和线段l2是否相交
bool Seg_inter_line(line l1,line l2) {
return cmp(xmult(l2.a,l1.a,l1.b))*cmp(xmult(l2.b,l1.a,l1.b)) <= 0;
}
//p点到线段st的距离
double dis_point_segment(const point p,const point s,const point t){
if(cmp(dot(p-s,t-s))<0) return (p-s).norm();
if(cmp(dot(p-t,s-t))<0) return (p-t).norm();
return fabs(det(s-p,t-p)/dist(t-s,t-s));
}
//p点到直线st的距离
double disptoline(point p,line l){
return fabs(xmult(p,l.a,l.b))/dist(l.a,l.b);
}
const int maxn=1000;
struct polygon{
int n;
point a[maxn];
polygon(){};
//多边形的周长
double perimeter(){
double sum=0;
a[n]=a[0];
for(int i=0;i<n;i++) sum+=(a[i+1]-a[i]).norm();
return sum;
}
//多边形的面积
double area(){
double sum=0;
a[n]=a[0];
for(int i=0;i<n;i++) sum+=det(a[i+1],a[i]);
return sum/2;
}
//判断点是否在多边形内,0多边形外,1多边形内,2边界上
int Point_In(point t){
int num=0;
a[n]=a[0];
for(int i=0;i<n;i++){
if(PointOnSegment(t,a[i],a[i+1])) return 2;
int k=cmp(det(a[i+1]-a[i],t-a[i]));
int d1=cmp(a[i].y-t.y);
int d2=cmp(a[i+1].y-t.y);
if(k>0&&d1<=0&&d2>0) num++;
if(k<0&&d2<=0&&d1>0) num--;
}
return num!=0;
}
};
struct Circle{
point p;
double r;
bool operator < (const Circle &o) const{
if(dcmp(r-o.r)!=0) return dcmp(r-o.r)==-1;
if(dcmp(p.x-o.p.x)!=0){
return dcmp(p.x-o.p.x)==-1;
}
return dcmp(p.y-o.p.y)==-1;
}
bool operator == (const Circle &o) const{
return dcmp(r-o.r)==0&&dcmp(p.x-o.p.x)==0&&dcmp(p.y-o.p.y)==0;
}
};
/*************************************/
int main(){
return 0;
}
二维计算几何模板(点,线)
最新推荐文章于 2020-04-24 11:07:48 发布