예제 #1
0
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;
    }
}
예제 #2
0
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));
}
예제 #3
0
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));
        }
    }
}
예제 #4
0
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.
}
예제 #5
0
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)));
}
예제 #6
0
int Triangulation::get_triangle_point(const TriEdge& tri_edge) const
{
    return get_triangle_point(tri_edge.tri, tri_edge.edge);
}