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@inrae.fr
0053 % Created: 2007-01-27
0054 % Copyright 2007-2024
0055 
0056 %% Parse input arguments
0057 
0058 % default arguments
0059 checkBounds = true;
0060 % type of cylinder, one of {'closed', 'open', 'infinite'}
0061 type = 'closed';
0062 
0063 % parse inputs
0064 while length(varargin)>1
0065     var = varargin{1};
0066     if strcmpi(var, 'checkbounds')
0067         checkBounds = varargin{2};
0068     elseif strcmpi(var, 'type')
0069         type = varargin{2};
0070     else
0071         error(['Unkown argument: ' var]);
0072     end
0073     varargin(1:2) = [];
0074 end
0075 
0076 
0077 %% Parse cylinder parameters
0078 
0079 % Starting point of the line
0080 l0 = line(1:3);
0081 
0082 % Direction vector of the line
0083 dl = line(4:6);
0084 
0085 % position of cylinder extremities
0086 c1 = cylinder(1:3);
0087 c2 = cylinder(4:6);
0088 
0089 % Direction vector of the cylinder
0090 dc = c2 - c1;
0091 
0092 % Radius of the cylinder
0093 r = cylinder(7);
0094 
0095 
0096 %% Resolution of a quadratic equation to find the increment
0097 
0098 % normalisation coefficient corresponding to direction of vector
0099 coef = dc / dot(dc, dc);
0100 
0101 % Substitution of parameters
0102 e = dl - dot(dl,dc) * coef;
0103 f = (l0-c1) - dot(l0-c1, dc) * coef;
0104 
0105 % Coefficients of 2-nd order equation
0106 A = dot(e, e);
0107 B = 2 * dot(e,f);
0108 C = dot(f,f) - r^2;
0109 
0110 % compute discriminant
0111 delta = B^2 - 4*A*C;
0112 
0113 % check existence of solution(s)
0114 if delta < 0
0115     points = zeros(0, 3);
0116     return;
0117 end
0118 
0119 % extract roots
0120 pos1 = (-B + sqrt(delta)) / (2*A);
0121 pos2 = (-B - sqrt(delta)) / (2*A);
0122 posList = [pos1;pos2];
0123 
0124 
0125 %% Estimation of point positions
0126 
0127 % process the smallest position
0128 pos1 = min(posList);
0129 
0130 % Point on the line: l0 + x*dl = p
0131 point1 = l0 + pos1 * dl;
0132 
0133 % process the greatest position
0134 pos2 = max(posList);
0135 
0136 % Point on the line: l0 + x*dl = p
0137 point2 = l0 + pos2 * dl;
0138 
0139 % Format result
0140 points = [point1 ; point2];
0141 
0142 
0143 %% Check if points are located between bounds
0144 
0145 % if checkBounds option is not set, we can simply skip the rest
0146 if ~checkBounds || strncmpi(type, 'infinite', 1)
0147     return;
0148 end
0149 
0150 % compute cylinder axis
0151 axis = [c1 dc];
0152 
0153 % compute position on axis
0154 ts = line3dPosition(points, axis);
0155 
0156 % check bounds for open cylinder
0157 % (keep only intersection points whose projection is between the two
0158 % cylinder extremities)
0159 if strncmpi(type, 'open', 1)
0160     ind = ts>=0 & ts<=1;
0161     points = points(ind, :);
0162     return;
0163 end
0164 
0165 % which intersection fall before and after bounds
0166 ind1 = find(ts < 0);
0167 ind2 = find(ts > 1);
0168 
0169 % case of both intersection on the same side -> no intersection
0170 if length(ind1) == 2 || length(ind2) == 2
0171     points = zeros(0, 3);
0172     return;
0173 end
0174 
0175 % Process the remaining case of closed cylinder
0176 % -> compute eventual intersection(s) with end faces
0177 if ~isempty(ind1)
0178     plane = createPlane(c1, dc);
0179     points(ind1, :) = intersectLinePlane(line, plane);
0180 end
0181 if ~isempty(ind2)
0182     plane = createPlane(c2, dc);
0183     points(ind2, :) = intersectLinePlane(line, plane);
0184 end
0185 
0186

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