Find the intersection of two lines: Difference between revisions
Content added Content deleted
m (→{{header|Python}}: Updated one primitive) |
|||
Line 1,356: | Line 1,356: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
Find the intersection |
Find the intersection without importing third-party libraries. |
||
<lang python>def line_intersect(Ax1, Ay1, Ax2, Ay2, Bx1, By1, Bx2, By2): |
<lang python>def line_intersect(Ax1, Ay1, Ax2, Ay2, Bx1, By1, Bx2, By2): |
||
""" returns a (x, y) tuple or None if there is no intersection """ |
""" returns a (x, y) tuple or None if there is no intersection """ |
||
Line 1,386: | Line 1,386: | ||
{{Works with|Python|3.7}} |
{{Works with|Python|3.7}} |
||
<lang python>'''The intersection of two lines.''' |
<lang python>'''The intersection of two lines.''' |
||
from |
from itertools import (product) |
||
# intersection :: Line -> Line -> Either String Point |
# intersection :: Line -> Line -> Either String Point |
||
def intersection(ab): |
def intersection(ab): |
||
Line 1,397: | Line 1,397: | ||
def delta(f): |
def delta(f): |
||
return lambda x: f(fst(x)) - f(snd(x)) |
return lambda x: f(fst(x)) - f(snd(x)) |
||
def prodDiff(abcd): |
def prodDiff(abcd): |
||
[a, b, c, d] = abcd |
[a, b, c, d] = abcd |
||
return (a * d) - (b * c) |
return (a * d) - (b * c) |
||
def go(pq): |
def go(pq): |
||
[abDX, pqDX, abDY, pqDY] = |
[abDX, pqDX, abDY, pqDY] = apList( |
||
[delta(fst), delta(snd)] |
[delta(fst), delta(snd)] |
||
)([ab, pq]) |
)([ab, pq]) |
||
determinant = prodDiff([abDX, abDY, pqDX, pqDY]) |
determinant = prodDiff([abDX, abDY, pqDX, pqDY]) |
||
def point(): |
def point(): |
||
[abD, pqD] = map( |
[abD, pqD] = map( |
||
lambda xy: prodDiff( |
lambda xy: prodDiff( |
||
apList([fst, snd])([fst(xy), snd(xy)]) |
|||
), [ab, pq] |
), [ab, pq] |
||
) |
) |
||
return |
return apList( |
||
[lambda abpq: prodDiff( |
[lambda abpq: prodDiff( |
||
[abD, fst(abpq), pqD, snd(abpq)]) / determinant] |
[abD, fst(abpq), pqD, snd(abpq)]) / determinant] |
||
Line 1,423: | Line 1,423: | ||
'( Parallel lines - no intersection )' |
'( Parallel lines - no intersection )' |
||
) |
) |
||
return lambda pq: bindLR(go(pq))( |
return lambda pq: bindLR(go(pq))( |
||
lambda xs: Right((fst(xs), snd(xs))) |
lambda xs: Right((fst(xs), snd(xs))) |
||
) |
) |
||
# |
# --------------------------TEST--------------------------- |
||
# main :: IO() |
# main :: IO() |
||
def main(): |
def main(): |
||
'''Test''' |
'''Test''' |
||
# Left(message - no intersection) or Right(point) |
# Left(message - no intersection) or Right(point) |
||
# lrPoint :: Either String Point |
# lrPoint :: Either String Point |
||
Line 1,444: | Line 1,444: | ||
lrPoint['Left'] or lrPoint['Right'] |
lrPoint['Left'] or lrPoint['Right'] |
||
) |
) |
||
# |
# --------------------GENERIC FUNCTIONS-------------------- |
||
# Left :: a -> Either a b |
# Left :: a -> Either a b |
||
def Left(x): |
def Left(x): |
||
Line 1,453: | Line 1,453: | ||
with an associated string.''' |
with an associated string.''' |
||
return {'type': 'Either', 'Right': None, 'Left': x} |
return {'type': 'Either', 'Right': None, 'Left': x} |
||
# Right :: b -> Either a b |
# Right :: b -> Either a b |
||
def Right(x): |
def Right(x): |
||
'''Constructor for a populated Either (option type) value''' |
'''Constructor for a populated Either (option type) value''' |
||
return {'type': 'Either', 'Left': None, 'Right': x} |
return {'type': 'Either', 'Left': None, 'Right': x} |
||
# |
# apList (<*>) :: [(a -> b)] -> [a] -> [b] |
||
def |
def apList(fs): |
||
'''The application of each of a list of functions, |
'''The application of each of a list of functions, |
||
to each of a list of values. |
to each of a list of values. |
||
⚫ | |||
⚫ | |||
def go(fx): |
|||
lambda a, f: a + reduce( |
|||
f, x = fx |
|||
) |
return f(x) |
||
⚫ | |||
⚫ | |||
go(x) for x |
|||
in product(fs, xs) |
|||
] |
|||
# bindLR (>>=) :: Either a -> (a -> Either b) -> Either b |
# bindLR (>>=) :: Either a -> (a -> Either b) -> Either b |
||
def bindLR(m): |
def bindLR(m): |
||
Line 1,481: | Line 1,484: | ||
mf(m.get('Right')) if None is m.get('Left') else m |
mf(m.get('Right')) if None is m.get('Left') else m |
||
) |
) |
||
# fst :: (a, b) -> a |
# fst :: (a, b) -> a |
||
def fst(tpl): |
def fst(tpl): |
||
'''First member of a pair.''' |
'''First member of a pair.''' |
||
return tpl[0] |
return tpl[0] |
||
# snd :: (a, b) -> b |
# snd :: (a, b) -> b |
||
def snd(tpl): |
def snd(tpl): |
||
'''Second member of a pair.''' |
'''Second member of a pair.''' |
||
return tpl[1] |
return tpl[1] |
||
# MAIN --- |
# MAIN --- |
||
if __name__ == '__main__': |
if __name__ == '__main__': |