#include<iostream>
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include<math.h>
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include<vector>
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include<algorithm>
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include<stdio.h>
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace std;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
const double eps = 1e-10;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
const double pi = acos( -1.0 );
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
const double inf = 1e100;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline int sig( double x ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return (x > eps) - (x < - eps);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) struct point {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double x, y, dis, angle;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) point() {}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) point( double x0, double y0 ):x(x0),y(y0) {}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//逻辑运算
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) inline bool operator < ( point t )const {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return sig ( y - t.y ) < 0 || sig ( y - t.y ) == 0 && sig( x - t.x ) < 0 ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) inline bool operator == ( point t )const {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return sig ( x - t.x ) == 0 && sig ( y - t.y ) == 0;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//算术运算
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) inline point operator - ( point b) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return point( x - b.x , y - b.y );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) inline point operator + ( point b ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return point( x + b.x, y + b.y );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) inline point operator * ( double t ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return point ( x * t , y * t );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) inline point operator / ( double t ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return point ( x / t , y / t );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//求长度
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) inline double len() {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return sqrt( x * x + y * y );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//长度的平方
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) inline double len2() {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return x * x + y * y ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) inline double dist( point t ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return sqrt( (x - t.x)*(x - t.x) + (y - t.y)*(y - t.y) );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//输入输出
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) int read() {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return scanf("%lf%lf",&x,&y);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) void out() {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
printf("(%.2lf %.2lf) ",x,y);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
};
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline bool _cmp( point a, point b ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return sig( a.angle - b.angle ) < 0 || sig( a.angle - b.angle ) == 0 && sig( a.dis - b.dis ) < 0;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// 点积
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline double dot( point a, point b ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return a.x * b.x + a.y * b.y ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline double dot( point p , point a, point b ) {//这种形式更常用
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return ( a.x - p.x ) * (b.x - p.x) + (a.y - p.y) * (b.y - p.y);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//叉积 ,遵循 左手定则(左旋为正)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline double cross( point a, point b) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return a.y * b.x - a.x * b.y ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline double cross( point p , point a, point b) {//这种形式更常用
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return (a.y - p.y) *(b.x - p.x) - (a.x - p.x) * (b.y - p.y);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//angle > 0 表示逆时针旋转,angle < 0 为顺时针
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//矢量pv以p为顶点逆时针旋转angle并放大scale倍
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline point rotate( point v, point p, double angle, double scale ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
point ret = p;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
v.x -= p.x, v.y -= p.y;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p.x = scale * cos(angle); p.y = scale * sin(angle);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
ret.x += v.x * p.x - v.y * p.y;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
ret.y += v.x * p.y + v.y * p.x;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return ret;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//向量 p 的法向量 ,p逆时针旋转90度
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline point faxiang( point p) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return point( - p.y , p.x );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//向量 ab 左移 r 长度
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline point left( point a, point b, double r) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
point ta, tb, tt;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
tt.x = b.y - a.y; tt.y = a.x - b.x;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double k = r / sqrt( tt.x * tt.x + tt.y * tt.y );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
tt.x = - tt.x * k; tt.y = - tt.y * k;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return tt;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//两向量之间的夹角[0,pi] , 乘以 cross( a, b ) 后便成了有向夹角。
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline double point_angle(point a,point b) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return acos( dot( a, b ) / sqrt( a.len2() * b.len2() ));
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return cross( a, b ) * acos( dot( a, b ) / sqrt( a.len2() * b.len2() ));
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//点到直线的距离
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline double point_to_line(point p, point a, point b) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return fabs( cross( a, p, b ) / ( b - a ).len());
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//返回点p与线段ab的距离,
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline double point_to_seg(point p , point a,point b) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( sig ( dot ( a, p, b ) ) < 0 )//p在a端外
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return ( p - a ).len();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( sig ( dot ( b, p, a ) ) < 0 )//p在b端外
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return ( p - b ).len();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return point_to_line( p , a , b );//p正对于ab
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//返回线段ab与线段cd之间的距离,相交(有一个公共点)返回0,交点为p。自己通过<,<=,来处理边界
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline double seg_to_seg ( point a , point b ,point c ,point d,point &p ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if( ! ( (sig ( max( a.x , b.x ) - min( c.x , d.x ) ) < 0 ) || ( sig ( max( d.x , c.x ) - min( a.x , b.x ) ) < 0 )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
||( sig ( max ( a.y , b.y ) - min( c.y , d.y ) ) < 0 ) || ( sig ( max( d.y , c.y ) - min ( a.y , b.y ) ) < 0 ) ) )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if ( sig ( cross( a, b, c ) * cross ( a, b, d) ) <= 0 && sig ( cross( c, d, a ) * cross ( c, d, b ) ) <= 0 ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p = a;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double t=((a.x-c.x)*(c.y-d.y)-(a.y-c.y)*(c.x-d.x))
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
/((a.x-b.x)*(c.y-d.y)-(a.y-b.y)*(c.x-d.x));
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p.x+=(b.x-a.x)*t;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p.y+=(b.y-a.y)*t;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 0;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//不相交
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return min( min( point_to_seg( a, c, d ) , point_to_seg( b, c, d ) ), min( point_to_seg( c, a, b), point_to_seg( d, a, b ) ));
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// 严格相交
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline int seg_insert_line ( point a, point b, point c, point d, point & p) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if ( sig ( cross( c, d, a ) * cross ( c, d, b ) ) < 0 ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p = a;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double t=((a.x-c.x)*(c.y-d.y)-(a.y-c.y)*(c.x-d.x))
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
/((a.x-b.x)*(c.y-d.y)-(a.y-b.y)*(c.x-d.x));
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p.x+=(b.x-a.x)*t;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p.y+=(b.y-a.y)*t;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 1;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 0;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// 求向量 a 的极角,角度范围为 [0,pi*2)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) double angle( point a ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double t = atan2( a.y, a.x );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return sig( t ) >= 0 ? t : t + pi * 2;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// 角度修正函数,根据不同的题目有不同写法和功能
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) void fix_angle( double & rad ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if( sig( rad - pi ) > 0 ) rad -= pi * 2;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if( sig( rad + pi ) < 0 ) rad += pi * 2;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//求直线和园相交。0为相离,1为相切,2为相交,交点v1,v2 ,且 v2到v1是逆时针指向
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) int cir_insert_line( point c, double r, point a, point b, point &v1, point &v2) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double h = fabs( cross( a, c, b )/(b - a).len());
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if( sig( h - r ) > 0 )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 0;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
point tmp = point ( -(b - a).y, (b - a).x );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( sig( cross( a, c, b )) > 0 )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
tmp.x = - tmp.x , tmp.y = -tmp.y;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
tmp = tmp*( h / tmp.len() );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
point mid = c + tmp;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if ( sig( h - r ) == 0 ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
v1 = mid;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 1;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double l2 = ( r * r - h * h );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
tmp = ( b - a );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
tmp = tmp * sqrt( l2 / tmp.len2() );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
v1 = tmp + mid; tmp.x = - tmp.x;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
tmp.y = - tmp.y; v2 = tmp + mid;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 2;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// 判断点在线段上,条件:pt,pl1,pl2共线
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline bool pt_in_seg( point pt, point pl1, point pl2 ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return ( sig( dot(pl1,pt,pl2)) >= 0 && sig( dot(pl2,pt,pl1) ) >= 0 );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// 判断点在线段上(不含端点),条件:pt,pl1,pl2共线
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline bool pt_in_segs( point pt, point pl1, point pl2 ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return ( sig( dot(pl1,pt,pl2)) > 0 && sig( dot(pl2,pt,pl1) ) > 0 );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline int pt_line( point p1, point p2 , point &ret ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
ret.y = p2.x - p1.x; ret.x = p1.y - p2.y;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
ret.dis = - dot( p1, ret );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 0;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//求直线和园相交。0为相离,1为相切,2为相交,交点v1,v2 ,且 v2到v1是逆时针指向
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
int lcins(point po,double r,point pl1,point pl2,point &ret1,point &ret2)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
point vl;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double tmp1, tmp2;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
pt_line( pl1, pl2, vl );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
tmp1 = dot( vl, po ) + vl.dis;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double ab = vl.len2(), mdis2 = ab * r * r - tmp1 * tmp1 ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if( sig( mdis2 ) < 0 )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 0;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
tmp1 = ( vl.y * cross( vl, po ) - vl.dis * vl.x );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
tmp2 = ( vl.x * cross( po, vl ) - vl.dis * vl.y );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( sig( mdis2 ) <= 0 )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
ret1.x = tmp1 / ab ; ret1.y = tmp2 / ab ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 1;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double sq = sqrt( mdis2 );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
ret1.x = ( tmp1 + vl.y * sq ) / ab; ret1.y = ( tmp2 - vl.x * sq ) / ab;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
ret2.x = ( tmp1 - vl.y * sq ) / ab; ret2.y = ( tmp2 + vl.x * sq ) / ab;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 2;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// 半径为r,圆心在原点的圆,与三角形 ps,pe,o的相交面积。
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) double area_c2p( double r, point ps, point pe ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double d1 = ps.len2(), d2 = pe.len2(), r2 = r * r;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double rad1, rad2, drad;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( d1 <= r2 && d2 <= r2 ) return cross( pe, ps ) * .5;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
point po(0,0), ins1, ins2;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
rad1 = angle( ps ); rad2 = angle( pe );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
drad = rad2 - rad1; fix_angle( drad );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
int nins = cir_insert_line( po, r, ps, pe, ins1, ins2 );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if( nins <= 1 ) return drad*.5*r*r;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if(( sig( dot( ps, ins1, pe ) ) < 0 && sig( dot( ps, ins2, pe) ) < 0 )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
||( sig( dot( pe, ins1, ps) ) < 0 && sig( dot( pe, ins2, ps ) ) < 0 ))
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return drad*.5*r*r;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
else if( pt_in_seg( ins1, ps, pe ) && pt_in_seg( ins2, ps, pe ))
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double radi1, radi2, drad2, ret;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( pt_in_segs( ins1, ps, ins2 ))
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
radi1 = angle( ins1 ); radi2 = angle( ins2 );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
ret = cross( ins2, ins1 ) * .5;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
radi1 = angle( ins2 ); radi2 = angle( ins1 );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
ret = cross( ins1, ins2 ) * .5;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
drad = radi1 - rad1;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
fix_angle( drad );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
drad2 = rad2 - radi2;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
fix_angle( drad2);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return ret + ( drad + drad2 ) * .5 * r * r;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
point pins, pout;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double radi;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( sig( dot( ps, ins1, pe )) < 0
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
|| sig( dot( pe, ins1, ps )) < 0 )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
pins = ins2, pout = ins1;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
pins = ins1, pout = ins2;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
radi = angle( pins );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( sig( dot( pe, pout, ps ) ) < 0 )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
drad = radi - rad1; fix_angle( drad );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return cross ( pe, pins ) * .5 + drad * .5 * r * r;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
drad = rad2 - radi; fix_angle( drad );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return cross( pins, ps ) * .5 + drad * .5 * r * r;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//半径为r圆,圆心在原点上的圆与多边形的相交面积
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) double area_cpoly( double r, point p[], int n ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
int i; double ret = 0;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p[n] = p[0];
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
for ( i = 1 ; i <= n ; i ++ )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
ret += area_c2p( r, p[i-1], p[i] );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return ret;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//求圆和圆相交,返回交点个数, 两圆重合返回 -1
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline int cir_insert_cir( point c1, double r1,point c2, double r2, point &p1, point &p2 ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double dist = c1.dist( c2 ) , tmp;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( sig ( dist - r1 - r2 ) > 0 )// 外离
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 0;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double r_min = min( r1, r2 ), r_max = max( r1, r2 );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( dist < r_max && sig ( dist + r_min - r_max ) < 0 )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 0;// 内离
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if ( sig( dist - r1 - r2 ) == 0 ) {// 外切
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p1 = c1 + (c2 - c1)*(r1)/(dist);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 1;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if ( dist < r_max && sig ( dist + r_min - r_max ) == 0 ) {// 内切
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if( sig( dist ) == 0 )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return -1; // 两圆重合
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p1 = c1 + (c2 - c1)*(r_max)/( dist );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 1;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
point u, v;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double t;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
t = (1.+(r1*r1-r2*r2)/dist/dist)/2;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
u.x = c1.x+(c2.x-c1.x)*t; u.y = c1.y+(c2.y-c1.y)*t;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
v.x = u.x+c1.y-c2.y; v.y = u.y-c1.x+c2.x;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cir_insert_line(c1,r1,u,v,p1,p2);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 2;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//求圆上两点之间的最小距离
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) inline double cir_dist( point a, point b, point c, double r) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double sita = point_angle( ( a - c ), ( b - c ) );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return r * sita;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//多边形
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) struct polygon {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
static const int MAXN = 10510;//多边形大小
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
point p[MAXN] ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
int n ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
// 构造函数
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) polygon() { n = 0 ; }
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
// 在多边形末尾加点
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) void add( point & t ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
this->p[ n ++ ] = t;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
// 求面积,逆时针为正,顺时针为负
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) inline double area() {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double sum = 0 ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p[n] = p[0];
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
for ( int i = 0 ; i < n ; i++ )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
sum += cross( p[ i + 1 ] , p[ i ] );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return sum * .5 ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
// 将多边形转为反向
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) inline int turn_back() {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double tmp = area();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if( sig( tmp ) < 0 )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
for ( int i = 0; i < n / 2 ; i ++ )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
swap( p[i], p[n - i - 1] );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return sig( tmp );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//求点集的凸包,存于 多边形con中 ,原多边形将乱序
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) inline int convex( polygon & con ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
int t = 0, i;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
point tmp;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
for( i = 1 ; i < n ; i ++ )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if( p[i] < p[t] )//先 y 值最小,再x值最小处理
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
t = i;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
swap( p[t], p[0] );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
for( i = 0 ; i < n ; i ++ )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
tmp = p[i] - p[0];
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p[i].dis = tmp.len2();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p[i].angle = atan2( tmp.y, tmp.x );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
sort( p, p + n, _cmp );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
int k = 0;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
con.p[ k ++ ] = p[n-1];
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
con.p[ k ++ ] = p[0];
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if( sig( p[1].angle - p[n-1].angle ) == 0 )//凸包为一线段
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
con.p[ k ++ ] = p[ n - 1];
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
for ( i = 1 ; i < n ; i ++ )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if( sig( cross( con.p[k-1], con.p[k-2], p[i] )) > 0 )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
con.p[ k ++ ] = p[i];
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
i -- , k -- ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
k -- ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
con.n = k;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return k;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
// 求多边形重心
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) inline point tri_centroid( point a, point b, point c ) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
point t( 0, 0 );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
t.x = ( a.x + b.x + c.x ) / 3 ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
t.y = ( a.y + b.y + c.y ) / 3 ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return t;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
inline point poly_centroid()
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
int i;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
double area = 0, tmp ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
point rel( 0, 0 );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
for ( i = 1 ; i < n - 1 ; i ++ )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
tmp = cross( p[0], p[i], p[ i + 1 ] );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
area += tmp;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
rel = ( tri_centroid( p[0], p[i], p[i+1] ) * tmp ) + rel;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( sig ( area ) != 0 )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
rel = rel / area;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return rel;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) inline int read() {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
int t = scanf("%d",&n);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( t == EOF )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return t;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
for( int i = 0 ; i < n ; i ++ )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p[ i ].read();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return n;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) inline void out() {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
printf("%d\n",n);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
for ( int i = 0 ; i < n ; i ++ )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p[i].out();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout<<endl;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
// 直线st->ed,切割多边形,留下st->ed左边的部分,q[]为辅助数组。
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
void cut( point st, point ed, point q[] )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
int i, j, k;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
point tmp;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
k = 0;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p[n] = p[0];
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
for ( j = 0 ; j < n ; j ++ )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( sig( cross( st, ed, p[j] ) ) <= 0 )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
q[ k ++ ] = p[j];
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( seg_insert_line( p[j], p[j+1], st, ed, tmp ) )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
q[ k ++ ] = tmp;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
n = k;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
for ( j = 0 ; j < n ; j ++ ) p[j] = q[j];
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
// O(n^2) 的半平面求交,多边形上的点逆时针输入
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) polygon half_plane2() {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
turn_back();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
polygon tmp;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
p[ n ] = p[ 0 ];
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
tmp = * this ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
point q[ MAXN ];
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
for ( int i = 0 ; i < n ; i ++ )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
tmp.cut( p[i], p[i+1], q );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return tmp;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
// tmp.n 为0的时候 ,无交集,即多边形的核
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
};
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
|