fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. typedef struct
  6. {
  7. float x;
  8. float y;
  9. float z;
  10. } vec3;
  11.  
  12. float
  13. dot(vec3 a, vec3 b)
  14. {
  15. return a.x * b.x + a.y * b.y + a.z * b.z;
  16. }
  17.  
  18. vec3
  19. scale(float s, vec3 a)
  20. {
  21. vec3 r;
  22. r.x = s * a.x;
  23. r.y = s * a.y;
  24. r.z = s * a.z;
  25. return r;
  26. }
  27.  
  28. vec3
  29. add(vec3 a, vec3 b)
  30. {
  31. vec3 r;
  32. r.x = a.x + b.x;
  33. r.y = a.y + b.y;
  34. r.z = a.z + b.z;
  35. return r;
  36. }
  37.  
  38. int
  39. intersect(vec3 a, vec3 b, vec3 *normals, vec3 *points, int nnormals)
  40. {
  41. vec3 ab = add(b, scale(-1, a));
  42. float tfirst = 0;
  43. float tlast = 1;
  44. int i;
  45. for(i = 0; i < nnormals; i++)
  46. {
  47. float d = dot(normals[i], points[i]);
  48. float denom = dot(normals[i], ab);
  49. float dist = d - dot(normals[i], a);
  50. float t = dist / denom;
  51. if(denom > 0 && t > tfirst)
  52. {
  53. tfirst = t;
  54. }
  55. else if(denom < 0 && t < tlast)
  56. {
  57. tlast = t;
  58. }
  59. }
  60. return tfirst < tlast ? 1 : 0;
  61. }
  62.  
  63. const vec3 N = {0,-1,0};
  64. const vec3 S = {0,1,0};
  65. const vec3 W = {-1,0,0};
  66. const vec3 E = {1,0,0};
  67. const vec3 D = {0,0,-1};
  68.  
  69. int
  70. main(void)
  71. {
  72. vec3 normals[5];
  73. vec3 player;
  74. vec3 *targets;
  75. int i;
  76. int j;
  77. vec3 *buildings;
  78. vec3 *b;
  79. int nbuildings = 0;
  80. int n;
  81. int m;
  82. char line[300];
  83. normals[0] = N;
  84. normals[1] = S;
  85. normals[2] = W;
  86. normals[3] = E;
  87. normals[4] = D;
  88. fgets(line, 300, stdin);
  89. n = atoi(line);
  90. /*5 sides for each building*/
  91. buildings = calloc(n * 5, sizeof(*buildings));
  92. b = buildings;
  93. for(i = 0; i < n; i++)
  94. {
  95. char *z;
  96. fgets(line, 300, stdin);
  97. for(j = 0; j < n && (z = strtok(j ? NULL : line, " \n")) != NULL; j++)
  98. {
  99. vec3 bottom;
  100. vec3 top;
  101. if(z[0] == '0') continue;
  102. nbuildings++;
  103. bottom.x = j;
  104. bottom.y = i;
  105. bottom.z = 0;
  106. top.x = j + 1;
  107. top.y = i + 1;
  108. top.z = atoi(z);
  109. b[0] = top;
  110. b[1] = bottom;
  111. b[2] = top;
  112. b[3] = bottom;
  113. b[4] = top;
  114. b += 5;
  115. }
  116. }
  117. fgets(line, 300, stdin);
  118. player.x = atof(strtok(line, " "));
  119. player.y = atof(strtok(NULL, " "));
  120. player.z = atof(strtok(NULL, " \n"));
  121. fgets(line, 300, stdin);
  122. m = atoi(line);
  123. targets = calloc(m, sizeof(*targets));
  124. for(i = 0; i < m; i++)
  125. {
  126. int hit = 1;
  127. fgets(line, 300, stdin);
  128. targets[i].x = atof(strtok(line, " "));
  129. targets[i].y = atof(strtok(NULL, " "));
  130. targets[i].z = atof(strtok(NULL, " \n"));
  131. for(j = 0; j < nbuildings; j++)
  132. {
  133. b = &buildings[j * 5];
  134. if(intersect(player, targets[i], normals, b, 5) == 1)
  135. {
  136. hit = 0;
  137. break;
  138. }
  139. }
  140. printf("%d\n", hit ? 1 : -1);
  141. }
  142. free(buildings);
  143. free(targets);
  144. return 0;
  145. }
Success #stdin #stdout 0s 2428KB
stdin
5
0 0 0 0 0
0 0 0 0 0
0 0 4 0 0
0 0 0 0 0
0 0 0 0 0
0.5 0.5 0.5
1
4.5 1.5 0.5
stdout
1