题意:给定你一个三角形的三个顶点,三角形一定是合法的,然后在给定你一个平面内的点,这个点可能不落在三角形的某一条边上,如果是这种情况那么就不合法输出-1,否则输出三角形边上的一个点的坐标使之与给定点连接形成的线段能够平分三角形的面积。
思路:首先合不合法的情况,我们可以利用叉积和点积判断,点要在三角形的边上,那么,叉积一定要等于0并且点积要是个负数,否则输出-1即可。
既然要平分面积,
假设给定的点p在点1,2那条边上,此时我们求出p到点1和点2的距离,如果d1 > d2(即图中p),否则为p’。这里以p为例,求出点p和点2分别到边13的距离d和h,边13的中点为mid,此时如果点x和点p的连线能够平分面积,就应该有 dis(mid,1) * h = dis(x,1) * d,可以解得 dis(x,1) = dis(mid,1) * (h/d)。然后就可以利用向量加减求出x的坐标了。
点p’类似无非就是往边23作高就可,给出的点在其他两条边的答案类似。
分类讨论即可。
然后flag代表的对应的边,点在三角形顶点处直接特判即可。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-10;
//直接模拟
int sign(double x)//判断符号可用
{
if(fabs(x) <= eps) return 0;
if(x > 0) return 1;
else return -1;
}
struct Point
{
double x,y;
Point(){}
//定义运算
Point(double _x,double _y){x = _x;y = _y;}
Point operator + (const Point &b)const{
return Point(x+b.x,y+b.y);
}
Point operator - (const Point &b)const{
return Point(x-b.x,y-b.y);
}
Point operator * (const double &k)const{//乘常数
return Point(x*k,y*k);
}
Point operator / (const double &k)const{
return Point(x/k,y/k);
}
double len(){ return x * x + y * y; }
};
typedef Point Vector;
double cross(Vector a,Vector b){
return a.x * b.y - a.y * b.x;
}
double dot(Vector a,Vector b){
return a.x * b.x + a.y * b.y;
}
double dis(Point a,Point b){
return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
int main(){
Point p[4],pp,ans;
int T;scanf("%d",&T);
while(T--){
for(int i = 1;i <= 3;i ++) scanf("%lf%lf",&p[i].x,&p[i].y);
scanf("%lf%lf",&pp.x,&pp.y);
if(pp.x == p[1].x && pp.y == p[1].y){
Point mid = (p[2] + p[3]) / 2.0;
printf("%.10f %.10f\n",mid.x,mid.y);
continue;
}
if(pp.x == p[2].x && pp.y == p[2].y){
Point mid = (p[1] + p[3]) / 2.0;
printf("%.10f %.10f\n",mid.x,mid.y);
continue;
}
if(pp.x == p[3].x && pp.y == p[3].y){
Point mid = (p[1] + p[2]) / 2.0;
printf("%.10f %.10f\n",mid.x,mid.y);
continue;
}
int flag = 0;
Vector v1 = pp - p[1],v2 = pp - p[2],v3 = pp - p[3];
if(sign(dot(v1,v2)) == -1 && sign(cross(v1,v2)) == 0) flag = 1;
else if(sign(dot(v1,v3)) == -1 && sign(cross(v1,v3)) == 0) flag = 2;
else if(sign(dot(v2,v3)) == -1 && sign(cross(v2,v3)) == 0) flag = 3;
if(!flag) { printf("-1\n");continue; }
// cout<<"***"<<flag<<endl;
if(flag == 1){
double d1 = dis(pp,p[1]),d2 = dis(pp,p[2]);
if(fabs(d1 - d2) <= eps) ans = p[3];
else {
if(d1 > d2){
double rate;
Vector tv1 = pp - p[1],tv2 = p[3] - p[1],tv3 = p[2] - p[1];
double dd = fabs(cross(tv1,tv2)) / tv2.len();
double hh = fabs(cross(tv3,tv2)) / tv2.len();
rate = hh / dd;
// cout<<"***"<<rate<<endl;
// cout<<hh<<' '<<dd<<endl;
ans = p[1] + (p[3]-p[1]) * 0.5 * rate;
}
else{
double rate;
Vector tv1 = pp - p[2],tv2 = p[3] - p[2],tv3 = p[1] - p[2];
double dd = fabs(cross(tv1,tv2)) / tv2.len();
double hh = fabs(cross(tv3,tv2)) / tv2.len();
rate = hh / dd;
// cout<<"***"<<rate<<endl;
// cout<<hh<<' '<<dd<<endl;
ans = p[2] + (p[3]-p[2]) * 0.5 * rate;
}
}
}
else if(flag == 2){
double d1 = dis(pp,p[1]),d2 = dis(pp,p[3]);
if(fabs(d1 - d2) <= eps) ans = p[2];
else {
if(d1 > d2){
double rate;
Vector tv1 = pp - p[1],tv2 = p[2] - p[1],tv3 = p[3] - p[1];
double dd = fabs(cross(tv1,tv2)) / tv2.len();
double hh = fabs(cross(tv3,tv2)) / tv2.len();
rate = hh / dd;
// cout<<hh<<' '<<dd<<endl;
// cout<<"***"<<rate<<endl;
ans = p[1] + (p[2]-p[1]) * 0.5 * rate;
}
else{
double rate;
Vector tv1 = pp - p[3],tv2 = p[2] - p[3],tv3 = p[1] - p[3];
double dd = fabs(cross(tv1,tv2)) / tv2.len();
double hh = fabs(cross(tv3,tv2)) / tv2.len();
rate = hh / dd;
// cout<<hh<<' '<<dd<<endl;
// cout<<"***"<<rate<<endl;
ans = p[3] + (p[2]-p[3]) * 0.5 * rate;
}
}
}
else if(flag == 3){
double d1 = dis(pp,p[2]),d2 = dis(pp,p[3]);
if(fabs(d1 - d2) <= eps) ans = p[1];
else {
if(d1 > d2){
double rate;
Vector tv1 = pp - p[2],tv2 = p[1] - p[2],tv3 = p[3] - p[2];
double dd = fabs(cross(tv1,tv2)) / tv2.len();
double hh = fabs(cross(tv3,tv2)) / tv2.len();
rate = hh / dd;
ans = p[2] + (p[1]-p[2]) * 0.5 * rate;
}
else{
double rate;
Vector tv1 = pp - p[3],tv2 = p[1] - p[3],tv3 = p[2] - p[3];
double dd = fabs(cross(tv1,tv2)) / tv2.len();
double hh = fabs(cross(tv3,tv2)) / tv2.len();
rate = hh / dd;
ans = p[3] + (p[1]-p[3]) * 0.5 * rate;
}
}
}
printf("%.10f %.10f\n", ans.x, ans.y);
}
return 0;
}