Advertisement
a53

parcele

a53
Feb 27th, 2017
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.03 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. typedef struct { double x, y; } vec_t, *vec;
  6.  
  7. inline double dot(vec a, vec b)
  8. {
  9. return a->x * b->x + a->y * b->y;
  10. }
  11.  
  12. inline double cross(vec a, vec b)
  13. {
  14. return a->x * b->y - a->y * b->x;
  15. }
  16.  
  17. inline vec vsub(vec a, vec b, vec res)
  18. {
  19. res->x = a->x - b->x;
  20. res->y = a->y - b->y;
  21. return res;
  22. }
  23.  
  24. int left_of(vec a, vec b, vec c)
  25. {
  26. vec_t tmp1, tmp2;
  27. double x;
  28. vsub(b, a, &tmp1);
  29. vsub(c, b, &tmp2);
  30. x = cross(&tmp1, &tmp2);
  31. return x < 0 ? -1 : x > 0;
  32. }
  33.  
  34. int line_sect(vec x0, vec x1, vec y0, vec y1, vec res)
  35. {
  36. vec_t dx, dy, d;
  37. vsub(x1, x0, &dx);
  38. vsub(y1, y0, &dy);
  39. vsub(x0, y0, &d);
  40. double dyx = cross(&dy, &dx);
  41. if (!dyx) return 0;
  42. dyx = cross(&d, &dx) / dyx;
  43. if (dyx <= 0 || dyx >= 1) return 0;
  44.  
  45. res->x = y0->x + dyx * dy.x;
  46. res->y = y0->y + dyx * dy.y;
  47. return 1;
  48. }
  49.  
  50. typedef struct { int len, alloc; vec v; } poly_t, *poly;
  51.  
  52. poly poly_new()
  53. {
  54. return (poly)calloc(1, sizeof(poly_t));
  55. }
  56.  
  57. void poly_free(poly p)
  58. {
  59. free(p->v);
  60. free(p);
  61. }
  62.  
  63. void poly_append(poly p, vec v)
  64. {
  65. if (p->len >= p->alloc) {
  66. p->alloc *= 2;
  67. if (!p->alloc) p->alloc = 4;
  68. p->v = (vec)realloc(p->v, sizeof(vec_t) * p->alloc);
  69. }
  70. p->v[p->len++] = *v;
  71. }
  72.  
  73. int poly_winding(poly p)
  74. {
  75. return left_of(p->v, p->v + 1, p->v + 2);
  76. }
  77.  
  78. void poly_edge_clip(poly sub, vec x0, vec x1, int left, poly res)
  79. {
  80. int i, side0, side1;
  81. vec_t tmp;
  82. vec v0 = sub->v + sub->len - 1, v1;
  83. res->len = 0;
  84.  
  85. side0 = left_of(x0, x1, v0);
  86. if (side0 != -left) poly_append(res, v0);
  87.  
  88. for (i = 0; i < sub->len; i++) {
  89. v1 = sub->v + i;
  90. side1 = left_of(x0, x1, v1);
  91. if (side0 + side1 == 0 && side0)
  92. if (line_sect(x0, x1, v0, v1, &tmp))
  93. poly_append(res, &tmp);
  94. if (i == sub->len - 1) break;
  95. if (side1 != -left) poly_append(res, v1);
  96. v0 = v1;
  97. side0 = side1;
  98. }
  99. }
  100.  
  101. poly poly_clip(poly sub, poly clip)
  102. {
  103. int i;
  104. poly p1 = poly_new(), p2 = poly_new(), tmp;
  105.  
  106. int dir = poly_winding(clip);
  107. poly_edge_clip(sub, clip->v + clip->len - 1, clip->v, dir, p2);
  108. for (i = 0; i < clip->len - 1; i++) {
  109. tmp = p2; p2 = p1; p1 = tmp;
  110. if(p1->len == 0) {
  111. p2->len = 0;
  112. break;
  113. }
  114. poly_edge_clip(p1, clip->v + i, clip->v + i + 1, dir, p2);
  115. }
  116.  
  117. poly_free(p1);
  118. return p2;
  119. }
  120.  
  121. vec_t *citire_poligon(int *vlen)
  122. {
  123. scanf("%d", vlen);
  124. vec_t *v;
  125. v = (vec_t *)malloc(*vlen * sizeof(vec_t));
  126. int i;
  127. for (i = 0; i < *vlen; ++i)
  128. {
  129. int x, y;
  130. scanf("%d %d", &x, &y);
  131. v[i].x = x;
  132. v[i].y = y;
  133. }
  134. return v;
  135. }
  136.  
  137. int main()
  138. {
  139. int i;
  140. freopen("parcele.in", "r", stdin);
  141. freopen("parcele.out", "w", stdout);
  142. vec_t *c, *s;
  143. int clen, slen;
  144. c = citire_poligon(&clen);
  145. s = citire_poligon(&slen);
  146.  
  147. poly_t clipper = {clen, 0, c};
  148. poly_t subject = {slen, 0, s};
  149.  
  150. poly res = poly_clip(&subject, &clipper);
  151.  
  152. printf("%d\n", res->len);
  153. for (i = 0; i < res->len; i++)
  154. printf("%0.2lf %0.2lf\n", res->v[i].x, res->v[i].y);
  155.  
  156. free(c);
  157. free(s);
  158. return 0;
  159. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement