30 views (last 30 days)

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.

KSSV
on 12 Mar 2018

Sign in to answer this question.

Opportunities for recent engineering grads.

Apply Today
## 1 Comment

## Direct link to this comment

https://de.mathworks.com/matlabcentral/answers/387543-vectorizing-a-point-to-line-segment-ray-distance-function#comment_544355

⋮## Direct link to this comment

https://de.mathworks.com/matlabcentral/answers/387543-vectorizing-a-point-to-line-segment-ray-distance-function#comment_544355

Sign in to comment.