天天看点

平面几何基本知识——学习笔记(2)

7.向量的旋转

向量可以绕起点旋转,如果向量(x,y)逆时针旋转a(a用弧制度表示),公式:

x0=xcosa-ysina

y0=xsina+ycosa

代码:

data Rotate(data x,double rad)
{
    return data(x.x*cos(rad)-x.y*sin(rad),x.x*sin(rad)+x.y*cos(rad));
}
           

8.点在直线上的投影点

在平面几何基本知识——学习笔记(1)中曾经说过关于点到线段的距离时提到过一个点q,但实际上这个点是有专名的,叫点在直线上的投影点,怎么说呢,投影点与直线外的点的连线的直线,刚好与原直线互相垂直。

平面几何基本知识——学习笔记(2)

给个例子,一切都明朗了,点Q就是点P关于直线AB所对应的投影点。

尽管在求点到直线(线段)距离中巧妙的避开了这个坑,但是某些作死题就是不放弃。所以为了求出点Q,要先把AB用参数方程A+tv表示,然后如果Q的参数为t0,那必有Q=A+t0*v,由于PQ垂直于AB,所以利用点积=向量A的长度向量B的长度两个向量的夹角的cos值,cos90度=0,所以PQ和AB的点积等于0。即:

dot(v,P-(A+t0v))=0

然而根据蓝书上的指引,点积竟然还满足分配率!!!拆开来:

dot(v,P-A)-t0*dot(v,v)=0

问题就成解有关t0的方程了,求出之后套参数方程即可求出投影点。

data getLm(data A,data B,data P)
{
    data v=B-A;
    return A+v*(dot(v,P-A)/dot(v,v));
}
           

9.凸多边形

凸多边形在数学上早已定义过,所以这里只讲如何判定,是zzkksunboy神犇教我的,主动加粗手动膜拜。Orz Matchperson。

用点积可以判断两个向量的夹角终边的位置,如果点积为正,夹角的终边在一,四象限,反之在二,三象限。那么由于在非凸多边形中至少有一个角大于π,所以非凸多边形的相邻两条边对应的向量的点积一定是负的,如果全程都没有点积是负的,那么这个多边形就是凸多边形。

//有的题目需要根据给出的点顺时针逆时针分别判断
bool check_Tu()
{
    bool f=true;
    for (int i=;i<=n;i++)
      if (fcmp(cross(a[i%n+]-a[i],a[(i-+n)%n+]-a[i]),)<) {f=false; break;}
    if (f) return true;
    for (int i=;i<=n;i++)
      if (fcmp(cross(a[(i+n-)%n+]-a[i],a[i%n+]-a[i]),)<) return false;
    return true;
}
           

10.求多边形面积

如果是个凸多边形,可以从某一个顶点出发,把凸多边形分成n-2个三角形,然后累加面积。

平面几何基本知识——学习笔记(2)

但是面对于非凸多边形,……或许有人已经发现,因为叉积是有正负的,事实上,因为三角形面积是有向的,在外面的部分可以正负抵消掉,所以这个方法可以推广到所有多边形。

还有一点建议,可以选择一个多边形上节点来划分顶点,可以减少计算量^_^

还有,点要按顺序求……不然下场很惨……

double getDS()
{
    double tem=;
    for (int i=;i<n;i++)
      tem+=cross(p[i]-p[],p[i+]-p[]);
    return tem/;
}
           

继续阅读