Home > matGeom > geom3d > clipRay3d.m

clipRay3d

PURPOSE ^

CLIPRAY3D Clip a 3D ray with a box and return a 3D edge.

SYNOPSIS ^

function edge = clipRay3d(ray, box)

DESCRIPTION ^

CLIPRAY3D Clip a 3D ray with a box and return a 3D edge.

   EDGE = clipRay3d(RAY, BOX)
   Clips the ray RAY with the bounds given in BOX, and returns the
   corresponding edge. 
   RAY is given as origin + direction vector: [X0 Y0 Z0  DX DY DZ]
   BOX is given as  [XMIN XMAX  YMIN YMAX  ZMIN ZMAX].
   The result EDGE is given as [X1 Y1 Z1  X2 Y2 Z2].

   Example
     % generate 50 random 3D rays
     origin = [29 28 27];
     v = rand(50, 3);
     v = v - centroid(v);
     ray = [repmat(origin, size(v,1),1) v];
     % clip the rays with a 3D box
     box = [10 40 10 40 10 40];
     edges = clipRay3d(ray, box);
     % draw the resulting 3D edges
     figure; axis equal; axis([0 50 0 50 0 50]); hold on; view(3);
     drawBox3d(box);
     drawEdge3d(edges, 'g');

   See also
     clipLine3d

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function edge = clipRay3d(ray, box)
0002 %CLIPRAY3D Clip a 3D ray with a box and return a 3D edge.
0003 %
0004 %   EDGE = clipRay3d(RAY, BOX)
0005 %   Clips the ray RAY with the bounds given in BOX, and returns the
0006 %   corresponding edge.
0007 %   RAY is given as origin + direction vector: [X0 Y0 Z0  DX DY DZ]
0008 %   BOX is given as  [XMIN XMAX  YMIN YMAX  ZMIN ZMAX].
0009 %   The result EDGE is given as [X1 Y1 Z1  X2 Y2 Z2].
0010 %
0011 %   Example
0012 %     % generate 50 random 3D rays
0013 %     origin = [29 28 27];
0014 %     v = rand(50, 3);
0015 %     v = v - centroid(v);
0016 %     ray = [repmat(origin, size(v,1),1) v];
0017 %     % clip the rays with a 3D box
0018 %     box = [10 40 10 40 10 40];
0019 %     edges = clipRay3d(ray, box);
0020 %     % draw the resulting 3D edges
0021 %     figure; axis equal; axis([0 50 0 50 0 50]); hold on; view(3);
0022 %     drawBox3d(box);
0023 %     drawEdge3d(edges, 'g');
0024 %
0025 %   See also
0026 %     clipLine3d
0027 
0028 % ------
0029 % Author: David Legland
0030 % E-mail: david.legland@inrae.fr
0031 % Created: 2020-05-25, using Matlab 9.8.0.1323502 (R2020a)
0032 % Copyright 2020-2024 INRAE - BIA Research Unit - BIBS Platform (Nantes)
0033 
0034 % get box limits
0035 xmin = box(1); xmax = box(2);
0036 ymin = box(3); ymax = box(4);
0037 zmin = box(5); zmax = box(6);
0038 
0039 % extreme corners of the box
0040 p000 = [xmin ymin zmin];
0041 p111 = [xmax ymax zmax];
0042 
0043 % main vectors
0044 ex   = [1 0 0];
0045 ey   = [0 1 0];
0046 ez   = [0 0 1];
0047 
0048 % box faces parallel to Oxy
0049 planeZ0 = [p000 ex ey];
0050 planeZ1 = [p111 ex ey];
0051 
0052 % box faces parallel to Oxz
0053 planeY0 = [p000 ex ez];
0054 planeY1 = [p111 ex ez];
0055 
0056 % box faces parallel to Oyz
0057 planeX0 = [p000 ey ez];
0058 planeX1 = [p111 ey ez];
0059 
0060 % number of rays
0061 nRays = size(ray, 1);
0062 
0063 % allocate memory for result
0064 edge = NaN * ones(nRays, 6);
0065 
0066 % iterate over rays to clip
0067 for i = 1:nRays
0068     % compute intersection point of supporting line with each clipping plane
0069     ipZ0 = intersectLinePlane(ray(i,:), planeZ0);
0070     ipZ1 = intersectLinePlane(ray(i,:), planeZ1);
0071     ipY0 = intersectLinePlane(ray(i,:), planeY0);
0072     ipY1 = intersectLinePlane(ray(i,:), planeY1);
0073     ipX1 = intersectLinePlane(ray(i,:), planeX1);
0074     ipX0 = intersectLinePlane(ray(i,:), planeX0);
0075 
0076     % concatenate resulting points
0077     points  = [ipX0;ipX1;ipY0;ipY1;ipZ0;ipZ1];
0078 
0079     % compute position of each point on the ray
0080     pos     = line3dPosition(points, ray(i,:));
0081 
0082     % keep only defined points
0083     ind     = find(~isnan(pos));
0084     pos     = pos(ind);
0085     points  = points(ind,:);
0086 
0087     if isempty(pos)
0088         continue;
0089     end
0090     
0091     % sort points with respect to their position
0092     [pos, ind] = sort(pos);
0093     points = points(ind, :);
0094 
0095     % keep median points wrt to position. These points define the limit of
0096     % the clipped edge.
0097     nv  = length(ind)/2;
0098     pos = pos([nv, nv+1]);
0099     points = points([nv nv+1], :);
0100     
0101     % case of second edge extremity before ray origin
0102     if pos(2) < 0
0103         continue;
0104     end
0105 
0106     % case of first edge extremity before ray origin
0107     if pos(1) < 0
0108         points(1,1:3) = ray(i,1:3);
0109     end
0110     
0111     % create resulting edge.
0112     edge(i,:)   = [points(1, :) points(2, :)];
0113 end
0114 
0115 % check that middle point of the edge is contained in the box
0116 midX = mean(edge(:, [1 4]), 2);
0117 xOk  = xmin <= midX & midX <= xmax;
0118 midY = mean(edge(:, [2 5]), 2);
0119 yOk  = ymin <= midY & midY <= ymax;
0120 midZ = mean(edge(:, [3 6]), 2);
0121 zOk  = zmin <= midZ & midZ <= zmax;
0122 
0123 % if one of the bounding condition is not met, set edge to NaN
0124 edge (~(xOk & yOk & zOk), :) = NaN;

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