In [92]:
import plotly
import plotly.graph_objs as go
import numpy as np
plotly.offline.init_notebook_mode()
In [93]:
X = np.random.uniform(-1,1,100)
Y = np.random.uniform(-1,1,100)
Z = np.random.uniform(-1,1,100)
points = np.vstack([X, Y, Z]).T
query_point = np.random.uniform(-1, 1, 3)
In [94]:
def generate_planes(n):
    return [np.random.uniform(-1,1,3) for i in range(n)]

def get_intersection_for_plane(p):
    a = p[0]
    b = p[1]
    c = p[2]
    
    points = []
    for i in [-1, 1]:
        for j in [[1, 1, 0], [1, 0, 1], [0, 1, 1]]:
            top = (-np.dot(np.array(j)*i, p))
            bottom = np.dot(np.abs(1-np.array(j)), p)
            new_coord = top / bottom           
            new_point = []
            for k in range(len(j)):
                if j[k] == 0:
                    new_point.append(new_coord)
                else:
                    new_point.append(i)
            points.append(new_point)            
    return np.transpose(points)
            
def filter_points_by_plane(points, plane, ref):
    if np.dot(plane, ref) > 0:
        return points[np.dot(points, plane) > 0]
    return points[np.dot(points, plane) < 0] 
In [95]:
planes = generate_planes(4)
plane_points = [get_intersection_for_plane(plane) for plane in planes]
In [96]:
colors =  [ 
    '#1f77b4',  
    '#ff7f0e',  
    '#2ca02c',  
    '#d62728',  
    '#9467bd',  
    '#e377c2',  
    '#bcbd22',  
    '#17becf'
]

trace = go.Scatter3d(
    x= X,
    y= Y,
    z= Z,
    mode='markers',
    marker={
        'size': 4,
        'opacity': 0.8,
        'color': 'blue'
    }
)
In [97]:
data = [trace]

layout = go.Layout(
    margin={'l': 0, 'r': 0, 'b': 0, 't': 0}
)

qp = go.Scatter3d(
    x = [query_point[0]],
    y = [query_point[1]],
    z = [query_point[2]],
    mode='markers',
    marker={
        'size': 4,
        'color': 'red',
        'opacity': 0.8,
    }
)

data.append(qp)
fig = go.Figure(data=data, layout=layout)
fig.update_layout(scene = dict(
        xaxis = dict(range=[-1,1]),
                     yaxis = dict( range=[-1,1]),
                     zaxis = dict( range=[-1,1]))
                     )
plotly.offline.iplot(fig)
In [98]:
f = points.T

for i in range(len(planes)+1):
    print(f.shape)   
    trace = go.Scatter3d(
        x= f[0],
        y= f[1],
        z= f[2],
        mode='markers',
        marker={
            'size': 4,
            'opacity': 0.8,
            'color': 'blue',
        }
    )

    data = [go.Mesh3d(x=plane_points[j][0].tolist(), y= plane_points[j][1].tolist(), z= plane_points[j][2].tolist(),
                       delaunayaxis='x',
                       opacity=.4,
                       color=colors[j]) for j in range(i)]

    data.append(trace)
    data.append(qp)

    layout = go.Layout(
        margin={'l': 0, 'r': 0, 'b': 0, 't': 0}
    )

    fig = go.Figure(data=data, layout=layout)
    fig.update_layout(scene = dict(
            xaxis = dict(range=[-1,1]),
                         yaxis = dict( range=[-1,1]),
                         zaxis = dict( range=[-1,1]))
                         )
    plotly.offline.iplot(fig)   
    if i < len(planes):
        f = filter_points_by_plane(f.T, planes[i], query_point).T
(3, 100)
(3, 54)
(3, 18)
(3, 14)
(3, 13)