The Abstract-Is-Better wayThe Abstract-Is-Better way
Below we talk about n\$n\$-dimensional space. I'll use "n"\$n\$-dimensional hyper-xyz" to denote something that would be called xyz in 3 dimensions. For example, a 2-dimensional hyper-block is a retanglerectangle, etc).
Say you want to divide an n\$n\$-dimensional hyper-block with a n-1\$n-1\$ dimensional hyper-plane. The hyper-plane has a normal unit vector N\$N\$ and its points X\$X\$ satisfy:
N·X + d = 0
$$N\cdot X + d = 0$$
where N·X\$N\cdot X\$ is a scalar: the dot product of the vectors N\$N\$ and X\$X\$, and d\$d\$ is a scalar giving the distance from the origin to the hyper-plane in units of N\$N\$: if d\$d\$ is negative then the hyper-plane just lays in the direction of -N\$-N\$ from the origin.
The n\$n\$-dimensional hyper-block can be thought of as being spanned by a set of n\$n\$ orthogonal "base vectors" B=(v0, v1, v2, ...)\$B=(v_0, v_1, v_2, ...)\$ and has 2n\$2n\$ hyper-planes as borders and 2^n\$2^n\$ corners. LetsLet's denote these corners with an n\$n\$-dimensional boolean vector (aka, C=(0,0,1,1,0,1,...)\$C=(0,0,1,1,0,1,...)\$) where the i-\$i\$th boolean gives us whether that corner is a part of the lower or higher hyper-plane that is perpendicular to the i-\$i\$th base vector v_i\$v_i\$.
Note the exact coordinates of corner C\$C\$ is now given by B·C\$B\cdot C\$, aka corner (0,0,0...)\$(0,0,0...)\$ is given by O + O + O + ... = O\$O + O + O + ... = O\$ (where O\$O\$ is the origin) and (1,1,1,...)\$(1,1,1,...)\$ is given by v0 + v1 + v2 + ....\$v0 + v1 + v2 + ....\$
We have to run over all corners and see on which side of the hyper-plane they are on; that is, if the distance from the corner to the hyper-plane requires adding or subtracting (a fraction of) N\$N\$.
We can determine this distance k\$k\$ by solving the line equation for B·C + kN \$B\cdot C + kN\$ (aka, how many times do we have to add the normal N\$N\$ to the corner to reach the hyper-plane?):
N·(B·C + kN) + d = 0
$$N\cdot(B\cdot C + kN) + d = 0$$
and since N\$N\$ is a unit vector N·kN = k N·N = k * 1 = k\$N\cdot kN = k N\cdot N = k * 1 = k\$, therefore:
k = - N·(B·C) - d
$$k = - N\cdot (B\cdot C) - d$$
If this k\$k\$ is negative then this Corner is on one side, if k\$k\$ is positive is it on the other side and if k=0\$k=0\$ then the hyper-plane goes through that corner and it doesn't matter which side you pick, so letslet's say:
k' = 0 if k <= 0, and k' = 1 if k > 0.
$$ \begin{align} k' &= 0 \text{ if } k <= 0 \text{ and}\\ k' &= 1 \text{ if } k > 0 \end{align} $$
and we have as many k'\$k'\$ values as corners (one for each C\$C\$): 2^n\$2^n\$ of them. You can draw a line between any two corner points that only differ in one bit of C\$C\$: n\$n\$ edges from every corner, where then you count every edge twice; so there are 2^n * n / 2 = 2^(n-1) * n\$2^n \frac{n}{2} = 2^{n-1} n\$ edges. However, you can also just run over all corners and then only toggle a single 1 (if there is one) to a 0 (for each 1 that that corner has); if the corresponding k'\$k'\$ changes value then the corresponding edge is cut by your hyper-plane and you can calculate the intersection point.
LetsLet's apply the above to an axis aligned rectangle (where one corner is the origin); in that case:
B = [(100,0), (0,100)]
\$B = [(100,0), (0,100)]\$
Having two points on the line: P1 = (50,50)\$P_1 = (x_1,y_1)=(50,50)\$ and P2 = (50,150)\$P_2 = (x_2,y_2)=(50,150)\$, the line goes -say- from P1 to P2: P2-P1 = (p2_x\$P_1\$ to - p1_x, p2_y\$P_2\$: - p1_y)\$P_2-P_1 = (x_2 - x_1, y_2 - y_1)\$ and the normal to that line N = (-(p2_y - p1_y), p2_x - p1_x)\$N = (-(y_2 - y_1), x_2 - x_1)\$. And the distance to the origin is for example d = -N·P1\$d = -N\cdot P_1\$. Working that out we get:
N = (-(150 - 50), 50 - 50) = (-100, 0) = (-1, 0) (normalized to length 1)
d = -(-1*50 + 0*50) = 50
$$ \begin{align} N &= (-(150 - 50), 50 - 50) = (-100, 0) = (-1, 0) \textit{ (normalized to length 1)} \\ d &= -(-1*50 + 0*50) = 50 \end{align} $$
Assuming B\$B\$ is column vector, letslet's make C\$C\$ a matrix that includes all corners at once:
C = [(0,0),(1,0),(0,1),(1,1)]
$$C = [(0,0),(1,0),(0,1),(1,1)]$$
where the first element of each column vector tells us if b0\$b_0\$ participates and the second element if b1\$b_1\$ does.
B·C = [(0,0), (100,0), (0,100), (100,100)]
$$B\cdot C = [(0,0), (100,0), (0,100), (100,100)]$$
the four corners. And the corresponding k\$k\$ values:
K = -N·(B·C) - d = [-50,50,-50,50]
$$K = -N\cdot (B\cdot C) - d = [-50,50,-50,50]$$
To calculate where, just parameterize the edge using the two corners that made the sign of k\$k\$ change - say C1\$C_1\$ and C2\$C_2\$ (e.g. (100,0) and (0,0)):
Edge: C1 + g(C2 - C1)
Edge: \$C_1 + g(C_2 - C_1)\$
N·(C1 + g(C2 - C1)) + d = 0
to find g:
g = -(N·C1 + d) / (N·(C2 - C1))
The intersection point then is C1 + g(C2 - C1).$$N\cdot (C_1 + g(C_2 - C_1)) + d = 0$$
For example, with C1=(100,0) and C2=(0,0)to find \$g\$:
g = -((-1,0)·(100,0) + 50)/((-1,0)·((0,0)-(100,0))) =
= -(-100 + 50)/((-1,0)·(-100,0)) =
= 50/100 = 1/2
$$g = -\frac{N\cdot C_1 + d}{N\cdot (C_2 - C_1)}$$
And thus theThe intersection point then is at (100,0) + 1/2(-100,0) = (50,0). While for C1=(100,100) and C2=(0,100) we get (50,100)\$C_1 + g(C_2 - C_1)\$.
PS If N·(C2For example, with \$C_1=(100,0)\$ and \$C_2=(0,0)\$: $$ \begin{align} g &= -\frac{(-1,0)\cdot (100,0) + 50}{(-1,0)\cdot ((0,0)-(100,0))} \\ &= -\frac{-100 + 50}{(-1,0)\cdot (-100,0)} \\ &= \frac{50}{100} \\ &= \frac{1}{2} \\ \end{align} $$ And thus the intersection is at (100,0) + 1/2(- C1100,0) = 0 we can't devide through it; this means that the hyper-plane goes through both corners and intersects the edge everywhere(50,0). In that case one should have picked the other possibility for when k=0 While for at least one of the corners\$C_1=(100,100)\$ and \$C_2=(0,100)\$ we get (50,100).
24 hours later
PS If \$N\cdot (C_2 - C_1) = 0\$ we can't devide through it; this means that the hyper-plane goes through both corners and intersects the edge everywhere. In that case one should have picked the other possibility for when \$k=0\$ for at least one of the corners.
Online test case: https://wandbox.org/permlink/5MTAowhWLxUkQVK9Online test case
Latest version: https://github.com/CarloWood/machine-learning/blob/master/src/intersection_points.hLatest version