二维几何基础


#include<stdio.h>
#include<math.h>
//常用定义
const double eps = 1e-10;
struct Point
{
	double x,y;
	Point( double x = 0,double y = 0 ): x(x),y(y) {}
};
typedef Point Vector;
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 p ) { return Vector( A.x * p,A.y * p ); }
Vector operator + ( Vector A,double p ) { return Vector( A.x / p,A.y / p ); }
Vector operator < ( const Point &a,const Point &b ) { 
	return a.x < b.x || ( a.x == b.x && a.y < b.y ); 
}
int dcmp( double x )
{
	if( fabs(x) < eps )	return 0; 
	else return x < 0?-1:1;
}
bool operator == ( const Point &a,const Point &b )
{
	return dcmp( a.x - b.x ) == 0 && dcmp( a.y - a.y ) == 0;
}
//基本运算
double Dot( Vector A,Vector B ) { return A.x * B.x + A.y * B.y; }      //点乘
double Length( Vector A ) { return sqrt( Dot(A,A) );  }                //取模
double Angle( Vector A,Vector B ) { return acos( Dot(A,B)/Length(A) );}//求角度
double Cross( Vector A,Vector B ) { return A.x * B.y - B.x * A.x; }    //叉乘
double Area2( Point A,Point B,Point C ) { return Cross( B - A,C - A ); }//求三角形面积
Vector Rotate( Vector A,double rad )									//向量旋转
{
	return Vector( A.x * cos(rad) - A.y * sin(rad),A.x * sin(rad) + A.y * cos(rad) );
}

//点与直线
Point GetLineIntersection( Point P,Vector v,Point Q, Vector w)          //直线交点
{
	Vector u = P - Q;
	double t = Cross( w,u ) / Cross( v,w );
	return P + v*t;
}
double DistanceToLine( Point P,Point A,Point B )						//点到直线距离
{
	Vector v1 = B - A, v2 = P - A;
	return fabs( Cross(v1,v2) )/Length(v1);     //如果不取绝对值,得到的是有向距离
}
double DistanceToSegment( Point P,Point A,Point B )                     //点到线段距离
{
	if( A == B )
		return Length(P-A);
	Vector v1 = B - A, v2 = P - A, v3 = P - B;
	if( dcmp( Dot( v1,v2 ) ) < 0 ) return Length( v2 );           //P点在点a左边
	else if( dcmp( Dot( v1,v2 ) ) > 0 ) return Length( v3 );      //P点在点b右边
	else return fabs( Cross(v1,v2) )/Length(v1); 
}
Point GetLineProjection( Point P,Point A,Point B )                     //点在直线上的投影
{
	Vector v = B - A;
	return A + v*( Dot(v,P-A)  / Dot(v,v) );
}
bool SegmentProperIntersection( Point a1,Point a2,Point b1,Point b2 )  //线段相交判定( 端点相交不算 )  
{  
    double c1 = Cross( a2-a1,b1-a1 ), c2 = Cross( a2-a1,b2-a1 ),  
        c3 = Cross( b2-b1,a1-b1 ),c4 = Cross( b2-b1,a2-b1 );  
    return dcmp(c1)*dcmp(c2) < 0 && dcmp(c3)*dcmp(c4) < 0 ;  
}  
bool OnSegment( Point p,Point a1,Point a2 )              //判断点是否在线段上
{
	return dcmp(Cross(a1-p,a2-p)) == 0 && dcmp(Dot(a1-p,a2-p)) < 0;
}
double PolygonArea( Point *p, int n )					//求多边形的有向面积
{
	double area = 0;
	for(int i = 1; i < n - 1; i ++ )
		area += Cross( p[i]-p[0],p[i+1]-p[0] );
	return area/2;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值