Home > matGeom > geom3d > geodesicCylinder.m

geodesicCylinder

PURPOSE ^

GEODESICCYLINDER Computes the geodesic between two points on a cylinder.

SYNOPSIS ^

function [geo, geoLength, conGeo, conGeoLength] = geodesicCylinder(pts, cyl, varargin)

DESCRIPTION ^

GEODESICCYLINDER Computes the geodesic between two points on a cylinder.

   [GEO, GEOLENGTH] = geodesicCylinder(PTS, CYL) computes the geodesic 
   between the two points PTS projected onto the infinite cylinder CYL.  
   PTS is a 2-by-3 array, and CYL is a 1-by-7 array. Result is the 
   polyline GEO (500-by-3 array) [500 = default] containing the  
   coordinates of the geodesic between two projected points. GEOLENGTH 
   contains the analytical length of the geodesic.

   [~, ~, CONGEO, CONGEOLENGTH] = geodesicCylinder(PTS, CYL) provides the
   conjugate geodesic and its analytical length.

   ... = geodesicCylinder(PTS, CYL, 'n', N) defines the number of points
   representing the geodesic and conjugate geodesic.

   Example
       demoGeodesicCylinder

   See also
     drawCylinder, projPointOnCylinder

   Source
     Based on the script 'geodesic.m' by Lei Wang
     https://mathworks.com/matlabcentral/fileexchange/6522

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [geo, geoLength, conGeo, conGeoLength] = geodesicCylinder(pts, cyl, varargin)
0002 %GEODESICCYLINDER Computes the geodesic between two points on a cylinder.
0003 %
0004 %   [GEO, GEOLENGTH] = geodesicCylinder(PTS, CYL) computes the geodesic
0005 %   between the two points PTS projected onto the infinite cylinder CYL.
0006 %   PTS is a 2-by-3 array, and CYL is a 1-by-7 array. Result is the
0007 %   polyline GEO (500-by-3 array) [500 = default] containing the
0008 %   coordinates of the geodesic between two projected points. GEOLENGTH
0009 %   contains the analytical length of the geodesic.
0010 %
0011 %   [~, ~, CONGEO, CONGEOLENGTH] = geodesicCylinder(PTS, CYL) provides the
0012 %   conjugate geodesic and its analytical length.
0013 %
0014 %   ... = geodesicCylinder(PTS, CYL, 'n', N) defines the number of points
0015 %   representing the geodesic and conjugate geodesic.
0016 %
0017 %   Example
0018 %       demoGeodesicCylinder
0019 %
0020 %   See also
0021 %     drawCylinder, projPointOnCylinder
0022 %
0023 %   Source
0024 %     Based on the script 'geodesic.m' by Lei Wang
0025 %     https://mathworks.com/matlabcentral/fileexchange/6522
0026 %
0027 
0028 % ------
0029 % Author: oqilipo
0030 % E-mail: N/A
0031 % Created: 2021-04-17, using MATLAB R2022b
0032 % Copyright 2021-2024
0033 
0034 parser = inputParser;
0035 addRequired(parser, 'pts', @(x) validateattributes(x, {'numeric'},...
0036     {'size',[2 3],'real','finite','nonnan'}));
0037 addRequired(parser, 'cyl', @(x) validateattributes(x, {'numeric'},...
0038     {'size',[1 7],'real','finite','nonnan'}));
0039 addParameter(parser,'n',500, @(x) validateattributes(x, {'numeric'},...
0040     {'scalar','>', 2,'<=', 1e5}));
0041 parse(parser,pts,cyl,varargin{:});
0042 pts = parser.Results.pts;
0043 cyl = parser.Results.cyl;
0044 n = parser.Results.n;
0045 
0046 % Radius of the cylinder
0047 cylRadius = cyl(7);
0048 
0049 % Project points onto the open (infinite) cylinder
0050 ptProj(1,:) = projPointOnCylinder(pts(1,:), cyl, 'open');
0051 ptProj(2,:) = projPointOnCylinder(pts(2,:), cyl, 'open');
0052 
0053 % Create a transformation for the points into the local cylinder coordinate
0054 % system. Align the cylinder axis with the z axis and translate the
0055 % starting point of the cylinder to the origin.
0056 TFM = createRotationVector3d(cyl(4:6)-cyl(1:3), [0 0 1])*createTranslation3d(-cyl(1:3));
0057 % Transform the points.
0058 ptTfm = transformPoint3d(ptProj, TFM);
0059 % Convert the transformed points to cylindrical coordinates.
0060 [ptsTheta, ptsRadius, ptsHeight] = cart2cyl(ptTfm);
0061 assert(ismembertol(ptsRadius(1),ptsRadius(2)))
0062 assert(ismembertol(ptsRadius(1),cylRadius))
0063 
0064 % Copy thetas for the conjugate geodesic
0065 ptsTheta(:,:,2) = ptsTheta;
0066 ptsTheta(1,1,2) = ptsTheta(1,1,2) + 2*pi;
0067 
0068 geoCyl = nan(n,3,size(ptsTheta,3));
0069 arcLength = nan(1,size(ptsTheta,3));
0070 for t = 1:size(ptsTheta,3)
0071     [geoCyl(:,:,t), arcLength(t)] = geoCurve(ptsTheta(:,:,t), cylRadius, ptsHeight, n);
0072 end
0073 
0074 % Select the shortest geodesic
0075 if arcLength(1) <= arcLength(2)
0076     % Transform the geodesics back to the global coordinate system
0077     geo = transformPoint3d(geoCyl(:,:,1), inv(TFM));
0078     conGeo = transformPoint3d(geoCyl(:,:,2), inv(TFM));
0079     geoLength = arcLength(1);
0080     conGeoLength = arcLength(2);
0081 else
0082     % Transform the geodesics back to the global coordinate system
0083     geo = transformPoint3d(geoCyl(:,:,2), inv(TFM));
0084     conGeo = transformPoint3d(geoCyl(:,:,1), inv(TFM));
0085     geoLength = arcLength(2);
0086     conGeoLength = arcLength(1);
0087 end
0088 
0089 end
0090 
0091 function [geo, arcLength] = geoCurve(theta, r, z, n)
0092 % Parametric expression of the geodesic curve
0093 u = linspace(theta(1),theta(2),n)';
0094 geo(:,1) = r*cos(u);
0095 geo(:,2) = r*sin(u);
0096 geo(:,3) = (z(2)-z(1))/(theta(2)-theta(1))*u + (z(1)*theta(2)-z(2)*theta(1))/(theta(2)-theta(1));
0097 if all(isnan(geo(:,3)))
0098     geo(:,3) = linspace(z(1),z(2),n)';
0099 end
0100 arcLength = sqrt(r^2*(theta(2)-theta(1))^2+(z(2)-z(1))^2);
0101 end

Generated on Thu 21-Nov-2024 11:30:22 by m2html © 2003-2022