-
Notifications
You must be signed in to change notification settings - Fork 0
/
lines_intesect.js
78 lines (65 loc) · 2.19 KB
/
lines_intesect.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
function intersectLines(x1,y1,x2,y2,x3,y3,x4,y4) {
let resultado = [];
(() => {
'use strict';
// INTERSECTION OF TWO LINES ----------------------------------------------
// intersection :: Line -> Line -> Either String (Float, Float)
const intersection = (ab, pq) => {
const
delta = f => x => f(fst(x)) - f(snd(x)),
[abDX, pqDX, abDY, pqDY] = apList(
[delta(fst), delta(snd)], [ab, pq]
),
determinant = abDX * pqDY - abDY * pqDX;
return determinant !== 0 ? Right((() => {
const [abD, pqD] = map(
([a, b]) => fst(a) * snd(b) - fst(b) * snd(a),
[ab, pq]
);
return apList(
[([pq, ab]) =>
(abD * pq - ab * pqD) / determinant
], [
[pqDX, abDX],
[pqDY, abDY]
]
);
})()) : Left('(Parallel lines – no intersection)');
};
// GENERIC FUNCTIONS ------------------------------------------------------
// Left :: a -> Either a b
const Left = x => ({
type: 'Either',
Left: x
});
// Right :: b -> Either a b
const Right = x => ({
type: 'Either',
Right: x
});
// A list of functions applied to a list of arguments
// <*> :: [(a -> b)] -> [a] -> [b]
const apList = (fs, xs) => //
[].concat.apply([], fs.map(f => //
[].concat.apply([], xs.map(x => [f(x)]))));
// fst :: (a, b) -> a
const fst = tpl => tpl[0];
// map :: (a -> b) -> [a] -> [b]
const map = (f, xs) => xs.map(f);
// snd :: (a, b) -> b
const snd = tpl => tpl[1];
// show :: a -> String
const show = x => JSON.stringify(x); //, null, 2);
// TEST --------------------------------------------------
// lrIntersection ::Either String Point
const lrIntersection = intersection([
[x1, y1],
[x2, y2]
], [
[x3, y3],
[x4, y4]
]);
resultado = show(lrIntersection.Left || lrIntersection.Right);
})();
return resultado
}