//============================================================================== 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 } }
//-------------------------------------------------------------- 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; }