欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[POJ1269]Intersecting Lines(计算几何-叉积)

程序员文章站 2022-04-01 13:35:17
...

题目:

我是超链接

题意:

每次给出两条直线,判断是否平行、重合、相交,相交的话就输出交点。

题解:

判断两条直线是否平行
两条直线两个方向向量平行(叉积为0)

判断两条直线是否重合
平行的基础上,在两条直线上各选一个点组成一个方向向量在去与前两个中的任意一个判平行(叉积为0)

那相交的话就是既不平行也不重合呗
求交点的话其实是这样的
a⃗ =A⃗ +tB⃗ 
b⃗ =C⃗ +uD⃗ 
两条直线相交

A⃗ +tB⃗ =C⃗ +uD⃗ 

两边同时叉乘D⃗ 得到

(A⃗ +tB⃗ )×D⃗ =(C⃗ +uD⃗ )×D⃗ 
因为D⃗ ×D⃗ =0
所以
A⃗ ×D⃗ +tB⃗ ×D⃗ =C⃗ ×D⃗ 
解出参数
t=(C⃗ A⃗ )×D⃗ /(B⃗ ×D⃗ )
带入一个含t的柿子就可以解出来啦

点积是满足交换律的,但叉积并不满足,但是满足反交换律,即a⃗ ×b⃗ =b⃗ ×a⃗ 
点积和叉积都满足加法的分配率

代码:

#include <cstdio>
using namespace std;
const double eps=1e-9;
struct vector
{
    double x,y;
    vector (double X=0,double Y=0){x=X;y=Y;}
};
struct line
{
    vector x,v;
    line(vector X=vector(0,0),vector Y=vector(0,0)){x=X; v=Y;}
};
vector operator +(vector a,vector b){return vector(a.x+b.x,a.y+b.y);}
vector operator -(vector a,vector b){return vector(a.x-b.x,a.y-b.y);}
vector operator *(vector a,double b){return vector(a.x*b,a.y*b);}
int dcmp(double x)
{
    if (x<=eps && x>=-eps) return 0;
    return (x>0)?1:-1;
}
double cj(vector x,vector y){return x.x*y.y-x.y*y.x;}
vector jd(vector a,vector b , vector c,vector d)//求交点坐标
{
    vector v=a-c;
    double t=cj(d,v)/cj(b,d);
    return a+b*t;
}
int main()
{
    int n;scanf("%d",&n);
    printf("INTERSECTING LINES OUTPUT\n");
    for (int i=1;i<=n;i++)
    {
        double x1,y1,x2,y2,x3,y3,x4,y4;
        scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
        int x=dcmp(cj(vector(x1-x2,y1-y2),vector(x3-x4,y3-y4)));
        int y=dcmp(cj(vector(x1-x2,y1-y2),vector(x1-x4,y1-y4)));
        if (!x && !y) printf("LINE\n");
        else 
        {
            if (!x) printf("NONE\n");
            else
            {
                vector p=jd(vector(x1,y1),vector(x1-x2,y1-y2),vector(x3,y3),vector(x3-x4,y3-y4));
                printf("POINT %.2lf %.2lf\n",p.x,p.y);
            }
        }
    }
    printf("END OF OUTPUT");
}
相关标签: 计算几何 叉积