Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  path-intersect.c

  Sprache: C
 

#include <gtk/gtk.h>

#define assert_path_point_equal(point,_contour,_idx,_t) \
  g_assert_cmpint ((point)->contour, ==, (_contour)); \
  g_assert_cmpint ((point)->idx, ==, (_idx)); \
  g_assert_cmpfloat_with_epsilon ((point)->t, (_t), 0.0001);

typedef struct
{
  GskPathPoint point1[20];
  GskPathPoint point2[20];
  GskPathIntersection kind[20];
  int found;
} CollectData;

static gboolean
collect_cb (GskPath             *path1,
            const GskPathPoint  *point1,
            GskPath             *path2,
            const GskPathPoint  *point2,
            GskPathIntersection  kind,
            gpointer             data)
{
  CollectData *res = data;
#if 0
  const char *kn[] = { "none""normal""start""end" };

  g_print ("%s idx1 %lu t1 %f idx2 %lu t2 %f\n",
           kn[kind],
           point1->idx, point1->t, point2->idx, point2->t);
#endif

  g_assert_true (res->found < 20);

  res->point1[res->found] = *point1;
  res->point2[res->found] = *point2;
  res->kind[res->found] = kind;
  res->found++;

  return TRUE;
}

static void
test_intersect_simple (void)
{
  GskPath *path1, *path2;
  graphene_point_t p1, p2;
  CollectData res;

  path1 = gsk_path_parse ("M 100 100 h 200 v 100 h -200 z");
  path2 = gsk_path_parse ("M 150 150 h 200 v 100 h -200 z");

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 2);
  assert_path_point_equal (&res.point1[0], 020.5);
  assert_path_point_equal (&res.point1[1], 030.75);
  assert_path_point_equal (&res.point2[0], 010.75);
  assert_path_point_equal (&res.point2[1], 040.5);
  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_NORMAL);

  gsk_path_point_get_position (&res.point1[0], path1, &p1);
  gsk_path_point_get_position (&res.point2[0], path2, &p2);
  g_assert_true (graphene_point_equal (&p1, &p2));

  gsk_path_point_get_position (&res.point1[1], path1, &p1);
  gsk_path_point_get_position (&res.point2[1], path2, &p2);
  g_assert_true (graphene_point_near (&p1, &p2, 0.001));

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_simple2 (void)
{
  GskPath *path1, *path2;
  CollectData res;

  path1 = gsk_path_parse ("M 100 100 h 200 v 100 h -200 z");
  path2 = gsk_path_parse ("M 100 100 h 200 v 100 h -200 z");

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 2);
  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_END);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_simple3 (void)
{
  GskPath *path1, *path2;
  CollectData res;

  path1 = gsk_path_parse ("M 100 100 h 200 v 100 h -200 z");
  path2 = gsk_path_parse ("M 300 100 h -200 v 100 h 200 z");

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 2);
  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_END);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_reverse (void)
{
  GskPath *path1, *path2;
  graphene_point_t p1, p2;
  CollectData res;

  path1 = gsk_path_parse ("M 100 100 h 200 v 100 h -200 z");
  path2 = gsk_path_parse ("M 150 150 v 100 h 200 v -100 z");

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 2);
  assert_path_point_equal (&res.point1[0], 020.5);
  assert_path_point_equal (&res.point1[1], 030.75);
  assert_path_point_equal (&res.point2[0], 040.25);
  assert_path_point_equal (&res.point2[1], 010.5);
  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_NORMAL);

  gsk_path_point_get_position (&res.point1[0], path1, &p1);
  gsk_path_point_get_position (&res.point2[0], path2, &p2);
  g_assert_true (graphene_point_equal (&p1, &p2));

  gsk_path_point_get_position (&res.point1[1], path1, &p1);
  gsk_path_point_get_position (&res.point2[1], path2, &p2);
  g_assert_true (graphene_point_equal (&p1, &p2));

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_line_box (void)
{
  GskPath *path1, *path2;
  graphene_point_t p1, p2;
  CollectData res;

  path1 = gsk_path_parse ("M 50 150 l 300 0");
  path2 = gsk_path_parse ("M 100 100 h 200 v 100 h -200 z");

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 2);
  assert_path_point_equal (&res.point1[0], 0150.f/300.f);
  assert_path_point_equal (&res.point1[1], 01250.f/300.f);
  assert_path_point_equal (&res.point2[0], 040.5);
  assert_path_point_equal (&res.point2[1], 020.5);
  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_NORMAL);

  gsk_path_point_get_position (&res.point1[0], path1, &p1);
  gsk_path_point_get_position (&res.point2[0], path2, &p2);
  g_assert_true (graphene_point_equal (&p1, &p2));

  gsk_path_point_get_position (&res.point1[1], path1, &p1);
  gsk_path_point_get_position (&res.point2[1], path2, &p2);
  g_assert_true (graphene_point_equal (&p1, &p2));

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_xplus (void)
{
  GskPath *path1, *path2;
  CollectData res;

  path1 = gsk_path_parse ("M 0 0 L 100 100 M 0 100 L 100 0");
  path2 = gsk_path_parse ("M 0 50 L 100 50 M 50 0 L 50 100");

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 4);
  assert_path_point_equal (&res.point1[0], 010.5);
  assert_path_point_equal (&res.point1[1], 010.5);
  assert_path_point_equal (&res.point1[2], 110.5);
  assert_path_point_equal (&res.point1[3], 110.5);

  assert_path_point_equal (&res.point2[0], 010.5);
  assert_path_point_equal (&res.point2[1], 110.5);
  assert_path_point_equal (&res.point2[2], 010.5);
  assert_path_point_equal (&res.point2[3], 110.5);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_point (void)
{
  GskPath *path1, *path2;
  CollectData res;

  path1 = gsk_path_parse ("M 0 50");
  path2 = gsk_path_parse ("M 0 0 L 0 100");

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);

  g_assert_true (res.found == 1);
  assert_path_point_equal (&res.point1[0], 001);
  assert_path_point_equal (&res.point2[0], 010.5);

  res.found = 0;
  gsk_path_foreach_intersection (path2, path1, collect_cb, &res);

  g_assert_true (res.found == 1);
  assert_path_point_equal (&res.point1[0], 010.5);
  assert_path_point_equal (&res.point2[0], 001);

  res.found = 0;
  gsk_path_foreach_intersection (path1, path1, collect_cb, &res);

  g_assert_true (res.found == 1);
  assert_path_point_equal (&res.point1[0], 001);
  assert_path_point_equal (&res.point2[0], 001);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_contours (void)
{
  GskPath *path1, *path2;
  CollectData res;

  path1 = gsk_path_parse ("M 0 100 L 200 100");
  path2 = gsk_path_parse ("M 150 0 150 200 M 50 0 50 200");

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 2);
  assert_path_point_equal (&res.point1[0], 010.25f);
  assert_path_point_equal (&res.point1[1], 010.75f);
  assert_path_point_equal (&res.point2[0], 110.5f);
  assert_path_point_equal (&res.point2[1], 010.5f);
  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_NORMAL);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_contours2 (void)
{
  GskPath *path1, *path2;
  CollectData res;

  path1 = gsk_path_parse ("M 0 100 L 200 100");
  path2 = gsk_path_parse ("M 150 0 L 150 200 M 50 0 L 50 200 M 60 100 L 140 100");

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 4);
  assert_path_point_equal (&res.point1[0], 010.25f);
  assert_path_point_equal (&res.point1[1], 010.3f);
  assert_path_point_equal (&res.point2[0], 110.5f);
  assert_path_point_equal (&res.point2[1], 210.f);
  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[2] == GSK_PATH_INTERSECTION_END);
  g_assert_true (res.kind[3] == GSK_PATH_INTERSECTION_NORMAL);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_contours3 (void)
{
  GskPath *path1, *path2;
  CollectData res;

  path1 = gsk_path_parse ("M 150 0 L 150 200 M 50 0 L 50 200 M 60 100 L 140 100");
  path2 = gsk_path_parse ("M 0 100 L 200 100");

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 4);
  assert_path_point_equal (&res.point1[0], 010.5f);
  assert_path_point_equal (&res.point1[1], 110.5f);
  assert_path_point_equal (&res.point2[0], 010.75f);
  assert_path_point_equal (&res.point2[1], 010.25f);
  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[2] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[3] == GSK_PATH_INTERSECTION_END);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_coincide (void)
{
  GskPath *path1, *path2;
  CollectData res;

  path1 = gsk_path_parse ("M 100 100 h 200 v 100 h -200 z");
  path2 = gsk_path_parse ("M 150 100 h 100 v 50 h -100 z");

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 2);
  assert_path_point_equal (&res.point1[0], 010.25);
  assert_path_point_equal (&res.point1[1], 010.75);
  assert_path_point_equal (&res.point2[0], 010);
  assert_path_point_equal (&res.point2[1], 011);
  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_END);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_coincide2 (void)
{
  GskPath *path1, *path2;
  CollectData res;

  path1 = gsk_path_parse ("M 150 100 h 100 v 50 h -100 z");
  path2 = gsk_path_parse ("M 100 100 h 200 v 100 h -200 z");

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 2);
  assert_path_point_equal (&res.point1[0], 010);
  assert_path_point_equal (&res.point1[1], 011);
  assert_path_point_equal (&res.point2[0], 010.25);
  assert_path_point_equal (&res.point2[1], 010.75);
  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_END);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_coincide3 (void)
{
  GskPath *path1, *path2;
  CollectData res;

  path1 = gsk_path_parse ("M 100 100 h 200 v 100 h -200 z");
  path2 = gsk_path_parse ("M 150 100 h 100 v 50 h -25 v -50 h -50 v 50 h -25 z");

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 4);
  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[2] == GSK_PATH_INTERSECTION_END);
  g_assert_true (res.kind[3] == GSK_PATH_INTERSECTION_END);

  assert_path_point_equal (&res.point1[0], 010.25);
  assert_path_point_equal (&res.point1[1], 010.375);
  assert_path_point_equal (&res.point1[2], 010.625);
  assert_path_point_equal (&res.point1[3], 010.75);

  assert_path_point_equal (&res.point2[0], 010);
  assert_path_point_equal (&res.point2[1], 051);
  assert_path_point_equal (&res.point2[2], 050);
  assert_path_point_equal (&res.point2[3], 011);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_coincide4 (void)
{
  GskPath *path1, *path2;
  CollectData res;

  path1 = gsk_path_parse ("M 100 100 h 200 v 100 h -200 z");
  path2 = gsk_path_parse ("M 150 100 h 100 v 50 h -25 v -100 h -50 v 100 h -25 z");

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 4);
  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[2] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[3] == GSK_PATH_INTERSECTION_END);

  assert_path_point_equal (&res.point1[0], 010.25);
  assert_path_point_equal (&res.point1[1], 010.375);
  assert_path_point_equal (&res.point1[2], 010.625);
  assert_path_point_equal (&res.point1[3], 010.75);

  assert_path_point_equal (&res.point2[0], 010);
  assert_path_point_equal (&res.point2[1], 060.5);
  assert_path_point_equal (&res.point2[2], 040.5);
  assert_path_point_equal (&res.point2[3], 011);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

/* the next few tests explore overlapping segments */
static void
test_intersect_coincide5 (void)
{
  GskPath *path1, *path2;
  CollectData res;

  path1 = gsk_path_parse ("M 150 100 h 100 v 100 h -100 z");
  path2 = gsk_path_parse ("M 100 100 h 200 v 50 h -100 v -50 h 25 v -50 h -100 z");

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 5);
  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[2] == GSK_PATH_INTERSECTION_END);
  g_assert_true (res.kind[3] == GSK_PATH_INTERSECTION_END);
  g_assert_true (res.kind[4] == GSK_PATH_INTERSECTION_NORMAL);

  assert_path_point_equal (&res.point1[0], 010);
  assert_path_point_equal (&res.point1[1], 010.5);
  assert_path_point_equal (&res.point1[2], 010.75);
  assert_path_point_equal (&res.point1[3], 011);
  assert_path_point_equal (&res.point1[4], 020.5);

  assert_path_point_equal (&res.point2[0], 010.25);
  assert_path_point_equal (&res.point2[1], 050);
  assert_path_point_equal (&res.point2[2], 051);
  assert_path_point_equal (&res.point2[3], 010.75);
  assert_path_point_equal (&res.point2[4], 030.5);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_coincide6 (void)
{
  GskPath *path1, *path2;
  CollectData res;

  path1 = gsk_path_parse ("M 150 100 h 75 l 25 50 v 50 h -100 z");
  path2 = gsk_path_parse ("M 100 100 h 200 v 50 h -100 v -50 h 50 v -50 h -125 z");

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 5);
  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[2] == GSK_PATH_INTERSECTION_END);
  g_assert_true (res.kind[3] == GSK_PATH_INTERSECTION_END);
  g_assert_true (res.kind[4] == GSK_PATH_INTERSECTION_NORMAL);

  assert_path_point_equal (&res.point1[0], 010);
  assert_path_point_equal (&res.point1[1], 012./3.);
  assert_path_point_equal (&res.point1[2], 011);
  assert_path_point_equal (&res.point1[3], 011);
  assert_path_point_equal (&res.point1[4], 030);

  assert_path_point_equal (&res.point2[0], 010.25);
  assert_path_point_equal (&res.point2[1], 050);
  assert_path_point_equal (&res.point2[2], 010.625);
  assert_path_point_equal (&res.point2[3], 050.5);
  assert_path_point_equal (&res.point2[4], 030.5);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static int
circle_intersect (const graphene_point_t *center1,
                  float                   radius1,
                  const graphene_point_t *center2,
                  float                   radius2,
                  graphene_point_t        points[2])
{
  float d;
  float a, h;
  graphene_point_t m;
  graphene_vec2_t n;

  g_assert (radius1 >= 0);
  g_assert (radius2 >= 0);

  d = graphene_point_distance (center1, center2, NULL, NULL);

  if (d < fabsf (radius1 - radius2))
    return 0;

  if (d > radius1 + radius2)
    return 0;

  if (d == radius1 + radius2)
    {
      graphene_point_interpolate (center1, center2, radius1 / (radius1 + radius2), &points['color: green'>0]);
      return 1;
    }

  /*
  a + b = d;

  a^2 + h^2 = r1^2
  b^2 + h^2 = r2^2

  a^2 - (d - a)^2 = r1^2 - r2^2
  a^2 - (d^2 - 2ad + a2) = r1^2 - r2^2

  2ad -d^2 = r1^2 - r2^2
  2ad = r1^2 - r2^2 + d^2
  a = (r1^2 - r2^2 + d^2) / (2d)

  p1/2 = c1 + a/d * (c2 - c1) +/- h * n(c1,c2);
  */


  a = (radius1*radius1 - radius2*radius2 + d*d)/(2*d);
  h = sqrtf (radius1*radius1 - a*a);

  graphene_point_interpolate (center1, center2, a/d, &m);
  graphene_vec2_init (&n, center2->y - center1->y, center1->x - center2->x);
  graphene_vec2_normalize (&n, &n);

  graphene_point_init (&points[0], m.x + graphene_vec2_get_x (&n) * h,
                                   m.y + graphene_vec2_get_y (&n) * h);
  graphene_point_init (&points[1], m.x - graphene_vec2_get_x (&n) * h,
                                   m.y - graphene_vec2_get_y (&n) * h);

  return 2;
}

static void
test_intersect_circle (void)
{
  GskPathBuilder *builder;
  GskPath *path1, *path2;
  CollectData res;

  builder = gsk_path_builder_new ();
  gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (00), 12);
  path1 = gsk_path_builder_free_to_path (builder);

  builder = gsk_path_builder_new ();
  gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (11), 10);
  path2 = gsk_path_builder_free_to_path (builder);

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 0);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_circle2 (void)
{
  GskPathBuilder *builder;
  GskPath *path1, *path2;
  CollectData res;

  builder = gsk_path_builder_new ();
  gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (00), 12);
  path1 = gsk_path_builder_free_to_path (builder);

  builder = gsk_path_builder_new ();
  gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (025), 10);
  path2 = gsk_path_builder_free_to_path (builder);

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 0);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_circle3 (void)
{
  GskPathBuilder *builder;
  GskPath *path1, *path2;
  CollectData res;

  builder = gsk_path_builder_new ();
  gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (00), 12);
  path1 = gsk_path_builder_free_to_path (builder);

  builder = gsk_path_builder_new ();
  gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (022), 10);
  path2 = gsk_path_builder_free_to_path (builder);

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 1);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_circle4 (void)
{
  GskPathBuilder *builder;
  GskPath *path1, *path2;
  CollectData res;
  graphene_point_t p[2], pos;
  int n;

  builder = gsk_path_builder_new ();
  gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (00), 12);
  path1 = gsk_path_builder_free_to_path (builder);

  builder = gsk_path_builder_new ();
  gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (018), 10);
  path2 = gsk_path_builder_free_to_path (builder);

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 2);

  n = circle_intersect (&GRAPHENE_POINT_INIT (00), 12,
                        &GRAPHENE_POINT_INIT (018), 10,
                        p);

  g_assert_true (n == 2);
  gsk_path_point_get_position (&res.point1[0], path1, &pos);
  g_assert_true (graphene_point_near (&p[0], &pos, 0.01));
  gsk_path_point_get_position (&res.point1[1], path1, &pos);
  g_assert_true (graphene_point_near (&p[1], &pos, 0.01));

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_circle5 (void)
{
  GskPathBuilder *builder;
  GskPath *path1, *path2;
  CollectData res;
  graphene_point_t p[2], pos;
  int n;

  builder = gsk_path_builder_new ();
  gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (00), 12);
  path1 = gsk_path_builder_free_to_path (builder);

  builder = gsk_path_builder_new ();
  gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (1010), 10);
  path2 = gsk_path_builder_free_to_path (builder);

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 2);

  n = circle_intersect (&GRAPHENE_POINT_INIT (00), 12,
                        &GRAPHENE_POINT_INIT (1010), 10,
                        p);

  g_assert_true (n == 2);
  gsk_path_point_get_position (&res.point1[0], path1, &pos);
  g_assert_true (graphene_point_near (&p[0], &pos, 0.01));
  gsk_path_point_get_position (&res.point1[1], path1, &pos);
  g_assert_true (graphene_point_near (&p[1], &pos, 0.01));

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_circle6 (void)
{
  GskPathBuilder *builder;
  GskPath *path1;
  CollectData res;

  builder = gsk_path_builder_new ();
  gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (100100), 12);
  path1 = gsk_path_builder_free_to_path (builder);

  res.found = 0;
  gsk_path_foreach_intersection (path1, path1, collect_cb, &res);
  g_assert_true (res.found == 2);

  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_END);

  gsk_path_unref (path1);
}

static void
test_intersect_circle7 (void)
{
  GskPathBuilder *builder;
  GskPath *path1, *path2;
  CollectData res;

  builder = gsk_path_builder_new ();
  gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (100100), 12);
  path1 = gsk_path_builder_free_to_path (builder);

  builder = gsk_path_builder_new ();
  gsk_path_builder_add_reverse_path (builder, path1);
  path2 = gsk_path_builder_free_to_path (builder);

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 2);

  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_END);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_circle_rounded_rect (void)
{
  GskRoundedRect rr;
  GskPathBuilder *builder;
  GskPath *path1, *path2;
  CollectData res;

  rr.bounds = GRAPHENE_RECT_INIT (1010100100);
  rr.corner[GSK_CORNER_TOP_LEFT] = GRAPHENE_SIZE_INIT (2020);
  rr.corner[GSK_CORNER_TOP_RIGHT] = GRAPHENE_SIZE_INIT (2020);
  rr.corner[GSK_CORNER_BOTTOM_RIGHT] = GRAPHENE_SIZE_INIT (2020);
  rr.corner[GSK_CORNER_BOTTOM_LEFT] = GRAPHENE_SIZE_INIT (2020);

  builder = gsk_path_builder_new ();
  gsk_path_builder_add_rounded_rect (builder, &rr);
  path1 = gsk_path_builder_free_to_path (builder);

  builder = gsk_path_builder_new ();
  gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (3030), 20);
  gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (9030), 20);
  gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (9090), 20);
  gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (3090), 20);
  path2 = gsk_path_builder_free_to_path (builder);

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 8);

  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_END);
  g_assert_true (res.kind[2] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[3] == GSK_PATH_INTERSECTION_END);
  g_assert_true (res.kind[4] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[5] == GSK_PATH_INTERSECTION_END);
  g_assert_true (res.kind[6] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[7] == GSK_PATH_INTERSECTION_END);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_loop_line (void)
{
  GskPathBuilder *builder;
  GskPath *path1, *path2;
  CollectData res;

  builder = gsk_path_builder_new ();
  gsk_path_builder_move_to (builder, 200);
  gsk_path_builder_cubic_to (builder, 120100, -20100800);
  path1 = gsk_path_builder_free_to_path (builder);

  builder = gsk_path_builder_new ();
  gsk_path_builder_move_to (builder, 500);
  gsk_path_builder_line_to (builder, 50150);
  path2 = gsk_path_builder_free_to_path (builder);

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 3);

  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[2] == GSK_PATH_INTERSECTION_NORMAL);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_intersect_mix_segment (void)
{
  GskPathBuilder *builder;
  GskPath *path1, *path2;
  CollectData res;

  builder = gsk_path_builder_new ();
  gsk_path_builder_move_to (builder, 1010);
  gsk_path_builder_line_to (builder, 10010);
  gsk_path_builder_line_to (builder, 100100);
  gsk_path_builder_line_to (builder, 10100);
  gsk_path_builder_close (builder);
  path1 = gsk_path_builder_free_to_path (builder);

  builder = gsk_path_builder_new ();
  gsk_path_builder_move_to (builder, 1000);
  gsk_path_builder_line_to (builder, 10050);
  gsk_path_builder_quad_to (builder, 100100125100);
  gsk_path_builder_quad_to (builder, 15010015075);
  gsk_path_builder_quad_to (builder, 150307030);
  path2 = gsk_path_builder_free_to_path (builder);

  res.found = 0;
  gsk_path_foreach_intersection (path1, path2, collect_cb, &res);
  g_assert_true (res.found == 3);

  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[2] == GSK_PATH_INTERSECTION_END);

  gsk_path_unref (path1);
  gsk_path_unref (path2);
}

static void
test_self_intersect_loop (void)
{
  GskPathBuilder *builder;
  GskPath *path1;
  CollectData res;
  graphene_point_t p0, p1;

  builder = gsk_path_builder_new ();
  gsk_path_builder_move_to (builder, 200);
  gsk_path_builder_cubic_to (builder, 120100, -20100800);
  path1 = gsk_path_builder_free_to_path (builder);

  res.found = 0;
  gsk_path_foreach_intersection (path1, NULL, collect_cb, &res);

  g_assert_cmpint (res.found, ==, 2);
  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_NORMAL);

  gsk_path_point_get_position (&res.point1[0], path1, &p0);
  gsk_path_point_get_position (&res.point1[1], path1, &p1);
  g_assert_true (graphene_point_near (&p0, &p1, 0.001));

  gsk_path_unref (path1);
}

static void
test_self_intersect_lollipop (void)
{
  GskPath *path1;
  CollectData res;

  path1 = gsk_path_parse ("M 150 0 L 150 100 Q 150 200 200 200 Q 250 200 250 100 Q 250 50 150 50 L 100 50 Q 50 50 50 100 Q 50 150 100 150 Q 150 150 150 100 L 150 0");

  res.found = 0;
  gsk_path_foreach_intersection (path1, NULL, collect_cb, &res);
  g_assert_cmpint (res.found, ==, 8);

  g_assert_true (res.kind[0] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[1] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[2] == GSK_PATH_INTERSECTION_END);
  g_assert_true (res.kind[3] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[4] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[5] == GSK_PATH_INTERSECTION_START);
  g_assert_true (res.kind[6] == GSK_PATH_INTERSECTION_NORMAL);
  g_assert_true (res.kind[7] == GSK_PATH_INTERSECTION_END);

  gsk_path_unref (path1);
}

int
main (int argc, char *argv[])
{
  (g_test_init) (&argc, &argv, NULL);
  g_test_set_nonfatal_assertions ();

  g_test_add_func ("/path/intersect/simple", test_intersect_simple);
  g_test_add_func ("/path/intersect/simple2", test_intersect_simple2);
  g_test_add_func ("/path/intersect/simple3", test_intersect_simple3);
  g_test_add_func ("/path/intersect/reverse", test_intersect_reverse);
  g_test_add_func ("/path/intersect/line-box", test_intersect_line_box);
  g_test_add_func ("/path/intersect/xplus", test_intersect_xplus);
  g_test_add_func ("/path/intersect/point", test_intersect_point);
  g_test_add_func ("/path/intersect/contours", test_intersect_contours);
  g_test_add_func ("/path/intersect/contours2", test_intersect_contours2);
  g_test_add_func ("/path/intersect/contours3", test_intersect_contours3);
  g_test_add_func ("/path/intersect/coincide", test_intersect_coincide);
  g_test_add_func ("/path/intersect/coincide2", test_intersect_coincide2);
  g_test_add_func ("/path/intersect/coincide3", test_intersect_coincide3);
  g_test_add_func ("/path/intersect/coincide4", test_intersect_coincide4);
  g_test_add_func ("/path/intersect/coincide5", test_intersect_coincide5);
  g_test_add_func ("/path/intersect/coincide6", test_intersect_coincide6);
  g_test_add_func ("/path/intersect/circle", test_intersect_circle);
  g_test_add_func ("/path/intersect/circle2", test_intersect_circle2);
  g_test_add_func ("/path/intersect/circle3", test_intersect_circle3);
  g_test_add_func ("/path/intersect/circle4", test_intersect_circle4);
  g_test_add_func ("/path/intersect/circle5", test_intersect_circle5);
  g_test_add_func ("/path/intersect/circle6", test_intersect_circle6);
  g_test_add_func ("/path/intersect/circle7", test_intersect_circle7);
  g_test_add_func ("/path/intersect/circle-rounded-rect", test_intersect_circle_rounded_rect);
  g_test_add_func ("/path/intersect/loop-line", test_intersect_loop_line);
  g_test_add_func ("/path/intersect/mix-segment", test_intersect_mix_segment);
  g_test_add_func ("/path/self-intersect/loop", test_self_intersect_loop);
  g_test_add_func ("/path/self-intersect/lollipop", test_self_intersect_lollipop);

  return g_test_run ();
}

Messung V0.5 in Prozent
C=100 H=92 G=95

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet am  2026-07-02) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik