you all know that creat2012 will go to a regional. and i want you all pray for us. thx.
for this problem, you need judge if two segments is intersection(相交的). if intersect(相交), print yes and the point. else print no.
easy ? ac it.
-
输入
-
T <= 100 cases
8 real numbers (double)
promise two segments is no coincidence.
输出
-
no
or yes and two real number (one decimal)
样例输入
-
2 0 0 2 2 1 0 3 2 0 0 2 2 0 2 2 0
样例输出
-
no yes 1.0 1.0
思路:PS 需要特殊情况 共线&&无交点 共线有交点
步骤:
(1),需一个四个大小的数组再次表示四个点坐标 对该数组排序 如果中间两个点坐标相等则 两线段相交。
(2),若不等则进行快速排斥实验 排除掉 共线无交点
(3),根据叉乘运算 确定线段是否相交, 若相交 则利用定比分点来求交点坐标
PS:定比分点:一条直线po,p(x1,y1),o(x2,y2),m是po两点中的一点 若pm/mo=k则m.x=(x1+kx2)/(1+k) m.y=(y1+ky2)/(1+k);
我的思路里 最后一步(通过了快速排斥实验见 转载日志)用到定比分点公式 即 四点能组成四边形,以st1 ed1线段为公共边的两个三角形 st1ed1st2 和三角形 st1 ed1 ed2
叉乘可知三角形的面积 面积比则为高的比 两个小直角三角形相似 大三角形高的比 即为小直角三角形斜边的比即:st2 O/ed2O即定比分点的k值 则可求O点坐标。
代码:
<pre name="code" class="cpp">#include<iostream>
#include<stdio.h>
#include <iomanip>
#include<algorithm>
#include<math.h>
using namespace std;
struct node
{
double x,y;
} st1,ed1,st2,ed2,s[4];
double area(node ss1,node ee1,node ss2)
{
//return ss1.x*ee1.y-ss1.y*ee1.x;
return (ss1.x-ee1.x)*(ss1.y-ss2.y)-(ss1.x-ss2.x)*(ss1.y-ee1.y);
}
int cmp(node a,node b)
{
if(a.x>b.x)
return a.x<b.x;
if(a.x==b.x)
return a.y<b.y;
}
int main()
{
int t,i,j;
cin>>t;
while(t--)
{
cin>>st1.x>>st1.y>>ed1.x>>ed1.y>>st2.x>>st2.y>>ed2.x>>ed2.y;
s[0]=st1;
s[1]=ed1;
s[2]=st2;
s[3]=ed2;
double s1=area(st1,ed1,st2);
double s2=area(st1,ed1,ed2);
double s3=area(st2,ed2,st1);
double s4=area(st2,ed2,ed1);
cout.setf(ios::fixed);
cout.precision(1);
sort(s,s+4,cmp);
if(s[1].x==s[2].x&&s[1].y==s[2].y)
cout<<"yes "<<s[2].x<<" "<<s[2].y<<endl;
else
{
if(!(min(st1.x,ed1.x)<=max(st2.x,ed2.x) && min(st1.y,ed1.y)<=max(st2.y,ed2.y)&&
min(st2.x,ed2.x)<=max(st1.x,ed1.x) && min(st2.y,ed2.y)<=max(st1.y,ed1.y)))
cout<<"no"<<endl;
else
{
if(s1*s2<=0&&s3*s4<=0)
{
if(s1==0)
cout<<"yes "<<st2.x<<" "<<st2.y<<endl;
else if(s2==0)
cout<<"yes "<<ed2.x<<" "<<ed2.y<<endl;
else if(s3==0)
cout<<"yes "<<st1.x<<" "<<st1.y<<endl;
else if(s4==0)
cout<<"yes "<<ed1.x<<" "<<ed1.y<<endl;
if(s1!=0&&s2!=0&&s3!=0&&s4!=0)
{
double ss=fabs(1.0*s1/s2);
//cout<<ss<<endl;
node ans;
ans.x=(st2.x+ss*ed2.x)/(1+ss);
ans.y=(st2.y+ss*ed2.y)/(1+ss);
cout<<"yes "<<ans.x<<" "<<ans.y<<endl;
}
}
else
cout<<"no"<<endl;
}
}
}
return 0;
}