Point-normal form and signed distance

In [21]:
import numpy as np
import numpy.linalg as la
import matplotlib.pyplot as pt
In [55]:
def draw_arrow(v, **kwargs):
    pt.arrow(0, 0, v[0], v[1], length_includes_head=True,
             head_width=0.1, **kwargs)
    
def set_up_plot():
    pt.xlim([-2,2])
    pt.ylim([-2,2])
    pt.gca().set_aspect("equal")
    pt.grid()

Let's grab some vector $v$:

In [48]:
np.random.seed(18)
v = np.array([1.6, 0.4])
v
Out[48]:
array([ 1.6,  0.4])
In [57]:
set_up_plot()
draw_arrow(v, color="blue")

Now let's find a unit normal vector $n$:

In [58]:
b = np.random.randn(2)
b = b - b.dot(v)/v.dot(v)*v
n = b/la.norm(b, 2)

Check:

In [59]:
print("Norm =", la.norm(n))
print("n.v =", n.dot(v))
Norm = 1.0
n.v = -2.77555756156e-16

Plot:

In [63]:
set_up_plot()
draw_arrow(v, color="blue")
draw_arrow(n, color="red")

Now let's grab a point $p$ and compute $r$:

In [95]:
np.random.seed(355342)
p = np.random.randn(2)

r = p.dot(n)
In [100]:
set_up_plot()
draw_arrow(v, color="blue")
draw_arrow(n, color="red")
draw_arrow(p)

Next, evaluate signed distance on a grid of points in the plane:

In [109]:
xs = np.linspace(-2, 2, 100)
ys = np.linspace(-2, 2, 100)


# make an grid of points in the plane
xys = np.empty((2, 100, 100))
xys[0] = xs
xys[1] = xs.reshape(-1, 1)

signed_dist = (
    xys[0]*n[0] + xys[1]*n[1] - r
    )
In [112]:
set_up_plot()
draw_arrow(v, color="blue")
draw_arrow(n, color="red")
draw_arrow(p)

pt.imshow(signed_dist, extent=(-2, 2, 2, -2), cmap="RdBu", vmin=-3, vmax=3)
pt.colorbar()
Out[112]:
<matplotlib.colorbar.Colorbar at 0x7fd9857736a0>
  • Where is the line parallel to $v$ through $p$? (that satisfies $x\cdot n -r = 0$)?

    (Hint: Look for plot values = 0.)

  • Can you read off the distance of the line from the origin?
  • Can you read off the distance of the line from $v$?
  • Can you read off the distance between the line and the top left corner of the plot?
  • How was each such distance computed?
In []: