学习笔记——计算几何

前言

高中数学必修二内容,基本理论见 oiwiki

向量及其基本运算

先上代码:

struct Node{
    double x,y;Node(){}
    Node(double _x,double _y){x=_x;y=_y;}
    void input(){scanf("%lf%lf",&x,&y);}
    Node friend operator+(Node a,Node b){return Node(a.x+b.x,a.y+b.y);
    Node friend operator-(Node a,Node b){return Node(a.x-b.x,a.y-b.y);}
    double friend operator*(Node a,Node b){return a.x*b.x+a.y*b.y;}//点积
    double friend operator^(Node a,Node b){return a.x*b.y-b.x-a.y;}//叉积
    void rot(double a){
        double x1=x*cos(a)-y*sin(a);
        double y1=y*cos(a)+x*sin(a);
        x=x1;y=y1;
    }
};

定义一个向量

根据向量的坐标表示,可以用 \((x,y)\) 来表示一个向量。

struct Node{
    double x,y;Node(){}
    Node(double _x,double _y){x=_x;y=_y;}
    void input(){scanf("%lf%lf",&x,&y);}
};

向量加减

由于我们用坐标表示一个向量,那么两个向量相加减实际上就是对应坐标的加减。

Node friend operator+(Node a,Node b){
    return Node(a.x+b.x,a.y+b.y);
}
Node friend operator-(Node a,Node b){
    return Node(a.x-b.x,a.y-b.y);
}

向量点积

我们都知道 \(\vec{a}\cdot\vec{b}=|\vec{a}||\vec{b}|\cos\theta\)。其中 \(|\vec{a}|=\sqrt{x_a^2+y_a^2}\),\(|\vec{b}|=\sqrt{x_b^2+y_b^2}\),然后根据余弦定理:\(d_{AB}^2=|\vec{a}|^2+|\vec{b}|^2-2|\vec{a}||\vec{b}|\cos\theta=(x_a-x_b)^2+(y_a-y_b)^2\),可以得到:\(-2|\vec{a}||\vec{b}|\cos\theta=-2x_ax_b-2y_ay_b\) 即 \(|\vec{a}||\vec{b}|\cos\theta=x_ax_b+y_ay_b\)。

所以 \(\vec{a}\cdot\vec{b}=x_ax_b+y_ay_b\)。

double friend operator*(Node a,Node b){
    return a.x*b.x+a.y*b.y;
}

向量叉积

我们都知道 \(|\vec{a}\times\vec{b}|=|\vec{a}||\vec{b}|\sin\theta\)。

我们都知道叉积有几何意义就是两条向量围成的三角形面积的两倍。

学习笔记——计算几何

看张图,可以发现所谓三角形面积的两倍就是图中黄色的面积。而黄色的面积就是 \(x_by_a-x_ay_b\),由于 \(\vec{a}\times\vec{b}\) 的结果根据右手螺旋定则是负的,所以叉积的表达式就是 \(|\vec{a}\times\vec{b}|=x_ay_b-x_by_a\)。

叉积的用处还是非常多的。

double friend operator^(Node a,Node b){
    return a.x*b.y-b.x-a.y;
}

向量旋转

嫖一张图:

学习笔记——计算几何

展开得:

\[\vec{b}=(l(\cos\theta\cos\alpha-\sin\theta\sin\alpha),l(\sin\theta\cos\alpha+\cos\theta\sin\alpha)) \]

\[=(l\cos\theta\cos\alpha-l\sin\theta\sin\alpha,l\sin\theta\cos\alpha+l\cos\theta\sin\alpha) \]

\[=(x\cos\alpha-y\sin\alpha,y\cos\alpha+x\sin\alpha) \]

void rot(double a){
    double x1=x*cos(a)-y*sin(a);
    double y1=y*cos(a)+x*sin(a);
    x=x1;y=y1;
}

直线及定义

先上代码:

struct Line{
    Node s,e;Line(){}
    Line(Node _s,Node _e){s=_s;e=_e}
    
}
上一篇:线段树学习笔记


下一篇:积分小练习