0001 function [d, pt1, pt2] = distanceLines3d(line1, line2)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 n1 = size(line1, 1);
0034 n2 = size(line2, 1);
0035
0036 if nargout <= 1
0037
0038 v1x = repmat(line1(:,4), [1 n2]);
0039 v1y = repmat(line1(:,5), [1 n2]);
0040 v1z = repmat(line1(:,6), [1 n2]);
0041 p1x = repmat(line1(:,1), [1 n2]);
0042 p1y = repmat(line1(:,2), [1 n2]);
0043 p1z = repmat(line1(:,3), [1 n2]);
0044
0045 v2x = repmat(line2(:,4)', [n1 1]);
0046 v2y = repmat(line2(:,5)', [n1 1]);
0047 v2z = repmat(line2(:,6)', [n1 1]);
0048 p2x = repmat(line2(:,1)', [n1 1]);
0049 p2y = repmat(line2(:,2)', [n1 1]);
0050 p2z = repmat(line2(:,3)', [n1 1]);
0051
0052
0053 vcross = cross([v1x(:) v1y(:) v1z(:)], [v2x(:) v2y(:) v2z(:)]);
0054 num = ([p1x(:) p1y(:) p1z(:)] - [p2x(:) p2y(:) p2z(:)]) .* vcross;
0055 t1 = sum(num,2);
0056 d = abs(t1) ./ (vectorNorm3d(vcross) + eps);
0057
0058
0059 d = reshape(d, n1, n2);
0060
0061 else
0062
0063
0064 if n1 ~= n2
0065 error('geom3d:distanceLines3d:IllegalInputArgument', ...
0066 'when output points are requested, number of lines should be the same');
0067 end
0068
0069 p1 = line1(:, 1:3);
0070 p2 = line2(:, 1:3);
0071 dp = p2 - p1;
0072 v1 = line1(:, 4:6);
0073 v2 = line2(:, 4:6);
0074
0075
0076 vcross = cross(v1, v2, 2);
0077 num = dp .* vcross;
0078 t1 = sum(num, 2);
0079 d = abs(t1) ./ (vectorNorm3d(vcross) + eps);
0080
0081
0082 a = dot(v1, v1, 2);
0083 b = dot(v1, v2, 2);
0084 e = dot(v2, v2, 2);
0085 den = a.*e - b.*b;
0086
0087
0088 r = line1(:,1:3) - line2(:,1:3);
0089
0090
0091 c = dot(v1, r, 2);
0092 f = dot(v2, r, 2);
0093 s = (b .* f - c .* e) ./ den;
0094 t = (a .* f - c .* b) ./ den;
0095
0096
0097 pt1 = line1(:,1:3) + v1 .* s;
0098 pt2 = line2(:,1:3) + v2 .* t;
0099 end