void Triangulation::calculate_edges() { _VERBOSE("Triangulation::calculate_edges"); Py_XDECREF(_edges); // Create set of all edges, storing them with start point index less than // end point index. typedef std::set<Edge> EdgeSet; EdgeSet edge_set; for (int tri = 0; tri < _ntri; ++tri) { if (!is_masked(tri)) { for (int edge = 0; edge < 3; edge++) { int start = get_triangle_point(tri, edge); int end = get_triangle_point(tri, (edge+1)%3); edge_set.insert(start > end ? Edge(start,end) : Edge(end,start)); } } } // Convert to python _edges array. npy_intp dims[2] = {static_cast<npy_intp>(edge_set.size()), 2}; _edges = (PyArrayObject*)PyArray_SimpleNew(2, dims, PyArray_INT); int* edges_ptr = (int*)PyArray_DATA(_edges); for (EdgeSet::const_iterator it = edge_set.begin(); it != edge_set.end(); ++it) { *edges_ptr++ = it->start; *edges_ptr++ = it->end; } }
long optimise_heuristic(long tri_id1, long tri_id2) { //return _DK_optimise_heuristic(tri_id1, tri_id2); struct Triangle *tri1; struct Triangle *tri3; struct Point *pt; long tri_id3,tri_lnk; long Ax,Ay,Bx,By,Cx,Cy,Dx,Dy; tri1 = get_triangle(tri_id1); tri_id3 = tri1->tags[tri_id2]; if (tri_id3 == -1) return 0; tri3 = get_triangle(tri_id3); if (get_triangle_tree_alt(tri_id3) != get_triangle_tree_alt(tri_id1)) { return 0; } tri_lnk = link_find(tri_id3, tri_id1); if (( (tri1->field_D & (1 << tri_id2)) == 0) || ( (tri3->field_D & (1 << tri_lnk)) == 0)) { return 0; } pt = get_triangle_point(tri_id3, MOD3[tri_lnk+2]); Ax = pt->x; Ay = pt->y; pt = get_triangle_point(tri_id1, MOD3[tri_id2+2]); Bx = pt->x; By = pt->y; pt = get_triangle_point(tri_id1, MOD3[tri_id2+1]); Cx = pt->x; Cy = pt->y; pt = get_triangle_point(tri_id1, MOD3[tri_id2]); Dx = pt->x; Dy = pt->y; if (LbCompareMultiplications(Ay-By, Dx-Bx, Ax-Bx, Dy-By) >= 0) return 0; if (LbCompareMultiplications(Ay-By, Cx-Bx, Ax-Bx, Cy-By) <= 0) return 0; return ((Bx-Ax) * (Bx-Ax)) + ((By-Ay) * (By-Ay)) < ((Dy-Ay) - (Cy-Ay)) * ((Dy-Ay) - (Cy-Ay)) + ((Dx-Ax) - (Cx-Ax)) * ((Dx-Ax) - (Cx-Ax)); }
void Triangulation::calculate_boundaries() { _VERBOSE("Triangulation::calculate_boundaries"); get_neighbors(); // Ensure _neighbors has been created. // Create set of all boundary TriEdges, which are those which do not // have a neighbor triangle. typedef std::set<TriEdge> BoundaryEdges; BoundaryEdges boundary_edges; for (int tri = 0; tri < _ntri; ++tri) { if (!is_masked(tri)) { for (int edge = 0; edge < 3; ++edge) { if (get_neighbor(tri, edge) == -1) { boundary_edges.insert(TriEdge(tri, edge)); } } } } // Take any boundary edge and follow the boundary until return to start // point, removing edges from boundary_edges as they are used. At the same // time, initialise the _tri_edge_to_boundary_map. while (!boundary_edges.empty()) { // Start of new boundary. BoundaryEdges::iterator it = boundary_edges.begin(); int tri = it->tri; int edge = it->edge; _boundaries.push_back(Boundary()); Boundary& boundary = _boundaries.back(); while (true) { boundary.push_back(TriEdge(tri, edge)); boundary_edges.erase(it); _tri_edge_to_boundary_map[TriEdge(tri, edge)] = BoundaryEdge(_boundaries.size()-1, boundary.size()-1); // Move to next edge of current triangle. edge = (edge+1) % 3; // Find start point index of boundary edge. int point = get_triangle_point(tri, edge); // Find next TriEdge by traversing neighbors until find one // without a neighbor. while (get_neighbor(tri, edge) != -1) { tri = get_neighbor(tri, edge); edge = get_edge_in_triangle(tri, point); } if (TriEdge(tri,edge) == boundary.front()) break; // Reached beginning of this boundary, so finished it. else it = boundary_edges.find(TriEdge(tri, edge)); } } }
void Triangulation::calculate_neighbors() { _VERBOSE("Triangulation::calculate_neighbors"); Py_XDECREF(_neighbors); // Create _neighbors array with shape (ntri,3) and initialise all to -1. npy_intp dims[2] = {_ntri,3}; _neighbors = (PyArrayObject*)PyArray_SimpleNew(2, dims, PyArray_INT); int* neighbors_ptr = (int*)PyArray_DATA(_neighbors); std::fill(neighbors_ptr, neighbors_ptr + 3*_ntri, -1); // For each triangle edge (start to end point), find corresponding neighbor // edge from end to start point. Do this by traversing all edges and // storing them in a map from edge to TriEdge. If corresponding neighbor // edge is already in the map, don't need to store new edge as neighbor // already found. typedef std::map<Edge, TriEdge> EdgeToTriEdgeMap; EdgeToTriEdgeMap edge_to_tri_edge_map; for (int tri = 0; tri < _ntri; ++tri) { if (!is_masked(tri)) { for (int edge = 0; edge < 3; ++edge) { int start = get_triangle_point(tri, edge); int end = get_triangle_point(tri, (edge+1)%3); EdgeToTriEdgeMap::iterator it = edge_to_tri_edge_map.find(Edge(end,start)); if (it == edge_to_tri_edge_map.end()) { // No neighbor edge exists in the edge_to_tri_edge_map, so // add this edge to it. edge_to_tri_edge_map[Edge(start,end)] = TriEdge(tri,edge); } else { // Neighbor edge found, set the two elements of _neighbors // and remove edge from edge_to_tri_edge_map. neighbors_ptr[3*tri + edge] = it->second.tri; neighbors_ptr[3*it->second.tri + it->second.edge] = tri; edge_to_tri_edge_map.erase(it); } } } } // Note that remaining edges in the edge_to_tri_edge_map correspond to // boundary edges, but the boundaries are calculated separately elsewhere. }
TriEdge Triangulation::get_neighbor_edge(int tri, int edge) const { int neighbor_tri = get_neighbor(tri, edge); if (neighbor_tri == -1) return TriEdge(-1,-1); else return TriEdge(neighbor_tri, get_edge_in_triangle(neighbor_tri, get_triangle_point(tri, (edge+1)%3))); }
int Triangulation::get_triangle_point(const TriEdge& tri_edge) const { return get_triangle_point(tri_edge.tri, tri_edge.edge); }