• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
ACM s1124yy
守りたいものが 強くさせること
博客园    首页    新随笔    联系   管理     

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;
}
posted @ 2017-04-19 19:29  s1124yy  阅读(164)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3