Exemple #1
0
static void convexhull_delete_circumference_rectangles(dlist_t *circumrects)
{
  dlink_t *a;

  assert(circumrects);

  while (circumrects->count > 0) {
    a = dlist_extract(circumrects);
    polygon_destroy((polygon_t *)a->object);
    dlink_destroy(a);
  }
}
Exemple #2
0
point_t *point_list_pop(point_list_t *list)
{
  dlink_t *link;
  point_t *p;

  assert(list);

  link = dlist_pop((dlist_t *)list);
  p = (point_t *)link->object;
  point_dec_ref(p);
  dlink_destroy(link);

  return p;
}
Exemple #3
0
line_t *line_list_pop(line_list_t *list)
{
  dlink_t *link;
  line_t *line;

  assert(list);

  link = dlist_pop((dlist_t *)list);
  line = (line_t *)link->object;
  line_dec_ref(line);
  dlink_destroy(link);

  return line;
}
Exemple #4
0
point_t *point_list_pick(int i, point_list_t *list)
{
  dlink_t *link;
  point_t *p;

  assert(list);
  assert(0 <= i && i < point_list_get_count(list));

  link = dlist_pick(i, (dlist_t *)list);
  p = (point_t *)link->object;
  point_dec_ref(p);
  dlink_destroy(link);

  return p;
}
Exemple #5
0
line_t *line_list_pick(int i, line_list_t *list)
{
  dlink_t *link;
  line_t *line;

  assert(list);
  assert(i >= 0 && i < line_list_get_count(list));

  link = dlist_pick(i, (dlist_t *)list);
  line = (line_t *)link->object;
  line_dec_ref(line);
  dlink_destroy(link);

  return line;
}
Exemple #6
0
void point_list_destroy(point_list_t *list)
{
  dlink_t *link;

  assert(list);

  if (point_list_get_ref(list) <= 0) {
    while (point_list_get_count(list) > 0) {
      link = dlist_pop((dlist_t *)list);
      point_destroy((point_t *)link->object);
      dlink_destroy(link);
    }
    dlist_destroy((dlist_t *)list);
  } else {
    list->reference--;
  }
}
Exemple #7
0
/*
void line_list_delete(line_list_t *list)
{
  dlink_t *link;
  line_t *line;

  assert(list);

  for (link = list->tail->next; link != list->head; link = link->next) {
    line = (line_t *)link->object;
    line_(line);
  }
}
*/
void line_list_destroy(line_list_t *list)
{
  dlink_t *link;

  assert(list);

  if (line_list_get_ref(list) <= 0) {
    while (line_list_get_count(list) > 0) {
      link = dlist_pop((dlist_t *)list);
      line_destroy((line_t *)link->object);
      dlink_destroy(link);
    }
    dlist_destroy((dlist_t *)list);
  } else {
    line_list_dec_ref(list);
  }
}
Exemple #8
0
/* -------------------------------------------------------------------------- *
 * Behandelt alle Ereignisse innerhalb der Kartenkonfiguration                *
 * -------------------------------------------------------------------------- */
int ui_config_card_proc(sgWidget *widget, sgEvent event)
{
  /* Allgemeine Ereignisbehandlung (für sound und so) */
  ui_generic_proc(widget, event);
  
  if(event == SG_EVENT_CHANGE)
  {
    /* Wenn die Rahmenstärke geändert hat, dann den Wert temporär in
       die Kartenconfig schreiben und die Vorschau neu zeichnen */
    if(widget == ui_config_card_border)
    {
      card_config.border = sgGetAdjustValue(ui_config_card_border, NULL) * 255 / 5;
      ui_config_card_redraw |= CARD_RENDER;
    }
    
    /* Wenn der Zoomfaktor geändert hat, dann den Wert temporär in 
       die Kartenconfig schreiben und die Vorschau neu zeichnen */
    if(widget == ui_config_card_zoom)
    {
      card_config.zoom = sgGetAdjustValue(ui_config_card_zoom, NULL);
      ui_config_card_redraw |= CARD_RENDER;
    }
    
    /* Wenn Kartenfarbe geändert hat, dann diese neu setzen: */
    /* Farbton hat geändert */
    if(widget == ui_config_card_hue)
    {
      sgColor color;      
      sgHSV hsv;
      
      hsv = sgGetColorSelHSV(ui_config_card_hue);
      color = sgHSVToRGB(hsv);
      
      card_tint.r = color.r;
      card_tint.g = color.g;
      card_tint.b = color.b;
      
      ui_config_card_redraw |= CARD_RENDER;
      
      if(ui_config_card_sat)
        sgSetColorSelHue(ui_config_card_sat, hsv.h);
      if(ui_config_card_val)
        sgSetColorSelHue(ui_config_card_val, hsv.h);
    }

    /* Sättigung hat geändert */
    if(widget == ui_config_card_sat)
    {
      sgColor color;
      sgHSV hsv;
      
      hsv = sgGetColorSelHSV(ui_config_card_sat);
      color = sgHSVToRGB(hsv);
      
      card_tint.r = color.r;
      card_tint.g = color.g;
      card_tint.b = color.b;
      
      ui_config_card_redraw |= CARD_RENDER;
      
      if(ui_config_card_hue)
        sgSetColorSelSaturation(ui_config_card_hue, hsv.s);
      if(ui_config_card_val)
        sgSetColorSelSaturation(ui_config_card_val, hsv.s);
    }
    
    /* Helligkeit hat geändert */
    if(widget == ui_config_card_val)
    {
      sgColor color;
      sgHSV hsv;
      
      hsv = sgGetColorSelHSV(ui_config_card_val);
      color = sgHSVToRGB(hsv);
      
      card_tint.r = color.r;
      card_tint.g = color.g;
      card_tint.b = color.b;
      
      ui_config_card_redraw |= CARD_RENDER;
      
      if(ui_config_card_hue)
        sgSetColorSelValue(ui_config_card_hue, hsv.v);
      if(ui_config_card_sat)
        sgSetColorSelValue(ui_config_card_sat, hsv.v);
    }
    
    /* Transparenz hat geändert */
    if(widget == ui_config_card_transparency)
    {
      card_tint.a = 255 - (sgGetAdjustValue(ui_config_card_transparency, NULL) * 255 / 100);
      
      ui_config_card_redraw |= CARD_RENDER;
    }
  }

  if(event == SG_EVENT_CLICK)
  {
    /* ..andere Karte wurde verlangt? */
    if(widget == ui_config_card_pick)
    {
      struct list list;
      
      /* Eine Liste mit der aktuellen Karte machen, 
         damit diese nicht wieder gewählt wird */
      dlink_list_zero(&list);
      dlink_add_head(&list, dlink_node_new(), ui_config_card_card);
      
      /* Alte Kartendaten freigeben */
      card_clean(ui_config_card_card);
      
      /* Neue Karte ziehen und redraw */
      ui_config_card_card = card_random(&list);
      ui_config_card_redraw |= CARD_RENDER;
      
      /* Liste wieder freigeben */
      dlink_destroy(&list);
    }
    
    /* Karte hervorheben in der Vorschau? */
    if(widget == ui_config_card_hilite)
      ui_config_card_redraw |= CARD_RENDER;
    
    /* Karte auswählen in der Vorschau? */
    if(widget == ui_config_card_select)
      ui_config_card_redraw |= CARD_RENDER;
  }
  
    
  return 0;  
}
Exemple #9
0
 /* some problem is occurred due to co-linear pixels,
  * so it need to be check the maximum distance within same minimum angle
  * comment : if break statement in the Right chain growth routine is converted
  * from "if (ycoord[imin] < ycoord[i-1]) break;"
  * to "if (ycoord[imin] <= ycoord[i-1]) break;"
  * , then some problem is removed.
  * However, if an point exits 
  * such that is resemble to "ycoord" of the extreme point
  * and has the minimum angle
  * then the convex hull that we want don't be created.
  */
static int jarvismarch(polygon_t *chull, point_list_t *points)
{
  real_t ang, dist, ymin;
  real_t amin, dmax, dx, dy;
  dlink_t *x, *y, *ax, *bx;
  point_t *p, *q;

  assert(chull);
  assert(points);
  assert(point_list_get_count(points) >= 3);

  // Preparing the polygon, and
  // Find the point with minimum value of y-coordinate
  for (ax = NULL, x = points->tail->next; x != points->head; x = x->next) {
    p = (point_t *)x->object;
    y = dlink_new();
    point_inc_ref(p);
    y->object = (void *)p;
    dlist_insert(y, chull);
    if (ax == NULL || point_get_y(p) < ymin) {
      ax = y;
      ymin = point_get_y(p);
    }
  }
  dlink_cutoff(ax);
  dlist_dec_count(chull);
  dlist_push(ax, chull);
  point_dump((point_t *)ax->object);

  // Scan right chain
  for (ax = chull->tail->next; ax->next != chull->head; ax = ax->next) {
    p = (point_t *)ax->object;
    for (bx = NULL, x = ax->next; x != chull->head; x = x->next) {
      q = (point_t *)x->object;
      dx = point_get_x(q) - point_get_x(p);
      dy = point_get_y(q) - point_get_y(p);
      ang = arctan2r(dy, dx);
      dist = sqrt(sqr(dx) + sqr(dy));
      // Find another vertex with min-angle and max-distance
      if (bx == NULL || ang < amin) {
	bx = x;
	amin = ang;
	dmax = dist;
      } else if (ang == amin && dist > dmax) {
	bx = x;
	dmax = dist;
      }
    }
    q = (point_t *)bx->object;

    // Right chain complete ?
    if (point_get_y(q) < point_get_y(p))
      break;

    // Swapping (coordinations and mark)
    dlink_cutoff(bx);
    dlink_append(bx, ax);
    point_dump((point_t *)bx->object);
  }
  //printf("n: %d\n", convexhull->count);

  // Scan left chain
  for (; ax->next != chull->head; ax = ax->next) {
    p = (point_t *)ax->object;
    for (bx = NULL, x = ax->next; x != chull->head; x = x->next) {
      q = (point_t *)x->object;
      dx = point_get_x(p) - point_get_x(q);
      dy = point_get_y(p) - point_get_y(q);
      ang = arctan2r(dy, dx);
      dist = sqrt(sqr(dx) + sqr(dy));
      if (bx == NULL || ang < amin) {
	bx = x;
	amin = ang;
	dmax = dist;
      } else if (ang == amin && dist > dmax) {
	bx = x;
	dmax = dist;
      }
    }

    y = chull->tail->next;
    q = (point_t *)y->object;
    dx = point_get_x(p) - point_get_x(q);
    dy = point_get_y(p) - point_get_y(q);
    ang = arctan2r(dy, dx);
    // Convexhull complete ?
    if (ang < amin) break;

    // Swapping
    dlink_cutoff(bx);
    dlink_append(bx, ax);
    point_dump((point_t *)bx->object);
  }
  //printf("n: %d\n", convexhull->count);

  while (ax->next != chull->head) {
    x = ax->next;
    dlink_cutoff(x);
    dlist_dec_count(chull);
    point_destroy((point_t *)x->object);
    dlink_destroy(x);
  }

  return dlist_get_count(chull);
}
Exemple #10
0
static int quickhull(polygon_t *chull, point_list_t *points)
{
  real_t ymin, ymax, yval;
  point_t *p, *v1, *v2, *v3;
  dlink_t *ax, *bx, *x, *y, *next;
  dlist_t *right_group, *left_group;

  assert(chull);
  assert(points);

  // Allocate the structure element of convex hull
  for (x = points->tail->next; x != points->head; x = x->next) {
    p = (point_t *)x->object;
    point_inc_ref(p);
    y = dlink_new();
    y->object = (void *)p;
    dlist_insert(y, chull);
  }

  // find the extreme points along y-axis
  ax = NULL;
  bx = NULL;
  for (x = chull->tail->next; x != chull->head; x = x->next) {
    yval = point_get_y((point_t *)(x->object));
    if (ax == NULL || yval < ymin) {
      ax = x;
      ymin = yval;
    }
    if (bx == NULL || yval > ymax) {
      bx = x;
      ymax = yval;
    }
  }
  dlink_cutoff(ax);
  dlist_dec_count(chull);
  dlink_cutoff(bx);
  dlist_dec_count(chull);
  //point_dump((point_t *)ax->object);
  //point_dump((point_t *)bx->object);

  v1 = point_new();
  v2 = point_new();
  v3 = point_new();

  //printf("for right section\n");
  right_group= dlist_new();
  dlist_insert(ax, right_group);
  point_subtract(v2, (point_t *)bx->object, (point_t *)ax->object);
  for (x = chull->tail->next; x != chull->head;) {
    //point_dump((point_t *)x->object);
    point_subtract(v1, (point_t *)x->object, (point_t *)ax->object);
    point_xproduct(v3, v1, v2);
    if (point_get_z(v3) > 0) {
      next = x->next;
      dlink_cutoff(x);
      dlist_dec_count(chull);
      dlist_insert(x, right_group);
      //printf(" ");
      //point_dump((point_t *)x->object);
      x = next;
    } else x = x->next;
  }
  dlist_insert(bx, right_group);
  quickhull_grouping(right_group);

  //printf("for left section\n");
  ax = dlist_pop(right_group);
  bx = dlist_extract(right_group);
  //point_dump((point_t *)ax->object);
  //point_dump((point_t *)bx->object);

  left_group = dlist_new();
  dlist_insert(bx, left_group);
  point_subtract(v2, (point_t *)ax->object, (point_t *)bx->object);
  for (x = chull->tail->next; x != chull->head; ) {
    point_subtract(v1, (point_t *)x->object, (point_t *)bx->object);
    point_xproduct(v3, v1, v2);
    if (point_get_z(v3) > 0) {
      next = x->next;
      dlink_cutoff(x);
      dlist_dec_count(chull);
      dlist_insert(x, left_group);
      //point_dump((point_t *)x->object);
      x = next;
    } else {
      next = x->next;
      dlink_cutoff(x);
      dlist_dec_count(chull);
      point_destroy((point_t *)x->object);
      dlink_destroy(x);
      x = next;
    }
  }
  dlist_insert(ax, left_group);
  quickhull_grouping(left_group);

  ax = dlist_extract(left_group);
  bx = dlist_pop(left_group);

  dlist_insert(ax, chull);
  while (dlist_get_count(right_group) > 0) {
    x = dlist_pop(right_group);
    dlist_insert(x, chull);
  }
  dlist_insert(bx, chull);

  while (dlist_get_count(left_group) > 0) {
    x = dlist_pop(left_group);
    dlist_insert(x, chull);
  }

  dlist_destroy(left_group);
  dlist_destroy(right_group);

  point_destroy(v3);
  point_destroy(v2);
  point_destroy(v1);

  return dlist_get_count(chull);
}
Exemple #11
0
/*
 * Quick-Hull
 * Here's an algorithm that deserves its name.
 * It's a fast way to compute the convex hull of a set of points on the plane.
 * It shares a few similarities with its namesake, quick-sort: 
 * - it is recursive.
 * - each recursive step partitions data into several groups.
 *
 * The partitioning step does all the work. The basic idea is as follows:
 * 1. We are given a some points, 
 *    and line segment AB which we know is a chord of the convex hull. 
 * 2. Among the given points, find the one which is farthest from AB.
 *    Let's call this point C.
 * 3. The points inside the triangle ABC cannot be on the hull.
 *    Put them in set s0.
 * 4. Put the points which lie outside edge AC in set s1,
 * and points outside edge BC in set s2.
 *
 * Once the partitioning is done, we recursively invoke quick-hull on sets s1 and s2.
 * The algorithm works fast on random sets of points 
 * because step 3 of the partition typically discards a large fraction of the points. 
 */
static int quickhull_grouping(dlist_t *group)
{
  dlink_t *x, *ax, *bx, *cx, *next;
  dlist_t *s1, *s2;
  point_t *v1, *v2, *v3;
  real_t area;

  assert(group);

  if (dlist_get_count(group) <= 2)
    return dlist_get_count(group);

  v1 = point_new();
  v2 = point_new();
  v3 = point_new();

  // Find the point with maximum parallelogram's area
  ax = dlist_pop(group);
  bx = dlist_extract(group);
  cx = NULL;

  point_subtract(v2, (point_t *)(bx->object), (point_t *)(ax->object));
  for (x = group->tail->next; x != group->head; x = x->next) {
    point_subtract(v1, (point_t *)(x->object), (point_t *)(ax->object));
    point_xproduct(v3, v1, v2);
    if (cx == NULL || point_get_z(v3) > area) {
      cx = x;
      area = point_get_z(v3);
    }
  }
  dlink_cutoff(cx);
  dlist_dec_count(group);

  // S1 grouping
  s1 = dlist_new();
  dlist_insert(ax, s1);
  point_subtract(v2, (point_t *)(cx->object), (point_t *)(ax->object));
  for (x = group->tail->next; x != group->head; ) {
    point_subtract(v1, (point_t *)(x->object), (point_t *)(ax->object));
    point_xproduct(v3, v1, v2);
    if (point_get_z(v3) > 0) {
      next = x->next;
      dlink_cutoff(x);
      dlist_dec_count(group);
      dlist_insert(x, s1);
      x = next;
    } else x = x->next;
  }
  dlist_insert(cx, s1);
  quickhull_grouping(s1);
  assert(cx == s1->head->prev);

  // S2 grouping and pop out others
  cx = dlist_extract(s1);
  s2 = dlist_new();
  dlist_insert(cx, s2);
  point_subtract(v2, (point_t *)bx->object, (point_t *)cx->object);
  for (x = group->tail->next; x != group->head;) {
    point_subtract(v1, (point_t *)x->object, (point_t *)cx->object);
    point_xproduct(v3, v1, v2);
    if (point_get_z(v3) > 0) {
      next = x->next;
      dlink_cutoff(x);
      dlist_dec_count(group);
      dlist_insert(x, s2);
      x = next;
    } else {
      next = x->next;
      dlink_cutoff(x);
      dlist_dec_count(group);
      point_destroy((point_t *)x->object);
      dlink_destroy(x);
      x = next;
    }
  }
  dlist_insert(bx, s2);
  quickhull_grouping(s2);
  assert(bx == s2->head->prev);

  assert(dlist_get_count(group) == 0);
  //assert(group->count == 0);

  // Merge s1 and s2 into group
  while (dlist_get_count(s1) > 0) {
    x = dlist_pop(s1);
    dlist_insert(x, group);
  }

  while (dlist_get_count(s2) > 0) {
    x = dlist_pop(s2);
    dlist_insert(x, group);
  }

  dlist_destroy(s2);
  dlist_destroy(s1);

  point_destroy(v3);
  point_destroy(v2);
  point_destroy(v1);

  return dlist_get_count(group);
}
Exemple #12
0
/* Graham's Scan
 * Given a set of points on the plane, Graham's scan computes their convex hull.
 * The algorithm works in three phases: 
 * 1. Find an extreme point.
 *    This point will be the pivot, is guaranteed to be on the hull,
 *    and is chosen to be the point with largest y coordinate. 
 * 2. Sort the points in order of increasing angle about the pivot.
 *    We end up with a star-shaped polygon (one in which one special point,
 *    in this case the pivot, can "see" the whole polygon). 
 * 3. Build the hull, by marching around the star-shaped poly, adding edges
 *    when we make a left turn, and back-tracking when we make a right turn. 
 */
static int grahamscan(polygon_t *chull, point_list_t *points)
{
  int i;
  real_t dx, dy, ymin;
  real_t *ang;
  point_t *p, *q;
  point_t *v1, *v2, *v3;
  dlink_t *ax, *bx, *cx, *x, *y, *tmp;
	
  assert(chull);
  assert(points);
  assert(point_list_get_count(points) >= 3);
	
  ang = (real_t *)malloc(point_list_get_count(points) * sizeof(real_t));
  assert(ang);

  // Find an extreme point
  // Preparing the polygon, and
  // Find the point with minimum value of y-coordinate
  for (ax = NULL, x = points->tail->next; x != points->head; x = x->next) {
    p = (point_t *)x->object;
    y = dlink_new();
    point_inc_ref(p);
    y->object = (void *)p;
    dlist_insert(y, chull);
    if (ax == NULL || point_get_y(p) < ymin) {
      ax = y;
      ymin = point_get_y(p);
    }
  }
  dlink_cutoff(ax);
  dlist_dec_count(chull);
  dlist_push(ax, chull);

  // Sort the points in order of increasing angle about the pivot.
  p = (point_t *)ax->object;
  //point_dump(p);
  for (i = 0, x = ax->next; x != chull->head; x = x->next) {
    q = (point_t *)x->object;
    dx = point_get_x(q) - point_get_x(p);
    dy = point_get_y(q) - point_get_y(p);
    ang[i] = arctan2r(dy, dx);
    x->spare = (void *)&(ang[i]);
    i++;
    //point_dump(q);
    //printf("ang: %lf\n", ang[i-1]);
  }

  for (x = ax->next; x->next != chull->head; x = x->next) {
    for (y = x->next; y != chull->head; y = y->next) {
      if (*((real_t *)y->spare) < *((real_t *)x->spare)) {
	dlink_exchange(x, y);
	tmp = x, x = y, y = tmp;
      }
    }
  }
  //point_dump((point_t *)c->object);

  v1 = point_new();
  v2 = point_new();
  v3 = point_new();

  cx = chull->tail->next->next->next;
  while (cx != chull->head) {
    bx = cx->prev;
    ax = bx->prev;

    point_subtract(v1, (point_t *)ax->object, (point_t *)bx->object);
    point_subtract(v2, (point_t *)cx->object, (point_t *)bx->object);
    point_xproduct(v3, v1, v2);

    // Convex ?
    if (point_get_z(v3) < 0) {
      cx = cx->next;
    } else {
      dlink_cutoff(bx);
      dlist_dec_count(chull);
      point_destroy((point_t *)bx->object);
      dlink_destroy(bx);
    }
  }

  for (x = chull->tail->next; x != chull->head; x = x->next)
    x->spare = NULL;

  point_destroy(v3);
  point_destroy(v2);
  point_destroy(v1);

  free(ang);

  return dlist_get_count(chull);
}