import Data.Ratio
main
= mapM_ printIntersection ls
where
ls =
[
((Point 0 8 , Point 4 0) , (Point 2 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 not (onSegment l
&& onSegment m
) || any isNaN [x
, y
] 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 l@(Line a b p) m@(Line c d q)
where
x = invd * p + invb * q
y
| a == 0 = c * x + q
| c == 0 = a * x + p
[inva
, invb
, invc
, invd
] = map (/ det l m
) [a
, -b
, -c
, d
] nan = 0 / 0
parallel
:: Line
-> Line
-> Boolparallel l m = det l m == (0 % 1)
det (Line a b _) (Line c d _) = a * d - b * c
aW1wb3J0IERhdGEuUmF0aW8KCm1haW4gOjogSU8gKCkKbWFpbiA9IG1hcE1fIHByaW50SW50ZXJzZWN0aW9uIGxzCiAgd2hlcmUKICAgIGxzID0KICAgICAgWwogICAgICAgICgoUG9pbnQgMCA4ICAgICAgLCBQb2ludCA0IDApICwgKFBvaW50IDIgNCAgICAgICwgUG9pbnQgOCAxMikpCiAgICAgICwgKChQb2ludCAwIDAgICAgICAsIFBvaW50IDQgNikgLCAoUG9pbnQgMCAwICAgICAgLCBQb2ludCA3IDE1KSkKICAgICAgLCAoKFBvaW50IDAgMCAgICAgICwgUG9pbnQgMSAyKSAsIChQb2ludCAxIDEgICAgICAsIFBvaW50IDIgMykpCiAgICAgICwgKChQb2ludCAoLTkpICgtOSksIFBvaW50IDkgOSkgLCAoUG9pbnQgNSAwICAgICAgLCBQb2ludCA1IDcpKQogICAgICAsICgoUG9pbnQgMyA0ICAgICAgLCBQb2ludCA2IDcpICwgKFBvaW50IDMgOCAgICAgICwgUG9pbnQgOSAoLTEpKSkKICAgICAgLCAoKFBvaW50ICgtMSkgMCAgICwgUG9pbnQgNCAxOCksIChQb2ludCAoLTIpICgtNSksIFBvaW50IDEgMykpCiAgICAgICwgKChQb2ludCAxIDIgICAgICAsIFBvaW50IDQgMTgpLCAoUG9pbnQgMSAyICAgICAgLCBQb2ludCA0IDE4KSkKICAgICAgXQoKcHJpbnRJbnRlcnNlY3Rpb24gOjogKFNlZ21lbnQsIFNlZ21lbnQpIC0+IElPICgpCnByaW50SW50ZXJzZWN0aW9uIChsLCBtKSA9IHB1dFN0ckxuIHMKICB3aGVyZQogICAgcyA9CiAgICAgIGlmIG5vdCAob25TZWdtZW50IGwgJiYgb25TZWdtZW50IG0pIHx8IGFueSBpc05hTiBbeCwgeV0gdGhlbgogICAgICAgICLkuqTngrnjgarjgZciCiAgICAgIGVsc2UKICAgICAgICBzaG93ICh4LCB5KQogICAgUG9pbnQgeCB5ID0gaW50ZXJzZWN0aW9uICh1bmN1cnJ5IGxpbmUgbCkgKHVuY3VycnkgbGluZSBtKQoKICAgIG9uU2VnbWVudCA6OiBTZWdtZW50IC0+IEJvb2wKICAgIG9uU2VnbWVudCAoKFBvaW50IHgxIHkxKSwgKFBvaW50IHgyIHkyKSkgPSBjaGVja1ggJiYgY2hlY2tZCiAgICAgIHdoZXJlCiAgICAgICAgY2hlY2tYICA9IGYgeDEgeCB4MgogICAgICAgIGNoZWNrWSAgPSBmIHkxIHkgeTIKICAgICAgICBmIGEgYiBjID0gZyAoaWYgYSA8PSBjIHRoZW4gKDw9KSBlbHNlICg+PSkpIFthLCBiLCBjXQogICAgICAgIGcgb3AgICAgPSBhbmQgLiAoZmxpcCAoemlwV2l0aCBvcCkgPTw8IHRhaWwpCgp0eXBlIFNlZ21lbnQgPSAoUG9pbnQsIFBvaW50KQpkYXRhIFBvaW50ICAgPSBQb2ludCBEb3VibGUgRG91YmxlCmRhdGEgTGluZSAgICA9IExpbmUgUmF0aW9uYWwgUmF0aW9uYWwgUmF0aW9uYWwKCmxpbmUgOjogUG9pbnQgLT4gUG9pbnQgLT4gTGluZQpsaW5lIChQb2ludCB4MSB5MSkgKFBvaW50IHgyIHkyKQogIHwgZHggLz0gMCAgID0gTGluZSAodG9SYXRpb25hbCBzbG9wZSkgKC0xKSAodG9SYXRpb25hbCAkIHNsb3BlICogeDEgLSB5MSkKICB8IG90aGVyd2lzZSA9IExpbmUgMSAwICh0b1JhdGlvbmFsIHgxKQogIHdoZXJlCiAgICBzbG9wZSA9IGR5IC8gZHgKICAgIGR4ICAgID0geDIgLSB4MQogICAgZHkgICAgPSB5MiAtIHkxCgppbnRlcnNlY3Rpb24gOjogTGluZSAtPiBMaW5lIC0+IFBvaW50CmludGVyc2VjdGlvbiBsQChMaW5lIGEgYiBwKSBtQChMaW5lIGMgZCBxKQogIHwgbm90ICQgcGFyYWxsZWwgbCBtID0gUG9pbnQgKGZyb21SYXRpb25hbCB4KSAoZnJvbVJhdGlvbmFsIHkpCiAgfCBvdGhlcndpc2UgICAgICAgICAgPSBQb2ludCBuYW4gbmFuCiAgd2hlcmUKICAgIHggPSBpbnZkICogcCArIGludmIgKiBxCiAgICB5CiAgICAgIHwgYSA9PSAwICAgID0gYyAqIHggKyBxCiAgICAgIHwgYyA9PSAwICAgID0gYSAqIHggKyBwCiAgICAgIHwgb3RoZXJ3aXNlID0gaW52YyAqIHAgKyBpbnZhICogcQogICAgW2ludmEsIGludmIsIGludmMsIGludmRdID0gbWFwICgvIGRldCBsIG0pIFthLCAtYiwgLWMsIGRdCiAgICBuYW4gOjogRG91YmxlCiAgICBuYW4gPSAwIC8gMAoKcGFyYWxsZWwgOjogTGluZSAtPiBMaW5lIC0+IEJvb2wKcGFyYWxsZWwgbCBtID0gZGV0IGwgbSA9PSAoMCAlIDEpCgpkZXQgOjogTGluZSAtPiBMaW5lIC0+IFJhdGlvbmFsCmRldCAoTGluZSBhIGIgXykgKExpbmUgYyBkIF8pID0gYSAqIGQgLSBiICogYwo=