热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

计算几何模板之二维点线面模板

#include#include#includeusingnamespacestd;精度误差constdoubleep

#include
#include
#include
using namespace std;
//================= 精度误差 ==============
const double eps = 1e-8;
int dcmp( double x )
{if( fabs(x)}//================= 点结构 ===============
struct pnode
{double x,y;pnode( double a=0.0,double b=0.0):x(a),y(b){}// X乘重载double operator ^ (const pnode &b)const{return x*b.y - b.x*y;}pnode operator - ( const pnode &b)const{return pnode( x-b.x, y-b.y);}pnode operator * (const double p)const{return pnode( x*p, y*p );}pnode operator + (const pnode&b)const{return pnode( x+b.x, y+b.y );}bool operator == (const pnode&b)const{return dcmp( x-b.x )== 0 && dcmp( y-b.y )==0;}bool operator <(const pnode&b)const{return x (const pnode&b)const{return x > b.x || ( dcmp( x-b.x )==0 && y>b.y );}
};
//================ 线结构 ==============
typedef pnode myvec;
struct pline
{pnode st,ed;//st:起始点 ed:终点myvec vec;//向量pline(){}pline(pnode a,pnode b):st(a),ed(b){vec = pnode(b-a);}
};/*x乘:公共起始点p0, V向量p0p1,W向量p0p2cross(v,w) > 0 W向量在 V向量左边
*/
double cross( pnode p0,pnode p1,pnode p2)
{return (p1-p0) ^ (p2-p0);
}
double cross(pline a,pline b)
{return (a.ed-a.st)^(b.ed-b.st);
}/*点乘:dot(v,w) == 二者长度乘积再乘上他们夹角的余弦夹角:从 v 到 w 逆时针旋转的角
*/
double dot( myvec v,myvec w)
{return v.x*w.x + v.y*w.y;
}
double dot( pline a,pline b)
{return a.vec.x * b.vec.x + a.vec.y * b.vec.y;
}//长度
double length( pline a)
{return sqrt(dot(a,a));
}
//返回夹角弧度值 逆时针为正
double angle( pline a,pline b)
{return acos( dot(a,b)/length(a)/length(b) );/*double acos(double x),x范围在 -1~1 之间返回的是一个数值的反余弦弧度值,其范围是 0~ pi 。例如: acos(1) 返回值是 0*/
}
//a向量旋转rad弧度 rad>0逆时针
myvec rotat(myvec a,double rad)
{return myvec( a.x*cos(rad)-a.y*sin(rad) , a.x*sin(rad)+a.y*cos(rad));
}
//矢量三角形面积*2
double area2(pnode p0,pnode p1,pnode p2)
{return cross(p0,p1,p2);
}//============= 直线,线段 ============//给定两条直线,求角平分线
myvec angle_bisector(pnode p, pline v1, pline v2)
{double rad = angle(v1, v2);return rotat(v1.vec, dcmp(cross(v1, v2)) * 0.5 * rad);
}//判断3点共线
bool line_coincide(pnode p1, pnode p2, pnode p3)
{return dcmp(cross(p1,p2,p3)) == 0;
}
//判断直线平行
bool line_parallel(pline v, pline w)
{return cross(v, w) == 0;
}
//判断直线垂直
bool line_vertical(pline v, pline w)
{return dot(v, w) == 0;
}
//点在直线上的投影点
pnode get_line_projection(pnode p, pline line)
{return line.st + line.vec * (dot(line, pline(line.st,p)) / dot(line, line));
}//判断点在线段上, 不包含端点
//dcmp(dot())<=0包含端点
bool on_segment(pnode p, pline line)
{return dcmp(cross(p,line.st, line.ed)) == 0 && dcmp(dot(line.st - p, line.ed - p)) <0;
}
//直线求交点 线判断非平行,非重合
//直线 p+tv ,q+tw 有唯一交点,当且仅当cross(v,w)!=0
pnode get_line_inter_point(pline v,pline w)
{pline u (w.st,v.st);double t = cross( w,u )/cross(v,w);return v.st + (v.ed-v.st) * t;
}//点到直线的距离
//平行四边形面积除以底
double dist_to_line( pnode p,pline line )
{pline v2 (line.st,p);return fabs( cross(line,v2)/length( line));//如果不区绝对值 得到的是有向距离
}//点到线段的距离
double dist_to_seg( pnode p ,pline seg)
{if( seg.st == seg.ed )return length( pline(seg.st,p) );pline v2 (seg.st,p);pline v3 (seg.ed,p);if( dcmp( dot(seg,v2) ) <0)return length( v2 );elseif( dcmp ( dot(seg,v2)) > 0)return length( v3 );elsereturn fabs( cross(seg,v2) )/length( seg );
}
//判断 线段 与 直线相交
bool seg_inter_line(pline line,pline seg)
{return ( dcmp( cross( seg.st,line.st,line.ed ) ) * dcmp( cross( seg.ed,line.st,line.ed) ) )<=0;
}
//判断 线段 与 线段 相交(允许端点在另一条线段上或者重合
bool seg_inter_seg(pline a,pline b)
{returnmax( a.st.x, a.ed.x) >= min( b.st.x, b.ed.x)&&max( b.st.x, b.ed.x) >= min( a.st.x, a.ed.x)&&max( a.st.y, a.ed.y) >= min( b.st.y, b.ed.y)&&max( b.st.y, b.ed.y) >= min( a.st.y, a.ed.y)&&//以上端点判断dcmp(cross( a.st, a.ed, b.st ))*dcmp(cross( a.st, a.ed, b.ed ))<=0&& dcmp(cross( b.st, b.ed, a.st ))*dcmp(cross( b.st, b.ed, a.ed ))<=0;
}
//两条线段有唯一一个不是端点的公共点
//线段规范相交(不允许端点在另一条线段上
bool seg_proper_inter_seg(pline a,pline b)
{double c1 = cross( a.st, a.ed, b.st );double c2 = cross( a.st, a.ed, b.ed );double c3 = cross( b.st, b.ed, a.st );double c4 = cross( b.st, b.ed, a.ed );return dcmp(c1)*dcmp(c2)<0&& dcmp(c3)*dcmp(c4)<0;
}
//判断线段是否在矩形内,允许线段端点再矩形四条边上
//参数(线段,矩形左上角顶点,矩形右下角顶点)
bool seg_in_rec(pline seg,double xl,double xr,double yt,double yb)
{returnseg.st.x >= min(xl,xr) && seg.st.x <= max(xl,xr)&& seg.ed.x >= min(xl,xr) && seg.ed.x <= max(xl,xr)&& seg.st.y >= min(yt,yb) && seg.st.y <= max(yt,yb)&& seg.ed.y >= min(yt,yb) && seg.ed.y <= max(yt,yb);
}
//多边形面积
double polygon_area(pnode*p,int n)
{double area = 0.0;for( int i = 1;i }
int main()
{
}



推荐阅读
  • 本文探讨了在C++中如何有效地清空输入缓冲区,确保程序只处理最近的输入并丢弃多余的输入。我们将介绍一种不阻塞的方法,并提供一个具体的实现方案。 ... [详细]
  • 本题探讨了在大数据结构背景下,如何通过整体二分和CDQ分治等高级算法优化处理复杂的时间序列问题。题目设定包括节点数量、查询次数和权重限制,并详细分析了解决方案中的关键步骤。 ... [详细]
  • 本题来自WC2014,题目编号为BZOJ3435、洛谷P3920和UOJ55。该问题描述了一棵不断生长的带权树及其节点上小精灵之间的友谊关系,要求实时计算每次新增节点后树上所有可能的朋友对数。 ... [详细]
  • 本文介绍如何从字符串中移除大写、小写、特殊、数字和非数字字符,并提供了多种编程语言的实现示例。 ... [详细]
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • 树链问题的优化解法:深度优先搜索与质因数分解
    本文介绍了一种通过深度优先搜索(DFS)和质因数分解来解决最长树链问题的方法。我们通过枚举树链上的最大公约数(GCD),将所有节点按其质因子分类,并计算每个类别的最长链,最终求得全局最长链。 ... [详细]
  • 在进行QT交叉编译时,可能会遇到与目标架构不匹配的宏定义问题。例如,当为ARM或MIPS架构编译时,需要确保使用正确的宏(如QT_ARCH_ARM或QT_ARCH_MIPS),而不是默认的QT_ARCH_I386。本文将详细介绍如何正确配置编译环境以避免此类错误。 ... [详细]
  • JSOI2010 蔬菜庆典:树结构中的无限大权值问题
    本文探讨了 JSOI2010 的蔬菜庆典问题,主要关注如何处理非根非叶子节点的无限大权值情况。通过分析根节点及其子树的特性,提出了有效的解决方案,并详细解释了算法的实现过程。 ... [详细]
  • 本文探讨了如何通过预处理器开关选择不同的类实现,并解决在特定情况下遇到的链接器错误。 ... [详细]
  • 本文介绍如何利用栈数据结构在C++中判断字符串中的括号是否匹配。通过顺序栈和链栈两种方式实现,并详细解释了算法的核心思想和具体实现步骤。 ... [详细]
  • Linux环境下C语言实现定时向文件写入当前时间
    本文介绍如何在Linux系统中使用C语言编程,实现在每秒钟向指定文件中写入当前时间戳。通过此示例,读者可以了解基本的文件操作、时间处理以及循环控制。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • Linux环境下进程间通信:深入解析信号机制
    本文详细探讨了Linux系统中信号的生命周期,从信号生成到处理函数执行完毕的全过程,并介绍了信号编程中的注意事项和常见应用实例。通过分析信号在进程中的注册、注销及处理过程,帮助读者理解如何高效利用信号进行进程间通信。 ... [详细]
  • 目录一、salt-job管理#job存放数据目录#缓存时间设置#Others二、returns模块配置job数据入库#配置returns返回值信息#mysql安全设置#创建模块相关 ... [详细]
  • 本文详细解释了为什么在成功执行移动赋值操作后,对象的析构函数会被调用,并提供了代码示例和详细的分析。 ... [详细]
author-avatar
mobiledu2502891853
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有