MATLAB: Can I find 2 points along a 3-dimensional linear line of best fit

linear regressionMATLAB

Is there a way to find 2 points along a 3-dimensional line of best fit? I have plotted 3-dimensional data as well as a linear line of best fit for the data, and am looking to find any 2 points along the linear line of best fit. Attached is the code I used to create the line of best fit as well as the final figure. (ignore the plot error.)

Best Answer

You can write a function that finds the point on the line that is closest to your data line, but this doesn't. It finds two points on the line that are closest to you data points, not the line Matlab draws between those points.
Next time, post your code as text and use the {}Code button to format it. You should make it easy for people to copy and paste your code to Matlab.
x=[ -77.0675, -75.3709, -73.4958, -70.8106, -68.0568, ...
-65.7213, -63.6809, -61.8022, -60.7548, -59.0176];
y=[-174.3252, -176.0859, -178.0156, -180.2053, -182.2752, ....
-184.0714, -186.6690, -189.5100, -191.8722, -194.4930];
z=[ 738.9531, 736.8734, 735.4359, 735.1597, 735.2994, ...
735.8879, 736.5197, 737.7522, 738.6343, 739.2247];
xyz=[x(:),y(:),z(:)];
r=mean(xyz);
xyz=bsxfun(@minus,xyz,r);
[~,~,V]=svd(xyz,0);
x_fit=@(z_fit) r(1)+(z_fit-r(3))/V(3,1)*V(1,1);
y_fit=@(z_fit) r(2)+(z_fit-r(3))/V(3,1)*V(2,1);
figure(1),clf(1)
plot3(x,y,z,'b')
hold on
plot3(x_fit(z),y_fit(z),z,'r')
%create a new z vector for more fine-grained matching
extra_factor=10;N_new=extra_factor*numel(z);
z2=linspace(min(z),max(z),N_new);
%implicit expansion (>=R2016b):
%dist_to_data=sqrt((x_fit(z2)'-x).^2+(y_fit(z2)'-y).^2+(z2'-z).^2);
dist_to_data=sqrt(...
bsxfun(@minus,x_fit(z2)',x).^2+...
bsxfun(@minus,y_fit(z2)',y).^2+...
bsxfun(@minus, z2',z).^2);
dist_to_data=min(dist_to_data,[],2);
%filter the first derivative and find the zero crossing to find the closest
%point to the data
filtered_dist=movmean(diff(dist_to_data),extra_factor);
%zero cross index finder (by Star Strider, matlabcentral/answers/267222 )
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0);
zero_cross_index=zci(filtered_dist);
%select the candidates and sort them based on distance to data
z_close=z2(zero_cross_index);
[~,order]=sort(dist_to_data(zero_cross_index));
z_close=z_close(order);
%plot only the two points closest to the data
plot3(x_fit(z_close(1)),y_fit(z_close(1)),z_close(1),'kx')
plot3(x_fit(z_close(2)),y_fit(z_close(2)),z_close(2),'ko')