1. 程式人生 > >計算機圖形學之計算相交線段交點

計算機圖形學之計算相交線段交點

老師佈置了一道題 判斷已知四點的兩個線段,先判斷是否相交  若相交求交點

題解:之前寫了一篇 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;
}