线段香蕉


判断两线段是否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]);
	
	
	
	
}
 
 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值