Esempio n. 1
0
static void sort_points (mc_point_t *A, int N) {
  int i, j;
  mc_point_t h, t;
  if (N <= 0) {
    return;
  }
  if (N == 1) {
    if (cmp_points (&A[0], &A[1]) > 0) {
      t = A[0];
      A[0] = A[1];
      A[1] = t;
    }
    return;
  }
  i = 0;
  j = N;
  h = A[j >> 1];
  do {
    while (cmp_points (&A[i], &h) < 0) { i++; }
    while (cmp_points (&A[j], &h) > 0) { j--; }
    if (i <= j) {
      t = A[i];  A[i++] = A[j];  A[j--] = t;
    }
  } while (i <= j);
  sort_points (A+i, N-i);
  sort_points (A, j);
}
Esempio n. 2
0
int partition(struct Point a[], int l, int r)
{
    int i, j;

    struct Point t, pivot;

    pivot = a[l];
    i = l;
    j = r + 1;

    while (1) {
	do
	    ++i;
	while (cmp_points(&a[i], &pivot, NULL) < 1 && i <= r);
	do
	    --j;
	while (cmp_points(&a[j], &pivot, NULL) == 1);

	if (i >= j)
	    break;

	if (a[i].line1 != NULL) {
	    if (a[i].line1->p1 == &a[i])
		a[i].line1->p1 = &a[j];
	    else
		a[i].line1->p2 = &a[j];
	}

	if (a[j].line1 != NULL) {
	    if (a[j].line1->p1 == &a[j])
		a[j].line1->p1 = &a[i];
	    else
		a[j].line1->p2 = &a[i];
	}

	if (a[i].line2 != NULL) {
	    if (a[i].line2->p1 == &a[i])
		a[i].line2->p1 = &a[j];
	    else
		a[i].line2->p2 = &a[j];
	}

	if (a[j].line2 != NULL) {
	    if (a[j].line2->p1 == &a[j])
		a[j].line2->p1 = &a[i];
	    else
		a[j].line2->p2 = &a[i];
	}

	t = a[i];
	a[i] = a[j];
	a[j] = t;

    }

    if (a[l].line1 != NULL) {
	if (a[l].line1->p1 == &a[l])
	    a[l].line1->p1 = &a[j];
	else
	    a[l].line1->p2 = &a[j];
    }

    if (a[j].line1 != NULL) {
	if (a[j].line1->p1 == &a[j])
	    a[j].line1->p1 = &a[l];
	else
	    a[j].line1->p2 = &a[l];
    }

    if (a[l].line2 != NULL) {
	if (a[l].line2->p1 == &a[l])
	    a[l].line2->p1 = &a[j];
	else
	    a[l].line2->p2 = &a[j];
    }

    if (a[j].line2 != NULL) {
	if (a[j].line2->p1 == &a[j])
	    a[j].line2->p1 = &a[l];
	else
	    a[j].line2->p2 = &a[l];
    }

    t = a[l];
    a[l] = a[j];
    a[j] = t;


    return j;
}
Esempio n. 3
0
/** for all points initiate their vis line to the one directly below
*/
void init_vis(struct Point *points, int num_points, struct Line *lines,
	      int num_lines)
{
    int i;
    double d;
    struct avl_table *tree = avl_create(cmp_points, NULL, NULL);
    struct avl_traverser it;
    struct Point *p;

    double y1, y2;

    struct Point *s1, *s2;

    for (i = 0; i < num_points; i++) {

	points[i].vis = NULL;
	d = PORT_DOUBLE_MAX;

	avl_t_init(&it, tree);

	/* loop through the tree */
	while ((p = avl_t_next(&it)) != NULL) {
	    if (segment1(p) == NULL && segment2(p) == NULL)
		continue;

	    /* test for intersection and get the intersecting point */
	    if (segment1(p) != NULL &&
		segment_intersect(segment1(p), &points[i], &y1) > -1) {
		/* find the closest one below */
		if (y1 < points[i].y && (points[i].y - y1) < d) {
		    d = points[i].y - y1;
		    points[i].vis = segment1(p);

		}
	    }


	    if (segment2(p) != NULL &&
		segment_intersect(segment2(p), &points[i], &y2) > -1) {
		if (y2 < points[i].y && (points[i].y - y2) < d) {
		    d = points[i].y - y2;
		    points[i].vis = segment2(p);
		}
	    }

	}			/* end loop */

	s1 = s2 = NULL;

	/* now if the other point is on the right, we can delete it */
	if (segment1(&points[i]) != NULL &&
	    cmp_points(&points[i], other1(&points[i]), NULL) > 0) {
	    p = other1(&points[i]);

	    /* unless the other point of it is on the left */
	    if (segment1(p) != NULL && other1(p) != &points[i] &&
		cmp_points(&points[i], other1(p), NULL) > 0)
		s1 = avl_delete(tree, p);
	    else if (segment2(p) != NULL && other2(p) != &points[i] &&
		     cmp_points(&points[i], other2(p), NULL) > 0)
		s1 = avl_delete(tree, p);
	}

	/* now if the other point is on the right, we can delete it */
	if (segment2(&points[i]) != NULL &&
	    cmp_points(&points[i], other2(&points[i]), NULL) > 0) {
	    p = other2(&points[i]);

	    /* unless the other point of it is on the left */
	    if (segment1(p) != NULL && other1(p) != &points[i] &&
		cmp_points(&points[i], other1(p), NULL) > 0)
		s2 = avl_delete(tree, p);
	    else if (segment2(p) != NULL && other2(p) != &points[i] &&
		     cmp_points(&points[i], other2(p), NULL) > 0)
		s2 = avl_delete(tree, p);
	}

	/* if both weren't deleted, it means there is at least one other
	   point on the left, so add the current */
	/* also there is no point adding the point if there is no segment attached to it */
	if ((s1 == NULL || s2 == NULL)) {
	    avl_insert(tree, &points[i]);
	}
    }


    avl_destroy(tree, NULL);
}