euclidean distance to a "curved" structure

Viewed 143

I have written a program that works with the Euclidean distance of a current resource to the surface of a geometric figure. In our geometric considerations the y-coordinate is always zero - so it is a 2D structure in x and z dimension. The figure shows how it looks:

picture 1

(length yellow = 100 , length blue = 500) -- so if for example the origin is in the middle of the second yellow section, the point source is then for example at a coordinate of coord=(700,0,510) and one can of course for each midpoint of a blue or yellow section the Euclidean distance by means of:

sqrt(sum(((midpoints-coord))^2)

but how can I do this if I "bend" this "stick" by say an angle $\alpha$ from a certain section?:

pic2

the y-coordinate is again zero and the source is again placed vertically in the z-direction - but how do I then determine the Euclidean distance to the centers of the sections? so we use the same length dimensions, only we bend the stick by 30% in the direction of the electrode, for example at the origin or at the 5 segment.The best way would be to manipulate the "x" value of the midpoints accordingly....

2 Answers

I do not have access to Matlab right now, so I wrote some code in python. Is this what you want to do?:

# plotting function of a polyline, a point and, if chosen, midpoints of polyline
def plot_polyline(P, P0, equal_axes, show_midpoints):
    M = midpoints_of(P)
    plt.figure()
    plt.plot(P0[0], P0[1], 'bo')
    plt.plot(P[:,0], P[:,1])
    for k in range(P.shape[0]):
        plt.plot(P[k,0], P[k,1], 'ro')
    if show_midpoints:
        for k in range(M.shape[0]):
            plt.plot(M[k,0], M[k,1], 'yo')
    axx = plt.gca()
    if equal_axes:
        axx.set_aspect('equal')
    plt.show()
    return None

def cos_sin(angle):
    return  math.cos(angle), math.sin(angle)

# generate a rotation matrix that rotates a 2D vector at an angle alpha
# observe the matrix format is [x1, y1] = [x, y].dot([[cos, -sin],
#                                                     [sin, cos]])
# and rotation is clockwise rotation of vector written as row-vectors 
def rot_matrx(angle):
    cs, sn = cos_sin(angle)
    return np.array([[  cs, -sn], 
                     [  sn,  cs]]) 

# performs a clockwise rotation of a point around a center at an angle 
def rotate(points, angle, center):
    U = rot_matrx(angle)
    return (points - center).dot(U) + center
 
# bending
def perform_bending(polyline, angle, index_bending_point):    
    x1 = polyline.copy()  
    x_bend  = x1[index_bending_point,:]
    # rotate half angle around point x_bend first         
    x1[0:index_bending_point,:] = rotate(x1[0:index_bending_point,:], 
                                               angle/2, x_bend) 
    # rotate the result from above half angle more around point x_(bend-1)   
    x_bend = x1[(index_bending_point-1),:]
    x1[0:(index_bending_point - 1),:] = rotate(x1[0:(index_bending_point - 1),:], 
                                                   angle/2, x_bend)      
    return x1

# calculate the array of midpoints of the polyline
def midpoints_of(polyline):
    k, m = polyline.shape
    return (polyline[0:(k-1), :] + polyline[1:k, :]) / 2

# calculate the distances from point to the midpoints of a polyline
def calc_distances(point, mids_of_polyline):
    return np.linalg.norm(point-mids_of_polyline, axis=1)


   
# initialize example:   
a = 2 # yellow segments' lenght
b = 5 # blue segments' lenght
n = 12 # number of segments + 1, number of points separating segments

alpha = 40  # angle of bending in degrees
alpha = math.pi * 40/180 # angle in bending in radians

# generate [0, 1, 2, 3, 4, 5, 6, 7]
I = np.arange(0,n)

# generate the x[0,] and x[1,] coordinates of the polygonal line
x = np.empty((n, 2), dtype=float)
I = np.floor(I / 2)*(a+b) + (I % 2)*a
x[:, 0] = I.T
x[:, 1] = 0

# point on x that is coordinate origin
x0 = (x[2,:] + x[3,:])/2
# shift initial polyline:
x = x - x0

# index of bending point
i_bend=5

x_bent = perform_bending(x, angle=alpha, index_bending_point=i_bend) 
x_mids = midpoints_of(x_bent)

# point
p = np.array([x_mids[i_bend-1, 0], 5.1])
    
dist = calc_distances(p, x_mids)

plot_polyline(x, p, equal_axes=True, show_midpoints=False)
plot_polyline(x_bent, p, equal_axes=True, show_midpoints=True)
plot_polyline(x_bent, p, equal_axes=True, show_midpoints=False)

print(dist)

Just you can do the same by a binary search and find the closest point on the curve (through midpoints) to the given point.

Also, if you have the closed-form of the curve, denoted by z = f(x), and a given point (x_1, 0, z_1), you can solve the following optimization problem:

argmin_{x} (x_1 - x)^2 + (z_1 - f(x))^2

The solution of the above optimization task is the nearest point of the curve to the given point.

To solve the optimization task, you can use different methods depending on the closed-form of f.

If you are using python, you can find many useful libraries for the optimization task, respectively.

Related