1## Copyright (C) 2021 David Legland
2## All rights reserved.
3##
4## Redistribution and use in source and binary forms, with or without
5## modification, are permitted provided that the following conditions are met:
6##
7##     1 Redistributions of source code must retain the above copyright notice,
8##       this list of conditions and the following disclaimer.
9##     2 Redistributions in binary form must reproduce the above copyright
10##       notice, this list of conditions and the following disclaimer in the
11##       documentation and/or other materials provided with the distribution.
12##
13## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS''
14## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
17## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23##
24## The views and conclusions contained in the software and documentation are
25## those of the authors and should not be interpreted as representing official
26## policies, either expressed or implied, of the copyright holders.
27
28function varargout = drawGrid3d(varargin)
29%DRAWGRID3D Draw a 3D grid on the current axis.
30%
31%   drawGrid3d
32%   draws a 3D square grid, with origin (0,0,0) and spacing 1 in each
33%   direction, with bounds corresponding to the bounds of current axis.
34%
35%   drawGrid3d(SPACING)
36%   where spacing is either a scalar or a [1x3] matrix, specifies the size
37%   of the unit cell.
38%
39%   drawGrid3d(ORIGIN, SPACING)
40%   Also specify origin of grid. ORIGIN is a [1x3] array.
41%
42%   drawGrid3d(..., EDGE)
43%   specifies whether function should draw edges touching edges of axis.
44%   EDGE is a characheter string, which can be :
45%   - 'OPEN' : each line start from one face of window to the opposite
46%   face. This results in a 'spiky' grid.
47%   - 'CLOSED' (default value) : each line stops at the last visible point
48%   of the grid for this line. The result looks like a box (no free spikes
49%   around the grid).
50%
51%   H = drawGrid3d(...);
52%   return a vector of handles for each LINE object which was crated.
53%
54
55%   ------
56%   Author: David Legland
57%   e-mail: david.legland@grignon.inra.fr
58%   Created: 2005-11-17
59%   Copyright 2005 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas).
60
61%% initialize variables -----
62
63% default values
64closed = true;
65origin = [0 0 0];
66spacing = [1 1 1];
67
68% check if grid is open or not
69str = '';
70if ~isempty(varargin)
71    str = varargin{end};
72end
73if ischar(str)
74    if strncmpi(str, 'open', 4)
75        closed = false;
76    end
77    varargin = varargin(1:end-1);
78end
79
80% check origin and grid spacing
81if length(varargin)==1
82    spacing = varargin{1};
83elseif length(varargin)==2
84    origin = varargin{1};
85    spacing = varargin{2};
86end
87
88%% Compute internam data -----
89
90% get axis limits
91ax = axis;
92x0 = ax(1); x1 = ax(2);
93y0 = ax(3); y1 = ax(4);
94z0 = ax(5); z1 = ax(6);
95
96% get first and last coordinates of the grid in each direction
97dx = spacing(1); dy = spacing(2); dz = spacing(3);
98xe = x0 + mod(origin(1) - x0, dx);
99xf = x1 - mod(x1 - origin(1), dx);
100ye = y0 + mod(origin(2) - y0, dy);
101yf = y1 - mod(y1 - origin(2), dy);
102ze = z0 + mod(origin(1) - z0, dz);
103zf = z1 - mod(z1 - origin(1), dz);
104
105% update first and last coordinate if grid is 'closed'
106if closed
107    x0 = xe; x1 = xf;
108    y0 = ye; y1 = yf;
109    z0 = ze; z1 = zf;
110end
111
112
113%% Draw the grid -----
114
115h = [];
116%TODO: rewrite code, avoiding loops
117
118% draw lines parallel to x axis
119for y = ye:dy:yf
120    for z = ze:dz:zf
121        h = [h; drawEdge3d([x0 y z x1 y z])]; %#ok<AGROW>
122    end
123end
124
125% draw lines parallel to y axis
126for x = xe:dx:xf
127    for z = ze:dz:zf
128        h = [h; drawEdge3d([x y0 z x y1 z])]; %#ok<AGROW>
129    end
130end
131
132% draw lines parallel to z axis
133for x = xe:dx:xf
134    for y = ye:dy:yf
135        h = [h; drawEdge3d([x y z0 x y z1])]; %#ok<AGROW>
136    end
137end
138
139
140%% Check output arguments -----
141
142if nargout>0
143    varargout{1} = h;
144end
145