計算機圖形學之計算相交線段交點
阿新 • • 發佈:2018-12-13
老師佈置了一道題 判斷已知四點的兩個線段,先判斷是否相交 若相交求交點
題解:之前寫了一篇 51nod的一道題判斷線段交點 現在只需要求交點就好
首先一般我們都傾向於用一般式 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; }