Home > matGeom > geom3d > clipRay3d.m

clipRay3d

PURPOSE ^

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

SYNOPSIS ^

function edge = clipRay3d(ray, box)

DESCRIPTION ^

 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 % 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 % INRAE - BIA Research Unit - BIBS Platform (Nantes)
0032 % Created: 2020-05-25,    using Matlab 9.8.0.1323502 (R2020a)
0033 % Copyright 2020 INRAE.
0034 
0035 % get box limits
0036 xmin = box(1); xmax = box(2);
0037 ymin = box(3); ymax = box(4);
0038 zmin = box(5); zmax = box(6);
0039 
0040 % extreme corners of the box
0041 p000 = [xmin ymin zmin];
0042 p111 = [xmax ymax zmax];
0043 
0044 % main vectors
0045 ex   = [1 0 0];
0046 ey   = [0 1 0];
0047 ez   = [0 0 1];
0048 
0049 % box faces parallel to Oxy
0050 planeZ0 = [p000 ex ey];
0051 planeZ1 = [p111 ex ey];
0052 
0053 % box faces parallel to Oxz
0054 planeY0 = [p000 ex ez];
0055 planeY1 = [p111 ex ez];
0056 
0057 % box faces parallel to Oyz
0058 planeX0 = [p000 ey ez];
0059 planeX1 = [p111 ey ez];
0060 
0061 % number of rays
0062 nRays = size(ray, 1);
0063 
0064 % allocate memory for result
0065 edge = NaN * ones(nRays, 6);
0066 
0067 % iterate over rays to clip
0068 for i = 1:nRays
0069     % compute intersection point of supporting line with each clipping plane
0070     ipZ0 = intersectLinePlane(ray(i,:), planeZ0);
0071     ipZ1 = intersectLinePlane(ray(i,:), planeZ1);
0072     ipY0 = intersectLinePlane(ray(i,:), planeY0);
0073     ipY1 = intersectLinePlane(ray(i,:), planeY1);
0074     ipX1 = intersectLinePlane(ray(i,:), planeX1);
0075     ipX0 = intersectLinePlane(ray(i,:), planeX0);
0076 
0077     % concatenate resulting points
0078     points  = [ipX0;ipX1;ipY0;ipY1;ipZ0;ipZ1];
0079 
0080     % compute position of each point on the ray
0081     pos     = linePosition3d(points, ray(i,:));
0082 
0083     % keep only defined points
0084     ind     = find(~isnan(pos));
0085     pos     = pos(ind);
0086     points  = points(ind,:);
0087 
0088     if isempty(pos)
0089         continue;
0090     end
0091     
0092     % sort points with respect to their position
0093     [pos, ind] = sort(pos);
0094     points = points(ind, :);
0095 
0096     % keep median points wrt to position. These points define the limit of
0097     % the clipped edge.
0098     nv  = length(ind)/2;
0099     pos = pos([nv, nv+1]);
0100     points = points([nv nv+1], :);
0101     
0102     % case of second edge extremity before ray origin
0103     if pos(2) < 0
0104         continue;
0105     end
0106 
0107     % case of first edge extremity before ray origin
0108     if pos(1) < 0
0109         points(1,1:3) = ray(i,1:3);
0110     end
0111     
0112     % create resulting edge.
0113     edge(i,:)   = [points(1, :) points(2, :)];
0114 end
0115 
0116 % check that middle point of the edge is contained in the box
0117 midX = mean(edge(:, [1 4]), 2);
0118 xOk  = xmin <= midX & midX <= xmax;
0119 midY = mean(edge(:, [2 5]), 2);
0120 yOk  = ymin <= midY & midY <= ymax;
0121 midZ = mean(edge(:, [3 6]), 2);
0122 zOk  = zmin <= midZ & midZ <= zmax;
0123 
0124 % if one of the bounding condition is not met, set edge to NaN
0125 edge (~(xOk & yOk & zOk), :) = NaN;

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