#include #include #define N 7 typedef struct coord_ { double x; double y; } coord; // рекурсивная структура - кольцо. typedef struct ring_ { coord *data; struct ring_ *next; struct ring_ *prev; } Ring; // Делаем элемент и заполняем данными Ring *makenew( Ring *ring, coord *data ) { ring = (Ring *)malloc(sizeof(Ring)); ring -> next = ring -> prev = NULL; ring -> data = data; return ( ring ); } // Делаем элемент и связываем с данным всеми способами. Для случая 2-х эл-ов. // // Было Станет // // ring ring <-> ring->next Ring *linkwith( Ring *ring, coord *data ) { ring -> next=(Ring *)malloc(sizeof(Ring)); ring -> next -> data=data; ring -> next -> prev=ring; ring -> prev = ring -> next; ring -> next -> next = ring; return (ring->next); } // // Было Станет // // will_be_before <-> ring will_be_before <-> _new_ <-> ring Ring *placeafter( Ring *will_be_before, coord *data ) { Ring *temp1, *temp2; temp1 = will_be_before -> next; temp2 = makenew( temp2, data ); temp2 -> next = temp1; temp1 -> prev = temp2; temp2 -> prev = will_be_before; will_be_before -> next = temp2; return (will_be_before->next); } // // Было Станет // // ring <-> will_be_after ring <-> _new_ <-> will_be_after Ring *placebefore( Ring *will_be_after, coord *data ) { Ring *temp1, *temp2; temp1 = will_be_after -> prev; temp2 = makenew( temp2, data ); temp2 -> prev = temp1; temp1 -> next = temp2; temp2 -> next = will_be_after; will_be_after -> prev = temp2; return (will_be_after->prev); } // // Было Станет // // 1 <-> ring <-> 2 1 <-> 2 void remove_elem( Ring *ring ) { ring -> prev -> next = ring -> next; ring -> next -> prev = ring -> prev; free ( ring ); } double sin_angle( Ring *ring1, Ring *ring2, Ring *ring3 ) { double x1,x2,y1,y2; x1 = ring1 -> data -> x - ring2 -> data -> x; y1 = ring1 -> data -> y - ring2 -> data -> y; x2 = ring3 -> data -> x - ring2 -> data -> x; y2 = ring3 -> data -> y - ring2 -> data -> y; return ( x1 * y2 - y1 * x2 ); } double sgn_cos_angle( Ring *ring1, Ring *ring2, Ring *ring3 ) { double x1,x2,y1,y2; x1 = ring1 -> data -> x - ring2 -> data -> x; y1 = ring1 -> data -> y - ring2 -> data -> y; x2 = ring3 -> data -> x - ring2 -> data -> x; y2 = ring3 -> data -> y - ring2 -> data -> y; return ( x1 * x2 + y1 * y2 ); } void convex_it( Ring *last ) { if (sin_angle(last->prev->prev, last->prev, last) == 0 ) { if ( sgn_cos_angle( last->prev->prev, last->prev, last ) <0 ) remove_elem(last->prev); } else while ( sin_angle ( last -> prev -> prev, last -> prev, last ) >= 0 ) remove_elem( last -> prev ); if (sin_angle(last->next->next, last->next, last) == 0 ) { if ( sgn_cos_angle(last->next->next, last->next, last )<0 ) remove_elem(last->next); } else while ( sin_angle ( last -> next -> next, last -> next, last ) <= 0 ) remove_elem( last -> next ); } void print_ring( Ring *last ) { Ring *temp; temp=last; for(;;) { printf("Printing Ring: x:%lf y:%lf\n",last->data->x,last->data->y); last = last -> next; if( last == temp | last == NULL ) break; } } void main() { coord *point; Ring *ring, *last, *new, *temp; int i; point=(coord *)malloc(sizeof(coord)*N); for (i=0;ix ),&( (point+i)->y)); ring=makenew( ring, point ); last=linkwith( ring , (point+1) ); for( i=2; iprev, last, temp) >= 0 ) last = placebefore( last, point+i ); else last = placeafter ( last, point+i ); convex_it(last); } print_ring(last); }