Home > matGeom > geom3d > intersectLineCylinder.m

intersectLineCylinder

PURPOSE ^

INTERSECTLINECYLINDER Compute intersection points between a line and a cylinder.

SYNOPSIS ^

function points = intersectLineCylinder(line, cylinder, varargin)

DESCRIPTION ^

INTERSECTLINECYLINDER Compute intersection points between a line and a cylinder.

   POINTS = intersectLineCylinder(LINE, CYLINDER)
   Returns intersection points between a line and a cylinder.

   Input parameters:
   LINE     = [x0 y0 z0  dx dy dz]
   CYLINDER = [x1 y1 z1 x2 y2 z2 R]

   Output:
   POINTS   = [x1 y1 z1 ; x2 y2 z2]

   POINTS = intersectLineCylinder(LINE, CYLINDER, 'checkBounds', B)
   Where B is a boolean (TRUE by default), check if the points are within
   the bounds defined by the two extreme points. If B is false, the
   cylinder is considered to be infinite.

   Example
     % Compute intersection between simple vertical cylinder and line
     line = [60 60 60 1 2 3];
     cylinder = [20 50 50 80 50 50 30];
     points = intersectLineCylinder(line, cylinder);
     % Display the different shapes
     figure;
     drawCylinder(cylinder);
     hold on; light;
     axis([0 100 0 100 0 100]);
     drawLine3d(line);
     drawPoint3d(points, 'ko');
     

     % Compute intersections when one of the points is outside the
     % cylinder
     line = [80 60 60 1 2 3];
     cylinder = [20 50 50 80 50 50 30];
     intersectLineCylinder(line, cylinder)
     ans = 
           67.8690   35.7380   23.6069

   
   See also
   lines3d, intersectLinePlane, drawCylinder, cylinderSurfaceArea

   References
   See the link:
   http://www.gamedev.net/community/forums/topic.asp?topic_id=467789

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function points = intersectLineCylinder(line, cylinder, varargin)
0002 %INTERSECTLINECYLINDER Compute intersection points between a line and a cylinder.
0003 %
0004 %   POINTS = intersectLineCylinder(LINE, CYLINDER)
0005 %   Returns intersection points between a line and a cylinder.
0006 %
0007 %   Input parameters:
0008 %   LINE     = [x0 y0 z0  dx dy dz]
0009 %   CYLINDER = [x1 y1 z1 x2 y2 z2 R]
0010 %
0011 %   Output:
0012 %   POINTS   = [x1 y1 z1 ; x2 y2 z2]
0013 %
0014 %   POINTS = intersectLineCylinder(LINE, CYLINDER, 'checkBounds', B)
0015 %   Where B is a boolean (TRUE by default), check if the points are within
0016 %   the bounds defined by the two extreme points. If B is false, the
0017 %   cylinder is considered to be infinite.
0018 %
0019 %   Example
0020 %     % Compute intersection between simple vertical cylinder and line
0021 %     line = [60 60 60 1 2 3];
0022 %     cylinder = [20 50 50 80 50 50 30];
0023 %     points = intersectLineCylinder(line, cylinder);
0024 %     % Display the different shapes
0025 %     figure;
0026 %     drawCylinder(cylinder);
0027 %     hold on; light;
0028 %     axis([0 100 0 100 0 100]);
0029 %     drawLine3d(line);
0030 %     drawPoint3d(points, 'ko');
0031 %
0032 %
0033 %     % Compute intersections when one of the points is outside the
0034 %     % cylinder
0035 %     line = [80 60 60 1 2 3];
0036 %     cylinder = [20 50 50 80 50 50 30];
0037 %     intersectLineCylinder(line, cylinder)
0038 %     ans =
0039 %           67.8690   35.7380   23.6069
0040 %
0041 %
0042 %   See also
0043 %   lines3d, intersectLinePlane, drawCylinder, cylinderSurfaceArea
0044 %
0045 %   References
0046 %   See the link:
0047 %   http://www.gamedev.net/community/forums/topic.asp?topic_id=467789
0048 %
0049 
0050 % ---
0051 % Author: David Legland, from a file written by Daniel Trauth (RWTH)
0052 % e-mail: david.legland@inra.fr
0053 % Created: 2007-01-27
0054 
0055 % HISTORY
0056 % 2010-10-21 change cylinder argument convention, add bounds check and doc
0057 % 2010-10-21 add check for points on cylinders, update doc
0058 
0059 
0060 %% Parse input arguments
0061 
0062 % default arguments
0063 checkBounds = true;
0064 % type of cylinder, one of {'closed', 'open', 'infinite'}
0065 type = 'closed';
0066 
0067 % parse inputs
0068 while length(varargin)>1
0069     var = varargin{1};
0070     if strcmpi(var, 'checkbounds')
0071         checkBounds = varargin{2};
0072     elseif strcmpi(var, 'type')
0073         type = varargin{2};
0074     else
0075         error(['Unkown argument: ' var]);
0076     end
0077     varargin(1:2) = [];
0078 end
0079 
0080 
0081 %% Parse cylinder parameters
0082 
0083 % Starting point of the line
0084 l0 = line(1:3);
0085 
0086 % Direction vector of the line
0087 dl = line(4:6);
0088 
0089 % position of cylinder extremities
0090 c1 = cylinder(1:3);
0091 c2 = cylinder(4:6);
0092 
0093 % Direction vector of the cylinder
0094 dc = c2 - c1;
0095 
0096 % Radius of the cylinder
0097 r = cylinder(7);
0098 
0099 
0100 %% Resolution of a quadratic equation to find the increment
0101 
0102 % normalisation coefficient corresponding to direction of vector
0103 coef = dc / dot(dc, dc);
0104 
0105 % Substitution of parameters
0106 e = dl - dot(dl,dc) * coef;
0107 f = (l0-c1) - dot(l0-c1, dc) * coef;
0108 
0109 % Coefficients of 2-nd order equation
0110 A = dot(e, e);
0111 B = 2 * dot(e,f);
0112 C = dot(f,f) - r^2;
0113 
0114 % compute discriminant
0115 delta = B^2 - 4*A*C;
0116 
0117 % check existence of solution(s)
0118 if delta < 0
0119     points = zeros(0, 3);
0120     return;
0121 end
0122 
0123 % extract roots
0124 pos1 = (-B + sqrt(delta)) / (2*A);
0125 pos2 = (-B - sqrt(delta)) / (2*A);
0126 posList = [pos1;pos2];
0127 
0128 
0129 %% Estimation of point positions
0130 
0131 % process the smallest position
0132 pos1 = min(posList);
0133 
0134 % Point on the line: l0 + x*dl = p
0135 point1 = l0 + pos1 * dl;
0136 
0137 % process the greatest position
0138 pos2 = max(posList);
0139 
0140 % Point on the line: l0 + x*dl = p
0141 point2 = l0 + pos2 * dl;
0142 
0143 % Format result
0144 points = [point1 ; point2];
0145 
0146 
0147 %% Check if points are located between bounds
0148 
0149 % if checkBounds option is not set, we can simply skip the rest
0150 if ~checkBounds || strncmpi(type, 'infinite', 1)
0151     return;
0152 end
0153 
0154 % compute cylinder axis
0155 axis = [c1 dc];
0156 
0157 % compute position on axis
0158 ts = linePosition3d(points, axis);
0159 
0160 % check bounds for open cylinder
0161 % (keep only intersection points whose projection is between the two
0162 % cylinder extremities)
0163 if strncmpi(type, 'open', 1)
0164     ind = ts>=0 & ts<=1;
0165     points = points(ind, :);
0166     return;
0167 end
0168 
0169 % which intersection fall before and after bounds
0170 ind1 = find(ts < 0);
0171 ind2 = find(ts > 1);
0172 
0173 % case of both intersection on the same side -> no intersection
0174 if length(ind1) == 2 || length(ind2) == 2
0175     points = zeros(0, 3);
0176     return;
0177 end
0178 
0179 % Process the remaining case of closed cylinder
0180 % -> compute eventual intersection(s) with end faces
0181 if ~isempty(ind1)
0182     plane = createPlane(c1, dc);
0183     points(ind1, :) = intersectLinePlane(line, plane);
0184 end
0185 if ~isempty(ind2)
0186     plane = createPlane(c2, dc);
0187     points(ind2, :) = intersectLinePlane(line, plane);
0188 end
0189 
0190

Generated on Wed 16-Feb-2022 15:10:47 by m2html © 2003-2019