//==============================================================================
int
sos_simplex_intersection2d(int k,
                           int pri0, const double* x0,
                           int pri1, const double* x1,
                           int pri2, const double* x2,
                           int pri3, const double* x3,
                           double* alpha0, 
                           double* alpha1, 
                           double* alpha2,
                           double* alpha3)
{
    assert(1<=k && k<=3);
    double sum1, sum2;
    switch(k){
        case 1: // point vs. triangle
            *alpha1=-sos_orientation2d(pri0, x0, pri2, x2, pri3, x3);
            *alpha2= sos_orientation2d(pri0, x0, pri1, x1, pri3, x3);
            if(!same_sign(*alpha1, *alpha2)) return 0;
            *alpha3=-sos_orientation2d(pri0, x0, pri1, x1, pri2, x2);
            if(!same_sign(*alpha1, *alpha3)) return 0;
            *alpha0=1;
            sum2=*alpha1+*alpha2+*alpha3;
            *alpha1/=sum2;
            *alpha2/=sum2;
            *alpha3/=sum2;
            return 1;
        case 2: // segment vs. segment
            *alpha0= sos_orientation2d(pri1, x1, pri2, x2, pri3, x3);
            *alpha1=-sos_orientation2d(pri0, x0, pri2, x2, pri3, x3);
            if(!same_sign(*alpha0, *alpha1)) return 0;
            *alpha2= sos_orientation2d(pri0, x0, pri1, x1, pri3, x3);
            *alpha3=-sos_orientation2d(pri0, x0, pri1, x1, pri2, x2);
            if(!same_sign(*alpha2, *alpha3)) return 0;
            sum1=*alpha0+*alpha1;
            *alpha0/=sum1;
            *alpha1/=sum1;
            sum2=*alpha2+*alpha3;
            *alpha2/=sum2;
            *alpha3/=sum2;
            return 1;
        case 3: // triangle vs. point
            return sos_simplex_intersection2d(1, pri3, x3,
                                              pri2, x2,
                                              pri1, x1,
                                              pri0, x0,
                                              alpha3, alpha2, alpha1, alpha0);
        default:
            return -1; // should never get here
    }
}
//==============================================================================
int
sos_simplex_intersection1d(int k,
                           int pri0, const double* x0,
                           int pri1, const double* x1,
                           int pri2, const double* x2,
                           double* alpha0, 
                           double* alpha1, 
                           double* alpha2)
{
    assert(1<=k && k<=2);
    assert(alpha0 && alpha1 && alpha2);
    
    if(alpha0 == NULL || alpha1 == NULL || alpha2 == NULL) //prevent null pointer warning
       return -1;

    double sum;
    switch(k){
        case 1: // point vs. segment
            *alpha1=-sos_orientation1d(pri0, x0, pri2, x2);
            *alpha2= sos_orientation1d(pri0, x0, pri1, x1);
            if(same_sign(*alpha1, *alpha2)){
                *alpha0=1;
                sum=*alpha1+*alpha2;
                *alpha1/=sum;
                *alpha2/=sum;
                return 1;
            }else
                return 0;
        case 2: // segment vs. point
            return sos_simplex_intersection1d(1, pri2, x2,
                                              pri1, x1,
                                              pri0, x0,
                                              alpha2, alpha1, alpha0);
        default:
            return -1; // should never get here
    }
}
//==============================================================================
int
sos_simplex_intersection4d(int k,
                           int pri0, const double* x0,
                           int pri1, const double* x1,
                           int pri2, const double* x2,
                           int pri3, const double* x3,
                           int pri4, const double* x4,
                           int pri5, const double* x5,
                           double* alpha0, 
                           double* alpha1, 
                           double* alpha2,
                           double* alpha3,
                           double* alpha4,
                           double* alpha5)
{
    assert(1<=k && k<=5);
    double sum1, sum2;
    switch(k){
        case 1: // point vs. pentachoron
            *alpha1=-sos_orientation4d(pri0,x0,pri2,x2,pri3,x3,pri4,x4,pri5,x5);
            *alpha2= sos_orientation4d(pri0,x0,pri1,x1,pri3,x3,pri4,x4,pri5,x5);
            if(!same_sign(*alpha1, *alpha2)) return 0;
            *alpha3=-sos_orientation4d(pri0,x0,pri1,x1,pri2,x2,pri4,x4,pri5,x5);
            if(!same_sign(*alpha1, *alpha3)) return 0;
            *alpha4= sos_orientation4d(pri0,x0,pri1,x1,pri2,x2,pri3,x3,pri5,x5);
            if(!same_sign(*alpha1, *alpha4)) return 0;
            *alpha5=-sos_orientation4d(pri0,x0,pri1,x1,pri2,x2,pri3,x3,pri4,x4);
            if(!same_sign(*alpha1, *alpha5)) return 0;
            *alpha0=1;
            sum2=*alpha1+*alpha2+*alpha3+*alpha4+*alpha5;
            *alpha1/=sum2;
            *alpha2/=sum2;
            *alpha3/=sum2;
            *alpha4/=sum2;
            *alpha5/=sum2;
            return 1;
        case 2: // segment vs. tetrahedron
            *alpha0= sos_orientation4d(pri1,x1,pri2,x2,pri3,x3,pri4,x4,pri5,x5);
            *alpha1=-sos_orientation4d(pri0,x0,pri2,x2,pri3,x3,pri4,x4,pri5,x5);
            if(!same_sign(*alpha0, *alpha1)) return 0;
            *alpha2= sos_orientation4d(pri0,x0,pri1,x1,pri3,x3,pri4,x4,pri5,x5);
            *alpha3=-sos_orientation4d(pri0,x0,pri1,x1,pri2,x2,pri4,x4,pri5,x5);
            if(!same_sign(*alpha2, *alpha3)) return 0;
            *alpha4= sos_orientation4d(pri0,x0,pri1,x1,pri2,x2,pri3,x3,pri5,x5);
            if(!same_sign(*alpha2, *alpha4)) return 0;
            *alpha5=-sos_orientation4d(pri0,x0,pri1,x1,pri2,x2,pri3,x3,pri4,x4);
            if(!same_sign(*alpha2, *alpha5)) return 0;
            sum1=*alpha0+*alpha1;
            *alpha0/=sum1;
            *alpha1/=sum1;
            sum2=*alpha2+*alpha3+*alpha4+*alpha5;
            *alpha2/=sum2;
            *alpha3/=sum2;
            *alpha4/=sum2;
            *alpha5/=sum2;
            return 1;
        case 3: // triangle vs. triangle
            *alpha0= sos_orientation4d(pri1,x1,pri2,x2,pri3,x3,pri4,x4,pri5,x5);
            *alpha1=-sos_orientation4d(pri0,x0,pri2,x2,pri3,x3,pri4,x4,pri5,x5);
            if(!same_sign(*alpha0, *alpha1)) return 0;
            *alpha2= sos_orientation4d(pri0,x0,pri1,x1,pri3,x3,pri4,x4,pri5,x5);
            if(!same_sign(*alpha0, *alpha2)) return 0;
            *alpha3=-sos_orientation4d(pri0,x0,pri1,x1,pri2,x2,pri4,x4,pri5,x5);
            *alpha4= sos_orientation4d(pri0,x0,pri1,x1,pri2,x2,pri3,x3,pri5,x5);
            if(!same_sign(*alpha3, *alpha4)) return 0;
            *alpha5=-sos_orientation4d(pri0,x0,pri1,x1,pri2,x2,pri3,x3,pri4,x4);
            if(!same_sign(*alpha3, *alpha5)) return 0;
            sum1=*alpha0+*alpha1+*alpha2;
            *alpha0/=sum1;
            *alpha1/=sum1;
            *alpha2/=sum1;
            sum2=*alpha3+*alpha4+*alpha5;
            *alpha3/=sum2;
            *alpha4/=sum2;
            *alpha5/=sum2;
            return 1;
        case 4: // tetrahedron vs. segment
        case 5: // pentachoron vs. point
            return sos_simplex_intersection4d(6-k, pri5, x5,
                                              pri4, x4,
                                              pri3, x3,
                                              pri2, x2,
                                              pri1, x1,
                                              pri0, x0,
                                              alpha5, alpha4, alpha3, alpha2, alpha1, alpha0);
        default:
            return -1; // should never get here
    }
}
Esempio n. 4
0
//--------------------------------------------------------------
int drawingCanvas::intersection(ofVec2f lineA1,ofVec2f lineA2,ofVec2f lineB1,ofVec2f lineB2){
	float s1;
	float s2;
	//this check if points of second line segment are on the same side of the first line segment or not
	//s1 = ((lineA2.x-lineA1.x)*(lineB1.y-lineA1.y))-((lineA2.y-lineA1.y)*(lineB1.x-lineA1.x));
	//s2 = ((lineA2.x-lineA1.x)*(lineB2.y-lineA1.y))-((lineA2.y-lineA1.y)*(lineB2.x-lineA1.x));
	//if(s1 == s2){
	//	return false;
	//}else{
	//	return true;
	//}

	//////better approach
	float a1, a2, b1, b2, c1, c2;
	float r1, r2 , r3, r4;
	float denom, offset, num;

	// Compute a1, b1, c1, where line joining points 1 and 2
	// is "a1 x + b1 y + c1 = 0".
	a1 = lineA2.y - lineA1.y;
	b1 = lineA1.x - lineA2.x;
	c1 = (lineA2.x * lineA1.y) - (lineA1.x * lineA2.y);

	// Compute r3 and r4.
	r3 = ((a1 * lineB1.x) + (b1 * lineB1.y) + c1);
	r4 = ((a1 * lineB2.x) + (b1 * lineB2.y) + c1);

	// Check signs of r3 and r4. If both point 3 and point 4 lie on
	// same side of line 1, the line segments do not intersect.
	if ((r3 != 0) && (r4 != 0) && same_sign(r3, r4)){
		return 0;//DONT intersect
	}

	// Compute a2, b2, c2
	a2 = lineB2.y - lineB1.y;
	b2 = lineB1.x - lineB2.x;
	c2 = (lineB2.x * lineB1.y) - (lineB1.x * lineB2.y);

	// Compute r1 and r2
	r1 = (a2 * lineA1.x) + (b2 * lineA1.y) + c2;
	r2 = (a2 * lineA2.x) + (b2 * lineA2.y) + c2;

	// Check signs of r1 and r2. If both point 1 and point 2 lie
	// on same side of second line segment, the line segments do
	// not intersect.
	if ((r1 != 0) && (r2 != 0) && (same_sign(r1, r2))){
		return 0;//DONT intersect
	}

	//Line segments intersect: compute intersection point.
	denom = (a1 * b2) - (a2 * b1);

	if (denom == 0) {
		return 1;//collinear
	}

	if (denom < 0){ 
		offset = -denom / 2; 
	} 
	else {
		offset = denom / 2 ;
	}

	// The denom/2 is to get rounding instead of truncating. It
	// is added or subtracted to the numerator, depending upon the
	// sign of the numerator.
	//num = (b1 * c2) - (b2 * c1);
	//if (num < 0){
	//	x = (num - offset) / denom;
	//} 
	//else {
	//	x = (num + offset) / denom;
	//}

	//num = (a2 * c1) - (a1 * c2);
	//if (num < 0){
	//	y = ( num - offset) / denom;
	//} 
	//else {
	//	y = (num + offset) / denom;
	//}

	// lines_intersect
	return 2;

}