Skip to content

Commit bd27715

Browse files
author
Rik
committed
fill.m: Overhaul input validation to be Matlab-compatible (bug #67535)
* NEWS.11.md: Announce changes in Matlab compatibility section. * fill.m: Document that specifying one color per polygon can be done with any vector (not just row vector). Use numel() in preference to length(). Add FIXME note about missing validation that inputs X, Y, and C are 2-D. Replace input logic for vector/matrix combinations with longer code that attempts to match the length of the vector to one of the dimensions of the matrix data. Replace use of isequal() (slow) with faster tests that don't require function call. Validate that RGB triplet data is in the range [0,1].
1 parent 31df213 commit bd27715

File tree

2 files changed

+53
-23
lines changed

2 files changed

+53
-23
lines changed

etc/NEWS.11.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ Summary of important user-visible changes for version 11 (yyyy-mm-dd):
7979
invocations for each cell element. In earlier versions, the elements were
8080
converted to a compatible type if possible.
8181

82+
- The function `fill` now handles all input combination of vector and matrix
83+
vertex data and color data in a Matlab-compatible way.
84+
8285
### Alphabetical list of new functions added in Octave 11
8386

8487
* `corrcov`

scripts/plot/draw/fill.m

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@
4040
## is a single color specification such as a @code{plot} format or an
4141
## RGB-triple. In this case the polygon(s) will have one unique color. If
4242
## @var{c} is a vector or matrix then the color data is first scaled using
43-
## @code{clim} and then indexed into the current colormap. A row vector will
44-
## color each polygon (a column from matrices @var{x} and @var{y}) with a
45-
## single computed color. A matrix @var{c} of the same size as @var{x} and
46-
## @var{y} will compute the color of each vertex and then interpolate the face
47-
## color between the vertices.
43+
## @code{clim} and then indexed into the current colormap. A vector will color
44+
## each polygon (a column from matrices @var{x} and @var{y}) with a single
45+
## computed color. A matrix @var{c} of the same size as @var{x} and @var{y}
46+
## will compute the color of each vertex and then interpolate the face color
47+
## between the vertices.
4848
##
4949
## Multiple property/value pairs for the underlying patch object may be
5050
## specified, but they must appear in pairs. The full list of properties is
@@ -53,8 +53,8 @@
5353
## If the first argument @var{hax} is an axes handle, then plot into this axes,
5454
## rather than the current axes returned by @code{gca}.
5555
##
56-
## The optional return value @var{h} is a vector of graphics handles to
57-
## the created patch objects.
56+
## The optional return value @var{h} is a vector of graphics handles to the
57+
## created patch objects.
5858
##
5959
## Example: red square
6060
##
@@ -102,20 +102,12 @@
102102
unwind_protect
103103
set (hax, "nextplot", "add");
104104

105-
for i = 1 : length (iargs)
105+
for i = 1 : numel (iargs)
106106
x = varargin{iargs(i)};
107107
y = varargin{iargs(i) + 1};
108108
cdata = varargin{iargs(i) + 2};
109109

110-
if (! size_equal (x, y))
111-
if (iscolumn (y) && rows (y) == rows (x))
112-
y = repmat (y, [1, columns(x)]);
113-
elseif (iscolumn (x) && rows (x) == rows (y))
114-
x = repmat (x, [1, columns(y)]);
115-
else
116-
error ("fill: X and Y must have same number of rows");
117-
endif
118-
endif
110+
## FIXME: Probably should validate that x, y, cdata are 2-D.
119111

120112
if (isrow (x))
121113
x = x(:);
@@ -124,17 +116,52 @@
124116
y = y(:);
125117
endif
126118

127-
if (ischar (cdata) || isequal (size (cdata), [1, 3]))
119+
if (! size_equal (x, y))
120+
if (iscolumn (x))
121+
rx = rows (x);
122+
[ry, cy] = size (y);
123+
if (rx == ry)
124+
x = repmat (x, [1, cy]);
125+
elseif (rx == cy)
126+
y = y.';
127+
x = repmat (x, [1, ry]);
128+
else
129+
error ("fill: vector X and matrix Y must have a length which matches along one dimension");
130+
endif
131+
elseif (iscolumn (y))
132+
ry = rows (y);
133+
[rx, cx] = size (x);
134+
if (ry == rx)
135+
y = repmat (y, [1, cx]);
136+
elseif (ry == cx)
137+
x = x.';
138+
y = repmat (y, [1, rx]);
139+
else
140+
error ("fill: matrix X and vector Y must have a length which matches along one dimension");
141+
endif
142+
else
143+
error ("fill: matrices X and Y must be the same size");
144+
endif
145+
endif
146+
147+
## Test for color specification as text ('r') or RGB triple.
148+
if (ischar (cdata) ||
149+
(all (size (cdata) == [1, 3]) && all (cdata >= 0 & cdata <= 1)))
128150
one_color = true;
129151
else
130152
one_color = false;
131153
endif
132154

133-
## For Matlab compatibility, replicate cdata to match size of data
134-
if (! one_color && iscolumn (cdata))
135-
sz = size (x);
136-
if (all (sz > 1))
137-
cdata = repmat (cdata, [1, sz(2)]);
155+
## Manage cdata to ensure for loop below works
156+
if (! one_color && isvector (cdata))
157+
if (numel (cdata) == columns (x))
158+
## One color per polygon
159+
cdata = cdata(:).';
160+
elseif (numel (cdata) == rows (x))
161+
## Vertex colors. Replicate cdata to match size of data.
162+
cdata = repmat (cdata(:), [1, columns(x)]);
163+
else
164+
error ("fill: invalid format for color data C");
138165
endif
139166
endif
140167

0 commit comments

Comments
 (0)