Changes

Jump to: navigation, search

Intersection Squares

22,348 bytes added, 15:42, 10 May 2018
Created page with "'''Home * Chess * Squares * Intersection Squares''' FILE:Two_Intersecting_Planes.jpg|border|right|thumb|link=http://www.mcescher.com/Gallery/back-bmp/..."
'''[[Main Page|Home]] * [[Chess]] * [[Squares]] * Intersection Squares'''

[[FILE:Two_Intersecting_Planes.jpg|border|right|thumb|link=http://www.mcescher.com/Gallery/back-bmp/LW377.jpg|[[Arts#Escher|M. C. Escher]] - Two Intersecting Planes, 1952 <ref>[http://www.mcescher.com/Gallery/gallery-back.htm Picture gallery "Back in Holland 1941 - 1954"] from [http://www.mcescher.com/ The Official M.C. Escher Website]</ref> ]]

'''Intersection squares''' are the result of the [https://en.wikipedia.org/wiki/Line-line_intersection intersection of two lines] from two different squares with two disjoint directions, either [[Ranks|rank]], [[Files|file]], [[Diagonals|diagonal]] or [[Anti-Diagonals|anti-diagonal]], in total 2*(3+2+1) = 12 possible combinations. Those lines (may) have up to one square, where both lines intersect - a square where two appropriate sliding pieces were able to move to in one step (assuming no obstructions).

In the set-wise world of [[Bitboards|bitboards]] one usually relies on [[General Setwise Operations#Intersection|set-wise intersection]] of [[Sliding Piece Attacks|sliding piece attacks]], but square-centric [[Board Representation|board representations]] may either use two-dimensional lookup tables, or rely on some algebra based on discrete [https://en.wikipedia.org/wiki/Linear_equation linear equations] and pure register computation. Programs may use these routines as a precondition whether an intersection point exist, for instance to determine a square where a sliding piece may check the opponent king.

=Rank and File=
or vice versa File and Rank

Two squares a and b have always two orthogonal intersection squares s1 and s2.
<pre>
. | . . . | . .
--1-------b----
. | . . . | . .
. | . . . | . .
. | . . . | . .
. | . . . | . .
--a-------2----
. | . . . | . .
</pre>

<pre>
s1 := 8*rankIndex(b) + fileIndex(a);
s2 := 8*rankIndex(a) + fileIndex(b);
</pre>
or
<pre>
s1 := (b & 56) + (a & 7);
s2 := (a & 56) + (b & 7);
</pre>

=Empty Intersection with 0x88 Math=
If diagonals or anti-diagonals are involved, the intersection square may off the board. Beside that, the intersection of a diagonal with an anti-diagonal becomes empty, if both lines are of different [[Color of a Square|square color]]. Considering [[0x88]]-square coordinates for the calculation, covers off the board intersection, and the different color issues en passant. Following [[C]]-routines work branchless, and return -1 if no intersection is possible by oring with following {0,-1} integer expression relying on arithmetical shift right:
<pre>
-(s88 & 0x88) >> (sizeof(int)-1)
</pre>
Feel free to use branches instead in a broader scope, since one need to branch on valid intersecion square anyway.

=Rank and Diagonal=
or vice versa Diagonal and Rank

<pre>
. . . . . . / .
. . . . . b . .
. . . . / . . .
. . . / . . . .
. . / . . . . .
. / . . . . . .
s-----a--------
. . . . . . . .
</pre>
with
diagonalIndex := rankIndex - fileIndex;
{| class="wikitable"
|-
! r/f
! 0
! 1
! 2
! 3
! 4
! 5
! 6
! 7
|-
! 7
| style="text-align:right;" | 7
| style="text-align:right;" | 6
| style="text-align:right;" | 5
| style="text-align:right;" | 4
| style="text-align:right;" | 3
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
|-
! 6
| style="text-align:right;" | 6
| style="text-align:right;" | 5
| style="text-align:right;" | 4
| style="text-align:right;" | 3
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
|-
! 5
| style="text-align:right;" | 5
| style="text-align:right;" | 4
| style="text-align:right;" | 3
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
|-
! 4
| style="text-align:right;" | 4
| style="text-align:right;" | 3
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
| style="text-align:right;" | -3
|-
! 3
| style="text-align:right;" | 3
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
| style="text-align:right;" | -3
| style="text-align:right;" | -4
|-
! 2
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
| style="text-align:right;" | -3
| style="text-align:right;" | -4
| style="text-align:right;" | -5
|-
! 1
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
| style="text-align:right;" | -3
| style="text-align:right;" | -4
| style="text-align:right;" | -5
| style="text-align:right;" | -6
|-
! 0
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
| style="text-align:right;" | -3
| style="text-align:right;" | -4
| style="text-align:right;" | -5
| style="text-align:right;" | -6
| style="text-align:right;" | -7
|}
==0x88 Math==
<pre>
rankIndex(s) := rankIndex(a);
fileIndex(s) := rankIndex(s) - diagonalIndex(s);
fileIndex(s) := rankIndex(a) - rankIndex(b) + fileIndex(b);
</pre>
Because the intersection of any rank with any diagonal may off the board, we rely on 0x88 math for a quick test:
<pre>
s88 := 16*rankIndex(s) + fileIndex(s);
s88 := 16*rankIndex(a) + (rankIndex(a) - rankIndex(b) + fileIndex(b));
s88 := 17*rankIndex(a) - rankIndex(b) + fileIndex(b);
if ( s88 & 0x88)
intersection off board;
else
sq := ((sq88 >> 1) & 56) + (sq88 & 7);
</pre>
==C-Source==
<pre>
/****************************************
* return: intersection square (if any)
* of rank of square a
* with diagonal of square b
* -1 if no intersection exists
****************************************/
int intersectRankDia(int a, int b) {
int s88 = 17*(a>>3) - (b >> 3) + (b & 7);
return (((s88 >> 1) & 56) + (s88 & 7)) | ( -(s88 & 0x88) >> 31);
}
</pre>

=File and Diagonal=
or vice versa Diagonal and File
<pre>
. . . | . . / .
. . . | . b . .
. . . | / . . .
. . . s . . . .
. . / | . . . .
. / . | . . . .
/ . . a . . . .
</pre>
with
diagonalIndex := rankIndex - fileIndex;
{| class="wikitable"
|-
! r/f
! 0
! 1
! 2
! 3
! 4
! 5
! 6
! 7
|-
! 7
| style="text-align:right;" | 7
| style="text-align:right;" | 6
| style="text-align:right;" | 5
| style="text-align:right;" | 4
| style="text-align:right;" | 3
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
|-
! 6
| style="text-align:right;" | 6
| style="text-align:right;" | 5
| style="text-align:right;" | 4
| style="text-align:right;" | 3
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
|-
! 5
| style="text-align:right;" | 5
| style="text-align:right;" | 4
| style="text-align:right;" | 3
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
|-
! 4
| style="text-align:right;" | 4
| style="text-align:right;" | 3
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
| style="text-align:right;" | -3
|-
! 3
| style="text-align:right;" | 3
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
| style="text-align:right;" | -3
| style="text-align:right;" | -4
|-
! 2
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
| style="text-align:right;" | -3
| style="text-align:right;" | -4
| style="text-align:right;" | -5
|-
! 1
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
| style="text-align:right;" | -3
| style="text-align:right;" | -4
| style="text-align:right;" | -5
| style="text-align:right;" | -6
|-
! 0
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
| style="text-align:right;" | -3
| style="text-align:right;" | -4
| style="text-align:right;" | -5
| style="text-align:right;" | -6
| style="text-align:right;" | -7
|}
==0x88 Math==
<pre>
fileIndex(s) := fileIndex(a);
rankIndex(s) := fileIndex(s) + diagonalIndex(s);
rankIndex(s) := fileIndex(a) + rankIndex(b) - fileIndex(b);
</pre>
Because the intersection of any file with any diagonal may off the board, we rely on 0x88 math for a quick test:
<pre>
s88 := 16*rankIndex(s) + fileIndex(s);
s88 := 16*(fileIndex(a) + rankIndex(b) - fileIndex(b)) + fileIndex(a);
s88 := 17*fileIndex(a) + 16*rankIndex(b) - 16*fileIndex(b);
if ( s88 & 0x88)
intersection off board;
else
sq := ((sq88 >> 1) & 56) + (sq88 & 7);
</pre>
==C-Source==
<pre>
/****************************************
* return: intersection square (if any)
* of file of square a
* with diagonal of square b
* -1 if no intersection exists
****************************************/
int intersectFileDia(int a, int b) {
int s88 = 17*(a & 7) + 2*(b & 56) - 16*(b & 7);
return (((s88 >> 1) & 56) + (s88 & 7)) | ( -(s88 & 0x88) >> 31);
}
</pre>

=Rank and Anti-Diagonal=
or vice versa Anti-Diagonal and Rank
<pre>
. . . . . . . .
. . . . . . . .
\ . . . . . . .
. b . . . . . .
. . \ . . . . .
. . . \ . . . .
------a-s------
. . . . . \ . .
</pre>
with
antidiagIndex := rankIndex + fileIndex;
{| class="wikitable"
|-
! r/f
! 0
! 1
! 2
! 3
! 4
! 5
! 6
! 7
|-
! 7
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
| style="text-align:right;" | 10
| style="text-align:right;" | 11
| style="text-align:right;" | 12
| style="text-align:right;" | 13
| style="text-align:right;" | 14
|-
! 6
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
| style="text-align:right;" | 10
| style="text-align:right;" | 11
| style="text-align:right;" | 12
| style="text-align:right;" | 13
|-
! 5
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
| style="text-align:right;" | 10
| style="text-align:right;" | 11
| style="text-align:right;" | 12
|-
! 4
| style="text-align:right;" | 4
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
| style="text-align:right;" | 10
| style="text-align:right;" | 11
|-
! 3
| style="text-align:right;" | 3
| style="text-align:right;" | 4
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
| style="text-align:right;" | 10
|-
! 2
| style="text-align:right;" | 2
| style="text-align:right;" | 3
| style="text-align:right;" | 4
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
|-
! 1
| style="text-align:right;" | 1
| style="text-align:right;" | 2
| style="text-align:right;" | 3
| style="text-align:right;" | 4
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
|-
! 0
| style="text-align:right;" | 0
| style="text-align:right;" | 1
| style="text-align:right;" | 2
| style="text-align:right;" | 3
| style="text-align:right;" | 4
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
|}
==0x88 Math==
<pre>
rankIndex(s) := rankIndex(a);
fileIndex(s) := antidiagIndex(s) - rankIndex(s);
fileIndex(s) := rankIndex(a) - rankIndex(b) + fileIndex(b);
</pre>
Because the intersection of any rank with any anti-diagonal may off the board, we rely on 0x88 math for a quick test:
<pre>
s88 := 16*rankIndex(s) + fileIndex(s);
s88 := 16*rankIndex(a) + rankIndex(a) - rankIndex(b) + fileIndex(b);
s88 := 17*rankIndex(a) - rankIndex(b) + fileIndex(b);
if ( s88 & 0x88)
intersection off board;
else
sq := ((sq88 >> 1) & 56) + (sq88 & 7);
</pre>
==C-Source==
<pre>
/****************************************
* return: intersection square (if any)
* of rank of square a
* with anti-diagonal of square b
* -1 if no intersection exists
****************************************/
int intersectRankAnt(int a, int b) {
int s88 = 17*(a >> 3) - (b >> 3) + (b & 7);
return (((s88 >> 1) & 56) + (s88 & 7)) | ( -(s88 & 0x88) >> 31);
}
</pre>

=File and Anti-Diagonal=
or vice versa Anti-Diagonal and File
<pre>
. . . | . . . .
. . . | . . . .
\ . . | . . . .
. b . | . . . .
. . \ | . . . .
. . . s . . . .
. . . a \ . . .
. . . | . \ . .
</pre>
with
antidiagIndex := rankIndex + fileIndex;
{| class="wikitable"
|-
! r/f
! 0
! 1
! 2
! 3
! 4
! 5
! 6
! 7
|-
! 7
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
| style="text-align:right;" | 10
| style="text-align:right;" | 11
| style="text-align:right;" | 12
| style="text-align:right;" | 13
| style="text-align:right;" | 14
|-
! 6
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
| style="text-align:right;" | 10
| style="text-align:right;" | 11
| style="text-align:right;" | 12
| style="text-align:right;" | 13
|-
! 5
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
| style="text-align:right;" | 10
| style="text-align:right;" | 11
| style="text-align:right;" | 12
|-
! 4
| style="text-align:right;" | 4
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
| style="text-align:right;" | 10
| style="text-align:right;" | 11
|-
! 3
| style="text-align:right;" | 3
| style="text-align:right;" | 4
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
| style="text-align:right;" | 10
|-
! 2
| style="text-align:right;" | 2
| style="text-align:right;" | 3
| style="text-align:right;" | 4
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
|-
! 1
| style="text-align:right;" | 1
| style="text-align:right;" | 2
| style="text-align:right;" | 3
| style="text-align:right;" | 4
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
|-
! 0
| style="text-align:right;" | 0
| style="text-align:right;" | 1
| style="text-align:right;" | 2
| style="text-align:right;" | 3
| style="text-align:right;" | 4
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
|}
==0x88 Math==
<pre>
fileIndex(s) := fileIndex(a);
rankIndex(s) := antidiagIndex(s) - fileIndex(s);
rankIndex(s) := rankIndex(b) + fileIndex(b) - fileIndex(a);
</pre>
Because the intersection of any rank with any anti-diagonal may off the board, we rely on 0x88 math for a quick test:
<pre>
s88 := 16*rankIndex(s) + fileIndex(s);
s88 := 16*(rankIndex(b) + fileIndex(b) - fileIndex(a)) + fileIndex(a);
s88 := 16*rankIndex(b) + 16*fileIndex(b) - 15*fileIndex(a);
if ( s88 & 0x88)
intersection off board;
else
sq := ((sq88 >> 1) & 56) + (sq88 & 7);
</pre>
==C-Source==
<pre>
/****************************************
* return: intersection square (if any)
* of file of square a
* with anti-diagonal of square b
* -1 if no intersection exists
****************************************/
int intersectFileAnt(int a, int b) {
int s88 = 2*(b & 56) + 16*(b & 7) - 15*(a & 7);
return (((s88 >> 1) & 56) + (s88 & 7)) | ( -(s88 & 0x88) >> 31);
}
</pre>

=Diagonal and Anti-Diagonal=
or vice versa Anti-Diagonal and Diagonal
<pre>
. . . . . . . .
. . . . . . . /
\ . . . . . / .
. b . . . / . .
. . \ . / . . .
. . . s . . . .
. . a . \ . . .
. / . . . \ . .
</pre>
with
diagonalIndex := rankIndex - fileIndex;
{| class="wikitable"
|-
! r/f
! 0
! 1
! 2
! 3
! 4
! 5
! 6
! 7
|-
! 7
| style="text-align:right;" | 7
| style="text-align:right;" | 6
| style="text-align:right;" | 5
| style="text-align:right;" | 4
| style="text-align:right;" | 3
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
|-
! 6
| style="text-align:right;" | 6
| style="text-align:right;" | 5
| style="text-align:right;" | 4
| style="text-align:right;" | 3
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
|-
! 5
| style="text-align:right;" | 5
| style="text-align:right;" | 4
| style="text-align:right;" | 3
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
|-
! 4
| style="text-align:right;" | 4
| style="text-align:right;" | 3
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
| style="text-align:right;" | -3
|-
! 3
| style="text-align:right;" | 3
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
| style="text-align:right;" | -3
| style="text-align:right;" | -4
|-
! 2
| style="text-align:right;" | 2
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
| style="text-align:right;" | -3
| style="text-align:right;" | -4
| style="text-align:right;" | -5
|-
! 1
| style="text-align:right;" | 1
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
| style="text-align:right;" | -3
| style="text-align:right;" | -4
| style="text-align:right;" | -5
| style="text-align:right;" | -6
|-
! 0
! 0
| style="text-align:right;" | -1
| style="text-align:right;" | -2
| style="text-align:right;" | -3
| style="text-align:right;" | -4
| style="text-align:right;" | -5
| style="text-align:right;" | -6
| style="text-align:right;" | -7
|}
and
antidiagIndex := rankIndex + fileIndex;
{| class="wikitable"
|-
! r/f
! 0
! 1
! 2
! 3
! 4
! 5
! 6
! 7
|-
! 7
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
| style="text-align:right;" | 10
| style="text-align:right;" | 11
| style="text-align:right;" | 12
| style="text-align:right;" | 13
| style="text-align:right;" | 14
|-
! 6
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
| style="text-align:right;" | 10
| style="text-align:right;" | 11
| style="text-align:right;" | 12
| style="text-align:right;" | 13
|-
! 5
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
| style="text-align:right;" | 10
| style="text-align:right;" | 11
| style="text-align:right;" | 12
|-
! 4
| style="text-align:right;" | 4
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
| style="text-align:right;" | 10
| style="text-align:right;" | 11
|-
! 3
| style="text-align:right;" | 3
| style="text-align:right;" | 4
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
| style="text-align:right;" | 10
|-
! 2
| style="text-align:right;" | 2
| style="text-align:right;" | 3
| style="text-align:right;" | 4
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
| style="text-align:right;" | 9
|-
! 1
| style="text-align:right;" | 1
| style="text-align:right;" | 2
| style="text-align:right;" | 3
| style="text-align:right;" | 4
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
| style="text-align:right;" | 8
|-
! 0
| style="text-align:right;" | 0
| style="text-align:right;" | 1
| style="text-align:right;" | 2
| style="text-align:right;" | 3
| style="text-align:right;" | 4
| style="text-align:right;" | 5
| style="text-align:right;" | 6
! 7
|}

==0x88 Math==
For same file and rank of intersection-point s:
<pre>
rankIndex(s) - diagonalIndex(a) == antidiagIndex(b) - rankIndex(s);
fileIndex(s) + diagonalIndex(a) == antidiagIndex(b) - fileIndex(s);
</pre>
and therefor
<pre>
2*rankIndex(s) == antidiagIndex(b) + diagonalIndex(a);
2*fileIndex(s) == antidiagIndex(b) - diagonalIndex(a);
</pre>
Because the intersection of any rank with any anti-diagonal may off the board, we rely on 0x88 math for a quick test:
<pre>
s88 = 16*rankIndex(s) + fileIndex(s);
</pre>
equation times two:
<pre>
s88x2 = 16*2*rankIndex(s) + 2*fileIndex(s);
s88x2 = 16*(antidiagIndex(b) + diagonalIndex(a)) + (antidiagIndex(b) - diagonalIndex(a) );
s88x2 = 17*antidiagIndex(b) + 15*diagonalIndex(a);
if ( s88x2 & 0x111)
intersection off board or empty;
else
sq := ((sq882 >> 2) & 56) + ((sq88>>1) & 7);
</pre>
Additionally, s88x2 becomes odd if a and b have different [[Color of a Square|square colors]], if s88x2 & 0x110 is true, the square is off the board. In both cases there is no intersection square, which can be combined by one test with 0x111. If AND 0x111 is false, we convert 0x88 coordinates to ordinary square coordinates, which might be done "speculative".
==C-Source==
<pre>
/****************************************
* return: intersection square (if any)
* of diagonal of square a
* with antidiagonal of square b
* -1 if no intersection exists
****************************************/
int intersectDiaAnt(int a, int b) {
int s88x2 = 17*((b>>3) + (b & 7)) + 15*((a>>3) - (a & 7));
return (((s88x2>>2)&56) + ((s88x2>>1)&7)) | ( -(s88x2&0x0111) >> 31);
}
</pre>
=See also=
* [[Checks and Pinned Pieces (Bitboards)]]

=External Links=
* [http://mathworld.wolfram.com/Line-LineIntersection.html Line-Line Intersection] from [http://mathworld.wolfram.com/ Wolfram MathWorld]
* [https://en.wikipedia.org/wiki/Line-line_intersection Line-line intersection from Wikipedia]
* [https://en.wikipedia.org/wiki/Line_%28geometry%29 Line (geometry) from Wikipedia]
* [https://en.wikipedia.org/wiki/Linear_equation Linear equations from Wikipedia]
* [https://en.wikipedia.org/wiki/Crossroads_%28culture%29 Crossroads (culture) from Wikipedia]
* [[Videos#SunRa|Sun Ra]] - Where Pathways Meet, from [https://en.wikipedia.org/wiki/Lanquidity Lanquidity] (1978), [https://en.wikipedia.org/wiki/YouTube YouTube] Video
: {{#evu:https://www.youtube.com/watch?v=L5vRHbQoTlc|alignment=left|valignment=top}}

=References=
<references />

'''[[Squares|Up one Level]]'''
[[Category:M. C. Escher]]

Navigation menu