Artifact Content
Not logged in

Artifact d88a2122970afda17ee85e9cfa0b0d50bdaf4cfc


//-------------------------------------------------------------
// ccw
//
// Verified by
//   - SRM 492 Div1 LV1
//-------------------------------------------------------------

double outer_prod(const CMP& a, const CMP& b) { return imag(conj(a)*b); }
double inner_prod(const CMP& a, const CMP& b) { return real(conj(a)*b); }

int ccw(const CMP& a, CMP b, CMP c) {
	b -= a; c -= a;
	if( outer_prod(b,c) > 0 ) return +1; // counter clockwise
	if( outer_prod(b,c) < 0 ) return -1; // clockwise
	if( inner_prod(b,c) < 0 ) return +2; // c--[a--b] on line
	if( norm(b) < norm(c) )   return -2; // [a--b]--c on line
	return 0; // [a--c--b] on line
}


// intersection of two line segments.
bool cross(CMP p1, CMP p2, CMP P1, CMP P2) {
	return ccw(p1,p2,P1)*ccw(p1,p2,P2)<=0 && ccw(P1,P2,p1)*ccw(P1,P2,p2)<=0;
}


// Intersection of two line segments, by p1+(*pos)(p2-p1) where 0<=*pos<=1.
// only tested by local simple unittest. be careful.
template<typename T>
bool cross(const std::complex<T>& p1, const std::complex<T>& p2,
           const std::complex<T>& P1, const std::complex<T>& P2, T* pos) {
	if( ccw(p1,p2,P1)*ccw(p1,p2,P2)<=0 && ccw(P1,P2,p1)*ccw(P1,P2,p2)<=0 ) {
		if(outer_prod(p2-p1, P2-P1) == 0)
			return false; // parallel
		*pos = outer_prod(P1-p1, P2-P1) / outer_prod(p2-p1, P2-P1);
		return true;
	}
	return false;
}