【第一道計算幾何題】 UVA11178 Morley‘s Theorem (二維幾何,旋轉直線求求交點)

繁凡さん發表於2020-09-27

在這裡插入圖片描述
在這裡插入圖片描述

要求D點我們只需要把直線BC向左旋轉a/3,向右旋轉b/3得到兩直線求交點即可。
秒啊秒啊
解鎖技能樹——計算幾何,終於能加一個計算幾何版塊了

#include<bits/stdc++.h>

using namespace std;

const int N = 5007, M = 50007, INF = 0x3f3f3f3f;
const double DINF = 12345678910, eps = 1e-10;
struct Point{
    double x, y;
    Point(double x = 0, double 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);}
//!點 - 點 = 向量(向量BC = C - B)
Vector operator - (Point A, Point B){return Vector(A.x - B.x, 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);}
//!點/向量的比較函式
bool operator < (const Point& a, Point& b) {return a.x < b.x || (a.x == b.x && a.y < b. y);}
//!三態函式dcmp用於判斷相等,減少精度問題
int dcmp(double x){
    if(fabs(x) < eps) return 0;
    else return x < 0 ? -1 : 1;
}
bool operator == (const Point& a, const Point& b){return !dcmp(a.x - b.x) && !dcmp(a.y - b.y);}
//!求極角
//單位弧度rad
double Polar_angle(Vector A){return atan2(A.y, A.x);}
//!點積(滿足交換律)
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));}
//!向量的叉積(不滿足交換律)
//等於兩向量有向面積的二倍(從v的方向看,w左,叉積>0,w右,叉積<0,共線,叉積=0)
//cross(x, y) = -cross(y, x)
//cross(x, y) : xAyB - xByA
double Cross(Vector A, Vector B){return A.x *  B.y - B.x * A.y;}
//!三個點確定兩個向量,(交點為A的兩個向量AB和AC)然後求這兩個向量的叉積(叉乘)
double Area2(Point A, Point B, Point C){return Cross(B - A, C - A);}
//!一個向量旋轉rad弧度之後的新向量
//!x' = xcosa - ysina, y' = xsina + ycosa
//rad:弧度
Vector Rotate(Vector A, double rad){
    return Vector(A.x * cos(rad) - A.y * sin(rad), A.x * sin(rad) + A.y * cos(rad));
}
//!向量的單位法線
//實際上就是將該向量向左旋轉90°
//因為是單位法線所以長度歸一化
//呼叫前請確保A不是零向量
Vector Normal(Vector A){
    double L = Length(A);
    return Vector(-A.y / L, A.x / L);
}

Point Get_line_intersection(Point P,Vector v,Point Q,Vector w)//相交
{
	Vector u = P - Q;
	double t = Cross(w, u) / Cross(v, w);
	return P + v * t;
}

//妙啊妙啊

int t;
Point A, B, C, D, E, F;

Point read_point()
{
    int x, y;
    scanf("%d %d", &x, &y);
    return Point(x, y);
}

Point get_point(Point A, Point B, Point C)
{
    Vector v1, v2;
    Vector v_BC = C - B;//BC
    Vector v_BA = A - B;//BA
    double a_ABC = Angle(v_BA, v_BC);//逆時針轉a / 3
    v1 = Rotate(v_BC, a_ABC / 3);

    Vector v_CB = B - C;//CB
    Vector v_CA = A - C;//CA
    double a_ACB = Angle(v_CA, v_CB);
    v2 = Rotate(v_CB, - a_ACB / 3);//順時針轉a / 3,用負數表示順時針

    return Get_line_intersection(B, v1, C, v2);
}
 
int main()
{
    scanf("%d", &t);
    while(t -- ){
        A = read_point();
        B = read_point();
        C = read_point();
        D = get_point(A, B, C);
        E = get_point(B, C, A);
        F = get_point(C, A, B);
        printf("%.6f %.6f %.6f %.6f %.6f %.6f\n", D.x, D.y, E.x, E.y, F.x, F.y);
    }
    return 0;
}

相關文章