直线(2)——点积和叉积

总结用点积和叉积求解直线各类模板:

#include<iostream>
#include<math.h>
using namespace std;
#define precision 0.000001
struct point
{
  double x,y;
};
//a^b=-2==>axb<0或axb=-1,消除浮点误差 
int dblcmp(double d)
{
    if(fabs(d)<precision)
      return 0;
    return (d>0)?1:-1;
}
//叉积运算 
double cc(double a,double b,double c,double d)
{
       return a*c-b*d;
}
double cross(point p1,point p2,point p3)
{
       return cc(p2.x-p1.x,p2.y-p1.y,p3.x-p1.x,p3.y-p1.y);
}
//求点积
double d(double a,double b,double c,double d)
{
       return a*c+b*d;
}
double dd(point a,point b,point c)
{
   return d(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);
}
//判断点a是否在bc范围内
int betweenCmp(point a,point b,point c)
{
  return dblcmp(dd(a,b,c));
}
//叉积求交点
int segcross(point a,point b,point c,point d,point &p)
{
   double s1,s2,s3,s4;
   int d1,d2,d3,d4;
   d1=dblcmp(s1=cross(a,b,c));
   d2=dblcmp(s2=cross(a,b,d));
   d3=dblcmp(s3=cross(c,d,a));
   d4=dblcmp(s4=cross(c,d,b));
   //规范性相交求交点 
   if((d1^d2==-2)&&(d3^d4)==-2)
   {
     p.x=(s2*c.x-s1*d.x)/(s2-s1);
     p.y=(s2*c.y-s1*d.y)/(s2-s1);
     return 1;
   }
   //非规范性求交点
   if(d1==0&&betweenCmp(c,a,b)<=0||
      d2==0&&betweenCmp(d,a,b)<=0||
      d3==0&&betweenCmp(a,c,d)<=0||
      d1==0&&betweenCmp(b,c,d)<=0) 
   {
      if(d1==0) p.x=c.x,p.y=c.y;
      if(d2==0) p.x=d.x,p.y=d.y;
      if(d3==0) p.x=a.x,p.y=a.y;
      if(d4==0) p.x=b.x,p.y=b.y;
      return 2;
   }
   return 0;
} 
int main()
{
    point p[4],p1;
    while(scanf("%d%d%d%d%d%d%d%d",&p[0].x,&p[0].y,&p[1].x,&p[1].y,&p[2].x,&p[2].y,&p[3].x,&p[3].y)!=EOF)
    {
       segcross(p[0],p[1],p[2],p[3],p1);
       printf("%.2lf %.2lf\n",p1.x,p1.y);
    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值