基础计算几何

结构体的定义

struct point
{
    double x, y;
    point(double _x, double _y):x(_x), y(_y){}

    // 点-点=向量
    point operator-(const point &v){
        return point(x-v.x, y-v.y);
    }

};

int dcmp(double x){
    if (fabs(x)<eps) return 0;
    else return x<0?-1:1;
}
bool operator == (const point &a, const point &b){
    return (dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0);
}

typedef point Vector; // Vector表示向量

//点积
double Dot(Vector a, Vector b){return a.x*b.x+a.y*b.y;}

//线段的长度
double Lenth(Vector a){return sqrt(Dot(a, a));}

//向量的夹角(弧度)
double Angle(Vector a, Vector b){return acos(Dot(a, b)/Lenth(a)/Lenth(b));}

//叉积
double Cross(Vector a, Vector b){return a.x*b.y-a.y*b.x;}

//三角形有向面积的2倍
double Area2(point a, point b, point c){return Cross(b-a, c-a);}

//向量旋转,a为逆时针旋转的角度
// rad是弧度
point Rotate(Vector a, double rad){
    return point(a.x*cos(rad)-a.y*sin(rad), a.x*sin(rad)+a.y*cos(rad));
}

//计算向量的单位法线
point Normal(Vector a){
    double L = Lenth(a);
    return point(-a.y/L, a.x/L);
}

直线

// 两条直线的交点
// 两条直线为 p+tv, q+tw,其中p, q为两直线上的一点, v,w是直线所在方向的向量,
// 交点在第一条直线的参数为t1, 第二条直线的参数为t2
// t1 = (cross(w,u)/cross(v,w));  t2 = (cross(v,u)/cross(v,w));
// 调用前要确保两直线有唯一交点,当且仅当两直线不共线
point Getline(point p, Vector v, point q, Vector w){
    point u = p-q;
    double t = Cross(w, u)/Cross(v, w);
    return point(p.x+v.x*t, p.y+v.y*t);
}

//点到直线的距离
double Dis(point p, point a, point b){
    Vector v1 = b-a, v2 = p-a;
    return fabs(Cross(v1, v2)/Lenth(v1));
}

//点到线段的距离
//点p在直线的投影可能在直线上,也可能不在直线上
double Dis2(point p, point a, point b){
    if (a==b) return Lenth(p-a);
    Vector v1=b-a, v2 = p-a, v3=p-b;
    if (dcmp(Dot(v1, v2))<0) return Lenth(v2); // 注意大小于号
    if (dcmp(Dot(v1, v3))>0) return Lenth(v3);
    else return fabs(Cross(v1, v2)/Lenth(v1));
}

//点在线段上的投影
point Getline2(point p, point a, point b){
    Vector v = b-a;
    double f = Dot(v, p-a)/Dot(v, v);
    return point(a.x+v.x*f, a.y+v.y*f);
}

//线段相交判定(交点不在端点的位置,且两直线仅有唯一交点)
bool Inter(point a1, point a2, point b1, point b2){
    double c1 = Cross(a2-a1, b1-a1), c2 = Cross(a2-a1, b2-a1),
           c3 = Cross(b2-b1, a1-b1), c4 = Cross(b2-b1, a2-b1);
    return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}
//线段相交判定,交点可以在一条直线端点位置(交点不在两直线端点得位置)
bool OneInter(point p, point a1, point a2){
    return dcmp(Cross(a1-p, a2-p))==0 && dcmp(Dot(a1-p, a2-p))<0;
}
// 视题目要求是否特判两直线有端点重合的情况

多边形

//多边形面积(有方向)
vector<point>ve;
double ConvexArea(int n){
    double area = 0;
    for(int i = 1; i < n-1; i++){
        area += Cross(ve[i]-ve[0], ve[i+1]-ve[0]);
    }
    return area/2;
}

整体一起

const double eps = 1e-10;
const double pi = acos(-1.0);

struct point
{
    double x, y;
    point(double _x, double _y):x(_x), y(_y){}

    // 点-点=向量
    point operator-(const point &v){
        return point(x-v.x, y-v.y);
    }

};

int dcmp(double x){
    if (fabs(x)<eps) return 0;
    else return x<0?-1:1;
}
bool operator == (const point &a, const point &b){
    return (dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0);
}

typedef point Vector; // Vector表示向量

//点积
double Dot(Vector a, Vector b){return a.x*b.x+a.y*b.y;}

//线段的长度
double Lenth(Vector a){return sqrt(Dot(a, a));}

//向量的夹角(弧度)
double Angle(Vector a, Vector b){return acos(Dot(a, b)/Lenth(a)/Lenth(b));}

//叉积
double Cross(Vector a, Vector b){return a.x*b.y-a.y*b.x;}

//三角形有向面积的2倍
double Area2(point a, point b, point c){return Cross(b-a, c-a);}

//向量旋转,a为逆时针旋转的角度
// rad是弧度
point Rotate(Vector a, double rad){
    return point(a.x*cos(rad)-a.y*sin(rad), a.x*sin(rad)+a.y*cos(rad));
}

//计算向量的单位法线
point Normal(Vector a){
    double L = Lenth(a);
    return point(-a.y/L, a.x/L);
}

// 两条直线的交点
// 两条直线为 p+tv, q+tw,其中p, q为两直线上的一点, v,w是直线所在方向的向量,
// 交点在第一条直线的参数为t1, 第二条直线的参数为t2
// t1 = (cross(w,u)/cross(v,w));  t2 = (cross(v,u)/cross(v,w));
// 调用前要确保两直线有唯一交点,当且仅当两直线不共线
point Getline(point p, Vector v, point q, Vector w){
    point u = p-q;
    double t = Cross(w, u)/Cross(v, w);
    return point(p.x+v.x*t, p.y+v.y*t);
}

//点到直线的距离
double Dis(point p, point a, point b){
    Vector v1 = b-a, v2 = p-a;
    return fabs(Cross(v1, v2)/Lenth(v1));
}

//点到线段的距离
//点p在直线的投影可能在直线上,也可能不在直线上
double Dis2(point p, point a, point b){
    if (a==b) return Lenth(p-a);
    Vector v1=b-a, v2 = p-a, v3=p-b;
    if (dcmp(Dot(v1, v2))<0) return Lenth(v2); // 注意大小于号
    if (dcmp(Dot(v1, v3))>0) return Lenth(v3);
    else return fabs(Cross(v1, v2)/Lenth(v1));
}

//点在线段上的投影
point Getline2(point p, point a, point b){
    Vector v = b-a;
    double f = Dot(v, p-a)/Dot(v, v);
    return point(a.x+v.x*f, a.y+v.y*f);
}

//线段相交判定(交点不在端点的位置,且两直线仅有唯一交点)
bool Inter(point a1, point a2, point b1, point b2){
    double c1 = Cross(a2-a1, b1-a1), c2 = Cross(a2-a1, b2-a1),
           c3 = Cross(b2-b1, a1-b1), c4 = Cross(b2-b1, a2-b1);
    return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}
//线段相交判定,交点可以在一条直线端点位置(交点不在两直线端点得位置)
bool OneInter(point p, point a1, point a2){
    return dcmp(Cross(a1-p, a2-p))==0 && dcmp(Dot(a1-p, a2-p))<0;
}
// 视题目要求是否特判两直线有端点重合的情况

//多边形面积(有方向)
vector<point>ve;
double ConvexArea(int n){
    double area = 0;
    for(int i = 1; i < n-1; i++){
        area += Cross(ve[i]-ve[0], ve[i+1]-ve[0]);
    }
    return area/2;
}

原文地址:https://www.cnblogs.com/ccut-ry/p/8981922.html

时间: 2024-11-10 14:07:11

基础计算几何的相关文章

poj1584 A Round Peg in a Ground Hole 判断多边形凹凸,点到线的距离【基础计算几何】

大致思路:首先对于所给的洞的点,判断是否是凸多边形,图形的输入和输出可以是顺时针或者逆时针,而且允许多点共线 Debug 了好几个小时,发现如下问题 判断三点是否共线,可用斜率公式判断 POINT point_A, point_B, point_C; if(point_A.x == point_B.x || point_B.x == point_C.x){ if(point_A.x == point_B.x && point_B.x == point_C.x) continue; }els

LightOJ 1062 - Crossed Ladders 基础计算几何

http://www.lightoj.com/volume_showproblem.php?problem=1062 题意:问两条平行边间的距离,给出从同一水平面出发的两条相交线段长,及它们交点到水平面的高. 思路:计算几何怎么可能直接算出答案orz解了好久方程觉得不对,应该是二分枚举平行边的距离,通过相似三角形,算出交点的高,与题目比较,小于误差范围就行了. /** @Date : 2016-12-10-18.18 * @Author : Lweleth ([email protected])

Kuangbin 带你飞-基础计算几何专题 题解

专题基本全都是模版应用.贴一下模版 const double eps = 1e-8; const int INF = 0x3f3f3f3f; int sgn(double x) { if (fabs(x) < eps) return 0; if (x < 0) return -1; return 1; } struct Point { double x,y; Point(){} Point(double tx,double ty) { x = tx; y = ty; } Point opera

lightoj1022&amp;&amp;1072&amp;&amp;1107&amp;&amp;1118&amp;&amp;1178&amp;&amp;1216【基础计算几何】

1022 - Circle in Square    PDF (English) Statistics Forum Time Limit: 0.5 second(s) Memory Limit: 32 MB A circle is placed perfectly into a square. The term perfectly placed means that each side of the square is touched by the circle, but the circle

计算几何及其应用——计算几何基础

写在前面:当时开计算几何这个专题神奇的从解析几何开始了,然后最近发现<计算几何及应用(金博)>这本书前面那章忽略掉了一些重要的东西比如说点定位.半平面相交之类的东西,恰好还有一些和计算几何扯上边但是不需要算法的简单题目没有整理,故在此开辟一块小空间. 我们再来看一道有关几何的问题.(Problem source:hdu2073)    数理分析:虽然这道题异常的简单,基本算不上计算几何这个专题当中的题目,但是把它拿到这里来,是源于这道简单几何题的思路其实体现了计算几何整个体系中比较重要的思维.

CG_Hadoop:基于MapReduce的计算几何

原作:Ahmed Eldawy:Mohamed F.Mokbel (UMN) 翻译:Leo(CAU) 注:由于本人翻译水平有限,如有错误,敬请谅解,可以在评论中指出,欢迎交流! 摘要:Hadoop使用了MapReduce编程范式,目前已经被公认为是分布式环境中分析大数据的标准框架.然而,它并不能很好的应用于大规模的计算几何处理.本文介绍的CG_Hadoop是一套可伸缩的和高效的MapReduce算法,用于处理各种基本计算几何问题,例如多边形合并.skyline(轮廓线).convex hull(

2017暑假集训前总结和规划

距离大一进来已经一年了啊,感觉还是啥也不会,哎,太差了,总结一下这一年都学了写什么吧! 大一寒假开始专题,刷过的有:dp,dfs和bfs,数论(gcd拓展gcd,欧拉定理等等,但是中国剩余定理没学,等复习的时候再学吧),并查集,最短路(bellman-fprd,dijkstra,floyd-warshall,spfa),最小生成树(prim,kruskal),线段树,二分三分 大一下学期有:拓扑排序,基础计算几何(直线线段相交,快速排除实验,跨立实验),矩阵快速幂,博弈基础(nim博弈,威佐夫博

学习,兴趣与娱乐

学习>兴趣>娱乐 排名应该就是这样了,但是总是控制不住我自己,从而变成了,娱乐>学习>兴趣(几乎没有) (一,手机问题),被手机消耗的时间极多,简直不可描述,自己都不知道自己在玩什么,所以我刚刚打开了qq浏览器,突然兴奋试试了qq浏览器的识别花的功能,然后看了一个新闻,然后看了一个笑话,,,,原来这就是手机的"正确"操作?我用手机好像并不是用来做这种事情的,正确姿势就是:一,联系父母和同学.二,学习英语,三,吃饭付款.四,收集图片存到微云里. 所以要控制自己玩手

java web 开发三剑客 -------电子书

Internet,人们通常称为因特网,是当今世界上覆盖面最大和应用最广泛的网络.根据英语构词法,Internet是Inter + net,Inter-作为前缀在英语中表示“在一起,交互”,由此可知Internet的目的是让各个net交互.所以,Internet实质上是将世界上各个国家.各个网络运营商的多个网络相互连接构成的一个全球范围内的统一网,使各个网络之间能够相互到达.各个国家和运营商构建网络采用的底层技术和实现可能各不相同,但只要采用统一的上层协议(TCP/IP)就可以通过Internet