void drawATriangle(int ix1, int ix2, int ix3) { LongInt xl,yl; int x1,x2,x3,y1,y2,y3; myPointSet.getPoint(ix1,xl,yl); x1=atof(xl.printOut().c_str())*scale[nowS]+DX; y1=atof(yl.printOut().c_str())*scale[nowS]+DY; myPointSet.getPoint(ix2,xl,yl); x2=atof(xl.printOut().c_str())*scale[nowS]+DX; y2=atof(yl.printOut().c_str())*scale[nowS]+DY; myPointSet.getPoint(ix3,xl,yl); x3=atof(xl.printOut().c_str())*scale[nowS]+DX; y3=atof(yl.printOut().c_str())*scale[nowS]+DY; glBegin(GL_POLYGON); glColor3f(0,0.5,0); glVertex2d(x1,y1); glVertex2d(x2,y2); glVertex2d(x3,y3); glEnd(); drawALine(x1,y1,x2,y2); drawALine(x1,y1,x3,y3); drawALine(x2,y2,x3,y3); }
bool IPhelper(Trist &tri1, int x, int y, bool readfile){ int i,a,b,c,d, triangleIdx1, triangleIdx2, triangleIdx3; MyPoint pd; //cout<<x<<endl;cout<<y<<endl; x=x/scale[nowS]; y=y/scale[nowS]; pd.x=LongInt(x); pd.y=LongInt(y); d=myPointSet.addPoint(LongInt(x),LongInt(y)); for (i=1;i<=tri1.noTri();i++){ tri1.getVertexIdx(i<<3,a,b,c); if (myPointSet.inTri(a,b,c,pd)>0){ vec.push_back(d); if(readfile){ tri1.delTri(i<<3); triangleIdx1 = tri1.makeTri(a,b,d); triangleIdx2 = tri1.makeTri(b,c,d); triangleIdx3 = tri1.makeTri(a,c,d); legalizeEdge(tri1,d,a,b, triangleIdx1); legalizeEdge(tri1,d,b,c, triangleIdx2); legalizeEdge(tri1,d,a,c, triangleIdx3); } return 1; } } return 0; }
// It's slightly awkward, but we assume that the PointSet we're // given is constant for rest of DAG; DirectedGraph::DirectedGraph(const PointSetArray& inputPointSet) { // TODO: If keep a separate copy of inputPointSet, // then wouldn't need delaunay.cpp to use `- 3` magic. // XXX Should use copy-c'tor for PointSetArray (test first?). // Copy points from the input set to Delaunay point set for (int i = 1; i <= inputPointSet.noPt(); i++) { LongInt x, y; inputPointSet.getPoint(i, x, y); pointSet_.addPoint(x, y); } int numPoints = pointSet_.noPt(); // Add a triangle which bounds all the points. findBoundingTri(pointSet_); // Construct root DAGNode as the bounding triangle. // (Delaunay Iteration algorithm can 'add' the 'actual' points, // which is also slightly awkward, but whatever). // Points of bounding tri are the last three, // so, numPoints+1, numPoints+2, numPoints+3 int boundingTriPt1 = numPoints + 1; TriRecord boundingTri(boundingTriPt1, boundingTriPt1 + 1, boundingTriPt1 + 2); root_ = shared_ptr<DAGNode>(new DAGNode(boundingTri)); root_->fIndex_ = trist_.addLinkedTri(boundingTri); dagNodes_.push_back(root_); }
void drawPointSetArray(const PointSetArray& pointSet) { // Draw input points for (int i = 1; i <= pointSet.noPt(); i++){ LongInt px, py; pointSet.getPoint(i, px, py); drawAPoint(px.doubleValue(), py.doubleValue()); } }
void readFile(){ string line_noStr; string line; // each line of the file string command;// the command of each line string numberStr; // for single LongInt operation string outputAns = "Answer of your computation"; // the answer you computed ifstream inputFile("input.txt",ios::in); int delay=0; const int largeCoor=5000; myPointSet.eraseAllPoints(); myTrist.eraseAllTris(); noIPTrist.eraseAllTris(); myPointSet.addPoint(-largeCoor,largeCoor/2); myPointSet.addPoint(largeCoor,largeCoor/2); myPointSet.addPoint(0,-largeCoor/2); myTrist.makeTri(1,2,3); if(inputFile.fail()){ cerr << "Error: Cannot read input file \"" << "input.txt" << "\""; return; } while(inputFile.good()){ getline(inputFile,line); if(line.empty()) { command = ""; continue; }// in case the line has nothing in it stringstream linestream(line); linestream >> line_noStr; linestream >> command; // get the command if (delay>0) Sleep(delay); if(!command.compare("AP")){ linestream >> numberStr; LongInt p1 = LongInt::LongInt(numberStr.c_str()); linestream >> numberStr; LongInt p2 = LongInt::LongInt(numberStr.c_str()); int output = myPointSet.addPoint(p1, p2); } else if(!command.compare("OT")){
TEST(PointSetTest, InCircleTrivialOutside) { PointSetArray pointSet; int p1 = pointSet.addPoint(0, 0); int p2 = pointSet.addPoint(100, 0); // int p3 = pointSet.addPoint(100, 100); int p4 = pointSet.addPoint(0, 100); // int p5 = pointSet.addPoint(50, 50); int p6 = pointSet.addPoint(2000, 2000); // (200,200) is *outside* the circum-circle of <p1,p2,p4> EXPECT_EQ(-1, pointSet.inCircle(p1, p2, p4, p6)); }
TEST(PointSetTest, InCircleTrivialWithin) { PointSetArray pointSet; int p1 = pointSet.addPoint(0, 0); int p2 = pointSet.addPoint(100, 0); // int p3 = pointSet.addPoint(100, 100); int p4 = pointSet.addPoint(0, 100); int p5 = pointSet.addPoint(50, 50); // int p6 = pointSet.addPoint(2000, 2000); // (50,50) is *within* the circum-circle of <p1,p2,p4> EXPECT_EQ(1, pointSet.inCircle(p1, p2, p4, p5)); }
// Delaunay algorithm breaking, e.g. of invalid: // 1. (425,342) // 2. (306,57) // 3. (120,31) // 4. (396,483) // *both* abd, dbc are illegal TEST(PointSetTest, InCircleOutsideDelaunayIllegal) { PointSetArray pointSet; // abd is a tri, as is dbc. // abd doesn't contain c, // dbc doesn't contain a int p1 = pointSet.addPoint(425, 342); int p2 = pointSet.addPoint(306, 57); int p3 = pointSet.addPoint(120, 31); int p4 = pointSet.addPoint(396, 483); // Both triangles illegal. (i.e. contains point) EXPECT_EQ(1, pointSet.inCircle(p1, p2, p4, p3)); EXPECT_EQ(1, pointSet.inCircle(p4, p2, p3, p1)); }
void insert(Trist &tri1, int pIdx){ int i,a,b,c,d, triangleIdx1, triangleIdx2, triangleIdx3; MyPoint pd; myPointSet.getPoint(pIdx,pd.x,pd.y); for (i=1;i<=tri1.noTri();i++){ tri1.getVertexIdx(i<<3,a,b,c); if (myPointSet.inTri(a,b,c,pd)>0){ tri1.delTri(i<<3); triangleIdx1 = tri1.makeTri(a,b,pIdx); triangleIdx2 = tri1.makeTri(b,c,pIdx); triangleIdx3 = tri1.makeTri(a,c,pIdx); legalizeEdge(tri1,pIdx,a,b, triangleIdx1); legalizeEdge(tri1,pIdx,b,c, triangleIdx2); legalizeEdge(tri1,pIdx,a,c, triangleIdx3); return; } } }
void display(void) { int i, ix1, ix2, ix3; LongInt x1,y1; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); for (i=1;i<=myTrist.noTri();i++){ myTrist.getVertexIdx(i<<3,ix1,ix2,ix3); drawATriangle(ix1,ix2,ix3); } for (i=1;i<=myPointSet.noPt();i++){ myPointSet.getPoint(i,x1,y1); drawAPoint(atof(x1.printOut().c_str()),atof(y1.printOut().c_str())); } glPopMatrix(); glutSwapBuffers (); }
TEST(PointSetTest, PointSetInTriSimple) { PointSetArray ps; int p1 = ps.addPoint(0, 0); // 1 int p2 = ps.addPoint(0, 4); // 2 int p3 = ps.addPoint(4, 0); // 3 int p4 = ps.addPoint(4, 4); // 4 int p5 = ps.addPoint(1, 1); // 5 // (1, 1) IS in tri 123 EXPECT_EQ(1, ps.inTri(p1, p2, p3, p5)); // (1, 1) IS in tri 124 EXPECT_EQ(0, ps.inTri(p1, p2, p4, p5)); // (1, 1) IS NOT in tri 234 EXPECT_EQ(-1, ps.inTri(p2, p3, p4, p5)); }
// Delaunay algorithm breaking, e.g. of invalid: // 1. (374,112) // 2. (-6514,-2005) // 3. (128,6768) // 4. (147,376) TEST(PointSetTest, InCircleOutsideDelaunayLegal) { PointSetArray pointSet; // abd is a tri, as is dbc. // abd doesn't contain c, // dbc doesn't contain a int p1 = pointSet.addPoint(374, 112); int p2 = pointSet.addPoint(-6514, -2005); int p3 = pointSet.addPoint(128, 6768); int p4 = pointSet.addPoint(147, 376); // Both triangles legal. EXPECT_EQ(-1, pointSet.inCircle(p1, p2, p4, p3)); EXPECT_EQ(-1, pointSet.inCircle(p4, p2, p3, p1)); }
void legalizeEdge(Trist &tri, int idx, int idx1, int idx2, int triangleIdx){ int triangleIdx2; int idx3 = getVertex(myTrist, idx, idx1,idx2, triangleIdx2); if(idx3==-1) return; int ans = myPointSet.inCircle(idx,idx1,idx2,idx3); //OrTri ef = myTrist.fnext(triangleIdx<<3); //cout<<"triangleIdx2 is "<<triangleIdx2<<endl; //cout<<"ef is "<<(ef>>3)<<endl; /* if(ans ==0){ cout<<"degenerate"<<endl; }*/ if(ans > 0){ // flip edge idx1idx2 with idxidx3 //int triIdx1 = tri.makeTri(idx,idx1,idx3); //int triIdx2 = tri.makeTri(idx,idx2,idx3); tri.flipping(triangleIdx,triangleIdx2,idx,idx1,idx2,idx3); legalizeEdge(tri,idx,idx1,idx3,triangleIdx); legalizeEdge(tri,idx,idx2,idx3,triangleIdx2); //tri.delTri(triangleIdx<<3); //tri.delTri(triangleIdx2<<3); } }