首页 > 其他分享 >计算几何笔记(一):点与向量

计算几何笔记(一):点与向量

时间:2023-01-21 10:11:07浏览次数:32  
标签:return Point double 笔记 times Vector 几何 向量

开始之前

圆周率
const pi = acos(-1);
浮点数的比较

对实数进行浮点运算难免会出现精度误差

为了控制精度,可以设置一个偏差值\(eps\)

const double eps = 1e-5;
int sgn(double x)
{
    if (fabs(x) < eps) return 0;
    return x < 0 ? -1 : 1;
}

int dcmp(double x, double y)
{
    if (fabs(x - y) < eps) return 0;
    return x < y ? -1 : 1;
}

点的表示

二维下点用\((x, y)\)表示

struct Point
{
    double x, y;
    Point(){};
    Point(double x, double y):x(x), y(y){}
};
点与点之间的距离
  • 使用库函数\(hypot()\)
double Dis1(Point A, Point B)
{
    return hypot(A.x - B.x, A.y - B.y);
}
  • 使用\(sqrt()\)
double Dis2(Point A, Point B)
{
    return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
}

向量

向量的表示

有大小和方向的量称为向量(矢量),向量用平面上两个点——起点\(P1\)和终点\(P2\)表示

向量只是一个量而不是线段,因此可以随意的移动,为了方便可以把向量的起点移动到原点,这样向量可用一条由原点到一点\((x, y)\)的有向线段表示

向量在表示上与点的表示相同

typedef Point Vector;
向量的运算
  • 加减乘除
Point operator + (Point B) {return Point(x + B.x, y + B.y);}
Point operator - (Point B) {return Point(x - B.x, y - B.y);}
Point operator * (double k) {return Point(x * k, y * k);}
Point operator / (double k) {return Point(x / k, y / k);}
  • 等于
bool operator == (Point B) {return !sgn(x - B.x) && !sgn(y - B.y);}
点乘
  • 定义

向量\(A\)和\(B\)的点乘\(A \cdot B = |A||B|cos \theta\),\(\theta\)为\(A\)、\(B\)之间的夹角

点乘的几何意义是求\(A\)在\(B\)上的投影长度乘以\(B\)的模长

若已知\(A(A.x, A.y)\),\(B(B.x, B.y)\),有\(A \cdot B = A.x \times B.x + A.y \times B.y\)

double Dot(Vector A, Vector B) {return A.x * B.x + A.y * B.y;}
  • 判断夹角

可根据点乘的正负判断夹角是锐角,直角,还是钝角:

若\(A \cdot B > 0\)且\(A \cdot B \neq 1\),\(A\)、\(B\)之间的夹角为锐角;

若\(A \cdot B < 0\)且\(A \cdot B \neq -1\)\(,\)A\(、\)B$之间的夹角为钝角;

若\(A \cdot B = 0\),\(A\)、\(B\)之间的夹角为直角;

若\(A \cdot B = 1\),\(A\)、\(B\)方向相同;

若\(A \cdot B = -1\),\(A\)、\(B\)方向相反

  • 求向量的长度
double Len(Vector A) {return sqrt(Dot(A, A));}	// 长度
double Len2(Vector A) {return Dot(A, A);}	// 长度的平方
  • 求夹角
double Angle(Vector A, Vector B) {return acos(Dot(A, B) / Len(A) / Len(B));}
叉乘
  • 定义

向量\(A\)和\(B\)的叉乘\(A \times B = |A||B|sin \theta\),\(\theta\)为向量\(A\)旋转到向量\(B\)所经过的夹角

叉乘的几何意义是向量\(A\)与向量\(B\)形成的平行四边形的有向面积

若已知\(A(A.x, A.y)\),\(B(B.x, B.y)\),有\(A \times B = A.x \times B.y - A.y \times B.x\)

double Cross(Vector A, Vector B) {return A.x * B.y - A.y * B.x;}

注意叉乘有正负,\(A \times B\) 与 \(B \times A\)相反

  • 判断向量A,B的方向关系

可根据叉乘的正负判断\(B\)在\(A\)的什么方向:

若\(A \times B > 0\),\(B\)在\(A\)的逆时针方向;

若\(A \times B < 0\),\(B\)在\(A\)的顺时针方向;

若\(A \times B = 0\),\(A\)与\(B\)共线,可能方向相同,可能方向相反

  • 计算平行四边形面积

三个点\(A\)、\(B\)、\(C\),可求以\(A\)为公共点得到的两个向量\(B - A\)、\(C - A\)构成的平行四边形面积

double Area2(Point A, Point B, Point C) {return fabs(Cross(B - A, C - A));}
  • 计算三角形面积

可求由三个点\(A\)、\(B\)、\(C\)构成的\(\Delta ABC\)的面积

double Area(Point A, Point B, Point C) {return Area2(A, B, C) / 2;}
  • 判断向量是否共线
bool Parallel(Vector A, Vector B) {return !sgn(Cross(A, B));}
向量旋转

使向量\(A(x, y)\)绕起点逆时针旋转\(\theta\),旋转后的向量为\(A^{'}(x^{'}, y^{'})\)

\(x^{'} = xcos\theta - ysin\theta\),\(y^{'} = xsin\theta + ycos\theta\)

Vector Rotate(Vector A, double rad) {return Vector(A.x * cos(rad) - A.y * sin(rad), A.x * sin(rad) + A.y * cos(rad));}
  • 求单位法向量

可以用\(Rotate()\)求

Vector Normal1(Vector A) {return Rotate(A, pi / 2) / Len(A);}

由于旋转\(90^\circ\)很特殊,也可以直接写

Vector Normal2(Vector A) {return Vector(-A.y / Len(A), A.x / Len(A));}

标签:return,Point,double,笔记,times,Vector,几何,向量
From: https://www.cnblogs.com/Panmaru/p/17063634.html

相关文章

  • fabric学习笔记10
    fabric学习笔记1020201303张奕博2023.1.22测试实践1.启动网络命令:cdfabric-samples/chaincode-docker-devmode/docker-compose-fdocker-compose-simple.......
  • 读函数式编程思维笔记02_转变思维
    1. 命令式编程1.1. 按照“程序是一系列改变状态的命令”来建模的一种编程风格1.2. 传统的for循环1.2.1. 确立初始状态1.2.2. 每次迭代都执行循环体中的一系列命......
  • Foundations of Embedded IoT Systems 复习笔记 南安
    Communicationshub,border-routerorGatewaylinkslowpowerhardwaretotheoutsideworldNetworkWifi/EthernetLowPowerWideAreaNetworksLowpowerIPv6n......
  • ZYNQ学习笔记 程序固化
    ZYNQ程序的固化PS:本次实验基于zynq7010芯片,开发软件为vivado2018.3。​ zynq7010和其他的fpga板一样,日常我们开发时使用的JTAG调试下载进去的二进制文件断电后会丢失的......
  • 舞蹈链 (DLX, Dancing Links X) 算法笔记
    舞蹈链(DLX,DancingLinksX)算法精确覆盖问题在一个全集X中若干子集的集合为S,S的子集S*,满足X中的每一个元素在S*中恰好出现一次。通俗地讲,给定一个\(N\)行\(M\)......
  • 【python】Matplotlib库学习笔记
    Matplotlib是python的绘图库。以下内容主要介绍Matplotlib的子库pyplot。pyplot是常用的2D绘图模块,包含一系列绘图相关函数。plot()函数plot()函数可以用来绘制......
  • IoT Network PHY 复习笔记 南安
    Sampling抽样Aliasing混叠Quantisation量化measurediscreteamplitudeinbits.Realsystemshavelimitedresourceintermsofthenumberofavailablebi......
  • 人工智能课程的复习笔记
    人工智能极大极小的算法实现的伪代码(9条消息)最清晰易懂的MinMax算法和Alpha-Beta剪枝详解Bug_Programmer的博客-CSDN博客minmax算法三个`加上Java,再敲一下空格就是代......
  • 【ABAQUS 二次开发笔记】使用keyword 、python和matlab一起处理Odb数据
    用conversionshellelement(S4R单元)建模层合板,有6层ply,每个lamina(ply)有3个integrationpoint,共计18个integrationpoint。我想得到集合SET-Middle-elem中所有integrati......
  • JDBC学习笔记
    1.JDBC的基本概念  1.1 JDBC是什么   JDBC(JavaDataBaseConnectivityJava数据库连接),可以理解为是一种用于执行SQL语句的API。  1.2JDBC的本质  ......