Пример #1
0
/**
 * Check if a point is "visible" from any one or more of the edges in a
 * given group.
 * Formally: Check if there is a line from @ref P to any of the edges in
 * @ref Edges so that the line does not cross any of the lines of the
 * PSLG @ref PSLG
 */
static gboolean
IsVisibleFromEdges (P2trPSLG    *PSLG,
                   P2trVector2 *P,
                   P2trPSLG    *Edges)
{
    gboolean  found_visibility_path = FALSE;
    P2trPSLG *KnownBlocks = p2tr_pslg_new ();
    GQueue   *BlocksForTest = g_queue_new ();

    P2trVector2 W;
    find_point_in_polygon (Edges, &W);

    if (TryVisibilityAroundBlock(PSLG, P, Edges, KnownBlocks, BlocksForTest, NULL, &W))
        found_visibility_path = TRUE;

    while (! g_queue_is_empty (BlocksForTest) && ! found_visibility_path)
      {
        const P2trBoundedLine *Block = (P2trBoundedLine*)g_queue_pop_head (BlocksForTest);

        if (p2tr_pslg_contains_line (KnownBlocks, Block))
            continue;
        else if (TryVisibilityAroundBlock(PSLG, P, Edges, KnownBlocks, BlocksForTest, Block, &Block->start)
            || TryVisibilityAroundBlock(PSLG, P, Edges, KnownBlocks, BlocksForTest, Block, &Block->end))
          {
            found_visibility_path = TRUE;
          }
        else
            p2tr_pslg_add_existing_line (KnownBlocks, Block);
      }

    p2tr_pslg_free (KnownBlocks);
    g_queue_free (BlocksForTest);

    return found_visibility_path;
}
Пример #2
0
gboolean
p2tr_visibility_is_visible_from_edges (P2trPSLG              *pslg,
                                       P2trVector2           *p,
                                       const P2trBoundedLine *lines,
                                       guint                  line_count)
{
  P2trPSLG *edges = p2tr_pslg_new ();
  gint i;
  gboolean result;
  
  for (i = 0; i < line_count; i++)
    p2tr_pslg_add_existing_line (edges, &lines[i]);
  
  result = IsVisibleFromEdges (pslg, p, edges);
  
  p2tr_pslg_free (edges);
  return result;
}
Пример #3
0
P2trCDT* p2tr_cdt_new (P2tCDT *cdt)
{
    P2tTrianglePtrArray cdt_tris = p2t_cdt_get_triangles (cdt);
    GHashTable *point_map = g_hash_table_new (g_direct_hash, g_direct_equal);
    P2trCDT *rmesh = g_slice_new (P2trCDT);

    gint i, j;

    rmesh->mesh = p2tr_mesh_new ();
    rmesh->outline = p2tr_pslg_new ();

    /* First iteration over the CDT - create all the points */
    for (i = 0; i < cdt_tris->len; i++)
    {
        P2tTriangle *cdt_tri = triangle_index (cdt_tris, i);
        for (j = 0; j < 3; j++)
        {
            P2tPoint *cdt_pt = p2t_triangle_get_point(cdt_tri, j);
            P2trPoint *new_pt = g_hash_table_lookup (point_map, cdt_pt);

            if (new_pt == NULL)
            {
                new_pt = p2tr_point_new2 (cdt_pt->x, cdt_pt->y);
                g_hash_table_insert (point_map, cdt_pt, new_pt);
            }
        }
    }

    /* Second iteration over the CDT - create all the edges and find the
     * outline */
    for (i = 0; i < cdt_tris->len; i++)
    {
        P2tTriangle *cdt_tri = triangle_index (cdt_tris, i);

        for (j = 0; j < 3; j++)
        {
            P2tPoint *start = p2t_triangle_get_point (cdt_tri, j);
            P2tPoint *end = p2t_triangle_get_point (cdt_tri, (j + 1) % 3);
            int edge_index = p2t_triangle_edge_index (cdt_tri, start, end);

            P2trPoint *start_new = g_hash_table_lookup (point_map, start);
            P2trPoint *end_new = g_hash_table_lookup (point_map, end);

            if (! p2tr_point_has_edge_to (start_new, end_new))
            {
                gboolean constrained = cdt_tri->constrained_edge[edge_index];
                P2trEdge *edge = p2tr_mesh_new_edge (rmesh->mesh, start_new, end_new, constrained);

                /* If the edge is constrained, we should add it to the
                 * outline */
                if (constrained)
                    p2tr_pslg_add_new_line(rmesh->outline, &start_new->c,
                                           &end_new->c);

                /* We only wanted to create the edge now. We will use it
                 * later */
                p2tr_edge_unref (edge);
            }
        }
    }

    /* Third iteration over the CDT - create all the triangles */
    for (i = 0; i < cdt_tris->len; i++)
    {
        P2tTriangle *cdt_tri = triangle_index (cdt_tris, i);

        P2trPoint *pt1 = g_hash_table_lookup (point_map, p2t_triangle_get_point (cdt_tri, 0));
        P2trPoint *pt2 = g_hash_table_lookup (point_map, p2t_triangle_get_point (cdt_tri, 1));
        P2trPoint *pt3 = g_hash_table_lookup (point_map, p2t_triangle_get_point (cdt_tri, 2));

        P2trTriangle *new_tri = p2tr_mesh_new_triangle (rmesh->mesh,
                                p2tr_point_get_edge_to(pt1, pt2),
                                p2tr_point_get_edge_to(pt2, pt3),
                                p2tr_point_get_edge_to(pt3, pt1));

        /* We won't do any usage of the triangle, so just unref it */
        p2tr_triangle_unref (new_tri);
    }

    return rmesh;
}
Пример #4
0
P2trCDT*
p2tr_cdt_new (P2tCDT *cdt)
{
  P2tTrianglePtrArray cdt_tris = p2t_cdt_get_triangles (cdt);
  GHashTable *point_map = g_hash_table_new (g_direct_hash, g_direct_equal);
  P2trCDT *rmesh = g_slice_new (P2trCDT);
  GHashTableIter iter;
  P2trPoint *pt_iter = NULL;

  P2trVEdgeSet *new_edges = p2tr_vedge_set_new ();

  guint i, j;

  rmesh->mesh = p2tr_mesh_new ();
  rmesh->outline = p2tr_pslg_new ();

  /* First iteration over the CDT - create all the points */
  for (i = 0; i < cdt_tris->len; i++)
  {
    P2tTriangle *cdt_tri = triangle_index (cdt_tris, i);
    for (j = 0; j < 3; j++)
      {
        P2tPoint *cdt_pt = p2t_triangle_get_point(cdt_tri, j);
        P2trPoint *new_pt = (P2trPoint*) g_hash_table_lookup (point_map, cdt_pt);

        if (new_pt == NULL)
          {
            new_pt = p2tr_mesh_new_point2 (rmesh->mesh, cdt_pt->x, cdt_pt->y);
            g_hash_table_insert (point_map, cdt_pt, new_pt);
          }
      }
  }

  /* Second iteration over the CDT - create all the edges and find the
   * outline */
  for (i = 0; i < cdt_tris->len; i++)
  {
    P2tTriangle *cdt_tri = triangle_index (cdt_tris, i);

    for (j = 0; j < 3; j++)
      {
        P2tPoint *start = p2t_triangle_get_point (cdt_tri, j);
        P2tPoint *end = p2t_triangle_get_point (cdt_tri, (j + 1) % 3);
        int edge_index = p2t_triangle_edge_index (cdt_tri, start, end);

        P2trPoint *start_new = (P2trPoint*) g_hash_table_lookup (point_map, start);
        P2trPoint *end_new = (P2trPoint*) g_hash_table_lookup (point_map, end);

        if (! p2tr_point_has_edge_to (start_new, end_new))
          {
            gboolean constrained = cdt_tri->constrained_edge[edge_index]
            || cdt_tri->neighbors_[edge_index] == NULL;
            P2trEdge *edge = p2tr_mesh_new_edge (rmesh->mesh, start_new, end_new, constrained);

            /* If the edge is constrained, we should add it to the
             * outline */
            if (constrained)
              p2tr_pslg_add_new_line(rmesh->outline, &start_new->c,
                  &end_new->c);

            /* We only wanted to create the edge now. We will use it
             * later */
            p2tr_vedge_set_add (new_edges, edge);
          }
      }
  }

  /* Third iteration over the CDT - create all the triangles */
  for (i = 0; i < cdt_tris->len; i++)
  {
    P2tTriangle *cdt_tri = triangle_index (cdt_tris, i);

    P2trPoint *pt1 = (P2trPoint*) g_hash_table_lookup (point_map, p2t_triangle_get_point (cdt_tri, 0));
    P2trPoint *pt2 = (P2trPoint*) g_hash_table_lookup (point_map, p2t_triangle_get_point (cdt_tri, 1));
    P2trPoint *pt3 = (P2trPoint*) g_hash_table_lookup (point_map, p2t_triangle_get_point (cdt_tri, 2));

    P2trTriangle *new_tri = p2tr_mesh_new_triangle (rmesh->mesh,
        p2tr_point_get_edge_to(pt1, pt2, FALSE),
        p2tr_point_get_edge_to(pt2, pt3, FALSE),
        p2tr_point_get_edge_to(pt3, pt1, FALSE));

    /* We won't do any usage of the triangle, so just unref it */
    p2tr_triangle_unref (new_tri);
  }

  /* And do an extra flip fix */
  p2tr_cdt_flip_fix (rmesh, new_edges);

  p2tr_vedge_set_free (new_edges);

  /* Now finally unref the points we added into the map */
  g_hash_table_iter_init (&iter, point_map);
  while (g_hash_table_iter_next (&iter, NULL, (gpointer*)&pt_iter))
    p2tr_point_unref (pt_iter);
  g_hash_table_destroy (point_map);

  return rmesh;
}
Пример #5
0
gboolean
p2tr_pslg_visibility_check (P2trPSLG    *pslg,
                            P2trVector2 *point,
                            P2trPSLG    *polygon)
{
    P2trPSLG *known_blocks;
    GArray   *second_points;
    gboolean  found_visibility_path = FALSE;

    /* W <- Some point in T (for example, center of weight) */
    P2trVector2 W;
    find_point_in_polygon (polygon, &W);

    /* KnownBlocks <- {} */
    known_blocks = p2tr_pslg_new ();

    /* SecondPoint <- {W} */
    second_points   = g_array_new (FALSE, FALSE, sizeof(P2trVector2));
    g_array_append_val (second_points, W);

    while ((! found_visibility_path) && second_points->len > 0)
    {
        P2trVector2 S;
        P2trBoundedLine PS;
        P2trVector2 poly_intersection;

        /* S <- Some point from SecondPoint */
        p2tr_vector2_copy (&S, &g_array_index(second_points, P2trVector2, 0));
        /* SecondPoint <- SecondPoint \ {S} */
        g_array_remove_index_fast (second_points, 0);

        /* PS <- The infinite line going through P and S */
        p2tr_bounded_line_init (&PS, &S, point);

        /* IF PS intersects @Poly */
        if (find_closest_intersection (polygon, &PS.infinite, point, &poly_intersection))
        {
            P2trBoundedLine PS_exact, *B;

            /* IF there is an edge B=(u,v) (from E) that intersects PS */
            p2tr_bounded_line_init (&PS_exact, point, &poly_intersection);
            B = pslg_line_intersection (pslg, &PS_exact);

            if (B != NULL)
            {
                /* IF B is not in KnownBlocks: */
                if (! p2tr_pslg_contains_line (known_blocks, B))
                {
                    /* SecondPoint <- SecondPoint + {u,v} */
                    g_array_append_val (second_points, B->start);
                    g_array_append_val (second_points, B->end);
                    /* KnownBlocks <- KnownBlocks + {B} */
                    p2tr_pslg_add_existing_line (known_blocks, B);
                }
            }
            else
            {
                found_visibility_path = TRUE;
            }
        }
    }

    g_array_free (second_points, TRUE);
    p2tr_pslg_free (known_blocks);

    return found_visibility_path;
}