double quadArea(vec3_t x0, vec3_t x1, vec3_t x2, vec3_t x3) { double A = 0; vec3_t p = .25*(x0+x1+x2+x3); A += triArea(x0,x1,p); A += triArea(x1,x2,p); A += triArea(x2,x3,p); A += triArea(x3,x0,p); return A; }
Edge *Subdivision::locate(const Vec2& x, Edge *start) { Edge *e = start; double t = triArea(x, e->Dest(), e->Org()); if (t>0) { // x is to the right of edge e t = -t; e = e->Sym(); } while (true) { Edge *eo = e->Onext(); Edge *ed = e->Dprev(); double to = triArea(x, eo->Dest(), eo->Org()); double td = triArea(x, ed->Dest(), ed->Org()); if (td>0) // x is below ed if (to>0 || to==0 && t==0) {// x is interior, or origin endpoint startingEdge = e; return e; } else { // x is below ed, below eo t = to; e = eo; } else // x is on or above ed if (to>0) // x is above eo if (td==0 && t==0) { // x is destination endpoint startingEdge = e; return e; } else { // x is on or above ed and above eo t = td; e = ed; } else // x is on or below eo if (t==0 && !leftOf(eo->Dest(), e)) // x on e but subdiv. is to right e = e->Sym(); else if (rand()&1) { // x is on or above ed and t = to; // on or below eo; step randomly e = eo; } else { t = td; e = ed; } } }
double cellVA(vtkUnstructuredGrid *grid, vtkIdType cellId, bool neg) { vtkIdType *pts; vtkIdType Npts; vec3_t p[8]; grid->GetCellPoints(cellId, Npts, pts); for (int i_pts = 0; i_pts < Npts; ++i_pts) { grid->GetPoints()->GetPoint(pts[i_pts], p[i_pts].data()); } vtkIdType cellType = grid->GetCellType(cellId); if (cellType == VTK_TRIANGLE) return triArea (p[0], p[1], p[2]); else if (cellType == VTK_QUAD) return quadArea(p[0], p[1], p[2], p[3]); else if (cellType == VTK_TETRA) return tetraVol(p[0], p[1], p[2], p[3], neg); else if (cellType == VTK_PYRAMID) return pyraVol (p[0], p[1], p[2], p[3], p[4], neg); else if (cellType == VTK_WEDGE) return prismVol(p[0], p[1], p[2], p[3], p[4], p[5], neg); else if (cellType == VTK_HEXAHEDRON) return hexaVol (p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], neg); return 0.0; }
//-------------------------------------------------------------- void calcSimplificaiton( vector < drawnPoint > & line){ int total = line.size(); // if we have 100 points, we have 98 triangles to look at int nTriangles = total - 2; triangle * triangles[ nTriangles ]; for (int i = 1; i < total-1; i++){ triangle * tempTri = new triangle(); tempTri->indices[0] = i-1; tempTri->indices[1] = i; tempTri->indices[2] = i+1; tempTri->area = triArea( line[tempTri->indices[0]].pos, line[tempTri->indices[1]].pos, line[tempTri->indices[2]].pos); triangles[i-1] = tempTri; } // set the next and prev triangles, use NULL on either end. this helps us update traingles that might need to be removed for (int i = 0; i < nTriangles; i++){ triangles[i]->prev = (i == 0 ? NULL : triangles[i-1]); triangles[i]->next = (i == nTriangles-1 ? NULL : triangles[i+1]); } std::vector<triangle*> trianglesVec; for (int i = 0; i < nTriangles; i++){ trianglesVec.push_back(triangles[i]); } int count = 0; while ( !trianglesVec.empty()){ ofSort(trianglesVec,compareTri); triangle * tri = trianglesVec[0]; line[tri->indices[1]].importance = total - count; // store the "importance" of this point in numerical order of removal (but inverted, so 0 = most improtant, n = least important. end points are 0. count ++; if (tri->prev != NULL){ tri->prev->next = tri->next; tri->prev->indices[2] = tri->indices[2]; // check! tri->prev->area = triArea( line[tri->prev->indices[0]].pos, line[tri->prev->indices[1]].pos, line[tri->prev->indices[2]].pos); } if (tri->next != NULL){ tri->next->prev = tri->prev; tri->next->indices[0] = tri->indices[0]; // check! tri->next->area = triArea( line[tri->next->indices[0]].pos, line[tri->next->indices[1]].pos, line[tri->next->indices[2]].pos); } trianglesVec.erase(trianglesVec.begin()); } // free the memory we just allocated above. for (int i = 0; i < nTriangles; i++){ delete triangles[i]; } }