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