计算几何总结1———点与向量


提示:这里用到的数据类型都为double,可根据具体情况更改

点与向量

1.点之间的距离

  • 二维平面的点用坐标(x,y)表示
struct Point{
	double x,y;
	Point(){}
	Point(double x,double y):x(x),y(y){}
};
  • 两点间的距离

1.用库函数hypot()计算三角形的斜边长

double Distance(Point A,Point B){return hypot(A.x-B.x,A.y-B.y);}

2.直接两点间的距离公式

总结

struct Point{
	double x,y;
	Point(){}
	Point(double x,double y):x(x),y(y){}
	double Distance(Point A,Point B){return hypot(A.x-B.x,A.y-B.y);}
};

2.向量的运算(加,减,乘,除)和判等

我们把向量也用点表示,但需注意,向量可以平移

typedef Point Vector;

两个点确定一个向量

Point (Point A,Point B){return Point(A.x-B.x,A.y-B.y);}

向量运算需要对运算符进行重载

  • 加法
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);}
  • 判等
    判等涉及到运算的精度,所以需要先定义浮点数的判等函数
const doube eps=1e-8;    //偏差值,有时用1e-10
int sgn(double x)		//判断x是否等于0:0为等于,1为大于,-1为小于
{
if(abs(x)<eps)
	return 0;
else
	return x<0?-1:1;
}
int dcmp(double x,double y)	//判断x是否等于y:0为等于,1为大于,-1为小于
{
if(abs(x-y)<eps)
	return 0;
else
	return x<y?-1:1;
}

所以向量的判等可以调用上面的sgn()函数dcmp()函数

bool operator ==(Point B){return sgn(x-B.x)==0&&sgn(y-B.y)==0;}

总结

typedef Point Vector
struct Point{
	double x,y;
	Point(){}
	Point (Point A,Point B){return Point(A.x-B.x,A.y-B.y);}
	Point(double x,double y):x(x),y(y){}
	const doube eps=1e-8;    //偏差值,有时用1e-10
	int sgn(double x)		//判断x是否等于0:0为等于,1为大于,-1为小于
	{
	if(abs(x)<eps)
		return 0;
	else
		return x<0?-1:1;
	}
	int dcmp(double x,double y)	//判断x是否等于y:0为等于,1为大于,-1为小于
	{
	if(abs(x-y)<eps)
		return 0;
	else
		return x<y?-1:1;
}
	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)==0&&sgn(y-B.y)==0;}
};

3.点积和叉积

  1. 点积
    数学公式: A ⋅ B = ∣ A ∣ ∣ B ∣ cos ⁡ θ = A . x ⋅ B . x + A . y ⋅ B . y \mathbf{A·B} =\left | A \right | \left | B \right | \cos \theta =A.x\cdot B.x+A.y\cdot B.y AB=ABcosθ=A.xB.x+A.yB.y
    代码如下:
double Dot(Vector A,Vector B){return A.x*B.x+A.y*B.y};

点积的正负可判断向量的夹角是锐角还是钝角
点积为0代表向量垂直
2. 叉积
数学公式: A × B = ∣ A ∣ ∣ B ∣ sin ⁡ θ = A . x ⋅ B . y − A . y ⋅ B . x \mathbf{A} \times \mathbf{B}=\left | A \right | \left | B \right | \sin \theta =A.x\cdot B.y-A.y\cdot B.x A×B=ABsinθ=A.xB.yA.yB.x
代码如下:

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

AB逆时针叉乘为正数,反之为负数
如果叉积为0,则向量共线,可能同向,也可能反向

4.叉积的应用

  1. 计算三角形面积
    我们知道,三角形的面积公式可表示为S=1/2absinC
    a×b=|a||b|sinC
    所以S=1/2(a×b)
  2. 计算多边形的面积(三角形面积推广)

在这里插入图片描述

如图,图中多边形ABCDEF的面积刚好为蓝色边和多边形的边围成的三角形的面积减去红色边和多边形的边围成的三角形的面积,设以O为起点,以点A,B,C,D
,E,F为终点的向量为a,b,c,d,e,f,所以四边形面积S=(a×b+b×c+c×d+d×e+e×f+
f×a)/2.
细想,因为是逆时针遍历每一个点,所以红色三角形的面积正好是负的,最终只需把每个叉积相加再除以二就行,下面看代码:

//假设有有n个点且恰好是逆时针给出
Point p[n];
Vector V[n+1];   //声明n+1个变量,因为我们需要完成一个循环
double S=0;  //面积
for (int i=0;i<n;i++)
{
	V[i].x=p[i].x;
	V[i].y=p[i].y;		//算出每个向量
}
V[n].x=p[0].x,V[n].y=p[0].y;
for (int i=0;i<=n;i++)
{
	S+=V[i].Cross(V[i+1]);
}
  1. 判断两个向量是否平行
    叉积为0代表向量平行
bool Parallel(Vector A,Vector B){return sgn(Cross(A,B))==0;}
  1. 向量旋转
    假如我们需要将向量(x,y)旋转θ度,则数学关系表达式为:
    x’=xcosθ-ysinθ
    y’=xsinθ+ycosθ
Vector Rotate(Vector A,double rad){
	return Vector (A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+y*cos(rad));
}

持续更新。。。。。。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值