判断两线段是否banana
包括 平面坐标计算
//http://blog.sina.com.cn/s/blog_71dbfe2e0101f7zb.html
//http://dev.gameres.com/Program/Abstract/Geometry.htm#矢量的概念
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
#include<math.h>
using namespace std;
const double eps=1e-8;
#define zero(x) (((x) > 0 ? (x) : (-x)) < eps)
double max(double a,double b)
{
if(a > b)
return a;
return b ;
}
double min(double a,double b)
{
if(a < b)
return a;
return b ;
}
struct point2d//点也是向量
{
double x,y;
point2d(double x=0,double y=0):x(x),y(y){}
};
//重载
point2d operator + (point2d a,point2d b)
{
return point2d(a.x+b.x,a.y+b.y);
}
point2d operator - (point2d a,point2d b)
{
return point2d(a.x-b.x,a.y-b.y);
}
point2d operator * (point2d a,double b)
{
return point2d(a.x*b,a.y*b);
}
point2d operator / (point2d a,double b)
{
return point2d(a.x/b,a.y/b);
}
//×乘
//矢量叉积:
//
// 计算矢量叉积是与直线和线段相关算法的核心部分。
//设矢量P = ( x1, y1 ),Q = ( x2, y2 ),则矢量叉积定义为由(0,0)、
//p1、p2和p1+p2所组成的平行四边形的带符号的面积,即:P × Q = x1*y2 - x2*y1,
//其结果是一个标量。显然有性质 P × Q = - ( Q × P ) 和 P × ( - Q ) = - ( P × Q )。
//一般在不加说明的情况下,本文下述算法中所有的点都看作矢量,
//两点的加减法就是矢量相加减,而点的乘法则看作矢量叉积。
// 叉积的一个非常重要性质是可以通过它的符号判断两矢量相互之间的顺逆时针关系:
// 若 P × Q > 0 , 则P在Q的顺时针方向。
// 若 P × Q < 0 , 则P在Q的逆时针方向。
// 若 P × Q = 0 , 则P与Q共线,但可能同向也可能反向。
double operator * (point2d a,point2d b)
{
return a.x*b.y-b.x*a.y;
}
//·乘
double pdp(point2d a,point2d b)
{
return a.x*b.x+a.y*b.y;
}
//两直线是否香蕉(包括边界香蕉),快速排斥&&跨立实验
int isbanana(point2d p1,point2d p2,point2d p3,point2d p4)
{
double s1_xl,s1_xr,s1_yu,s1_yd;
double s2_xl,s2_xr,s2_yu,s2_yd;
s1_xl = min(p1.x,p2.x);
s1_xr = max(p1.x,p2.x);
s1_yd = min(p1.y,p2.y);
s1_yu = max(p1.y,p2.y);
s2_xl = min(p3.x,p4.x);
s2_xr = max(p3.x,p4.x);
s2_yd = min(p3.y,p4.y);
s2_yu = max(p3.y,p4.y);
// printf("%lf %lf %lf %lf\n",s1_xl,s1_xr,s1_yu,s1_yd);
// printf("%lf %lf %lf %lf\n",s2_xl,s2_xr,s2_yu,s2_yd);
double xl,xr,yu,yd;
xl = max(s1_xl,s2_xl);
xr = min(s1_xr,s2_xr);
yd = max(s1_yd,s2_yd);
yu = min(s1_yu,s2_yu);
// printf("%lf %lf %lf %lf\n",xl,xr,yu,yd);
if(xl>xr||yu<yd)
{
printf("no\n");
return 0;
}
if(pdp(((p3-p1)*(p2-p1)),((p4-p1)*(p2-p1)))<0)
{
printf("yes\n");
return 1;
}
printf("no\n");
return 0;
}
int main()
{
point2d a[4];
point2d b[4];
point2d c[4];
point2d d[4];
a[0] = point2d(0,-1);
a[1] = point2d(0,1);
a[2] = point2d(-1,0);
a[3] = point2d(1,0);
b[0] = point2d(-1,0);
b[1] = point2d(1,0);
b[2] = point2d(0,1);
b[3] = point2d(0,4);
c[0] = point2d(1,4);
c[1] = point2d(4,1);
c[2] = point2d(1,1);
c[3] = point2d(4,4);
d[0] = point2d(4,4);
d[1] = point2d(1,1);
d[2] = point2d(5,4);
d[3] = point2d(7,1);
point2d e = point2d(3,1);
isbanana(a[0],a[1],a[2],a[3]);
isbanana(b[0],b[1],b[2],b[3]);
isbanana(e,c[1],c[2],c[3]);
isbanana(d[0],d[1],d[2],d[3]);
}