fork download
  1. /*
  2.   プログラミングのお題スレ Part13
  3.   ttps://mevius.5ch.net/test/read.cgi/tech/1549160513/
  4.  
  5.   473デフォルトの名無しさん2019/03/03(日) 08:56:00.68ID:NMVimqZR
  6.   お題:2つの円が重なった時、重なった部分の面積を求めなさい。
  7.  
  8.   このプログラムでは以下のURLの画像の場合を計算します。
  9.   ttps://imgur.com/i2G9Ahd
  10. */
  11. #include <stdio.h>
  12. #include <math.h>
  13. #define M_PI 3.14159265358979323846
  14.  
  15. typedef struct{
  16. double x;
  17. double y;
  18. double r;
  19. }cir_t;
  20.  
  21. double hoge(cir_t a, cir_t b){
  22. double l = sqrt( (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) );
  23. double theta_a = 2.0 * acos( (l * l + a.r * a.r - b.r * b.r) / (2.0 * l * a.r) );
  24. double theta_b = 2.0 * acos( (l * l + b.r * b.r - a.r * a.r) / (2.0 * l * b.r) );
  25. double area_a = 0.5 * a.r * a.r * (theta_a - sin(theta_a));
  26. double area_b = 0.5 * b.r * b.r * (theta_b - sin(theta_b));
  27. return (area_a + area_b);
  28. }
  29.  
  30. double fuga(cir_t a, cir_t b){
  31. double l = sqrt( (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) );
  32. double theta_a = 2.0 * acos( (l * l + a.r * a.r - b.r * b.r) / (2.0 * l * a.r) );
  33. double theta_b = 2.0 * acos( (l * l + b.r * b.r - a.r * a.r) / (2.0 * l * b.r) );
  34. double area_a = 0.5 * a.r * a.r * (theta_a - sin(theta_a));
  35. double area_b = 0.5 * b.r * b.r * (theta_b - sin(theta_b));
  36. double area_c = b.r * b.r * sin(2.0 * M_PI - theta_b);
  37. return (area_a + area_b + area_c);
  38. }
  39.  
  40. double piyo(cir_t a){
  41. return (a.r * a.r * M_PI);
  42. }
  43.  
  44. double hogehoge(cir_t a, cir_t b){
  45. if(a.r < b.r){
  46. cir_t tmp = a;
  47. a = b;
  48. b = tmp;
  49. }
  50. double l = sqrt( (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) );
  51. if(a.r + b.r <= l){
  52. return (0.0);
  53. }
  54. else if(a.r < l){
  55. return (hoge(a,b));
  56. }
  57. else if(a.r < l + b.r){
  58. return (fuga(a,b));
  59. }
  60. else{
  61. return (piyo(b));
  62. }
  63. }
  64.  
  65. void calc(cir_t a, cir_t b){
  66. printf("座標x1 = %f\n"
  67. "座標y1 = %f\n"
  68. "半径r1 = %f\n",
  69. a.x,a.y,a.r);
  70. printf("座標x2 = %f\n"
  71. "座標y2 = %f\n"
  72. "半径r2 = %f\n",
  73. b.x,b.y,b.r);
  74. printf("重複面積 = %f\n\n",hogehoge(a,b));
  75. }
  76.  
  77. int main(void){
  78. cir_t no_0 = {-1200.0, 600.0, 400};
  79. cir_t no_1 = {-500.0, 600.0, 200};
  80. cir_t no_2 = {-1200.0, -600.0, 400};
  81. cir_t no_3 = {-700.0, -600.0, 200};
  82. cir_t no_4 = { 400.0, 600.0, 400};
  83. cir_t no_5 = { 700.0, 600.0, 200};
  84. cir_t no_6 = { 400.0, -600.0, 400};
  85. cir_t no_7 = { 500.0, -600.0, 200};
  86.  
  87. puts("No.0とNo.1"); calc(no_0, no_1);
  88. puts("No.2とNo.3"); calc(no_2, no_3);
  89. puts("No.4とNo.5"); calc(no_4, no_5);
  90. puts("No.6とNo.7"); calc(no_6, no_7);
  91.  
  92. return (0);
  93. }
  94.  
Success #stdin #stdout 0s 9432KB
stdin
Standard input is empty
stdout
No.0とNo.1
座標x1 = -1200.000000
座標y1 = 600.000000
半径r1 = 400.000000
座標x2 = -500.000000
座標y2 = 600.000000
半径r2 = 200.000000
重複面積 = 0.000000

No.2とNo.3
座標x1 = -1200.000000
座標y1 = -600.000000
半径r1 = 400.000000
座標x2 = -700.000000
座標y2 = -600.000000
半径r2 = 200.000000
重複面積 = 20896.772083

No.4とNo.5
座標x1 = 400.000000
座標y1 = 600.000000
半径r1 = 400.000000
座標x2 = 700.000000
座標y2 = 600.000000
半径r2 = 200.000000
重複面積 = 115066.911461

No.6とNo.7
座標x1 = 400.000000
座標y1 = -600.000000
半径r1 = 400.000000
座標x2 = 500.000000
座標y2 = -600.000000
半径r2 = 200.000000
重複面積 = 125663.706144