コード例 #1
0
ファイル: visibility.c プロジェクト: ChristianBusch/gegl
/**
 * 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
ファイル: rcdt.c プロジェクト: KyleLink/poly2tri-c
void
p2tr_cdt_free_full (P2trCDT* self, gboolean clear_mesh)
{
  p2tr_pslg_free (self->outline);
  if (clear_mesh)
    p2tr_mesh_clear (self->mesh);
  p2tr_mesh_unref (self->mesh);

  g_slice_free (P2trCDT, self);
}
コード例 #3
0
ファイル: visibility.c プロジェクト: ChristianBusch/gegl
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;
}
コード例 #4
0
ファイル: visibility.c プロジェクト: ChristianBusch/gegl
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;
}