void H2PolygonTriangulater::findCutInSubpolygon2(const std::vector<uint> &indices, uint &outputIndex1, uint &outputIndex2) const { uint i,j; double max = 0, angle; for(j=2;j<indices.size()-1;++j) { if (!sameSide(indices[0], indices[j])) { angle = minAngleOfCutInSubpolygon(indices,0,j); if(angle>max) { max = angle; outputIndex1 = 0; outputIndex2 = j; } } } for(i = 1;i+2<indices.size();++i) { for(j=i+2;j<indices.size();++j) { if (!sameSide(indices[i], indices[j])) { angle = minAngleOfCutInSubpolygon(indices,i,j); if(angle>max) { max = angle; outputIndex1 = i; outputIndex2 = j; } } } } }
void intersect(double ret[2], double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4 ){ if(sameSide(x1,y1,x2,y2,x3,y3,x4,y4) > 0){ printf("Both points on the same side at begining\n"); exit(1); } double tx = x2; double ty = y2; double ox = x1; double oy = y1; while(1==1){ double side = sameSide(x1,y1,tx,ty,x3,y3,x4,y4); if(sameSide(tx,ty,ox,oy,x3,y3,x4,y4) > 0){ printf("both points on same side\n"); break; } if(fabs((tx-ox)/2) < 0.01 && fabs((ty-oy)/2) < 0.01 ) { ret[0]=tx; ret[1]=ty; return; } else if(side > 0){ double tempx, tempy; tempx = tx - ((tx-ox)/2); tempy = ty - ((ty-oy)/2); if(sameSide(tx,ty,tempx,tempy,x3,y3,x4,y4) > 0){ tx = tempx; ty = tempy; }else{ ox = tempx; oy = tempy; } }else if(side < 0){ double tempx, tempy; tempx = ox - ((ox-tx)/2); tempy = oy - ((oy-ty)/2); if(sameSide(ox,oy,tempx,tempy,x3,y3,x4,y4) > 0){ ox = tempx; oy = tempy; }else{ tx = tempx; ty = tempy; } } else if(side == 0 ){ ret[0]=tx; ret[1]=ty; return; } } }
bool verticesInTriangle ( int a, int b, int c, Vec2Array* vertices, vector<int>& valid ) { for ( int i = 0; i < valid.size(); i++ ) { if ( valid[i] == a || valid[i] == b || valid[i] == c ) continue; if ( sameSide(vertices->at( valid[i] ), vertices->at(a), vertices->at(b), vertices->at(c)) && sameSide(vertices->at( valid[i] ), vertices->at(b), vertices->at(a), vertices->at(c)) && sameSide(vertices->at( valid[i] ), vertices->at(c), vertices->at(a), vertices->at(b)) ) { return true; } } return false; }
bool DegradeAnObject::isAPointInATriangle(Point_3 p, Point_3 a, Point_3 b, Point_3 c) { Plane_3 pl(a, b, c); if(pl.has_on(p)) { if(sameSide(p, a, b, c) && sameSide(p, b, a, c) && sameSide(p, c, a, b)) { return true; } else { return false; } } else { return false; } }
/*************************************************************************** ISINTRIANGLE NAME: isInTriangle PURPOSE: Giving a triangle ABC, this function tell us a point D is inside this triangle or not. This function uses the SAMESIDE function described below. CALLING SEQUENCE: int inTrinagle = isInTriangle() INPUTS : struct Vector *AB : Line joining the A vertex with his first coordinate B struct Vector *AD : Line joining the point D for the A vertex struct Vector *AC : Line joining the A vertex with his second coordinate C struct Vector *CA : Line joining the C vertex with his first coordinate A struct Vector *CD : Line joining the point D for the C vertex struct Vector *CB : Line joining the C vertex with his second coordinate D struct Vector *BA : Line joining the B vertex with his first coordinate A struct Vector *BD : Line joining the point D for the B vertex struct Vector *BC : Line joining the B vertex with his second coordinate C OUTPUTS : No outputs RETURN : Return code with a boolean effect : * 0 : inside the triangle (True) * 1 : outside the triangle (False) *****************************************************************************/ int isInTriangle(struct Vector *AB, struct Vector *AD, struct Vector *AC, struct Vector *CA, struct Vector *CD, struct Vector *CB, struct Vector *BA, struct Vector *BD, struct Vector *BC) { int s1; int s2; int s3; s1 = sameSide(&AB, &AD, &AC); s2 = sameSide(&CA, &CD, &CB); s3 = sameSide(&BA, &BD, &BC); if ((s1 == 0) && (s2 == 0) && (s3 == 0)) { return 0; } else { return 1; } }
int vertLineCheck (double x0, double x1, double x2, double y2, double px, double py, double m, double b){ int result; if (x1 == x0) { result = ((px <= x0) == (x2 <= x0)); } else { result = sameSide (px, py, m, b, x2, y2); } return result; }
int tests () { // vertPosition (px, py, m, b); assert (vertPosition (2.0, 1.0, 1.0, 0.0 ) == UNDER); assert (vertPosition (2.0, 2.0, 1.0, 0.0 ) == ON_LINE); assert (vertPosition (2.0, 3.0, 1.0, 0.0 ) == ABOVE); assert (vertPosition (2.0, 1.0, -1.0, 4.0 ) == UNDER); assert (vertPosition (2.0, 2.0, -1.0, 4.0 ) == ON_LINE); assert (vertPosition (2.0, 3.0, -1.0, 4.0 ) == ABOVE); assert (vertPosition (-2.0, -2.0, 1.0, 2.0 ) == UNDER); assert (vertPosition (-2.0, 0.0, 1.0, 2.0 ) == ON_LINE); assert (vertPosition (-2.0, 2.0, 1.0, 2.0 ) == ABOVE); assert (vertPosition (0.0, 1.0, 0.0, 0.0 ) == ABOVE); assert (vertPosition (0.0, 0.0, 0.0, 0.0 ) == ON_LINE); assert (vertPosition (0.0, -1.0, 0.0, 0.0 ) == UNDER); // bothAbove (test1 (px, py, m, b, lx, ly)); assert (sameSide (1.0, 4.0, 1.0, 2.0, 3.0, 6.0) == TRUE); assert (sameSide (1.0, 4.0, 1.0, 2.0, 3.0, 2.0) == FALSE); assert (sameSide (1.0, 4.0, 1.0, 2.0, 1.0, 1.0) == FALSE); assert (sameSide (1.0, 1.0, 1.0, 1.0, 3.0, 2.0) == TRUE); assert (sameSide (1.0, 1.0, 0, 1.0, 2.0, 1.0) == TRUE); assert (sameSide (1.0, 0.0, 0, 0.0, 2.0, 0.0) == TRUE); assert (sameSide (0.5, 0.0, 0, 0.0, 0.0, 1.0) == FALSE); // assert (triangleTest (x0, y0, x1, y1, x2, y2, px, py)); // assert (triangleTest (0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.25, 0.25) == TRUE); assert (triangleTest (0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 2.0, 2.0) == FALSE); /* Special case where P(x,y) lies on a hozizontal line. Not sure if this should be true or false. Test is below for either. I will assume a FALSE result for my program assert (tritest (0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.5, 0.0) == TRUE); XXX Special */ assert (triangleTest (0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.5, 0.0) == FALSE); assert (triangleTest (0.0, 0.0, 0.0, -1.0, -1.0, 0.0, -0.25, -0.25) == TRUE); printf("Tests Completed Sucessfully.\n"); return EXIT_SUCCESS; }
bool pointInsideTriangle(RX::vec2 p1, RX::vec2 p2, RX::vec2 p3, RX::vec2 p) { if((sameSide(p, p1, p2, p3))&&(sameSide(p, p2, p1, p3))&&(sameSide(p, p3, p1, p2))) return true; return false; }
bool H2PolygonTriangulater::attemptFlip() { TriangulationTriangle leftTriangle, rightTriangle; uint sharedIndex1, sharedIndex2, unsharedIndexLeft, unsharedIndexRight, leftTriangleIndex, rightTriangleIndex; bool out = false; std::vector<uint> quadrilateralIndices; quadrilateralIndices.reserve(4); uint l1, l2, l3, k1, k2, k3; bool rightTriangleCheats = false; uint cutIndex=0; while (!out && cutIndex<cuts.size()) { quadrilateralIndices.clear(); sharedIndex1 = cuts[cutIndex].vertexIndex1; sharedIndex2 = cuts[cutIndex].vertexIndex2; leftTriangleIndex = cuts[cutIndex].leftTriangleIndex; rightTriangleIndex = cuts[cutIndex].rightTriangleIndex; leftTriangle = triangles[leftTriangleIndex]; rightTriangle = triangles[rightTriangleIndex]; leftTriangle.getVertices(sharedIndex1, unsharedIndexLeft, sharedIndex2); rightTriangle.getVertices(l1, l2, l3); if (l1==cuts[cutIndex].vertexIndex1) { rightTriangleCheats = false; rightTriangle.getVertices(sharedIndex1, sharedIndex2, unsharedIndexRight); } else if (l2==cuts[cutIndex].vertexIndex1) { rightTriangleCheats = true; rightTriangle.getVertices(unsharedIndexRight, sharedIndex1, sharedIndex2); } else { throw(QString("ERROR in H2PolygonTriangulater::testQuadrilateralForFlipLengths: A triangle abutting a cut doesn't have vertices compatible with the desired cut")); } quadrilateralIndices.push_back(sharedIndex1); quadrilateralIndices.push_back(unsharedIndexLeft); quadrilateralIndices.push_back(sharedIndex2); quadrilateralIndices.push_back(unsharedIndexRight); //if (testQuadrilateralForFlipLengths(quadrilateralIndices) && !sameSide(unsharedIndex1,unsharedIndex2)) if (testQuadrilateralForFlipAngles(quadrilateralIndices) && !sameSide(unsharedIndexLeft,unsharedIndexRight)) { getCutsFromTriangle(leftTriangleIndex, l1, l2, l3); getCutsFromTriangle(rightTriangleIndex, k1, k2, k3); if (l1 < cuts.size()) { cuts[l1].rightTriangleIndex = rightTriangleIndex; } else { sideTrianglesIndices[sharedIndex1] = rightTriangleIndex; sideTrianglesBoundarySideIndices[sharedIndex1] = 0; } if (l3 < cuts.size()) { cuts[l3].rightTriangleIndex = leftTriangleIndex; } else { sideTrianglesIndices[unsharedIndexLeft] = leftTriangleIndex; sideTrianglesBoundarySideIndices[unsharedIndexLeft] = 0; } if (!rightTriangleCheats) { if (k2 < cuts.size()) { cuts[k2].leftTriangleIndex = rightTriangleIndex; } else { sideTrianglesIndices[unsharedIndexRight] = rightTriangleIndex; sideTrianglesBoundarySideIndices[unsharedIndexRight] = 2; } if (k3 < cuts.size()) { cuts[k3].rightTriangleIndex = leftTriangleIndex; } else { sideTrianglesIndices[sharedIndex2] = leftTriangleIndex; sideTrianglesBoundarySideIndices[unsharedIndexRight] = 1; } } else { if (k1 < cuts.size()) { cuts[k1].rightTriangleIndex = rightTriangleIndex; } else { sideTrianglesIndices[unsharedIndexRight] = rightTriangleIndex; sideTrianglesBoundarySideIndices[unsharedIndexRight] = 0; } if (k2 < cuts.size()) { cuts[k2].leftTriangleIndex = leftTriangleIndex; } else { sideTrianglesIndices[sharedIndex2] = leftTriangleIndex; sideTrianglesBoundarySideIndices[unsharedIndexRight] = 2; } } if (!rightTriangleCheats) { triangles[leftTriangleIndex] = TriangulationTriangle(unsharedIndexLeft,sharedIndex2,unsharedIndexRight); triangles[rightTriangleIndex] = TriangulationTriangle(sharedIndex1,unsharedIndexLeft,unsharedIndexRight); } else { triangles[leftTriangleIndex] = TriangulationTriangle(unsharedIndexRight,unsharedIndexLeft,sharedIndex2); triangles[rightTriangleIndex] = TriangulationTriangle(unsharedIndexRight,sharedIndex1,unsharedIndexLeft); } if (!rightTriangleCheats) { cuts[cutIndex] = TriangulationCut(unsharedIndexLeft,unsharedIndexRight,leftTriangleIndex,rightTriangleIndex); } else { cuts[cutIndex] = TriangulationCut(unsharedIndexRight,unsharedIndexLeft,rightTriangleIndex,leftTriangleIndex); } return true; } ++cutIndex; } return false; }
bool FEdge::intersectParametric(FEdge & fe2, Vec3r viewpoint, real t3D, real u3D) { Vec3r A1 = vertexA()->getPoint3D(); Vec3r B1 = vertexB()->getPoint3D(); Vec3r A2 = fe2.vertexA()->getPoint3D(); Vec3r B2 = fe2.vertexB()->getPoint3D(); if (sameSide(A1,B1,viewpoint, A2, B2) || sameSide(A2, B2, viewpoint, A1, B1)) return false; // now, there *must* be an intersection. // for each edge, the normal of the plane containing the edge and the viewpoint Vec3r N1 = (A1-viewpoint) ^ (B1-viewpoint); Vec3r N2 = (A2-viewpoint) ^ (B2-viewpoint); // direction vector of the intersection of the two planes. Vec3r V = N1 ^ N2; // check if the planes coincide (i.e., source edges are colinear) assert(V.norm() > 0); // ----- compute t parameter ------ // form a plane for line 1, normal to the plane containing the viewpoint Vec3r BA1 = B1 - A1; Vec3r hsNormal1 = N1 ^ BA1; // intersect ray in direction of V through the plane real w1; GeomUtils::intersection_test res1 = GeomUtils::intersectLinePlanePN(viewpoint, V, hsNormal1, A1, w1); if (res1 != GeomUtils::DO_INTERSECT) { printf("res1 = %d\n", res1); printf("viewpoint = [%f %f %f]\n", viewpoint[0], viewpoint[1], viewpoint[2]); printf("A1 = [%f %f %f]\n", A1[0], A1[1], A1[2]); printf("B1 = [%f %f %f]\n", B1[0], B1[1], B1[2]); printf("A2 = [%f %f %f]\n", A2[0], A2[1], A2[2]); printf("B2 = [%f %f %f]\n", B2[0], B2[1], B2[2]); printf("N1 = [%f %f %f]\n", N1[0], N1[1], N1[2]); printf("N2 = [%f %f %f]\n", N2[0], N2[1], N2[2]); printf("V = [%f %f %f]\n", V[0], V[1], V[2]); printf("hsNormal1 = [%f %f %f]\n", hsNormal1[0], hsNormal1[1], hsNormal1[2]); } assert(res1 == GeomUtils::DO_INTERSECT); Vec3r pt1 = viewpoint + w1 * V; t3D = ((pt1 - A1) * BA1) / (BA1*BA1); assert(t3D >=0 && t3D <= 1); // if (t3D < 0 || t3D > 1) // return false; // ----- compute u parameter ------ // form a half-space plane for line 2 Vec3r BA2 = B2 - A2; Vec3r hsNormal2 = N2 ^ BA2; real w2; GeomUtils::intersection_test res2 = GeomUtils::intersectLinePlanePN(viewpoint, V, hsNormal2, A2, w2); if (res2 != GeomUtils::DO_INTERSECT) { printf("res1 = %d\n", res1); printf("viewpoint = [%f %f %f]\n", viewpoint[0], viewpoint[1], viewpoint[2]); printf("A1 = [%f %f %f]\n", A1[0], A1[1], A1[2]); printf("B1 = [%f %f %f]\n", B1[0], B1[1], B1[2]); printf("A2 = [%f %f %f]\n", A2[0], A2[1], A2[2]); printf("B2 = [%f %f %f]\n", B2[0], B2[1], B2[2]); printf("N1 = [%f %f %f]\n", N1[0], N1[1], N1[2]); printf("N2 = [%f %f %f]\n", N2[0], N2[1], N2[2]); printf("V = [%f %f %f]\n", V[0], V[1], V[2]); printf("hsNormal2 = [%f %f %f]\n", hsNormal2[0], hsNormal2[1], hsNormal2[2]); } assert(res2 == GeomUtils::DO_INTERSECT); Vec3r pt2 = viewpoint + w2 * V; u3D = ((pt2 - A2) * BA2) / (BA2*BA2); assert( u3D >=0 && u3D <=1); // if (u3D < 0 || u3D > 1) // return false; return true; }
int clip(double xp[], double yp[], int size){ int i, j; int count = 0; double tempx[1000], tempy[1000]; // printf("init\n"); for(i=0; i<size;i++){ tempx[i]=xp[i]; tempy[i]=yp[i]; count++; } for(i=0;i<cSize;i++){ double clipx[1000],clipy[1000]; int tcount = 0; int f; // printf("Coords \n"); for(j=0;j<count;j++){ double spointSide = sameSide(center[0], center[1], tempx[j], tempy[j], cx[i], cy[i], cx[(i+1)%cSize] ,cy[(i+1)%cSize]); double epointSide = sameSide(center[0], center[1], tempx[(j+1)%count], tempy[(j+1)%count], cx[i], cy[i],cx[(i+1)%cSize] ,cy[(i+1)%cSize]); if(spointSide > 0 && epointSide > 0){//both inside clipx[tcount] = tempx[(j+1)%count]; clipy[tcount] = tempy[(j+1)%count]; tcount++; } else if(spointSide < 0 && epointSide < 0){//both outside } else if(spointSide > 0 && epointSide < 0){//start in end out double point[2]; intersect(point,tempx[j],tempy[j],tempx[(j+1)%count],tempy[(j+1)%count],cx[i],cy[i],cx[(i+1)%cSize],cy[(i+1)%cSize] ); clipx[tcount] = point[0]; clipy[tcount] = point[1]; tcount++; }else if(spointSide < 0 && epointSide > 0){//start out end in double point[2]; intersect(point,tempx[(j+1)%count],tempy[(j+1)%count],tempx[j],tempy[j],cx[i],cy[i],cx[(i+1)%cSize],cy[(i+1)%cSize] ); clipx[tcount] = point[0]; clipy[tcount] = point[1]; tcount++; clipx[tcount] = tempx[(j+1)%count]; clipy[tcount] = tempy[(j+1)%count]; tcount++; } else if(spointSide == 0 && epointSide == 0){//both on the line clipx[tcount] = tempx[(j+1)%count]; clipy[tcount] = tempy[(j+1)%count]; tcount++; } else if(epointSide == 0 && spointSide > 0){//end on line start inside clipx[tcount] = tempx[(j+1)%count]; clipy[tcount] = tempy[(j+1)%count]; tcount++; } else if(epointSide == 0 && spointSide < 0){//end on line start outside clipx[tcount] = tempx[(j+1)%count]; clipy[tcount] = tempy[(j+1)%count]; tcount++; } else if(spointSide == 0 && epointSide > 0){//start on line end inside //add start and end point to array clipx[tcount] = tempx[j]; clipy[tcount] = tempy[j]; tcount++; clipx[tcount] = tempx[(j+1)%count]; clipy[tcount] = tempy[(j+1)%count]; tcount++; } else if(spointSide == 0 && epointSide < 0){//start on line end outside // add start point to array clipx[tcount] = tempx[j]; clipy[tcount] = tempy[j]; tcount++; } else{ printf("nothing works and everything is terrible \n"); } } int k; count = tcount; for(k=0;k<count;k++){ tempx[k] = clipx[k]; tempy[k] = clipy[k]; } } for(i=0; i<count;i++){ xp[i]=tempx[i]; yp[i]=tempy[i]; } return count; }