8
20
2010
0

几何模板(未完成)

 

namespace geometry{
	typedef complex<double> Pt;
	double eps = 1e-10;
#define X real()
#define Y imag() // Not real(), don't forget it when copy and paste
	template<class T> T ccw(const complex<T>& a, const complex<T>& b){
		return imag( conj(a) * b );
	}
	int sign(double x){
		return fabs(x) < eps ? 0 : x < 0 ? -1 : 1;
	}

	//直线相交
	void line_abc(Pt s, Pt t, double &a, double &b, double &c){
		// a x + b y + c == 0
		// s.X * ( s.Y - t.Y ) - s.Y * ( s.X - t.X ) + ccw(s,t) == 0
		a = s.Y - t.Y;
		b = -(s.X - t.X);
		c = ccw(s,t);
	}
	// 两直线交点
	char inter_line(Pt a, Pt b, Pt c, Pt d, Pt &p){
		typedef T double;
		T a1, b1, c1, a2, b2, c2;
		line_abc(a,b,a1,b1,c1);
		line_abc(c,d,a2,b2,c2);
		// 二元一次方程组
		// [a1 b1 c1]
		// [a2 b2 c2]
		T d = a1 * b2 - a2 * b1;
		if( !sign(d) ) return ( !sign(a1*c2-a2*c1) && !sign(b1*c2-b2*c1) ) ? '-' : '='; // 平行或重合
		p = Pt( (b1*c2-b2*c1) / d, -(a1*c2-a2*c1) / d );
		return 'x';
	}
	// 两线段交点
	char inter_seg(Pt a, Pt b, Pt c, Pt d, Pt &p){
#define SERPARATE(a,b,c,d,X) sign( max(a.X,b.X), min(c.X,d.X) ) < 0
#define T double
		if( SERPARATE(a,b,c,d,X) ||
				SERPARATE(a,b,c,d,Y) ||
				SERPARATE(c,d,a,b,X) ||
				SERPARATE(c,d,a,b,Y) ){
			return '0'; // 不相交
		}
		T u1 = ccw(b-a,c-a), u2 = (b-a,d-a);
		T u3 = ccw(d-c,a-c), u4 = (d-c,b-c);
		int bac = sign(u1), bad = sign(u2);
		int dca = sign(u3), dcb = sign(u4);
		if( bac * bad > 0 ) return '0';
		if( dca * dcb > 0 ) return '0';
		if( bac * bad < 0 && dca * dcb < 0 ){
			p.X = ( c.X * u2 - d.X * u1 ) / ( u2 - u1 );
			p.Y = ( c.Y * u2 - d.Y * u1 ) / ( u2 - u1 );
			return 'x'; //规范相交
		}
		if( !bac && !bad ) return 'e'; // 在同一直线上且一定有交点(第一步已判显性分离)
		else if( !bac ) p = c;
		else if( !bad ) p = d;
		else if( !dca ) p = a;
		else if( !dcb ) p = b;
		else assert(0);
		return 'v'; // 端点相交
	}
}
Category: 未分类 | Tags: | Read Count: 1102

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com