# vectorizing a point to line/segment/ray distance function

30 views (last 30 days)
ThT on 10 Mar 2018
Commented: ThT on 12 Mar 2018
Hi, I am using the function from here in order to calculate the distances of multiple rays to multiple points in the space. The way I am doing it now is by forming two `for` loops as you can notice in the code below since the `distancePoint2Line()` function is not vectorized. However, when I have to through an amount of rays around 2000-3000 rays and find their distance in an amount of 6000-7000 points in the space this takes a lot of time. Therefore, I would like if possible to vectorize the `distancePoint2Line()` in order to optimize the processing time.
The input to the existing `distancePoint2Line()` function is the starting point, the end point of the line, segment or ray, an independent point in the space and the type of line and is briefly given as:
function [d, C, t0] = distancePoint2Line(A, B, P, varargin)
% - lineType definition
if (nargin < 4)
lineType = 'line';
%%Algorithm
% Direction vector
% M = B - A;
M = B;
% Running parameter t0 defines the intersection point of line through A and B
% and the perpendicular through P
t0 = dot(M, P - A) / dot(M, M);
% Intersection point of the perpendicular and line through A and B
intersectPnt = A + t0 * M;
switch lower(lineType)
case 'line'
% Line: intersection point is always closest.
C = intersectPnt;
case 'segment'
% Line segment
if t0 < 0
% Start point is closest.
C = A;
elseif t0 > 1
% End point is closest.
C = B;
else
% Intersection point is closest.
C = intersectPnt;
end
case 'ray'
% Ray
if t0 < 0
% Start point is closest.
C = A;
else
% Intersection point is closest.
C = intersectPnt;
end
end
% Distance between independent point and closest point
d = norm(P-C);
end
So if I consider that I have the following figure: where the green point is my origin, the blue rays are the rays thrown in the space from origin and red points are the individual points in the space for which I want to measure their distance to each ray the way I am doing it so far is the following:
origin = [10 10 0];
rays = [ 0.0420891179448099 -0.246431544552697 0.968245836551854;
0.310536647204174 0.682690992135673 0.661437827766148;
-0.746496065726383 -0.0724128707829756 0.661437827766148;
0.435959418522208 -0.610278121352698 0.661437827766148];
mypts = [4579 4246 1962;
3961 4670 3277;
4796 3393 856;
3277 3787 3529;
179 3713 160];
for j=1:size(rays,1)
for i=1:size(mypts,1)
[D(i,j), C(i,j,:), t0(i,j)] = distancePoint2Line(origin, rays(j,:), mypts(j,:), 'ray');
end
end
However, as I said the above implementation is too slow when the number of rays and individual points increases.
Therefore, I tried to modify the `distancePoint2Line()` function so that I vectorize the processing and pass as arguments the origin point, all the ending points, and all the individual points at once.
[d, c, tt0] = distancePoint2LineVec(origin, rays, mypts, 'ray');
Below is my modification until getting the intersection points:
function [d, C, t0] = distancePoint2LineVec(A, B, P, varargin)
% - lineType definition
if (nargin < 4)
lineType = 'line';
%%Algorithm
% Direction vector
% M = B - A;
% M = bsxfun(@minus, B, A);
M = B;
% Running parameter t0 defines the intersection point of line through A and B
% and the perpendicular through P
% t0 = dot(M, P - A) / dot(M, M);
K = bsxfun(@minus, P, A);
V = M*K.';
U = M*M.';
t0 = bsxfun(@rdivide, V, diag(U));
t0 = t0(:);
% Intersection point of the perpendicular and line through A and B
% intersectPnt = A + t0 * M;
mul = M.*repmat(t0, [1 size(M,1)]); <---- Getting matrix dimension error here
intersectPnt = bsxfun(@plus,A,mul);
switch lower(lineType)
case 'line'
% Line: intersection point is always closest.
C = intersectPnt;
case 'segment'
% Line segment
if t0 < 0
% Start point is closest.
C = A;
elseif t0 > 1
% End point is closest.
C = B;
else
% Intersection point is closest.
C = intersectPnt;
end
case 'ray'
% Ray
if t0 < 0
% Start point is closest.
C = A;
else
% Intersection point is closest.
C = intersectPnt;
end
end
% Distance between independent point and closest point
d = norm(P-C);
end
but the point is that I am getting an error there since the dimensions are not matching for the multiplication. Could someone give any ideas how to optimize the function and make it more efficient?
Thanks.

#### 1 Comment

Jan on 12 Mar 2018
Please post the complete error message instead of a rough rephrased version. It is useful to know, in which line the error occurs.

KSSV on 12 Mar 2018
YOu may refer the following function in file-exchange...where I have calculated distance by vectors. https://in.mathworks.com/matlabcentral/fileexchange/44334-nearest-neighboring-particle-search-using-all-particles-search

#### 1 Comment

ThT on 12 Mar 2018
@KSSV thank for the reply. I managed to get it work at the end. Solution posted here https://stackoverflow.com/questions/49196921/vectorizing-a-point-to-line-segment-ray-distance-function-matlab