/*
ttps://ideone.com/trIqHxの修正版
2019/03/03 関数hogehogeの条件分岐を修正。
2019/03/04 関数fugaの計算方法が間違っていたので修正。
プログラミングのお題スレ Part13
ttps://mevius.5ch.net/test/read.cgi/tech/1549160513/
473デフォルトの名無しさん2019/03/03(日) 08:56:00.68ID:NMVimqZR
お題:2つの円が重なった時、重なった部分の面積を求めなさい。
このプログラムでは以下のURLの画像の場合を計算します。
ttps://imgur.com/i2G9Ahd
注: マジで実装する場合は1つ1つのコードが本当に正しいか確認してください。
*/
#include <stdio.h>
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif /* M_PI */
/* 円の構造体定義 */
typedef struct{
double x; //座標x
double y; //座標y
double r; //半径r
}cir_t;
double hoge(cir_t a, cir_t b){
double l
= sqrt( (a.
x - b.
x) * (a.
x - b.
x) + (a.
y - b.
y) * (a.
y - b.
y) ); double theta_a
= 2.0 * acos( (l
* l
+ a.
r * a.
r - b.
r * b.
r) / (2.0 * l
* a.
r) ); double theta_b
= 2.0 * acos( (l
* l
+ b.
r * b.
r - a.
r * a.
r) / (2.0 * l
* b.
r) ); double area_a
= 0.5 * a.
r * a.
r * (theta_a
- sin(theta_a
)); double area_b
= 0.5 * b.
r * b.
r * (theta_b
- sin(theta_b
)); return (area_a + area_b);
}
double fuga(cir_t a, cir_t b){
double l
= sqrt( (a.
x - b.
x) * (a.
x - b.
x) + (a.
y - b.
y) * (a.
y - b.
y) ); double theta_a
= 2.0 * acos( (l
* l
+ a.
r * a.
r - b.
r * b.
r) / (2.0 * l
* a.
r) ); double theta_b
= 2.0 * acos( (l
* l
+ b.
r * b.
r - a.
r * a.
r) / (2.0 * l
* b.
r) ); double area_a
= 0.5 * a.
r * a.
r * (theta_a
- sin(theta_a
)); double area_b = 0.5 * b.r * b.r * theta_b;
double area_c
= 0.5 * b.
r * b.
r * sin(2.0 * M_PI
- theta_b
); return (area_a + area_b + area_c);
}
double piyo(cir_t a){
return (a.r * a.r * M_PI);
}
double hogehoge(cir_t a, cir_t b){
if(a.r < 0.0 || b.r < 0.0){
return (NAN);
}
if(a.r < b.r){
cir_t tmp = a;
a = b;
b = tmp;
}
double l
= sqrt( (a.
x - b.
x) * (a.
x - b.
x) + (a.
y - b.
y) * (a.
y - b.
y) );
if(a.r + b.r <= l){
return (0.0);
}
else if(b.r + l < a.r){
return (piyo(b));
}
else{
double l_a = (l * l + a.r * a.r - b.r * b.r) / (2.0 * l * a.r) * a.r;
if(l_a < l){
return(hoge(a,b));
}
else{
return(fuga(a,b));
}
}
}
void calc(cir_t a, cir_t b){
"座標y1 = %f\n"
"半径r1 = %f\n",
a.x,a.y,a.r);
"座標y2 = %f\n"
"半径r2 = %f\n",
b.x,b.y,b.r);
double val = hogehoge(a,b);
if(isnan(val)){
}
else{
printf("重複面積 = %f\n\n",hogehoge
(a
,b
)); }
}
int main(void){
cir_t no_0 = { -1200.0, 600.0, 400.0 };
cir_t no_1 = { -500.0, 600.0, 200.0 };
cir_t no_2 = { -1200.0, -600.0, 400.0 };
cir_t no_3 = { -700.0, -600.0, 200.0 };
cir_t no_4 = { 400.0, 600.0, 400.0 };
cir_t no_5 = { 700.0, 600.0, 200.0 };
cir_t no_6 = { 400.0, -600.0, 400.0 };
cir_t no_7 = { 500.0, -600.0, 200.0 };
puts("No.0とNo.1"); calc
(no_0
, no_1
); puts("No.2とNo.3"); calc
(no_2
, no_3
); puts("No.4とNo.5"); calc
(no_4
, no_5
); puts("No.6とNo.7"); calc
(no_6
, no_7
);
return (0);
}
LyoKICB0dHBzOi8vaWRlb25lLmNvbS90cklxSHjjga7kv67mraPniYgKICAyMDE5LzAzLzAzIOmWouaVsGhvZ2Vob2dl44Gu5p2h5Lu25YiG5bKQ44KS5L+u5q2j44CCCiAgMjAxOS8wMy8wNCDplqLmlbBmdWdh44Gu6KiI566X5pa55rOV44GM6ZaT6YGV44Gj44Gm44GE44Gf44Gu44Gn5L+u5q2j44CCCiAgCiAg44OX44Ot44Kw44Op44Of44Oz44Kw44Gu44GK6aGM44K544OsIFBhcnQxMwogIHR0cHM6Ly9tZXZpdXMuNWNoLm5ldC90ZXN0L3JlYWQuY2dpL3RlY2gvMTU0OTE2MDUxMy8KCiAgNDcz44OH44OV44Kp44Or44OI44Gu5ZCN54Sh44GX44GV44KTMjAxOS8wMy8wMyjml6UpIDA4OjU2OjAwLjY4SUQ6Tk1WaW1xWlIKICDjgYrpoYzvvJoy44Gk44Gu5YaG44GM6YeN44Gq44Gj44Gf5pmC44CB6YeN44Gq44Gj44Gf6YOo5YiG44Gu6Z2i56mN44KS5rGC44KB44Gq44GV44GE44CCCiAg44GT44Gu44OX44Ot44Kw44Op44Og44Gn44Gv5Lul5LiL44GuVVJM44Gu55S75YOP44Gu5aC05ZCI44KS6KiI566X44GX44G+44GZ44CCCiAgdHRwczovL2ltZ3VyLmNvbS9pMkc5QWhkCiAgCiAgCiAg5rOoOiDjg57jgrjjgaflrp/oo4XjgZnjgovloLTlkIjjga8x44GkMeOBpOOBruOCs+ODvOODieOBjOacrOW9k+OBq+ato+OBl+OBhOOBi+eiuuiqjeOBl+OBpuOBj+OBoOOBleOBhOOAggoqLwojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPG1hdGguaD4KCiNpZm5kZWYgTV9QSQojZGVmaW5lIE1fUEkgMy4xNDE1OTI2NTM1ODk3OTMyMzg0NgojZW5kaWYgLyogTV9QSSAqLwoKLyog5YaG44Gu5qeL6YCg5L2T5a6a576pICovCnR5cGVkZWYgc3RydWN0ewogIGRvdWJsZSB4OyAvL+W6p+aomXgKICBkb3VibGUgeTsgLy/luqfmqJl5CiAgZG91YmxlIHI7IC8v5Y2K5b6Ecgp9Y2lyX3Q7Cgpkb3VibGUgaG9nZShjaXJfdCBhLCBjaXJfdCBiKXsKICBkb3VibGUgbCA9IHNxcnQoIChhLnggLSBiLngpICogKGEueCAtIGIueCkgKyAoYS55IC0gYi55KSAqIChhLnkgLSBiLnkpICk7CiAgZG91YmxlIHRoZXRhX2EgPSAyLjAgKiBhY29zKCAobCAqIGwgKyBhLnIgKiBhLnIgLSBiLnIgKiBiLnIpIC8gKDIuMCAqIGwgKiBhLnIpICk7CiAgZG91YmxlIHRoZXRhX2IgPSAyLjAgKiBhY29zKCAobCAqIGwgKyBiLnIgKiBiLnIgLSBhLnIgKiBhLnIpIC8gKDIuMCAqIGwgKiBiLnIpICk7CiAgZG91YmxlIGFyZWFfYSA9IDAuNSAqIGEuciAqIGEuciAqICh0aGV0YV9hIC0gc2luKHRoZXRhX2EpKTsKICBkb3VibGUgYXJlYV9iID0gMC41ICogYi5yICogYi5yICogKHRoZXRhX2IgLSBzaW4odGhldGFfYikpOwogIHJldHVybiAoYXJlYV9hICsgYXJlYV9iKTsKfQoKZG91YmxlIGZ1Z2EoY2lyX3QgYSwgY2lyX3QgYil7CiAgZG91YmxlIGwgPSBzcXJ0KCAoYS54IC0gYi54KSAqIChhLnggLSBiLngpICsgKGEueSAtIGIueSkgKiAoYS55IC0gYi55KSApOwogIGRvdWJsZSB0aGV0YV9hID0gMi4wICogYWNvcyggKGwgKiBsICsgYS5yICogYS5yIC0gYi5yICogYi5yKSAvICgyLjAgKiBsICogYS5yKSApOwogIGRvdWJsZSB0aGV0YV9iID0gMi4wICogYWNvcyggKGwgKiBsICsgYi5yICogYi5yIC0gYS5yICogYS5yKSAvICgyLjAgKiBsICogYi5yKSApOwogIGRvdWJsZSBhcmVhX2EgPSAwLjUgKiBhLnIgKiBhLnIgKiAodGhldGFfYSAtIHNpbih0aGV0YV9hKSk7CiAgZG91YmxlIGFyZWFfYiA9IDAuNSAqIGIuciAqIGIuciAqIHRoZXRhX2I7CiAgZG91YmxlIGFyZWFfYyA9IDAuNSAqIGIuciAqIGIuciAqIHNpbigyLjAgKiBNX1BJIC0gdGhldGFfYik7CiAgcmV0dXJuIChhcmVhX2EgKyBhcmVhX2IgKyBhcmVhX2MpOwp9Cgpkb3VibGUgcGl5byhjaXJfdCBhKXsKICByZXR1cm4gKGEuciAqIGEuciAqIE1fUEkpOwp9Cgpkb3VibGUgaG9nZWhvZ2UoY2lyX3QgYSwgY2lyX3QgYil7CiAgaWYoYS5yIDwgMC4wIHx8IGIuciA8IDAuMCl7CglyZXR1cm4gKE5BTik7CQogIH0KCiAgaWYoYS5yIDwgYi5yKXsKICAgIGNpcl90IHRtcCA9IGE7CiAgICBhID0gYjsKICAgIGIgPSB0bXA7CiAgfQogIGRvdWJsZSBsID0gc3FydCggKGEueCAtIGIueCkgKiAoYS54IC0gYi54KSArIChhLnkgLSBiLnkpICogKGEueSAtIGIueSkgKTsKCiAgaWYoYS5yICsgYi5yIDw9IGwpewogICAgcmV0dXJuICgwLjApOwogIH0KICBlbHNlIGlmKGIuciArIGwgPCBhLnIpewogICAgcmV0dXJuIChwaXlvKGIpKTsKICB9CiAgZWxzZXsKICAgIGRvdWJsZSBsX2EgPSAobCAqIGwgKyBhLnIgKiBhLnIgLSBiLnIgKiBiLnIpIC8gKDIuMCAqIGwgKiBhLnIpICogYS5yOwogICAgaWYobF9hIDwgbCl7CiAgICAgIHJldHVybihob2dlKGEsYikpOwogICAgfQogICAgZWxzZXsKICAgICAgcmV0dXJuKGZ1Z2EoYSxiKSk7CiAgICB9CiAgfQp9Cgp2b2lkIGNhbGMoY2lyX3QgYSwgY2lyX3QgYil7CiAgcHJpbnRmKCLluqfmqJl4MSA9ICVmXG4iCgkgIuW6p+aomXkxID0gJWZcbiIKCSAi5Y2K5b6EcjEgPSAlZlxuIiwKCSBhLngsYS55LGEucik7CiAgcHJpbnRmKCLluqfmqJl4MiA9ICVmXG4iCgkgIuW6p+aomXkyID0gJWZcbiIKCSAi5Y2K5b6EcjIgPSAlZlxuIiwKCSBiLngsYi55LGIucik7CgkgCiAgZG91YmxlIHZhbCA9IGhvZ2Vob2dlKGEsYik7CiAgaWYoaXNuYW4odmFsKSl7CiAgCXB1dHMoIk4vQSIpOwogIH0KICBlbHNlewogICAgcHJpbnRmKCLph43opIfpnaLnqY0gPSAlZlxuXG4iLGhvZ2Vob2dlKGEsYikpOwogIH0KfQoKaW50IG1haW4odm9pZCl7CiAgY2lyX3Qgbm9fMCA9IHsgLTEyMDAuMCwgIDYwMC4wLCA0MDAuMCB9OwogIGNpcl90IG5vXzEgPSB7IC01MDAuMCwgICA2MDAuMCwgMjAwLjAgfTsKICBjaXJfdCBub18yID0geyAtMTIwMC4wLCAtNjAwLjAsIDQwMC4wIH07CiAgY2lyX3Qgbm9fMyA9IHsgLTcwMC4wLCAgLTYwMC4wLCAyMDAuMCB9OwogIGNpcl90IG5vXzQgPSB7ICA0MDAuMCwgICA2MDAuMCwgNDAwLjAgfTsKICBjaXJfdCBub181ID0geyAgNzAwLjAsICAgNjAwLjAsIDIwMC4wIH07CiAgY2lyX3Qgbm9fNiA9IHsgIDQwMC4wLCAgLTYwMC4wLCA0MDAuMCB9OwogIGNpcl90IG5vXzcgPSB7ICA1MDAuMCwgIC02MDAuMCwgMjAwLjAgfTsKCiAgcHV0cygiTm8uMOOBqE5vLjEiKTsgY2FsYyhub18wLCBub18xKTsKICBwdXRzKCJOby4y44GoTm8uMyIpOyBjYWxjKG5vXzIsIG5vXzMpOwogIHB1dHMoIk5vLjTjgahOby41Iik7IGNhbGMobm9fNCwgbm9fNSk7CiAgcHV0cygiTm8uNuOBqE5vLjciKTsgY2FsYyhub182LCBub183KTsKCiAgcmV0dXJuICgwKTsKfQogICAgICAK