#include <stdio.h>
struct point2d { /* 2次元空間の点のx座標とy座標をそれぞれdoubleに格納 */
double x, y;
};
struct linesegment { /* 線分の始点sと終点eをそれぞれstruct point2dに格納 */
struct point2d s, e;
};
/* 交点判定 (1:交わる、0:交わらない) */
int if_intersect(struct linesegment line1, struct linesegment line2)
{
double m[2]; /* 傾き */
int f_mv[2]; /* y軸と平行かのフラグ */
struct point2d kt; /* 交点 */
/* 傾き */
f_mv[0] = (line1.e.x == line1.s.x) ? 1 : 0;
if (f_mv[0] == 0) {
m[0] = (line1.e.y - line1.s.y) / (line1.e.x - line1.s.x);
}
f_mv[1] = (line2.e.x == line2.s.x) ? 1 : 0;
if (f_mv[1] == 0) {
m[1] = (line2.e.y - line2.s.y) / (line2.e.x - line2.s.x);
}
/* 平行か? */
if (f_mv[0] == 1 && f_mv[1] == 1) {
return 0;
}
if (f_mv[0] == 0 && f_mv[1] == 0) {
if (m[0] == m[1]) {
return 0;
}
}
/* 交点計算 */
if (f_mv[0] == 0 && f_mv[1] == 0) {
kt.x = (m[0] * line1.s.x - line1.s.y - m[2] * line2.s.x + line2.s.y) / (m[0] - m[1]);
kt.y = m[0] * kt.x - m[0] * line1.s.x + line1.s.y;
} else if (f_mv[0]) {
kt.x = line1.s.x;
kt.y = m[1] * line1.s.x - m[1] * line2.s.x + line2.s.y;
} else if (f_mv[1]) {
kt.x = line2.s.x;
kt.y = m[0] * line2.s.x - m[0] * line1.s.x + line1.s.y;
}
/* 交点が線分の範囲内か判定 */
if (f_mv[0]) {
if (line1.s.y < line1.e.y) {
if (line1.s.y <= kt.y && kt.y <= line1.e.y) {
return 1;
}
} else {
if (line1.e.y <= kt.y && kt.y <= line1.s.y) {
return 1;
}
}
}
if (f_mv[1]) {
if (line2.s.y < line2.e.y) {
if (line2.s.y <= kt.y && kt.y <= line2.e.y) {
return 1;
}
} else {
if (line2.e.y <= kt.y && kt.y <= line2.s.y) {
return 1;
}
}
}
return 0;
}
/* main */
int main()
{
struct linesegment line1 = {
{0.0, 0.0},
{2.0, 1.0}
};
struct linesegment line2 = {
{1.0, 2.0},
{1.0, 0.6}
};
"線分 [%f, %f]-[%f, %f]\n"
"と [%f, %f]-[%f, %f]\n"
"は、交わ%s\n"
, line1.s, line1.e, line2.s, line2.e
, if_intersect(line1, line2) ? "る" : "らない"
);
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CgpzdHJ1Y3QgcG9pbnQyZCB7ICAgICAgICAgICAgICAgIC8qIDLmrKHlhYPnqbrplpPjga7ngrnjga545bqn5qiZ44GoeeW6p+aomeOCkuOBneOCjOOBnuOCjGRvdWJsZeOBq+agvOe0jSAqLwogICAgZG91YmxlIHgsIHk7Cn07CgpzdHJ1Y3QgbGluZXNlZ21lbnQgeyAgICAgICAgICAgIC8qIOe3muWIhuOBruWni+eCuXPjgajntYLngrll44KS44Gd44KM44Ge44KMc3RydWN0IHBvaW50MmTjgavmoLzntI0gKi8KICAgIHN0cnVjdCBwb2ludDJkIHMsIGU7Cn07CgovKiDkuqTngrnliKTlrpogKDE65Lqk44KP44KL44CBMDrkuqTjgo/jgonjgarjgYQpICovCmludCBpZl9pbnRlcnNlY3Qoc3RydWN0IGxpbmVzZWdtZW50IGxpbmUxLCBzdHJ1Y3QgbGluZXNlZ21lbnQgbGluZTIpCnsKICAgIGRvdWJsZSBtWzJdOyAgICAgICAgICAgICAgICAvKiDlgr7jgY0gICAgICAgICAgICAgICAgICovCiAgICBpbnQgZl9tdlsyXTsgICAgICAgICAgICAgICAgLyogeei7uOOBqOW5s+ihjOOBi+OBruODleODqeOCsCAgKi8KICAgIHN0cnVjdCBwb2ludDJkIGt0OyAgICAgICAgICAvKiDkuqTngrkgICAgICAgICAgICAgICAgICovCgogICAgLyog5YK+44GNICovCiAgICBmX212WzBdID0gKGxpbmUxLmUueCA9PSBsaW5lMS5zLngpID8gMSA6IDA7CiAgICBpZiAoZl9tdlswXSA9PSAwKSB7CiAgICAgICAgbVswXSA9IChsaW5lMS5lLnkgLSBsaW5lMS5zLnkpIC8gKGxpbmUxLmUueCAtIGxpbmUxLnMueCk7CiAgICB9CiAgICBmX212WzFdID0gKGxpbmUyLmUueCA9PSBsaW5lMi5zLngpID8gMSA6IDA7CiAgICBpZiAoZl9tdlsxXSA9PSAwKSB7CiAgICAgICAgbVsxXSA9IChsaW5lMi5lLnkgLSBsaW5lMi5zLnkpIC8gKGxpbmUyLmUueCAtIGxpbmUyLnMueCk7CiAgICB9CiAgICAvKiDlubPooYzjgYvvvJ8gKi8KICAgIGlmIChmX212WzBdID09IDEgJiYgZl9tdlsxXSA9PSAxKSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBpZiAoZl9tdlswXSA9PSAwICYmIGZfbXZbMV0gPT0gMCkgewogICAgICAgIGlmIChtWzBdID09IG1bMV0pIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQogICAgLyog5Lqk54K56KiI566XICovCiAgICBpZiAoZl9tdlswXSA9PSAwICYmIGZfbXZbMV0gPT0gMCkgewogICAgICAgIGt0LnggPSAobVswXSAqIGxpbmUxLnMueCAtIGxpbmUxLnMueSAtIG1bMl0gKiBsaW5lMi5zLnggKyBsaW5lMi5zLnkpIC8gKG1bMF0gLSBtWzFdKTsKICAgICAgICBrdC55ID0gbVswXSAqIGt0LnggLSBtWzBdICogbGluZTEucy54ICsgbGluZTEucy55OwogICAgfSBlbHNlIGlmIChmX212WzBdKSB7CiAgICAgICAga3QueCA9IGxpbmUxLnMueDsKICAgICAgICBrdC55ID0gbVsxXSAqIGxpbmUxLnMueCAtIG1bMV0gKiBsaW5lMi5zLnggKyBsaW5lMi5zLnk7CiAgICB9IGVsc2UgaWYgKGZfbXZbMV0pIHsKICAgICAgICBrdC54ID0gbGluZTIucy54OwogICAgICAgIGt0LnkgPSBtWzBdICogbGluZTIucy54IC0gbVswXSAqIGxpbmUxLnMueCArIGxpbmUxLnMueTsKICAgIH0KICAgIC8qIOS6pOeCueOBjOe3muWIhuOBruevhOWbsuWGheOBi+WIpOWumiAqLwogICAgaWYgKGZfbXZbMF0pIHsKICAgICAgICBpZiAobGluZTEucy55IDwgbGluZTEuZS55KSB7CiAgICAgICAgICAgIGlmIChsaW5lMS5zLnkgPD0ga3QueSAmJiBrdC55IDw9IGxpbmUxLmUueSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAobGluZTEuZS55IDw9IGt0LnkgJiYga3QueSA8PSBsaW5lMS5zLnkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgaWYgKGZfbXZbMV0pIHsKICAgICAgICBpZiAobGluZTIucy55IDwgbGluZTIuZS55KSB7CiAgICAgICAgICAgIGlmIChsaW5lMi5zLnkgPD0ga3QueSAmJiBrdC55IDw9IGxpbmUyLmUueSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAobGluZTIuZS55IDw9IGt0LnkgJiYga3QueSA8PSBsaW5lMi5zLnkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIDA7Cn0KCi8qICBtYWluICAgICAgICAqLwppbnQgbWFpbigpCnsKICAgIHN0cnVjdCBsaW5lc2VnbWVudCBsaW5lMSA9IHsKICAgICAgICB7MC4wLCAwLjB9LAogICAgICAgIHsyLjAsIDEuMH0KICAgIH07CiAgICBzdHJ1Y3QgbGluZXNlZ21lbnQgbGluZTIgPSB7CiAgICAgICAgezEuMCwgMi4wfSwKICAgICAgICB7MS4wLCAwLjZ9CiAgICB9OwoKICAgIHByaW50ZigKICAgICAgICAi57ea5YiGIFslZiwgJWZdLVslZiwgJWZdXG4iCiAgICAgICAgIuOBqCAgIFslZiwgJWZdLVslZiwgJWZdXG4iCiAgICAgICAgIuOBr+OAgeS6pOOCjyVzXG4iCiAgICAgICAgLCBsaW5lMS5zLCBsaW5lMS5lLCBsaW5lMi5zLCBsaW5lMi5lCiAgICAgICAgLCBpZl9pbnRlcnNlY3QobGluZTEsIGxpbmUyKSA/ICLjgosiIDogIuOCieOBquOBhCIKICAgICk7CiAgICByZXR1cm4gMDsKfQo=