0001 function ptProj = projPointOnCylinder(pt, cyl, varargin)
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 parser = inputParser;
0028 addRequired(parser, 'pt', @(x) validateattributes(x, {'numeric'},...
0029 {'size',[1 3],'real','finite','nonnan'}));
0030 addRequired(parser, 'cyl', @(x) validateattributes(x, {'numeric'},...
0031 {'size',[1 7],'real','finite','nonnan'}));
0032 capParValidFunc = @(x) (islogical(x) ...
0033 || isequal(x,1) || isequal(x,0) || any(validatestring(x, {'open','closed'})));
0034 addOptional(parser,'cap','open', capParValidFunc);
0035 parse(parser,pt,cyl,varargin{:});
0036 pt = parser.Results.pt;
0037 cyl = parser.Results.cyl;
0038 cap = lower(parser.Results.cap(1));
0039
0040
0041 cylRadius = cyl(7);
0042
0043 cylBottom = -Inf;
0044 cylHeight = Inf;
0045 if cap == 'c' || cap == 1
0046 cylBottom = 0;
0047 cylHeight = distancePoints3d(cyl(1:3),cyl(4:6));
0048 end
0049
0050
0051
0052 TFM = createRotationVector3d(cyl(4:6)-cyl(1:3), [0 0 1])*createTranslation3d(-cyl(1:3));
0053
0054
0055
0056
0057
0058 ptTfm = transformPoint3d(pt,TFM);
0059
0060 [ptTheta, ptRadius, ptHeight] = cart2cyl(ptTfm);
0061
0062 if ptRadius <= cylRadius && (ptHeight <= cylBottom || ptHeight >= cylHeight)
0063
0064 if ptHeight <= cylBottom
0065 ptProj_cyl = [ptTheta, ptRadius, 0];
0066 else
0067 ptProj_cyl = [ptTheta, ptRadius, cylHeight];
0068 end
0069 elseif ptRadius > cylRadius && (ptHeight <= cylBottom || ptHeight >= cylHeight)
0070
0071 if ptHeight <= cylBottom
0072 ptProj_cyl = [ptTheta, cylRadius, 0];
0073 else
0074 ptProj_cyl = [ptTheta, cylRadius, cylHeight];
0075 end
0076 elseif ptRadius < cylRadius && (ptHeight > cylBottom && ptHeight < cylHeight)
0077
0078 deltaRadius = cylRadius - ptRadius;
0079 deltaHeight = cylHeight - ptHeight;
0080 if (deltaRadius < ptHeight && deltaRadius < deltaHeight) || isinf(cylBottom)
0081
0082
0083 ptProj_cyl = [ptTheta, cylRadius, ptHeight];
0084 else
0085 if ptHeight < deltaHeight
0086 ptProj_cyl = [ptTheta, ptRadius, 0];
0087 else
0088 ptProj_cyl = [ptTheta, ptRadius, cylHeight];
0089 end
0090 end
0091 elseif ptRadius >= cylRadius && (ptHeight > cylBottom && ptHeight < cylHeight)
0092
0093 ptProj_cyl = [ptTheta, cylRadius, ptHeight];
0094 end
0095
0096
0097 ptProj_cart = cyl2cart(ptProj_cyl);
0098
0099 ptProj = transformPoint3d(ptProj_cart,inv(TFM));
0100
0101 end