老师布置了一道题 判断已知四点的两个线段,先判断是否相交 若相交求交点
题解:之前写了一篇 51nod的一道题判断线段交点 现在只需要求交点就好
那道题题解:https://blog.csdn.net/gao_jay/article/details/82931469
首先一般我们都倾向于用一般式 y=k*x+b,但是这种式子需要判断k是否存在 又要分情况
所以用 直线一般方程式a*x+b*y+c=0; 已知两点 (x1,y1),(x2,y2), 求其中一个线段的表达式 a=y1-y2; b=x2-x1;c=x1*y2-x2*y1;
p1=a1*x+b1*y+c1;
p2=a2*x+b2*y+c2;
求解 交点 (x0,y0)
p1=p2;
i j k
a1 b1 c1
a2 b2 c2
x0= (b1*c2 – b2*c1)/D;
y = (a2*c1– a1*c2)/D;
D = a1*b2 – a2*b1;
D为0表示平行但是算交点之前先判断是否线段相交;
变量有点多了 以后要注意这一方面
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
const double p=1e-10;
double x0,p0;
double k1,k2,b1,b2;
double D;
struct node
{
double x,y;
}a,b,c,d;
struct xing
{
double a0;
double b0;
double c0;
}m,n;
int jisuan(node a,node b,node c,node d)
{
double p1,p2,p3,p4;
p1=(d.x-c.x)*(d.y-a.y)-(d.y-c.y)*(d.x-a.x);//DCxDA
p2=(d.x-c.x)*(d.y-b.y)-(d.y-c.y)*(d.x-b.x);//DCxDB
p3=(b.x-a.x)*(b.y-d.y)-(b.y-a.y)*(b.x-d.x);//BAxBD
p4=(b.x-a.x)*(b.y-c.y)-(b.y-a.y)*(b.x-c.x);//BAxBC
if(p1*p2<=p&&p3*p4<=p)//double判断有精度问题 注意
return 1;
return 0;
}
xing jiaodian(node a,node b,node c,node d)
{
m.a0=a.y-b.y;
m.b0=b.x-a.x;
m.c0=a.x*b.y-a.y*b.x;
n.a0=c.y-d.y;
n.b0=d.x-c.x;
n.c0=c.x*d.y-c.y*d.x;
D=m.a0*n.b0-n.a0*m.b0;
x0=(m.b0*n.c0-n.b0*m.c0)/D;
p0=(n.a0*m.c0-m.a0*n.c0)/D;
printf("交点坐标\n");
printf("x: ");
cout<<x0<<endl;
printf("y: ");
cout<<p0<<endl;
}
void duandian()
{
scanf("%lf%lf",&a.x,&a.y);
scanf("%lf%lf",&b.x,&b.y);
scanf("%lf%lf",&c.x,&c.y);
scanf("%lf%lf",&d.x,&d.y);
if(jisuan(a,b,c,d))
{
cout<<"yes"<<endl;
jiaodian(a,b,c,d);
}
else
cout<<"no"<<endl;
}
int main()
{
int T;
cin>>T;
while(T--)
{
duandian();
}
return 0;
}