Triangle
题目链接
给定一个三角形,和三角形上一个点,求三角形上另一个点,两点将三角形分成面积均等的两份。
利用比值的思想,即可求解。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
ll x1,x2,x3,y11,y2,y3,x,y;
bool check(ll x1,ll y11,ll x2,ll y2,ll x,ll y) {//判断给定点是不是在三角形的三条边上
if(x1==x2) {
if(x==x1) {
if(min(y11,y2)<=y&&y<=max(y11,y2))return true;
else return false;
} else {
return false;
}
}
if(y11==y2) {
if(y==y11) {
if(min(x1,x2)<=x&&x<=max(x1,x2))return true;
else return false;
} else {
return false;
}
}
ll cut = (y - y11) * (x2 - x1) - (x - x1) * (y2 - y11);
if(cut==0) {
if(min(x1,x2)<=x&&x<=max(x1,x2))return true;
else return false;
} else {
return false;
}
}
db len(ll x1,ll y11,ll x2,ll y2) {//两点的距离
return sqrt(1.0*(x1-x2)*(x1-x2)+1.0*(y11-y2)*(y11-y2));
}
db len2(ll x1,ll y11,ll x2,ll y2) {//两点的距离的平方
return 1.0*(x1-x2)*(x1-x2)+1.0*(y11-y2)*(y11-y2);
}
db S(ll x1,ll y11,ll x2,ll y2,ll x3,ll y3) {//给定三角形三个顶点求面积
db co=len2(x2,y2,x3,y3)+len2(x1,y11,x3,y3)-len2(x1,y11,x2,y2);
co=co/(2.0*len(x2,y2,x3,y3)*len(x1,y11,x3,y3));//余弦公式:cosc=(a^2+b^2-c^2)/(2*a*b);
db si=sqrt(1.0-co*co);//sina^2+cosa^2==1;
db ans=0.5*len(x2,y2,x3,y3)*len(x1,y11,x3,y3)*si;//三角形面积公式:S=a*b*sinc/2;
return ans;
}
db d(ll x1,ll y11,ll x2,ll y2,ll x,ll y) {//点到直线的距离
ll A=y11-y2;
ll B=x2-x1;
ll C=x1*(y2-y11)-y11*(x2-x1);
double ans=fabs(1.0*A*x+1.0*B*y+1.0*C);
ans=ans/sqrt(1.0*A*A+1.0*B*B);
return ans;
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
cin>>x1>>y11>>x2>>y2>>x3>>y3>>x>>y;
int falg=0;
if(!check(x1,y11,x2,y2,x,y))falg++;
if(!check(x1,y11,x3,y3,x,y))falg++;
if(!check(x2,y2,x3,y3,x,y))falg++;
if(falg==3) {//给定点不在三条边上
printf("-1\n");
continue;
}
if(falg==1) {//给定点在三角形定点上
db ansx=0,ansy=0;
if(x==x1&&y==y11) {
ansx=1.0*(x2+x3)/2;
ansy=1.0*(y2+y3)/2;
} else if(x==x2&&y==y2) {
ansx=1.0*(x1+x3)/2;
ansy=1.0*(y11+y3)/2;
} else if(x==x3&&y==y3) {
ansx=1.0*(x1+x2)/2;
ansy=1.0*(y11+y2)/2;
}
printf("%.10lf %.10lf\n",ansx,ansy);
continue;
}
//给定点在边上
db s=S(x1,y11,x2,y2,x3,y3);//三角形面积
if(check(x2,y2,x3,y3,x,y)) {//交换 保证给定点在1点和2点之间
swap(x1,x3),swap(y11,y3);
}
if(check(x1,y11,x3,y3,x,y)) {
swap(x2,x3),swap(y2,y3);
}
db ansx,ansy;//保存答案
db hl=d(x1,y11,x3,y3,x,y);//右面的高
db hr=d(x2,y2,x3,y3,x,y);//左面的高
db dl=s/hl;//右面的底
db dr=s/hr;//左面的底
db kl=dl/len(x1,y11,x3,y3);//右面的底与右面的边的比值
db kr=dr/len(x2,y2,x3,y3);//左面的底与左面的边的比值
if(kl<=1.0) {
ansx=1.0*x1+kl*(x3-x1);
ansy=1.0*y11+kl*(y3-y11);
} else {
ansx=1.0*x2+kr*(x3-x2);
ansy=1.0*y2+kr*(y3-y2);
}
printf("%.10lf %.10lf\n",ansx,ansy);
}
return 0;
}
计蒜客的编译器不让我定义y1,所以改成了y11,很别扭。