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

[转]计算几何模板Orz

11#include22#defineMAXN100033#defineoffset1000044#defineeps1e-855#definePIacos(-1.0)3.1415
  1   1 #include
  2   2 #define MAXN 1000
  3   3 #define offset 10000
  4   4 #define eps 1e-8
  5   5 #define PI acos(-1.0)//3.14159265358979323846
  6   6 //判断一个数是否为0,是则返回true,否则返回false
  7   7 #define zero(x)(((x)>0?(x):-(x))  8   8 //返回一个数的符号,正数返回1,负数返回2,否则返回0
  9   9 #define _sign(x)((x)>eps?1:((x)<-eps?2:0))
 10  10 struct point 
 11  11 {
 12  12     double x,y;
 13  13 };
 14  14 struct line
 15  15 {
 16  16     point a,b;
 17  17 };//直线通过的两个点,而不是一般式的三个系数
 18  18 //求矢量[p0,p1],[p0,p2]的叉积
 19  19 //p0是顶点
 20  20 //若结果等于0,则这三点共线
 21  21 //若结果大于0,则p0p2在p0p1的逆时针方向
 22  22 //若结果小于0,则p0p2在p0p1的顺时针方向
 23  23 double xmult(point p1,point p2,point p0)
 24  24 {
 25  25     return(p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
 26  26 }
 27  27 //计算dotproduct(P1-P0).(P2-P0)
 28  28 double dmult(point p1,point p2,point p0)
 29  29 {
 30  30     return(p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
 31  31 }
 32  32 //两点距离
 33  33 double distance(point p1,point p2)
 34  34 {
 35  35     return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
 36  36 }
 37  37 //判三点共线
 38  38 int dots_inline(point p1,point p2,point p3)
 39  39 {
 40  40     return zero(xmult(p1,p2,p3));
 41  41 }
 42  42 //判点是否在线段上,包括端点
 43  43 int dot_online_in(point p,line l)
 44  44 {
 45  45     return zero(xmult(p,l.a,l.b))&&(l.a.x-p.x)*(l.b.x-p.x)eps;
 46  46 }
 47  47 //判点是否在线段上,不包括端点
 48  48 int dot_online_ex(point p,line l)
 49  49 {
 50  50     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));
 51  51 }
 52  52 //判两点在线段同侧,点在线段上返回0
 53  53 int same_side(point p1,point p2,line l)
 54  54 {
 55  55     return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)>eps;
 56  56 }
 57  57 //判两点在线段异侧,点在线段上返回0
 58  58 int opposite_side(point p1,point p2,line l)
 59  59 {
 60  60     return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)<-eps;
 61  61 }
 62  62 //判两直线平行
 63  63 int parallel(line u,line v)
 64  64 {
 65  65     return zero((u.a.x-u.b.x)*(v.a.y-v.b.y)-(v.a.x-v.b.x)*(u.a.y-u.b.y));
 66  66 }
 67  67 //判两直线垂直
 68  68 int perpendicular(line u,line v)
 69  69 {
 70  70     return zero((u.a.x-u.b.x)*(v.a.x-v.b.x)+(u.a.y-u.b.y)*(v.a.y-v.b.y));
 71  71 }
 72  72 //判两线段相交,包括端点和部分重合
 73  73 int intersect_in(line u,line v)
 74  74 {
 75  75     if(!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))
 76  76         return!same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);
 77  77     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);
 78  78 }
 79  79 //判两线段相交,不包括端点和部分重合
 80  80 int intersect_ex(line u,line v)
 81  81 {
 82  82     return opposite_side(u.a,u.b,v)&&opposite_side(v.a,v.b,u);
 83  83 }
 84  84 //计算两直线交点,注意事先判断直线是否平行!
 85  85 //线段交点请另外判线段相交(同时还是要判断是否平行!)
 86  86 point intersection(line u,line v)
 87  87 {
 88  88     point ret=u.a;
 89  89     double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))/((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));
 90  90     ret.x+=(u.b.x-u.a.x)*t;
 91  91     ret.y+=(u.b.y-u.a.y)*t;
 92  92     return ret;
 93  93 }
 94  94 //点到直线上的最近点
 95  95 point ptoline(point p,line l)
 96  96 {
 97  97     point t=p;
 98  98     t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;
 99  99     return intersection(p,t,l.a,l.b);
100 100 }
101 101 //点到直线距离
102 102 double disptoline(point p,line l)
103 103 {
104 104     return fabs(xmult(p,l.a,l.b))/distance(l.a,l.b);
105 105 }
106 106 //点到线段上的最近点
107 107 point ptoseg(point p,line l)
108 108 {
109 109     point t=p;
110 110     t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;
111 111     if(xmult(l.a,t,p)*xmult(l.b,t,p)>eps)
112 112         return distance(p,l.a)l.a:l.b;
113 113     return intersection(p,t,l.a,l.b);
114 114 }
115 115 //点到线段距离
116 116 double disptoseg(point p,line l)
117 117 {
118 118     point t=p;
119 119     t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;
120 120     if(xmult(l.a,t,p)*xmult(l.b,t,p)>eps)
121 121         return distance(p,l.a)distance(p,l.a):distance(p,l.b);
122 122     return fabs(xmult(p,l.a,l.b))/distance(l.a,l.b);
123 123 }
124 124 struct TPoint
125 125 {
126 126     double x,y;
127 127     TPoint operator-(TPoint&a)
128 128     {
129 129         TPoint p1;
130 130         p1.x=x-a.x;
131 131         p1.y=y-a.y;
132 132         return p1;
133 133     }
134 134 };
135 135 
136 136 struct TLine
137 137 {
138 138     double a,b,c;
139 139 };
140 140 
141 141 //求p1关于p2的对称点
142 142 TPoint symmetricalPoint(TPoint p1,TPoint p2)
143 143 {
144 144     TPoint p3;
145 145     p3.x=2*p2.x-p1.x;
146 146     p3.y=2*p2.y-p1.y;
147 147     return p3;
148 148 }
149 149 //p点关于直线L的对称点
150 150 TPoint symmetricalPointofLine(TPoint p,TLine L)
151 151 {
152 152     TPoint p2;
153 153     double d;
154 154     d=L.a*L.a+L.b*L.b;
155 155     p2.x=(L.b*L.b*p.x-L.a*L.a*p.x-2*L.a*L.b*p.y-2*L.a*L.c)/d;
156 156     p2.y=(L.a*L.a*p.y-L.b*L.b*p.y-2*L.a*L.b*p.x-2*L.b*L.c)/d;
157 157     return p2;
158 158 }
159 159 //求线段所在直线,返回直线方程的三个系数
160 160 //两点式化为一般式
161 161 TLine lineFromSegment(TPoint p1,TPoint p2)
162 162 {
163 163     TLine tmp;
164 164     tmp.a=p2.y-p1.y;
165 165     tmp.b=p1.x-p2.x;
166 166     tmp.c=p2.x*p1.y-p1.x*p2.y;
167 167     return tmp;
168 168 }
169 169 //求直线的交点
170 170 //求直线的交点,注意平行的情况无解,避免RE
171 171 TPoint LineInter(TLine l1,TLine l2)
172 172 {
173 173     //求两直线得交点坐标
174 174     TPoint tmp;
175 175     double a1=l1.a;
176 176     double b1=l1.b;
177 177     double c1=l1.c;
178 178     double a2=l2.a;
179 179     double b2=l2.b;
180 180     double c2=l2.c;
181 181     //注意这里b1=0
182 182     if(fabs(b1)<eps){
183 183         tmp.x=-c1/a1;
184 184         tmp.y=(-c2-a2*tmp.x)/b2;
185 185     }
186 186     else{
187 187         tmp.x=(c1*b2-b1*c2)/(b1*a2-b2*a1);
188 188         tmp.y=(-c1-a1*tmp.x)/b1;
189 189     }
190 190     //cout<<"交点坐标"<
191 191     //cout<
192 192     //cout<
193 193     return tmp;
194 194 }
195 195 //矢量(点)V以P为顶点逆时针旋转angle(弧度)并放大scale倍
196 196 point rotate(point v,point p,double angle,double scale){
197 197     point ret=p;
198 198     v.x-=p.x,v.y-=p.y;
199 199     p.x=scale*cos(angle);
200 200     p.y=scale*sin(angle);
201 201     ret.x+=v.x*p.x-v.y*p.y;
202 202     ret.y+=v.x*p.y+v.y*p.x;
203 203     return ret;
204 204 }
205 205 //矢量(点)V以P为顶点逆时针旋转angle(弧度)
206 206 point rotate(point v,point p,double angle){
207 207     double cs=cos(angle),sn=sin(angle);
208 208     v.x-=p.x,v.y-=p.y;
209 209     p.x+=v.x*cs-v.y*sn;
210 210     p.y+=v.x*sn+v.y*cs;
211 211     return p;
212 212 }

[转] 计算几何模板Orz


推荐阅读
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
author-avatar
机加工N_918
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有