一、几何

常考却不怎么掌握的:
​
数据结构:分块
​
字符串:后缀数组、后缀自动机
​
数学:FFT、DFT、NTT、杜教筛、拉格朗日插值等
​
图论:网络流、最小费用最大流
​
动规:五边形数优化dp

1、判断一个点在一条直线的左侧还是右侧 叉乘方向法

向量的叉积,p1,p2,p3三个点,判断p3在p1p2向量的左边还是右边,左右跟向量的方向有关,如果是p1p2的方向,那么就是对|p1,p2,p3|进行叉积计算,根据右手法则,如果计算的答案大于0,就是左侧,小于0就是右侧,等于0就是在直线上。

2、判断一个点是否在矩形内 叉乘同向法

3、判断点是否在三角形内

假设点P位于三角形内,会有这样一个规律,当我们沿着ABCA的方向在三条边上行走时,你会发现点P始终位于边AB,BC和CA的右侧。我们就利用这一点。

但是如何判断一个点在线段的左侧还是右侧呢?我们可以从另一个角度来思考,当选定线段AB时,点C位于AB的右侧,同理选定BC时,点A位于BC的右侧,最后选定CA时,点B位于CA的右侧,所以当选择某一条边时,我们只需验证点P与该边所对的点在同一侧即可。

问题又来了,如何判断两个点在某条线段的同一侧呢?可以通过叉积来实现,连接AP,将AP和AB做叉积,再将AC和AB做叉积,如果两个叉积的结果方向一致,那么两个点p、c 在同一侧,同理另外两条边一样的计算方案。

判断两个向量的是否同向可以用点积实现,如果点积大于0,则两向量夹角是锐角,否则是钝角。

*注释:*为什么叉乘就可以判断方向性,因为叉乘是满足反交换律的,e= a x b = -b x a, 满足右手定则(按夹角为锐角,顺时针),顺时针由a到b,大拇指的方向就是e的方向,AP x AB 与 AC x AB 叉乘的结果是同向的,方向都是垂直三角形ABC这个平面朝上的,而AQ x AB 则是方向朝下,所以q和c不在同一侧;根据此原理就能判断一个点是否在一个三角形中。

二、计算几何基础整合(point类)

参考来自:博客

1、首先定义Point类

const double eps=1e-8;
​
int dcmp(double x) {return fabs(x)<=eps?0:x>eps?1:-1;}
​
struct Point {double x,y;Point(double x=0,double y=0):x(x),y(y) {}Point operator + (const Point &a) {return Point(x+a.x,y+a.y);}Point operator - (const Point &a) {return Point(a.x-x,a.y-y);} //注意翻转!!Point operator * (double a) {return Point(x*a,y*a);}Point operator / (double a) {return Point(x/a,y/a);}bool operator < (const Point &b) const {return x<b.x||(x==b.x&&y<b.y);}bool operator == (Point b) {return dcmp(x-b.x)==0&&dcmp(y-b.y)==0;}double length() {return sqrt(x*x+y*y);}Point rotate(double rad) {return Point(x*cos(rad)-y*sin(rad),x*sin(rad)+y*cos(rad));} //逆时针Point normal(Point a) {return Point(-a.y/a.length(),a.x/a.length());} //长度归一
};
​
typedef Point Vector; //仅为了写法方便,但意义不同

值得注意的是,在重载减法的时候,为了代码方便将其反过来定义了,这样a−ba−b就表示a→ba→b这个向量。但如果要用到减法时请将它翻转回去。

类中定义了两个操作:

  • 向量旋转

    根据仿射变换,逆时针旋转α度时需要执行:

  • 长度归一 这是方向向量的一种定义方法,向量只有方向没有长度。

2、叉积点积,夹角以及三角形面积

double Cross(const Vector& a,const Vector& b) {return a.x*b.y-b.x*a.y;}
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)/a.length()/b.length());}
double Area(Point a,Point b,Point c) {return Cross(b-a,c-a);}

3、判断p是否在线段上

通过叉积判断面积是否为0,也就是判断是否在直线上。通过点积判断投影是否小于0,也就是判断p到线段端点是否同向。

bool OnSegment(Point st,Point ed,Point p) {return dcmp(Cross(st-p,ed-p))==0&&dcmp(Dot(st-p,ed-p))<0;}

4、判断线段是否相交

bool Segment_Intersection(Point a1,Point a2,Point b1,Point b2) {return dcmp(Cross(a2-a1,b1-a1))*dcmp(Cross(a2-a1,b2-a1))<0&&dcmp(Cross(b2-b1,a1-b1))*dcmp(Cross(b2-b1,a2-b1))<0;}

然后考虑第三种情况,也就是非规范相交,有至少三点共线。 这情况发生时有一个点在其它线段上,判断一下即可。

bool _Segment_Intersection(Point a1,Point a2,Point b1,Point b2) {return Segment_Intersection(a1,a2,b1,b2)||OnSegment(a1,a2,b1)||OnSegment(a1,a2,b2)||OnSegment(a1,b1,b2)||OnSegment(a2,b1,b2);}

5、计算直线交点

Point GetLineIntersection(Point P,Vector v,Point Q,Vector w) {return P+v*(Cross(P-Q,w)/Cross(v,w));}

6、点到直线距离

叉积除以长度即可得到高度。

double DistanceToLine(Point p,Point a,Point b) {Vector v1=b-a,v2=p-a;return fabs(Cross(v1,v2))/v1.length();}

7、点到线段距离

判断下点是否在两个端点的中间,是则是垂直线,否则就是距离端点的距离才是点到线段的距离

double DistanceToSegment(Point p,Point a,Point b) {if(a==b)return (p-a).length();Vector v1=b-a,v2=p-a,v3=p-b;if(dcmp(Dot(v1,v2))<0)return v2.length();else if(dcmp(Dot(v1,v3))>0)return v3.length();else return DistanceToLine(p,a,b);
}

8、多边形面积、叉乘计算面积

#include<bits/stdc++.h>
using namespace std;
const int N=30;
struct Point{double x,y;
}p[N];int n;
double polygonarea()
{int i,j;double area = 0;for(i = 0;i < n;++i){j = (i+1)%n;area += p[i].x*p[j].y;area -= p[i].y*p[j].x;}area /= 2.0;return area;
}
python写法:
class point:def __init__(self, x1, y1):self.x = x1self.y = y1
​
p = []
n = 0
​
def run():global nans = 0for i in range(n):j = (i+1)%nprint(i, " ", j)ans += p[i].x*p[j].yans -= p[i].y*p[j].xreturn ans/2
​
​
n = int(input())
for i in range(n):x, y = map(int, input().split())a = point(x, y)p.append(a)
​
print(run())

计算几何基础知识 叉乘、点乘、点到直线距离、叉积方向法等相关推荐

  1. 二维计算几何基础知识

    1.点积: 向量点积的定义:(x1,y1)*(x2,y2)=x1*x2+y1*y2:满足交换律 向量点积的代数意义:向量V1的模 * 向量V2的模 * cos<V1,V2> 向量点积的几何 ...

  2. 数据处理(一):点到直线距离

    1 点到直线距离计算 import mathdef getDis(pointX,pointY,lineX1,lineY1,lineX2,lineY2):#这里的XY代表要求的点,(x1,y1)(x2, ...

  3. 已知两点求直线一般方程、点到直线距离、点是否在线上方/下方

    struct Point {double x = 0.0;double y = 0.0; }//直线方程 Ax + By + C = 0: Point pt1; Point pt2; double A ...

  4. 数学:SVM(2)点到直线距离

    点到直线距离 点P0:(x0,y0) 直线L0:ax + by + c = 0 即 WTX + b,其中W为列向量<a,b>,X为列向量<x,y> 首先,过点P0必有一条和直线 ...

  5. AcWing 2983. 玩具 / POJ 2318.toys(计算几何基础、二分、判断点和直线的位置关系)

    计算几何基础题 题目大意就是一个盒子被分成了若干个区域,有m个小球,问每个区域里分别有多少个小球. 我们首先考虑暴力. 我们如何判断小球是否在一个区域内呢,我们发现一个小球在区域x,也就是说所有小于x ...

  6. cocos lua 获取点到直线距离

    最近做一款台球游戏,需要做这种效果,所以需要求的彩色球到直线的距离,高中数学几乎快忘光了. Google了一波,挖出了几个数学公式. 我的手中有这几个数据: 1.直线绕X轴正方向的角度,注意,这里co ...

  7. 点到面距离公式向量法_点到线或面的距离公式

    我们知道高中解析几何或立体几何题中时常需要知道点到线的距离或点到面的距离.下面我们给出这两个公式以及它们的巧妙证明. 点到线的距离 已知直线 的方程为 ,平面上任意一点 到该直线的距离 的公式为: 证 ...

  8. 求两条轨迹间的hausdorff距离_题型 | 圆上有n个点到直线距离为d?

    圆上有n个点到直线的距离为d 圆 上到直线 的距离为 的点有( )个 方法一:常规方法,画图分析 由图象可以明显看出,圆在直线上方的部分内没有满足题意的点,在直线下方的部分内有两个满足题意的点. 但是 ...

  9. java点到直线距离_求取点到直线的距离

    问题描述: 已知点P(px,py),直线L(P1,P2),求点P到L的距离. 首先,推导直线公式: 点$$P_1(x_1,y_1)$$, 点$$P_2(x_2,y_2)$$ 可知直线方程为: $$x( ...

最新文章

  1. 专访趋势科技CEO陈怡桦:病毒行业需要反省
  2. python默认数据类型转换_Python 数据类型转换
  3. 【 C 】转移表(理论与实践)(实现一个简单的计算器)
  4. 分布式的事务该怎么做?
  5. 批量图纸数据抽取及更新的实现(可不打开文件)
  6. java 建表 框架_【Java框架型项目从入门到装逼】第九节 - 数据库建表和CRUD操作...
  7. The Quad - Directory Explorer(一款四窗口的文件资源管理器)
  8. jquery的img的动态title换行
  9. 三问百度云,ABC如何帮它跑赢马拉松?
  10. 使用envi将遥感数据从uint16转为uint8
  11. 道路照明之电缆线路 - 设计笔记
  12. 当电子工程师十余年,感慨万千
  13. 三地检方分别对程颖、谭元生、聂作坤案提起公诉
  14. MySQL之子查询优化
  15. 基于Go语言GoFrame+Layui的OA办公系统
  16. 小程序改变swiper样式(带缩略图)
  17. 2次成功投诉EMS和中国移动的经验
  18. 使用matlab编程给qq或163邮箱等发邮件
  19. 【图像去噪】基于最小二乘方滤波实现图像去噪含Matlab源码
  20. 计算机音乐三生三世,抖音上很火的三生三世是什么歌?

热门文章

  1. Maven配置阿里云镜像仓库地址
  2. Linux进程和任务管理和分析和排查系统故障
  3. 从0开始安装fedora23的笔记-- 以及使用fedora的常规问题
  4. SpringCloud教程二
  5. 集成电路领域核心会议与期刊
  6. BotDetect CAPTCHA 网站验证码生成器
  7. 34. java8新特性
  8. 深度之眼——效率提升3倍的Paper 阅读方法
  9. linux backtrace使用
  10. Samba无法连接问题解决方法