uva 011178 Morley's Theorem 计算几何
2016-08-08 21:46
519 查看
连接:http://acm.hust.edu.cn/vjudge/problem/18543
我们通过一个具体的题目来学习几个计算几何的知识点。
在计算几何中所谓的知识点,其实就是一个又一个的函数,因此在学习过程中要注意积累这些函数,并且要充分理解它们的使用条件,这样在用的时候才能够得心应手。
Ex1:
Morley定理告诉我们,任意三角形的三个角的6条三等分线会交出一个等边三角形记作△DEF,那么现在给出△ABC的三个顶点,请计算D、E、F的坐标.
分析:既然这道题目给出了原理,那么它的难点就主要在于如何取编程实现计算。我们首先来看一下为了求解这三个顶点,我们需要做一些什么,然后各自独立的分析,形成功能独立的函数。
首先,求解三个顶点的过程中是存在对称性,因此我们找到求出一个顶点的方法即可,根据Morley定理,我们需要找到两个角的各自三等分线(靠近公共边的),他们的交点就是正三角形中的一个顶点。
(1):两条三等分怎么找?
考察这里我们有的已知条件:初始向量BC,旋转角度,旋转方向。然后现在我们想要求解旋转后的向量BD,因此这里我们用到向量旋转公式:
(2)旋转角度怎么求?
已知两个向量,求其夹角,用简单的点积就可以实现。
(3)求得两条三等分直线后,如何求交点呢?
需要注意的是,上文求得的所谓的“三等分直线”本质上是向量,而向量是可以平移的,因此我们需要用直线上边的点来限制向量的平移,也就是说,这里我们用向量参数来表示一条直线。
看t1、t2的形式是不是很像克莱姆法则啊,猜对了,其实它就是一个线性方程组的解。
完成了这些准备工作,关于代码实现,也就一目了然了。
简单的参考代码如下:
我们通过一个具体的题目来学习几个计算几何的知识点。
在计算几何中所谓的知识点,其实就是一个又一个的函数,因此在学习过程中要注意积累这些函数,并且要充分理解它们的使用条件,这样在用的时候才能够得心应手。
Ex1:
Morley定理告诉我们,任意三角形的三个角的6条三等分线会交出一个等边三角形记作△DEF,那么现在给出△ABC的三个顶点,请计算D、E、F的坐标.
分析:既然这道题目给出了原理,那么它的难点就主要在于如何取编程实现计算。我们首先来看一下为了求解这三个顶点,我们需要做一些什么,然后各自独立的分析,形成功能独立的函数。
首先,求解三个顶点的过程中是存在对称性,因此我们找到求出一个顶点的方法即可,根据Morley定理,我们需要找到两个角的各自三等分线(靠近公共边的),他们的交点就是正三角形中的一个顶点。
(1):两条三等分怎么找?
考察这里我们有的已知条件:初始向量BC,旋转角度,旋转方向。然后现在我们想要求解旋转后的向量BD,因此这里我们用到向量旋转公式:
(2)旋转角度怎么求?
已知两个向量,求其夹角,用简单的点积就可以实现。
(3)求得两条三等分直线后,如何求交点呢?
需要注意的是,上文求得的所谓的“三等分直线”本质上是向量,而向量是可以平移的,因此我们需要用直线上边的点来限制向量的平移,也就是说,这里我们用向量参数来表示一条直线。
看t1、t2的形式是不是很像克莱姆法则啊,猜对了,其实它就是一个线性方程组的解。
完成了这些准备工作,关于代码实现,也就一目了然了。
简单的参考代码如下:
#include<iostream> #include<stdlib.h> #include<stdio.h> #include<cmath> #include<algorithm> #include<string> #include<string.h> #include<set> #include<queue> #include<stack> #include<vector> #include<functional> #include<map> using namespace std; const int maxn = 200 + 10; const int INF = (int)1e9; struct Point { int x; int y; Point(int x = 0,int y = 0):x(x),y(y){} }; typedef Point Vector; Vector operator + (Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); } Vector operator - (Point A, Point B) { return Vector(A.x - B.y, A.y - B.y); } Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); } Vector operator / (Vector A, double p) { return Vector(A.x / p, A.y*p); } double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }//向量点乘 double Length(Vector A) { return sqrt(Dot(A, A)); } //向量模长 double Angle(Vector A, Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); } //向量之间夹角 double Cross(Vector A, Vector B) { //叉积计算 公式 return A.x*B.y - A.y*B.x; } Vector Rotate(Vector A, double rad)//向量旋转 公式 { return Vector(A.x*cos(rad) - A.y*sin(rad), A.x*sin(rad) + A.y*cos(rad)); } Point getLineIntersection(Point P, Vector v, Point Q, Vector w)//两直线交点t1 t2计算 公式 { Vector u = P - Q; double t = Cross(w, u) / Cross(v, w); //求得是横坐标 return P + v*t; //返回一个点 } Point getD(Point A, Point B, Point C) { Vector v1 = C - B; double a1 = Angle(A - B, v1); v1 = Rotate(v1, a1 / 3);//在B点旋转后的向量 Vector v2 = B - C; double a2 = Angle(A - C, v2); v2 = Rotate(v2, -a2 / 3);//在C点旋转后的向量 注意符号 return getLineIntersection(B, v1, C, v2);//返回交点 } int main() { int T; Point A, B, C, D, E, F; scanf("%d", &T); while (T--) { scanf("%lf %lf %lf %lf %lf %lf", &A.x, &A.y, &B.x, &B.y, &C.x, &C.y); D = getD(A, B, C);//注意顺序 E = getD(B, C, A); F = getD(C, A, B); printf("%.6lf %.6lf %.6lf %.6lf %.6lf %.6lf", D.x, D.y, E.x, E.y, F.x, F.y); } //system("pause"); return 0; }
相关文章推荐
- uva 11178 Morley's Theorem(计算几何-点和直线)
- UVA 11178 Morley’s Theorem(计算几何直线的交点)
- UVA-11178 - Morley's Theorem(计算几何)
- UVA 11178 - Morley's Theorem(计算几何)
- uva 11178 Morley's Theorem(计算几何-点和直线)
- uva 11178 Morley's Theorem 计算几何
- 【UVa 11178】Morley's Theorem (计算几何)
- UVA - 11178 - Morley's Theorem (计算几何~~)
- uva_11178 Morley's Theorem(计算几何)
- UVA 11178 Morley’s Theorem(二维计算几何基础)
- UVA 11178-Morley's Theorem(计算几何_莫雷定理)
- uva 11178 morley定理(计算几何基础)
- UVA 11178 Morley's Theorem(几何)
- uva 11178 Morley's Theorem(计算几何-点和直线)
- Uva 11178 Morley's Theorem (几何+模拟)
- UVa 11178 Morley's Theorem(几何)
- Morley's Theorem 计算几何
- uva 11178 - Morley's Theorem(几何)
- UVA 11178 Morley's Theorem(二维几何基础)
- UVA 11178 Morley's Theorem (计算几何)