-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 6b806ef
Showing
4 changed files
with
242 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
This function calculates the distance between a 2D or 3D line and one or more points. | ||
You can input either a 2D or a 3D line and 2D or 3D points. This function is an extended version of the line below, with some input checking: | ||
distance=norm(cross(v1-v2,pt-v2))/norm(v1-v2) | ||
|
||
Licence: CC by-nc-sa 4.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
function aaa___examples___point_to_line_distance | ||
v1 = [0,0,0]; | ||
v2 = [3,0,0]; | ||
pt = [0,5,0;0,10,0;0,15,0]; | ||
distance_3D = point_to_line_distance(pt, v1, v2); | ||
disp(distance_3D) | ||
|
||
v1 = [0,0]; | ||
v2 = [3,0]; | ||
pt = [0,5;0,10;0,15]; | ||
distance_2D = point_to_line_distance(pt, v1, v2); | ||
disp(distance_2D) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
function aaa___test___point_to_line_distance(varargin) | ||
%test by running some examples of working input and syntax errors | ||
|
||
% suppress v6.5 warning | ||
v=version;v(strfind(v,'.'):end)='';v=str2double(v); | ||
if v<=7 | ||
warning off MATLAB:m_warning_end_without_block;clc | ||
end | ||
|
||
%if nargin==0,RunTestHeadless=false;else,RunTestHeadless=true;end | ||
clc | ||
ThrowError=false; | ||
for n_test=1:10^3%basically inf | ||
try | ||
success=eval(sprintf('test%02d',n_test)); | ||
%#ok<*DEFNU,*NASGU,*LERR> | ||
catch | ||
break | ||
end | ||
|
||
if success | ||
fprintf('test %d succeded\n',n_test) | ||
else | ||
ME=lasterror;id=ME.identifier; | ||
fprintf('test %d failed\n(id: %s)\n',n_test,id) | ||
ThrowError=true; | ||
end | ||
end | ||
if ThrowError | ||
error('test did not match expected result') | ||
else | ||
disp('test completed') | ||
end | ||
end | ||
function success=test01 | ||
success=true; | ||
try | ||
v1 = [0,0,0]; | ||
v2 = [3,0,0]; | ||
pt = [0,5,0;0,10,0;0,15,0]; | ||
d = point_to_line_distance(pt, v1, v2); | ||
catch | ||
success=false; | ||
end | ||
end | ||
function success=test02 | ||
success=true; | ||
try | ||
v1 = [0,0]; | ||
v2 = [3,0]; | ||
pt = [0,5;0,10;0,15]; | ||
d = point_to_line_distance(pt, v1, v2); | ||
catch | ||
success=false; | ||
end | ||
end | ||
function success=test03 | ||
success=true; | ||
try | ||
v1 = [0,0,0]; | ||
v2 = [3,0]; | ||
pt = [0,5;0,10;0,15]; | ||
d = point_to_line_distance(pt, v1, v2); | ||
success=false; | ||
catch | ||
ME=lasterror; | ||
if ~strcmp(ME.identifier,'HJW:point_to_line_distance:v_type_size') | ||
success=false; | ||
end | ||
end | ||
end | ||
function success=test04 | ||
success=true; | ||
try | ||
v1 = [0,0,0]; | ||
v2 = [3,0,0]; | ||
pt = [0,5;0,10;0,15]; | ||
d = point_to_line_distance(pt, v1, v2); | ||
success=false; | ||
catch | ||
ME=lasterror; | ||
if ~strcmp(ME.identifier,'HJW:point_to_line_distance:v_type_size') | ||
success=false; | ||
end | ||
end | ||
end | ||
function distance=point_to_line_distance(pt, v1, v2) | ||
%Calculate distance between a point and a line in 2D or 3D. | ||
% syntax: | ||
% distance = point_to_line(pt, v1, v2) | ||
% pt is a nx3 matrix with xyz coordinates for n points | ||
% v1 and v2 are vertices on the line (each 1x3) | ||
% d is a nx1 vector with the orthogonal distances | ||
% | ||
% 2D inputs are extended to 3D by setting all z-values to 0, all inputs should be either nx2 or nx3 | ||
% (1x2 or 1x3 for v1 and v2). | ||
% | ||
% The actual calculation is a slightly edit version of this line (which only works for 3D points): | ||
% distance=norm(cross(v1-v2,pt-v2))/norm(v1-v2) | ||
% | ||
% _______________________________________________________________________ | ||
% | Compatibility | Windows 10 | Ubuntu 20.04 LTS | MacOS 10.15 Catalina | | ||
% |---------------|-------------|------------------|----------------------| | ||
% | ML R2020a | works | not tested | not tested | | ||
% | ML R2018a | works | works | not tested | | ||
% | ML R2015a | works | works | not tested | | ||
% | ML R2011a | works | works | not tested | | ||
% | ML 6.5 (R13) | works | not tested | not tested | | ||
% | Octave 5.2.0 | works | works | not tested | | ||
% | Octave 4.4.1 | works | not tested | works | | ||
% """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | ||
% | ||
% Version: 1.3.2 | ||
% Date: 2020-06-28 | ||
% Author: H.J. Wisselink | ||
% Licence: CC by-nc-sa 4.0 ( creativecommons.org/licenses/by-nc-sa/4.0 ) | ||
% Email= 'h_j_wisselink*alumnus_utwente_nl'; | ||
% Real_email = regexprep(Email,{'*','_'},{'@','.'}) | ||
|
||
%check inputs | ||
if nargin~=3 | ||
error('HJW:point_to_line_distance:nargin',... | ||
'Incorrect number of inputs, expected 3.'); | ||
end | ||
if ~isnumeric(pt) || ~any(size(pt,2)==[2 3]) || any(size(pt)==0) | ||
error('HJW:point_to_line_distance:pt_type_size',... | ||
'First input (pt) is not numeric or has an incorrect shape.') | ||
end | ||
if ~isnumeric(v1) || numel(v1)~=size(pt,2) | ||
error('HJW:point_to_line_distance:v_type_size',... | ||
['Second input (v1) is not numeric or has an incorrect size.',char(10),... | ||
'Expected 1x3 or 1x2, which should match the first input.']) %#ok<CHARTEN> | ||
end | ||
if ~isnumeric(v2) || numel(v2)~=size(pt,2) | ||
error('HJW:point_to_line_distance:v_type_size',... | ||
['Third input (v2) is not numeric or has an incorrect size.',char(10),... | ||
'Expected 1x3 or 1x2, which should match the first input.']) %#ok<CHARTEN> | ||
end | ||
|
||
%prepare inputs | ||
v1=v1(:)';%force 1x3 or 1x2 | ||
v2=v2(:)';%force 1x3 or 1x2 | ||
if length(v1)==2,v1(3)=0; end%extend 1x2 to 1x3 if needed | ||
if length(v2)==2,v2(3)=0; end%extend 1x2 to 1x3 if needed | ||
if size(pt,2)==2,pt(1,3)=0;end%extend nx2 to nx3 if needed | ||
v1_ = repmat(v1,size(pt,1),1); | ||
v2_ = repmat(v2,size(pt,1),1); | ||
|
||
%actual calculation | ||
a = v1_ - v2_; | ||
b = pt - v2_; | ||
distance = sqrt(sum(cross(a,b,2).^2,2)) ./ sqrt(sum(a.^2,2)); | ||
%this is equivalent to the following line for a single point | ||
%distance=norm(cross(v1-v2,pt-v2))/norm(v1-v2) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
function distance=point_to_line_distance(pt, v1, v2) | ||
%Calculate distance between a point and a line in 2D or 3D. | ||
% syntax: | ||
% distance = point_to_line(pt, v1, v2) | ||
% pt is a nx3 matrix with xyz coordinates for n points | ||
% v1 and v2 are vertices on the line (each 1x3) | ||
% d is a nx1 vector with the orthogonal distances | ||
% | ||
% 2D inputs are extended to 3D by setting all z-values to 0, all inputs should be either nx2 or nx3 | ||
% (1x2 or 1x3 for v1 and v2). | ||
% | ||
% The actual calculation is a slightly edit version of this line (which only works for 3D points): | ||
% distance=norm(cross(v1-v2,pt-v2))/norm(v1-v2) | ||
% | ||
% _______________________________________________________________________ | ||
% | Compatibility | Windows 10 | Ubuntu 20.04 LTS | MacOS 10.15 Catalina | | ||
% |---------------|-------------|------------------|----------------------| | ||
% | ML R2020a | works | not tested | not tested | | ||
% | ML R2018a | works | works | not tested | | ||
% | ML R2015a | works | works | not tested | | ||
% | ML R2011a | works | works | not tested | | ||
% | ML 6.5 (R13) | works | not tested | not tested | | ||
% | Octave 5.2.0 | works | works | not tested | | ||
% | Octave 4.4.1 | works | not tested | works | | ||
% """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | ||
% | ||
% Version: 1.3.2 | ||
% Date: 2020-06-28 | ||
% Author: H.J. Wisselink | ||
% Licence: CC by-nc-sa 4.0 ( creativecommons.org/licenses/by-nc-sa/4.0 ) | ||
% Email= 'h_j_wisselink*alumnus_utwente_nl'; | ||
% Real_email = regexprep(Email,{'*','_'},{'@','.'}) | ||
|
||
%check inputs | ||
if nargin~=3 | ||
error('HJW:point_to_line_distance:nargin',... | ||
'Incorrect number of inputs, expected 3.'); | ||
end | ||
if ~isnumeric(pt) || ~any(size(pt,2)==[2 3]) || any(size(pt)==0) | ||
error('HJW:point_to_line_distance:pt_type_size',... | ||
'First input (pt) is not numeric or has an incorrect shape.') | ||
end | ||
if ~isnumeric(v1) || numel(v1)~=size(pt,2) | ||
error('HJW:point_to_line_distance:v_type_size',... | ||
['Second input (v1) is not numeric or has an incorrect size.',char(10),... | ||
'Expected 1x3 or 1x2, which should match the first input.']) %#ok<CHARTEN> | ||
end | ||
if ~isnumeric(v2) || numel(v2)~=size(pt,2) | ||
error('HJW:point_to_line_distance:v_type_size',... | ||
['Third input (v2) is not numeric or has an incorrect size.',char(10),... | ||
'Expected 1x3 or 1x2, which should match the first input.']) %#ok<CHARTEN> | ||
end | ||
|
||
%prepare inputs | ||
v1=v1(:)';%force 1x3 or 1x2 | ||
v2=v2(:)';%force 1x3 or 1x2 | ||
if length(v1)==2,v1(3)=0; end%extend 1x2 to 1x3 if needed | ||
if length(v2)==2,v2(3)=0; end%extend 1x2 to 1x3 if needed | ||
if size(pt,2)==2,pt(1,3)=0;end%extend nx2 to nx3 if needed | ||
v1_ = repmat(v1,size(pt,1),1); | ||
v2_ = repmat(v2,size(pt,1),1); | ||
|
||
%actual calculation | ||
a = v1_ - v2_; | ||
b = pt - v2_; | ||
distance = sqrt(sum(cross(a,b,2).^2,2)) ./ sqrt(sum(a.^2,2)); | ||
%this is equivalent to the following line for a single point | ||
%distance=norm(cross(v1-v2,pt-v2))/norm(v1-v2) | ||
end |