UVA 11178 Morley's Theorem(几何)

Morley's Theorem

【题目链接】Morley's Theorem

【题目类型】几何

&题解:

蓝书P259 简单的几何模拟,但要熟练的应用模板,还有注意模板的适用范围和传参不要传混了

&代码:

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;
const int maxn= 1e3 +7;

//蓝书P255
//1.点的定义
struct Point {
    double x,y;
    Point (double x=0,double y=0):x(x),y(y) {}
};
//点和向量是一样的内容 所以会出来2个名字
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);}
//向量/数=向量
Vector operator / (Vector A,double p) {return Vector(A.x/p,A.y/p);}
bool operator < (const Point& a,const Point& b) {return a.x<b.x||(a.x==b.x&&a.y<b.y);}

const double eps=1e-10;
//doublue的三态函数
int dcmp(double x) {
    if(fabs(x)<eps) x=0;
    else return x<0?-1:1;
}
bool operator == (const Point& a,const Point& b) {return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;}

//点积
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;}
//有向面积,数值是三角形面积的2倍
double Area2(Point A,Point B,Point C) {return Cross(B-A,C-A);}

//向量旋转,doublue的都是弧度
Vector Rotate(Vector A,double rad) {
    return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}

//求单位法向量
Vector Normal(Vector A) {
    double L=Length(A);
    return Vector(-A.y/L,A.x/L);
}

//2.点和直线
//调用前请确保两条直线P+tv和Q+tw有唯一交点.当且仅当Cross(v,w)非0
Point 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;
}

//点P到直线(过点A,B)的距离
double DistanceToLine(Point P,Point A,Point B) {
    Vector v1=B-A,v2=P-A;
    return fabs(Cross(v1,v2))/Length(v1);//不加fabs,得到的是有向距离
}

//点P到线段AB的距离
double DistanceToSegment(Point P,Point A,Point B) {
    if(A==B) return Length(P-A);
    Vector v1=B-A,v2=P-A,v3=P-B;
    if(dcmp(Dot(v1,v2))>0) return Length(v2);
    else if(dcmp(Dot(v1,v3))>0) return Length(v3);
    else return fabs(Cross(v1,v2))/Length(v1);
}

//求点P在直线AB的投影点Q
Point GetLineProjection(Point P,Point A,Point B) {
    Vector v=B-A;
    return A+v*(Dot(v,P-A)/Dot(v,v));
}

//线段相交判定,两线段恰好有一个公共点,且不在任何一条线段的端点
bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2) {
    double c1=Cross(a2-a1,b1-a1), c2=Cross(a2-a1,b2-a1),
           c3=Cross(b2-b1,a1-b1), c4=Cross(b2-b1,a2-b1);
    return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;
}

//判断点P是否在线段AB上(不包含线段的端点)
bool OnSegment(Point p,Point a1,Point a2) {
    return dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dot(a1-p,a2-p))<0;
}

//多边形的有向面积
double PolygonArea(Point* p,int n) {
    double area=0;
    for(int i=1; i<n-1; i++) {
        area+=Cross(p[i]-p[0],p[i+1]-p[0]);
    }
    return area/2;
}

//解题代码
Point GetD(Point A,Point B,Point C) {
    double tht1=Angle(A-B,C-B),tht2=Angle(A-C,B-C);
    Vector v1=Rotate(C-B,tht1/3),v2=Rotate(B-C,-tht2/3);//顺时针转,角度呀变负,逆时针转,角度是正的
    return GetLineIntersection(B,v1,C,v2);
}
int main() {
    //("E:1.in","r",stdin);
    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("%f %f %f %f %f %f\n",D.x,D.y,E.x,E.y,F.x,F.y);
    }
    return 0;
}

转载于:https://www.cnblogs.com/s1124yy/p/6735134.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值