void add_segments(DCEL_segment *n,DCEL_segment *act,DCEL_segment *first, int direction) { DCEL_segment *k; /* the new segment */ point p; /* p will contain the point of the segment act that doesn't touch n */ if (point_equal(act->v1,n->v1)) p = act->v2; else p = act->v1; if (visible(direction,n->v1,n->v2,p)) { /* p is visible from n.v2 */ k = (DCEL_segment *) malloc (sizeof(DCEL_segment)); /* set the coordinats of the new segment */ k->v1 = p; /* The "smallest" point */ k->v2 = n->v2; if (direction == l) { /* Add segments left of the new line */ k->p1 = act->p1; /* no 5. */ k->p2 = n; /* no 2. */ k->q1 = act; /* no 4. */ k->q2 = first; /* no 8. */ n->q2 = k; /* no 1. */ /* set_previous_segment_pointer no 7. */ if (point_equal(act->p1->v1,p)) act->p1->q1 = k; else act->p1->q2 = k; act->p1 = k; /* no 6. */ first->p2 = k; /* no 3. */ add_segments(k,k->p1,first,direction); } else { /* Add segments right of the new line */ k->q1 = act->q1; /* no 5. */ k->q2 = n; /* no 8. */ k->p1 = act; /* no 4. */ k->p2 = first; /* no 2. */ n->p2 = k; /* no 1. */ /* set_previous_segment_pointer no 7. */ if (point_equal(act->q1->v1,p)) act->q1->p1 = k; else act->q1->p2 = k; act->q1 = k; /* no 6. */ first->q2 = k; /* no 3. */ add_segments(k,k->q1,first,direction); } } }
static int cluster_update(array_t *clusters) { int k = array_length(clusters); /* update clusters */ for (int j=0; j<k; j++) { point_t sum={0,0}; cluster_t *cl = array_at(clusters, j); point_t old_c = cl->centroid; int cl_size = array_length(cl->points); /* sum all points in this cluster */ for (int i=0; i<cl_size; i++) { point_t *p = array_at(cl->points, i); sum.x += p->x; sum.y += p->y; } cl->centroid.x = sum.x/cl_size; cl->centroid.y = sum.y/cl_size; if (point_equal(&cl->centroid, &old_c)) { /* cluster centroid didn't move */ return 0; } } return 1; }
/** Deletes redundant nodes. * @param pl Polyline * @param eps A small number used in tests on two points being the same or * three points belonging to one line. */ void poly_compact(poly* pl, double eps) { int n = pl->n; double* x = pl->x; double* y = pl->y; int* ids = NULL; int nnew; int ileft, imiddle, iright; int i; if (n <= 4) return; /* do not bother */ ids = malloc(pl->n * sizeof(int)); nnew = 0; for (i = 0, imiddle = 0, ileft = n - 1; i < n - 1; ++i) if (!point_equal(x[ileft], y[ileft], x[imiddle], y[imiddle], eps)) break; else ileft--; for (i = 0, iright = 1; i < n; ++i) { if (!point_equal(x[iright], y[iright], x[imiddle], y[imiddle], eps)) { if (!ononeline(x, y, ileft, imiddle, iright, eps)) { ids[nnew++] = imiddle; ileft = imiddle; } imiddle = iright; } iright = (iright + 1) % n; } if (nnew != n) { for (i = 0; i < nnew; ++i) { x[i] = x[ids[i]]; y[i] = y[ids[i]]; } pl->n = nnew; } free(ids); pl->x = realloc(pl->x, sizeof(double) * pl->n); pl->y = realloc(pl->y, sizeof(double) * pl->n); pl->nallocated = pl->n; }
int eat_self(struct snake * s) { struct point head_pos = s->head->pos; for (struct bone * b = s->tail; b != s->head; b = b->next) { if (point_equal(b->pos, head_pos)) { return TRUE; } } return FALSE; }
void gameloop(int nrow, int ncol) { timeout(1000 / SAMPLING_RATE); const clock_t checkpoint = (clock_t) (CLOCKS_PER_SEC/GAME_SPEED); clock_t last_update = clock(); struct snake * snake = new_snake(ncol/2, nrow/2); struct point food_pos = generate_food(nrow, ncol, snake); redraw(snake, food_pos); for (;;) { struct point tail_pos = snake->tail->pos; int ch; if ((ch = getch()) != ERR) { switch (ch) { case KEY_UP: case KEY_DOWN: case KEY_LEFT: case KEY_RIGHT: if (to_dir(ch) == reverse_dir(snake->heading)) { break; } else { snake->heading = to_dir(ch); step_snake(snake); tail_pos = snake->tail->pos; redraw(snake, food_pos); } break; default: break; } } if (clock() - last_update >= checkpoint) { step_snake(snake); tail_pos = snake->tail->pos; redraw(snake, food_pos); last_update = clock(); } if (point_equal(snake->head->pos, food_pos)) { grow_snake(snake, tail_pos); food_pos = generate_food(nrow, ncol, snake); redraw(snake, food_pos); } if (out_of_border(snake->head->pos, nrow, ncol) || eat_self(snake)) { display_lose(nrow, ncol); return; } if (snake->length == (nrow-2)*(ncol-2)) { display_win(nrow, ncol); return; } } }
struct point generate_food(int nrow, int ncol, struct snake * s) { struct point p; p.x = rand() % (ncol-2) + 1; p.y = rand() % (nrow-2) + 1; for (struct bone * b = s->tail; b != NULL; b = b->next) { if (point_equal(b->pos, p)) { return generate_food(nrow, ncol, s); } } return p; }
BOOL stack_has_point(SqStack *stack, Point *p){ Point *base = (Point *)stack->base; Point *top = (Point *)stack->top; while(base < top){ if (point_equal(base, p)){ return TRUE; } base++; } return FALSE; }
CHpoints *get_points_on_hull(DCEL_segment *left,DCEL_segment *right) { DCEL_segment *n; DCEL_segment *end, *tmp; CHpoints *P=NULL; end = right; /* line((int) right->v1.x,(int) right->v1.y, (int) right->v2.x,(int) right->v2.y); */ point_list_insert(&P,left->v2); if (left->q1 == right) tmp=left->p2; else tmp=left->p1; right=left; left=tmp; if (left != end) { while (left != end) { /* line((int) right->v1.x,(int) right->v1.y, (int) right->v2.x,(int) right->v2.y); */ if (left->q1 == right) { point_list_insert(&P,left->v1); tmp=left->p2; } else { point_list_insert(&P,left->v2); tmp=left->p1; } right=left; left=tmp; } if (left->q1 == right) point_list_insert(&P,left->v1); else point_list_insert(&P,left->v2); /* line((int) right->v1.x,(int) right->v1.y, (int) right->v2.x,(int) right->v2.y);*/ } else { if (!(point_equal(right->v2,right->v1))) point_list_insert(&P,right->v1); } return P; }
/** Resamples a polyline including only points more than the threshold * distance apart. * @param pl Polyline * @param eps Threshold distance */ void poly_resample(poly* pl, double eps) { double* xs = pl->x; double* ys = pl->y; int n = pl->n; int i, nn; if (pl->n <= 1) return; for (i = 1, nn = 0; i < n; ++i) { if (!point_equal(xs[nn], ys[nn], xs[i], ys[i], eps)) { nn++; xs[nn] = xs[i]; ys[nn] = ys[i]; } } if (pl->n != nn + 1) { pl->n = nn + 1; poly_recalcextent(pl); } }
static void layer_trace_block_edge__( const layer_type * layer , int_point2d_type start_point , int i , int j , int value , edge_dir_enum dir , struct_vector_type * corner_list, int_vector_type * cell_list) { int_point2d_type current_point; int_point2d_type next_point; current_point.i = i; current_point.j = j; next_point = current_point; if (dir == BOTTOM_EDGE) point_shift( &next_point , 1 , 0 ); else if (dir == RIGHT_EDGE) { point_shift( ¤t_point , 1 , 0 ); point_shift( &next_point , 1 , 1 ); } else if (dir == TOP_EDGE) { point_shift( ¤t_point , 1 , 1 ); point_shift( &next_point , 0 , 1 ); } else if (dir == LEFT_EDGE) point_shift( ¤t_point , 0 , 1 ); struct_vector_append( corner_list , ¤t_point ); { int cell_index = i + j*layer->nx; int_vector_append( cell_list , cell_index ); } if ( !point_equal(&start_point , &next_point) ) { if (dir == BOTTOM_EDGE) { if (layer_iget_edge_value( layer , i,j,RIGHT_EDGE) == value) layer_trace_block_edge__( layer , start_point , i , j , value , RIGHT_EDGE , corner_list , cell_list); else if (layer_iget_edge_value( layer , i + 1 , j ,BOTTOM_EDGE) == value) layer_trace_block_edge__( layer , start_point , i + 1 , j , value , BOTTOM_EDGE , corner_list , cell_list); else if (layer_iget_edge_value( layer , i + 1 , j - 1 , LEFT_EDGE) == -value) layer_trace_block_edge__( layer , start_point , i + 1 , j -1 , value , LEFT_EDGE , corner_list , cell_list); else util_abort("%s: dir == BOTTOM_EDGE \n",__func__); } if (dir == RIGHT_EDGE) { if (layer_iget_edge_value( layer , i,j,TOP_EDGE) == -value) layer_trace_block_edge__( layer , start_point , i , j , value , TOP_EDGE , corner_list , cell_list); else if (layer_iget_edge_value( layer , i , j + 1 ,RIGHT_EDGE) == value) layer_trace_block_edge__( layer , start_point , i , j + 1, value , RIGHT_EDGE , corner_list , cell_list); else if (layer_iget_edge_value( layer , i + 1 , j + 1 ,BOTTOM_EDGE) == value) layer_trace_block_edge__( layer , start_point , i + 1 , j + 1, value , BOTTOM_EDGE , corner_list , cell_list); else util_abort("%s: dir == RIGHT_EDGE \n",__func__); } if (dir == TOP_EDGE) { if (layer_iget_edge_value( layer , i , j , LEFT_EDGE) == -value) layer_trace_block_edge__( layer , start_point , i , j , value , LEFT_EDGE , corner_list , cell_list); else if (layer_iget_edge_value( layer , i - 1 , j ,TOP_EDGE) == -value) layer_trace_block_edge__( layer , start_point , i - 1 , j , value , TOP_EDGE , corner_list , cell_list); else if (layer_iget_edge_value( layer , i - 1 , j + 1 ,RIGHT_EDGE) == value) layer_trace_block_edge__( layer , start_point , i - 1 , j + 1, value , RIGHT_EDGE , corner_list , cell_list); else util_abort("%s: dir == TOP_EDGE \n",__func__); } if (dir == LEFT_EDGE) { if (layer_iget_edge_value( layer , i , j , BOTTOM_EDGE) == value) layer_trace_block_edge__( layer , start_point , i , j , value , BOTTOM_EDGE , corner_list , cell_list); else if (layer_iget_edge_value( layer , i , j - 1 , LEFT_EDGE) == -value) layer_trace_block_edge__( layer , start_point , i , j - 1, value , LEFT_EDGE , corner_list , cell_list); else if (layer_iget_edge_value( layer , i -1 , j - 1 , TOP_EDGE) == -value) layer_trace_block_edge__( layer , start_point , i-1 , j - 1, value , TOP_EDGE , corner_list , cell_list); else util_abort("%s: dir == LEFT_EDGE \n",__func__); } } }
/** Checks whether the polyline is closed. * @param pl Polyline * @param eps Distance tolerance * @return 1 for yes, 0 for no */ int poly_isclosed(poly* pl, double eps) { return pl->n > 1 && point_equal(pl->x[0], pl->y[0], pl->x[pl->n - 1], pl->y[pl->n - 1], eps); }
bool line_ispoint(line l) { return (point_equal(l->v1,l->v2)); }
/*!\fn bool line_equal(line l1, line l2) Compara dos segmentos de linea, en este caso el orden de los extremos importa en la operacion \param [in] l1 Linea en 2 dimensiones \param [in] l2 Linea en 2 dimensiones \return Verdadero si los segmentos de recta son iguales, falso en caso contrario */ bool line_equal(line l1, line l2) { return (point_equal(l1->v1,l2->v1) && point_equal(l1->v2, l2->v2)); }