UVA 11178 Audiophobia 几何基础

来源:互联网 发布:联合作战指挥体系 知乎 编辑:程序博客网 时间:2024/05/16 19:31

向量旋转,直线交点

#include <cstdio>#include <cmath>#include <iostream>using namespace std;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);}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);}//点积 等于两向量长度的乘积再乘上它们夹角的余弦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));}//直线交点,调用前确保两条直线P+tv和Q+tw有唯一交点。当且仅当Cross(v,w)非0Point GetLineIntersection(Point P, Vector v, Point Q, Vector w){    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;              //射线BC    double a1 = Angle(A - B, v1);   //角ABC    v1 = Rotate(v1, a1 / 3);        //BC逆时针旋转 a1/3 直线BD    Vector v2 = B - C;    double a2 = Angle(A - C, v2);    v2 = Rotate(v2, -a2 / 3);       //负数表示顺时针旋转,得到直线CD    return GetLineIntersection(B, v1, C, v2);   //交点D}Point read_point(){    Point p;    scanf("%lf%lf", &p.x, &p.y);    return p;}int main(){    int T;    Point A, B, C, D, E, F;    scanf("%d", &T);    while (T--)    {        A = read_point();        B = read_point();        C = read_point();        D = getD(A, B, C);        E = getD(B, C, A);        F = getD(C, A, B);        printf("%.6lf %.6lf %.6lf %.6lf %.6lf %.6lf\n", D.x, D.y, E.x, E.y, F.x, F.y);    }    return 0;}


1 0
原创粉丝点击