import Data.Ratio
main
= mapM_ printIntersection ls
where
ls =
[
((Point 0 8 , Point 4 0) , (Point 1 4 , Point 8 12))
, ((Point 0 0 , Point 4 6) , (Point 0 0 , Point 7 15))
, ((Point 0 0 , Point 1 2) , (Point 1 1 , Point 2 3))
, ((Point (-9) (-9), Point 9 9) , (Point 5 0 , Point 5 7))
, ((Point 3 4 , Point 6 7) , (Point 3 8 , Point 9 (-1)))
, ((Point (-1) 0 , Point 4 18), (Point (-2) (-5), Point 1 3))
, ((Point 1 2 , Point 4 18), (Point 1 2 , Point 4 18))
]
printIntersection
:: (Segment
, Segment
) -> IO () where
s =
if any isNaN [x
, y
] || not (onSegment l
&& onSegment m
) then "交点なし"
else
onSegment
:: Segment
-> Bool onSegment (Point x1 y1, Point x2 y2) = checkX && checkY
where
checkX = f x1 x x2
checkY = f y1 y y2
f a b c = g (if a <= c then (<=) else (>=)) [a, b, c]
type Segment = (Point, Point)
line :: Point -> Point -> Line
line (Point x1 y1) (Point x2 y2)
where
slope = dy / dx
dx = x2 - x1
dy = y2 - y1
intersection :: Line -> Line -> Point
intersection (Line a b p) (Line c d q)
where
x = invd * p + invb * q
y = invc * p + inva * q
[inva
, invb
, invc
, invd
] = map (/ det
) [a
, -b
, -c
, d
] nan = 0 / 0
parallel = det == 0
det = a * d - b * c
aW1wb3J0IERhdGEuUmF0aW8KCm1haW4gOjogSU8gKCkKbWFpbiA9IG1hcE1fIHByaW50SW50ZXJzZWN0aW9uIGxzCiAgd2hlcmUKICAgIGxzID0KICAgICAgWwogICAgICAgICgoUG9pbnQgMCA4ICAgICAgLCBQb2ludCA0IDApICwgKFBvaW50IDEgNCAgICAgICwgUG9pbnQgOCAxMikpCiAgICAgICwgKChQb2ludCAwIDAgICAgICAsIFBvaW50IDQgNikgLCAoUG9pbnQgMCAwICAgICAgLCBQb2ludCA3IDE1KSkKICAgICAgLCAoKFBvaW50IDAgMCAgICAgICwgUG9pbnQgMSAyKSAsIChQb2ludCAxIDEgICAgICAsIFBvaW50IDIgMykpCiAgICAgICwgKChQb2ludCAoLTkpICgtOSksIFBvaW50IDkgOSkgLCAoUG9pbnQgNSAwICAgICAgLCBQb2ludCA1IDcpKQogICAgICAsICgoUG9pbnQgMyA0ICAgICAgLCBQb2ludCA2IDcpICwgKFBvaW50IDMgOCAgICAgICwgUG9pbnQgOSAoLTEpKSkKICAgICAgLCAoKFBvaW50ICgtMSkgMCAgICwgUG9pbnQgNCAxOCksIChQb2ludCAoLTIpICgtNSksIFBvaW50IDEgMykpCiAgICAgICwgKChQb2ludCAxIDIgICAgICAsIFBvaW50IDQgMTgpLCAoUG9pbnQgMSAyICAgICAgLCBQb2ludCA0IDE4KSkKICAgICAgXQoKcHJpbnRJbnRlcnNlY3Rpb24gOjogKFNlZ21lbnQsIFNlZ21lbnQpIC0+IElPICgpCnByaW50SW50ZXJzZWN0aW9uIChsLCBtKSA9IHB1dFN0ckxuIHMKICB3aGVyZQogICAgcyA9CiAgICAgIGlmIGFueSBpc05hTiBbeCwgeV0gfHwgbm90IChvblNlZ21lbnQgbCAmJiBvblNlZ21lbnQgbSkgdGhlbgogICAgICAgICLkuqTngrnjgarjgZciCiAgICAgIGVsc2UKICAgICAgICBzaG93ICh4LCB5KQogICAgUG9pbnQgeCB5ID0gaW50ZXJzZWN0aW9uICh1bmN1cnJ5IGxpbmUgbCkgKHVuY3VycnkgbGluZSBtKQoKICAgIG9uU2VnbWVudCA6OiBTZWdtZW50IC0+IEJvb2wKICAgIG9uU2VnbWVudCAoUG9pbnQgeDEgeTEsIFBvaW50IHgyIHkyKSA9IGNoZWNrWCAmJiBjaGVja1kKICAgICAgd2hlcmUKICAgICAgICBjaGVja1ggID0gZiB4MSB4IHgyCiAgICAgICAgY2hlY2tZICA9IGYgeTEgeSB5MgogICAgICAgIGYgYSBiIGMgPSBnIChpZiBhIDw9IGMgdGhlbiAoPD0pIGVsc2UgKD49KSkgW2EsIGIsIGNdCiAgICAgICAgZyBvcCAgICA9IGFuZCAuIChmbGlwICh6aXBXaXRoIG9wKSA9PDwgdGFpbCkKCnR5cGUgU2VnbWVudCA9IChQb2ludCwgUG9pbnQpCmRhdGEgUG9pbnQgICA9IFBvaW50IERvdWJsZSBEb3VibGUKZGF0YSBMaW5lICAgID0gTGluZSBSYXRpb25hbCBSYXRpb25hbCBSYXRpb25hbAoKbGluZSA6OiBQb2ludCAtPiBQb2ludCAtPiBMaW5lCmxpbmUgKFBvaW50IHgxIHkxKSAoUG9pbnQgeDIgeTIpCiAgfCBkeCAvPSAwICAgPSBMaW5lICh0b1JhdGlvbmFsIHNsb3BlKSAoLTEpICh0b1JhdGlvbmFsICQgc2xvcGUgKiB4MSAtIHkxKQogIHwgb3RoZXJ3aXNlID0gTGluZSAxIDAgKHRvUmF0aW9uYWwgeDEpCiAgd2hlcmUKICAgIHNsb3BlID0gZHkgLyBkeAogICAgZHggICAgPSB4MiAtIHgxCiAgICBkeSAgICA9IHkyIC0geTEKCmludGVyc2VjdGlvbiA6OiBMaW5lIC0+IExpbmUgLT4gUG9pbnQKaW50ZXJzZWN0aW9uIChMaW5lIGEgYiBwKSAoTGluZSBjIGQgcSkKICB8IG5vdCAkIHBhcmFsbGVsID0gUG9pbnQgKGZyb21SYXRpb25hbCB4KSAoZnJvbVJhdGlvbmFsIHkpCiAgfCBvdGhlcndpc2UgICAgICA9IFBvaW50IG5hbiBuYW4KICB3aGVyZQogICAgeCA9IGludmQgKiBwICsgaW52YiAqIHEKICAgIHkgPSBpbnZjICogcCArIGludmEgKiBxCiAgICBbaW52YSwgaW52YiwgaW52YywgaW52ZF0gPSBtYXAgKC8gZGV0KSBbYSwgLWIsIC1jLCBkXQogICAgbmFuIDo6IERvdWJsZQogICAgbmFuID0gMCAvIDAKICAgIHBhcmFsbGVsIDo6IEJvb2wKICAgIHBhcmFsbGVsID0gZGV0ID09IDAKICAgIGRldCA6OiBSYXRpb25hbAogICAgZGV0ID0gYSAqIGQgLSBiICogYwo=