文章目录
  1. 1. 题意
  2. 2. 分析

题意

给定一个三角形,求每个角的两条三等分线相交的三个点的坐标。

分析

计算几何基础,已知三个点的坐标,由向量可以求出角度,并直接旋转三条边得到六条三等分线,直接两两求交点就行了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <bits/stdc++.h>
#define MaX 500008
#define ll long long
using namespace std;
const double 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);
}
Vector operator - (Vector a,Vector b){
return Vector(a.x-b.x,a.y-b.y);
}
//向量乘除数值
Vector operator * (Vector a,double b){
return Vector(a.x*b,a.y*b);
}
Vector operator / (Vector a,double b){
return Vector(a.x/b,a.y/b);
}
//eps控制,重载<和==
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 a.x-b.x<eps||(dcmp(a.x-b.x)==0&&a.y-b.y<eps);
}
bool operator == (const Point& a,const Point& b){
return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
//计算a的极角
double AngleX(Vector a){
return atan2(a.y,a.x);
}
//向量点乘
double Dot(Vector a,Vector b){
return a.x*b.x+a.y*b.y;
}
//向量a的模
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;
}
//三点组成的面积
double Area2(Point a,Point b,Point c){
return Cross(b-a,c-a);
}
//将向量a旋转rad度,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));
}
//计算向量的单位法向量,先判a不是零向量
Vector Normal(Vector a){
double L=Length(a);
return Vector(-a.y/L,a.x/L);
}
//计算两个直线交点,直线方程为p+tv,q+tw,先判Cross(v,w)!=0
Point GetLineInter(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到直线ab的距离
double DisToL(Point p,Point a,Point b){
Vector v1=b-a,v2=p-a;
return fabs(Cross(v1,v2))/Length(v1);//不取绝对值为有向距离
}
//点p到线段ab的距离
double DisToS(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上的投影
Point GetLineProj(Point p,Point a,Point b){
Vector v=b-a;
return a+v*(Dot(v,p-a)/Dot(v,v));
}
//线段ab,cd相交判定(交点不能为两个端点)
bool segProInter(Point a,Point b,Point c,Point d){
double p1=Cross(b-a,c-a),p2=Cross(b-a,d-a),
p3=Cross(d-c,a-c),p4=Cross(d-c,b-c);
return dcmp(p1)*dcmp(p2)<0&&dcmp(p3)*dcmp(p4)<0;
}
//如果相交允许为端点,直接判一下是否有端点在另一条直线上
bool OnSeg(Point p,Point a,Point b){
return dcmp(Cross(a-p,b-p))==0&&dcmp(Dot(a-p,b-p))<0;
}
int main()
{
int t;
Point a,b,c,d,f,e;
Vector bd,bf,cd,ce,ae,af;
scanf("%d",&t);
for(int i=0;i<t;i++){
scanf("%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y);
bd=Rotate((c-b),Angle(c-b,a-b)/3);
bf=Rotate((c-b),2*(Angle(c-b,a-b)/3));
cd=Rotate((a-c),2*(Angle(a-c,b-c)/3));
ce=Rotate((a-c),Angle(a-c,b-c)/3);
ae=Rotate((b-a),2*(Angle(b-a,c-a)/3));
af=Rotate((b-a),Angle(b-a,c-a)/3);
d=GetLineInter(b,bd,c,cd);
e=GetLineInter(a,ae,c,ce);
f=GetLineInter(a,af,b,bf);
printf("%lf %lf %lf %lf %lf %lf\n",d.x,d.y,e.x,e.y,f.x,f.y);
}
}
文章目录
  1. 1. 题意
  2. 2. 分析