计算几何基础-1

文章目录

  • 基本概念
    • 点与向量的运算
      • 精度问题
    • 线段,射线和直线
    • 点积:
    • 夹角
    • 叉积
    • 向量的极角
    • 旋转一个向量
    • 求三角形面积
    • 直线交点
    • 点到直线距离
    • 点在直线上的投影
    • 判断两条线段是否相交
    • 点与直线的位置关系
      • 点是否在直线左侧
      • 点是否在直线上
      • 点是否在线段上
    • 点与多边形的位置关系
      • 扫描法:
      • 转角法
    • 线段与多边形位置关系
    • 多边形的面积

基本概念

点:平面上一点,用坐标(x,y)来表示

struct Point{double x,y;
}; 

向量:同时具有大小和方向的量 。把向量从原点出发到达的点的坐标作为该向量的坐标

typedef Point Vector;

点与向量的运算

点 + 向量 = 点
向量 + 向量 = 向量
点 - 点 = 向量
向量 * k = 向量

Vector operator +(Vector a,Vector b)
{return Vector(a.x+b.x,a.y+b.y);
}
Vector operator -(Vector a,Vector b)
{return Vector(a.x-b.x,a.y-b.y);
}
Vector operator *(Vector a,double p)
{return Vector(a.x*p , a.y*p);
}
Vector operator /(Vector a,double p)
{return Vector(a.x/p , a.y/p);
}
struct point{double x,y;point(){}point(double x1,double y1):x(x1),y(y1){}point operator +(const point &z)const{return point(x+z.x,y+z.y);}point operator -(const point &z)const{return point(x-z.x,y-z.y);}point operator 8 (const double &rate)const{return point(x*rate,y*rate);}
}p[N];

精度问题

因为浮点数的精度问题会造成微小的偏差

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

线段,射线和直线

表示方式:

  1. 解析几何(y = kx+b)
  2. 点+向量
  3. 具体区分线段射线和直线
struct Line{Point p;Vector v;int f;
};
f=0 说明是线段
f=1 说明是射线 
f=2 说明是直线 
struct Line{point p,v;Line(){}Line(point _p.point _v):p(_p),v(_v){}
}L[N];

点积:

点积表示的是两个向量的长度之积再乘上他们夹角的余弦值,也就是a在b上的投影长度乘上b的模长

double dot(Vector a,Vector b)
{return a.x*b.x+a.y*b.y;
}

在这里插入图片描述

夹角

利用点积的定义:
在这里插入图片描述

double angle(Vector a,Vector b)
{return acos(dot(a,b)/length(a)/length(b));
}

叉积

叉积表示的是两个向量的长度之积再乘上它们的夹角的正弦值
也就是以这两个向量为相邻两边所成平行四边形的面积
(叉积还可以表示方向)

double cross(Vector a,Vector b)
{return a.x*b.y-a.y* b.x;
}

v2在v1的顺时针方向那么sin<v1,v2>就是负值,否则就输正值。“顺负逆正”
sin函数的符号就是叉积的符号
叉积的一个非常重要性质是可以通过它的符号判断两矢量相互之间的顺逆时针关系:
若 P × Q > 0 , 则P在Q的顺时针方向。(用手势判断,大拇指朝上)
若 P × Q < 0 , 则P在Q的逆时针方向。
若 P × Q = 0 , 则P与Q共线,但可能同向也可能反向。
a×b的方向:四指由a开始,指向b,拇指的指向就是a×b的方向,垂直于a和b所在的平面;(大拇指朝上为正)
在这里插入图片描述

向量的极角

在这里插入图片描述
求α
tan α=y/x
这里的极角范围是[-π, π)

double Polar_angle(int x,int y)
{return atan2(y,x);
}

旋转一个向量

利用极坐标
在这里插入图片描述
在这里插入图片描述

point rotate(double alpha)
{return point(x * cos(alpha) - y * sin(alpha),x * sim(alpha) + y * cos(alpha));
}

求三角形面积

此处为有向面积

double trianglearea(Point a,Point b,Point c)
{return cross(b-a,c-a)/2;
}

直线交点

Point getline(Point p,Vector v,Point q,Vector w)
{Vector u=p-q;double t=cross(w,u)/cross(v,w);return p+v*t;
}

有正负性质
在这里插入图片描述
在这里插入图片描述

点到直线距离

double distancetoline(Point p,point a,Point b)
{Vector v1=b-a,v2=p-a;return fabs(cross(v1,v2))/length(v1);
}

在这里插入图片描述

点在直线上的投影

double getlineprojection(Point p,Point a,Point b)
{Vector v=b-a;return a+v*(dot(v,p-a)/dot(v,v));
}

dot(v,v):ab的模长
dot(v,p-a):ab的模长 * ap的模长
在这里插入图片描述

判断两条线段是否相交

bool segement(Point a1,Point a2,Point b1,Point b2)
{double c1=cross(a2-a1,b1-a1);double c2=cross(a2-a1,b2-b1);double c3=cross(b2-b1,a1-b1);double c4=cross(b2-b1,a2-b1);return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;
}

返回是否等号
相当于判断b1和b2是否在线段a1a2的两侧
在这里插入图片描述

点与直线的位置关系

点是否在直线左侧

利用叉积的性质

bool onleft(Line l,Point p)
{return cross(l.v,p-l.p)>0;
}

点p是否在直线l的左侧
大于 0说明点在线段的左侧

点是否在直线上

bool on_line(Line l,Point p)
{return fabs(cross(l.v,p-l.p))<eps;
}

点是否在线段上

bool on_seg(Point a,Point b,Point p)
{bool flag1=fabs((p-a),(b-a))<eps;//AB与PA的叉积=0 bool flag2=dot(p-a,p-b)<-eps;//PA与PB的点积<0 return flag1&flag2;
}

点与多边形的位置关系

判断点与多边形的内部,外部或者边上(不一定为凸多边形)
判断点在边哪一侧(适用于凸多边形)
在这里插入图片描述

扫描法:

从给定点水平向右放出射线,根据射线与多边形交点个数的奇偶性来判断
考虑特殊情况:射线与顶点相交或与边重合
解决方法:水平边不考虑,顶点只考虑在对应边上较高或较低的点

转角法

求出从一固定点沿某一方向每次连接多边形上相邻两点所成有向角之和
若该点在多边形内,角度和为360度,在多边形外则为0度

利用叉积来求角度(带方向)在这里插入图片描述
在这里插入图片描述

线段与多边形位置关系

先判断线段的两个端点
若线段与某条边严格相交,则必然不在多边形内

若线段与若干顶点相交,则需要考虑相邻交点连成的线段是否在多边形内
在这里插入图片描述

多边形的面积

与转角法类似,只需要每次所形成的三角形的有向面积累加即可
在这里插入图片描述

double area(Vector<Point>poly)
{double sum=cross(poly[0],poly[poly.size()-1]);for(int i=1;i<poly.size();i++)sum+=cross(poly[i],poly[i-1]);return sum/2;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318486.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.net core i上 K8S(四).netcore程序的pod管理,重启策略与健康检查

目录1.pod管理2.重启策略3.健康检查4.进入容器正文上一章我们已经通过yaml文件将.netcore程序跑起来了&#xff0c;但还有一下细节问题可以分享给大家。1.pod管理1.1创建podkubectl create -f netcore-pod.yaml我们创建一个netcore-pod.yaml文件&#xff0c;内容如下&#xff1…

洛谷P2680:运输计划(倍增、二分、树上差分)

传送门 文章目录题目描述解析问题代码题目描述 解析 求最大值的最小值 容易想到二分 然后。。。就没有然后了。。。 看了题解 学会了一个新技能&#xff1a;树上差分 &#xff08;其实学长之前好像讲过。。。&#xff09; 一般的&#xff0c;对于一条A到B的路径&#xff0c;如…

计算几何基础-2

文章目录直线&#xff1a;图形&#xff1a;求垂足求两圆交点直线与圆交点多边形问题判断一个点是否在任意多边形内部Pick定理凸包求点集的凸包水平法&#xff1a;增量法&#xff1a;半平面半平面交求半平面交直线&#xff1a; struct Line{point p,v;Line(){}Line(point _p.po…

eShopOnContainers 看微服务 ②:配置 启动

一、什么是dockerDocker 是一个开源项目&#xff0c;通过把应用程序打包为可移植的、自给自足的容器&#xff08;可以运行在云端或本地&#xff09;的方式&#xff0c;实现应用程序的自动化部署。使用 Docker 的时候&#xff0c;需要创建一个应用或服务&#xff0c;然后把它和它…

判断整除(opj)(动态规划)

解析 与取模结合的动归&#xff0c;正常做即可 问题 眼瞎&#xff01;&#xff01;&#xff01; 这个序列的每个数都必须用到&#xff01;&#xff01;&#xff01; if(f[i-1][j]) f[i][j]1;上面这行就是不对的&#xff01;&#xff01;&#xff01; 头疼 仔细审题 opj的题…

[USACO09FEB]Revamping Trails G

题意&#xff1a; 约翰一共有 N 个牧场.由 MM 条布满尘埃的小径连接。小径可以双向通行。每天早上约翰从牧场 1 出发到牧场 N 去给奶牛检查身体。 通过每条小径都需要消耗一定的时间。约翰打算升级其中 K 条小径&#xff0c;使之成为高速公路。在高速公路上的通行几乎是瞬间完…

NET Core微服务之路:自己动手实现Rpc服务框架,基于DotEasy.Rpc服务框架的介绍和集成...

本篇内容属于非实用性&#xff08;拿来即用&#xff09;介绍&#xff0c;如对框架设计没兴趣的朋友&#xff0c;请略过。 快一个月没有写博文了&#xff0c;最近忙着两件事;一&#xff1a;阅读刘墉先生的《说话的魅力》&#xff0c;以一种微妙的&#xff0c;你我大家都会经常遇…

花店橱窗布置(洛谷P1854)(动态规划)

传送门 文章目录解析问题代码解析 一道很正常的动态规划 dp[i][j]表示到第j个花瓶放了第j朵花的dp最优值 注意&#xff1a;是严格使第i朵放在j瓶 找到最优解递归输出即可 问题 又是初始化的问题&#xff01;&#xff01;&#xff01; 一开始把dp赋值成负无穷时落掉了j0的一行…

P4009 汽车加油行驶问题

题目描述&#xff1a; 题解&#xff1a; 看了很多题解&#xff0c;无论什么解法都绕不开分层图 在本题中加满油的车每次可以移动K步&#xff0c;那么我们就可以建立一个K1层的分层图&#xff0c;表示汽车油量k的状态&#xff08;油量0…k&#xff09;&#xff0c;然后根据题目…

.net core i上 K8S(五).netcore程序的hostip模式

正文上一章讲了pod的管理&#xff0c;今天再分享一个pod的访问方式1.Pod的HostIP模式Pod的HostIP模式&#xff0c;可以通过宿主机访问pod内的服务&#xff0c;创建yaml文件如下apiVersion: v1 kind: Pod metadata: name: netcore-podlabels:app: netcorepod spec:containers: …

状态压缩:枚举子集(最优组队)(ybtoj)(动态规划)

解析 很裸的状压dp 但是直接暴力的话状态2n,枚举2n 乘在一起会T诶 怎么办呢&#xff1f; 使用下面这个循环&#xff0c;就可以保证只会枚举当前状态s的子集 for(int i(s-1)&s;i;i(i-1)&s){........ }证明 举举例子就挺明显了 为什么不重不漏呢&#xff1f; 首先i肯…

【活动(深圳)】告别2018之12.22 大湾区.NET Meet 大会 ,同时有网络直播

今年的 Connect(); 主题更加聚焦开发者工具生产力、开源&#xff0c;以及无服务器&#xff08;Serverless&#xff09;云服务。Visual Studio 2019 AI 智能加持的 IntelliCode、实时代码协作共享 Live Share&#xff0c;.NET Core 3.0的预览版本附带了大量更新&#xff0c;旨在…

最短路径(状压dp)(ybtoj)

解析 “bug总有de完的一天” 头疼 暴力写的话本题显然复杂度是假的 有一个很好的思路优化时间复杂度 先用dp[k][i]表示**从第k个关键点到任意i点的最短路 跑k遍 SPFA或迪杰斯特拉 即可 然后转移时可以只考虑关键点 使状态转移数大大降低 细节 头真疼 边界条件&#xff1a; …

P2403 [SDOI2010]所驼门王的宝藏(强连通分量)(拓扑排序)

文章目录题目描述解析代码洛谷传送门题目描述 解析 看题目要求很容易想到强连通分量缩点加拓扑dp 但是问题在于存图 第一感就是和暴力和每个点连边 但那样无论点数和边数都很爆炸 随后我们发现这个图非常稀疏 所以我们可以只连有宝藏的点 然而这样边数会被一行横门这样的数据…

Xamarin.Forms之UserDialogs 重制版本

在 forms 里面&#xff0c;目前使用比较多的弹出组件是 Acr.UserDialogs &#xff0c;但是这个组件有些小问题&#xff0c;比如 loading .hide 会同时把 toast 给一起关掉&#xff0c;android 下的 toast 希望是 安卓原生的toast 样子&#xff0c;而不是 底部弹出一个横条&…

H.Minimum-cost Flow

H.Minimum-cost Flow 题目&#xff1a; 其实就是给出每条边的单位费用&#xff0c;q次查询&#xff0c;每次查询改变所有边的容量&#xff08;所有边容量一样&#xff09;&#xff0c;问最后流出1流量的最小花费是多少&#xff1f; 题解&#xff1a; 暴力做法肯定是每次询问…

eShopOnContainers 看微服务③:Identity Service

引言通常&#xff0c;服务所公开的资源和 API 必须仅限受信任的特定用户和客户端访问。那进行 API 级别信任决策的第一步就是身份认证——确定用户身份是否可靠。在微服务场景中&#xff0c;身份认证通常统一处理。一般有两种实现形式&#xff1a;基于API 网关中心化认证&#…

P2168 [NOI2015] 荷马史诗(哈夫曼编码树)

传送门 文章目录题目描述解析细节代码题目描述 解析 其实就是构造一棵树 另所有带权点都为叶子节点 其代价为权值与深度的乘积 求最小代价及最小代价下的最小深度 可以看成一开始有n棵小树 每次把k棵合并在一起 最后合成一棵大树就行了 每次合并的代价是k棵树的权值和 看到这…

B-Suffix Array

B-Suffix Array 题意&#xff1a; 一个字符串只含有a和b&#xff0c;先给出b数组的构造方式&#xff1a; 对于每个位置i来说&#xff1a; 如果存在一个位置j&#xff0c;使得j<i,且s[j] s[i],则b[i]i-j否则b[i]0 现在对字符串每个后缀都构造B数组&#xff0c;并按照字典…

线段树合并、分裂

基本概念&#xff1a; 如果需要维护许多个大小为 \(10^5\) 级别的多重集&#xff0c;可以看做给每一个多重集建立一棵线段树。线段树的合并、分裂就是多重集的累加、分开。 这里使用动态开点的方式存储线段树树。 如果一个节点为空&#xff0c;那么它的编号为 \(0\) 。 变量释义…