Example #1
0
/*-----------------------------------------------------------------------*/
VINDEX next_vertex(GRAPH *g, VINDEX vertex)
{
    GR_ASSERT(is_vertex(g, vertex), "next_vertex is_vertex(g,vertex)\n");

    while (1) {
        if (is_vertex(g, ++vertex))
            return vertex;
        else if (vertex >= GRAPH_vmax(g))
            return INVALID_VINDEX;
    }
}
Example #2
0
/*----------------------------------------------------------------------*/
EINDEX add_edge(GRAPH *g, VINDEX from, VINDEX to, void *user)
{
    EINDEX new_edge, e2;
    MEM_POOL *m = GRAPH_m(g);

    GR_ASSERT(is_vertex(g,from), "add_edge is_vertex(g, from\n");
    GR_ASSERT(is_vertex(g,from), "add_edge is_vertex(g, to\n");

    /* are there any free edges? */
    if(GRAPH_efree(g) == -1)

        /* grow the edge list if no free edges */
        grow_edge(g);

    /* get a free edge */
    new_edge = GRAPH_efree(g);

    /* reset the free edge pointer */
    GRAPH_efree(g)=  EDGE_nfrom(&GRAPH_e_i(g,new_edge));

    /* store the user information  */
    EDGE_user(&GRAPH_e_i(g,new_edge)) = user;

    /* from vertex is = from       */
    EDGE_from(&GRAPH_e_i(g,new_edge)) = from;

    /* to vertex is = to           */
    EDGE_to(&GRAPH_e_i(g,new_edge)) = to;

    /* incr. from count for from vertex */
    VERTEX_fcnt(&GRAPH_v_i(g,from))++;

    /* incr. to count for to vertex */
    VERTEX_tcnt(&GRAPH_v_i(g,to))++;

    /* incr. total used edge count  */
    GRAPH_ecnt(g)++;

    /* set up the list of from edges for the from vertex */
    e2 =  VERTEX_from(&GRAPH_v_i(g,from));
    EDGE_nfrom(&GRAPH_e_i(g,new_edge)) = e2;
    VERTEX_from(&GRAPH_v_i(g,from)) = new_edge;

    /* set up the list of to edges for the to vertex */
    e2 = VERTEX_to(&GRAPH_v_i(g,to));
    EDGE_nto(&GRAPH_e_i(g,new_edge)) = e2;
    VERTEX_to(&GRAPH_v_i(g,to)) = new_edge;

    /* set the recursive edge field to be zero */
    EDGE_etype(&GRAPH_e_i(g,new_edge)) = 0;

    return new_edge;
}
Example #3
0
/*---------------------------------------------------------------------*/
void* delete_vertex(GRAPH *g, VINDEX vertex)
{
    void *user;
    EINDEX from, nfrom, to, nto;

    GR_ASSERT(is_vertex(g, vertex), "delete vertex is_vertex\n");

    user = VERTEX_user(&GRAPH_v_i(g,vertex));

    /* delete the from edges */
    from = VERTEX_from(&GRAPH_v_i(g,vertex));
    while (from != INVALID_EINDEX)
    {
        nfrom = EDGE_nfrom(&GRAPH_e_i(g,from));
        delete_edge(g, from);
        from = nfrom;
    }

    /* delete the to edges */
    to =  VERTEX_to(&GRAPH_v_i(g,vertex));
    while (to != INVALID_EINDEX)
    {
        nto = EDGE_nto(&GRAPH_e_i(g,to));
        delete_edge(g, to);
        to = nto;
    }

    VERTEX_fcnt(&GRAPH_v_i(g,vertex)) = -1;
    VERTEX_from(&GRAPH_v_i(g,vertex)) = GRAPH_vfree(g);
    GRAPH_vfree(g) = vertex;
    GRAPH_vcnt(g)--;

    return user;

}
Example #4
0
 unsigned vertex(double* x, double* y)
 {
     unsigned cmd = m_src->vertex(x, y);
     if(is_vertex(cmd))  ++m_points;
     if(is_move_to(cmd)) ++m_contours;
     return cmd;
 }
 //------------------------------------------------------------------------
 void vcgen_contour::add_vertex(double x, double y, unsigned cmd)
 {
     m_status = initial;
     if(is_move_to(cmd))
     {
         m_src_vertices.modify_last(vertex_dist(x, y));
     }
     else
     {
         if(is_vertex(cmd))
         {
             m_src_vertices.add(vertex_dist(x, y));
         }
         else
         {
             if(is_end_poly(cmd))
             {
                 m_closed = get_close_flag(cmd);
                 if(m_orientation == path_flags_none) 
                 {
                     m_orientation = get_orientation(cmd);
                 }
             }
         }
     }
 }
Example #6
0
/*---------------------------------------------------------------*/
void* get_edge(GRAPH *g, VINDEX from, VINDEX to)
{
    EINDEX e;


    GR_ASSERT(is_vertex(g, from), "get_edge is_vertex from\n");
    GR_ASSERT(is_vertex(g, to), "get_edge is_vertex to\n");

    e = VERTEX_from(&GRAPH_v_i(g, from));

    while ( e != INVALID_EINDEX ) {
        if(EDGE_to(&GRAPH_e_i(g,e)) == to)
            break;
        e = (EDGE_nfrom(&GRAPH_e_i(g,e)));
    }
    return EDGE_user(&GRAPH_e_i(g,e));
}
Example #7
0
/*---------------------------------------------------------------*/
int
edge_count(GRAPH* g, VINDEX from, VINDEX to)
{
    int count= 0;
    EINDEX e;

    GR_ASSERT(is_vertex(g, from), "edge_count is_vertex from\n");
    GR_ASSERT(is_vertex(g, to), "edge_count is_vertex to\n");

    e = VERTEX_from(&GRAPH_v_i(g, from));

    while ( e != INVALID_EINDEX ) {
        if(EDGE_to(&GRAPH_e_i(g,e)) == to)
            ++count;
        e = (EDGE_nfrom(&GRAPH_e_i(g,e)));
    }
    return count;
}
Example #8
0
/* Count the vertices in a matrix of external points */
static size_t count_vertices(const dd_MatrixPtr generators)
{
  dd_rowrange i;
  int vertex_count = 0;
  for (i = 0; i < generators->rowsize; i++) {
    /* Check if row is vertex (first column 0) */
    if (is_vertex(generators->matrix[i][0]))
      vertex_count++;
  }

  return vertex_count;
}
void vcgen_stroke::add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd)
{
    m_status = initial;
    if(is_move_to(cmd)) {
        m_src_vertices.modify_last(vertex_dist_cmd(x, y, cmd));
    } else {
        if(is_vertex(cmd)) {
            m_src_vertices.add(vertex_dist_cmd(x, y, cmd));
        } else {
            m_closed = get_close_flag(cmd);
        }
    }
}
Example #10
0
 //------------------------------------------------------------------------
 void path_renderer::move_to(double x, double y, bool rel)          // M, m
 {
     if(rel && m_storage.total_vertices()) {
        double x2,y2;
        unsigned cmd = m_storage.last_vertex(&x2,&y2);
        if(is_end_poly(cmd)) {
            // rewind until we find a real vertex
            unsigned idx = m_storage.total_vertices()-1;
            while(idx && !is_vertex(m_storage.vertex(--idx,&x2,&y2)));
        }
        x += x2;
        y += y2;
     }
     m_storage.move_to(x, y);
 }
Example #11
0
 //------------------------------------------------------------------------
 void vcgen_bspline::add_vertex(double x, double y, unsigned cmd)
 {
     m_status = initial;
     if(is_move_to(cmd))
     {
         m_src_vertices.modify_last(point_d(x, y));
     }
     else
     {
         if(is_vertex(cmd))
         {
             m_src_vertices.add(point_d(x, y));
         }
         else
         {
             m_closed = get_close_flag(cmd);
         }
     }
 }
Example #12
0
 //------------------------------------------------------------------------
 void vcgen_smooth_poly1::add_vertex(double x, double y, unsigned cmd)
 {
     m_status = initial;
     if(is_move_to(cmd))
     {
         m_src_vertices.modify_last(vertex_dist(x, y));
     }
     else
     {
         if(is_vertex(cmd))
         {
             m_src_vertices.add(vertex_dist(x, y));
         }
         else
         {
             m_closed = get_close_flag(cmd);
         }
     }
 }
Example #13
0
 int hit_test(double x, double y, double r)
 {
     m_affine.inverse_transform(&x, &y);
     r /= m_affine.scale();
     unsigned i;
     for(i = 0; i < m_path.total_vertices(); i++)
     {
         double vx, vy;
         unsigned cmd = m_path.vertex(i, &vx, &vy);
         if(is_vertex(cmd))
         {
             if(calc_distance(x, y, vx, vy) <= r)
             {
                 return i;
             }
         }
     }
     return -1;
 }
Example #14
0
    double path_length(VertexSource& vs, unsigned path_id = 0)
    {
        double len = 0.0;
        double start_x = 0.0;
        double start_y = 0.0;
        double x1 = 0.0;
        double y1 = 0.0;
        double x2 = 0.0;
        double y2 = 0.0;
        bool first = true;

        unsigned cmd;
        vs.rewind(path_id);
        while(!is_stop(cmd = vs.vertex(&x2, &y2)))
        {
            if(is_vertex(cmd))
            {
                if(first || is_move_to(cmd))
                {
                    start_x = x2;
                    start_y = y2;
                }
                else
                {
                    len += calc_distance(x1, y1, x2, y2);
                }
                x1 = x2;
                y1 = y2;
                first = false;
            }
            else
            {
                if(is_close(cmd) && !first)
                {
                    len += calc_distance(x1, y1, start_x, start_y);
                }
            }
        }
        return len;
    }
Example #15
0
 //------------------------------------------------------------------------
 void vcgen_markers_term::add_vertex(double x, double y, unsigned cmd)
 {
     if(is_move_to(cmd))
     {
         if(m_markers.size() & 1)
         {
             // Initial state, the first coordinate was added.
             // If two of more calls of start_vertex() occures
             // we just modify the last one.
             m_markers.modify_last(coord_type(x, y));
         }
         else
         {
             m_markers.add(coord_type(x, y));
         }
     }
     else
     {
         if(is_vertex(cmd))
         {
             if(m_markers.size() & 1)
             {
                 // Initial state, the first coordinate was added.
                 // Add three more points, 0,1,1,0
                 m_markers.add(coord_type(x, y));
                 m_markers.add(m_markers[m_markers.size() - 1]);
                 m_markers.add(m_markers[m_markers.size() - 3]);
             }
             else
             {
                 if(m_markers.size())
                 {
                     // Replace two last points: 0,1,1,0 -> 0,1,2,1
                     m_markers[m_markers.size() - 1] = m_markers[m_markers.size() - 2];
                     m_markers[m_markers.size() - 2] = coord_type(x, y);
                 }
             }
         }
     }
 }
Example #16
0
/*
 * Parse the generator output. Find the generators which are vertices
 * (non-rays) add their corresponding inequalities to an output set.
 *
 * Returns a matrix where each row contains the x-coordinate of the vertex,
 * y-coordinate of the vertex, and 0-based index of the inequality which bounds
 * the polytope to the right of the vertex. output_size is set to the total
 * length of the ouptut.
 */
static double *list_extreme_vertices(const dd_MatrixPtr generators,
                                     const dd_SetFamilyPtr incidence,
                                     const size_t nrows,
                                     long lower_bound_index,
                                     /*OUT*/ size_t * output_size)
{
  assert(generators->rowsize > 0);
  assert(generators->colsize > 2);

  set_type cur_vert_set, next_vert_set, s;
  dd_rowrange i;
  long elem;
  size_t out_row = 0, r;

  size_t vertex_count = count_vertices(generators);

  /* Last vertex intersects with upper bound - not output */
  *output_size = 3 * (vertex_count - 1);
  double *output = (double *) malloc(sizeof(double) * (*output_size));

  /* Sorted indices into generators */
  size_t *indices = sort_generators(generators);

  assert(*output_size > 0);

  /* Loop over vertices in generators, extracting solutions
   *
   * For vertices 0..n_vertices-2, find the inequality incident to the vertex
   * also incident in the next vertex.
   */
  for (i = 0; i < vertex_count - 1; i++) {
    r = indices[i];

    assert(is_vertex(generators->matrix[r][0]));
    assert(is_vertex(generators->matrix[indices[i + 1]][0]));

    assert(out_row < vertex_count - 1);
    cur_vert_set = incidence->set[r];

    next_vert_set = incidence->set[indices[i + 1]];

    /* Sets should be same size */

    assert(cur_vert_set[0] == next_vert_set[0]);
    set_initialize(&s, cur_vert_set[0]);
    set_int(s, cur_vert_set, next_vert_set);

    /* Remove added index for first item */
    /*if (!i)*/
      /*set_delelem(s, lower_bound_index);*/

    /* Set may have > 1 solution if ~identical slopes and intercepts due to
     * rounding. */
    /*assert(set_card(s) == 1); */

    /* Only one item in the set */
    elem = set_first(s);
    set_free(s);

    /* Fill output row */
    int base = out_row * 3;
    output[base] = *generators->matrix[r][1];     /* x */
    output[base + 1] = *generators->matrix[r][2]; /* y */
    output[base + 2] = (double) (elem - 1);       /* ineq index, converted to 0-base */

    out_row++;
  }

  free(indices);

  return output;
}
Example #17
0
/*---------------------------------------------------------------*/
int num_succs(GRAPH *g, VINDEX vertex)
{
    GR_ASSERT(is_vertex(g,vertex), "num_succs is_vertex\n");

    return (VERTEX_fcnt(&GRAPH_v_i(g,vertex)));
}
Example #18
0
/*---------------------------------------------------------------*/
void* get_vertex(GRAPH *g, VINDEX vertex)
{
    GR_ASSERT(is_vertex(g,vertex), "get_vertex\n");

    return (VERTEX_user(&GRAPH_v_i(g,vertex)));
}
Example #19
0
    unsigned conv_adaptor_vpgen<VertexSource, VPGen>::vertex(double* x, double* y)
    {
        unsigned cmd = path_cmd_stop;
        for(;;)
        {
            cmd = m_vpgen.vertex(x, y);
            if(!is_stop(cmd)) break;

            if(m_poly_flags && !m_vpgen.auto_unclose())
            {
                *x = 0.0;
                *y = 0.0;
                cmd = m_poly_flags;
                m_poly_flags = 0;
                break;
            }

            if(m_vertices < 0)
            {
                if(m_vertices < -1) 
                {
                    m_vertices = 0;
                    return path_cmd_stop;
                }
                m_vpgen.move_to(m_start_x, m_start_y);
                m_vertices = 1;
                continue;
            }

            double tx, ty;
            cmd = m_source->vertex(&tx, &ty);
            if(is_vertex(cmd))
            {
                if(is_move_to(cmd)) 
                {
                    if(m_vpgen.auto_close() && m_vertices > 2)
                    {
                        m_vpgen.line_to(m_start_x, m_start_y);
                        m_poly_flags = path_cmd_end_poly | path_flags_close;
                        m_start_x    = tx;
                        m_start_y    = ty;
                        m_vertices   = -1;
                        continue;
                    }
                    m_vpgen.move_to(tx, ty);
                    m_start_x  = tx;
                    m_start_y  = ty;
                    m_vertices = 1;
                }
                else 
                {
                    m_vpgen.line_to(tx, ty);
                    ++m_vertices;
                }
            }
            else
            {
                if(is_end_poly(cmd))
                {
                    m_poly_flags = cmd;
                    if(is_closed(cmd) || m_vpgen.auto_close())
                    {
                        if(m_vpgen.auto_close()) m_poly_flags |= path_flags_close;
                        if(m_vertices > 2)
                        {
                            m_vpgen.line_to(m_start_x, m_start_y);
                        }
                        m_vertices = 0;
                    }
                }
                else
                {
                    // path_cmd_stop
                    if(m_vpgen.auto_close() && m_vertices > 2)
                    {
                        m_vpgen.line_to(m_start_x, m_start_y);
                        m_poly_flags = path_cmd_end_poly | path_flags_close;
                        m_vertices   = -2;
                        continue;
                    }
                    break;
                }
            }
        }
        return cmd;
    }