Thư viện tri thức trực tuyến
Kho tài liệu với 50,000+ tài liệu học thuật
© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

CRC.Press A Guide to MATLAB Object Oriented Programming May.2007 Episode 1 Part 5 pdf
Nội dung xem thử
Mô tả chi tiết
54 A Guide to MATLAB Object-Oriented Programming
Modify the constructor by replacing all occurrences of mColorRgb with mColorHsv. Also
in the constructor, set the value for mColorHsv to rgb2hsv([0 0 1])’. The modified
constructor code is shown in Code Listing 15. Line 5 replaces mColorRgb with mColorHsv
and assigns blue as the default color. Line 8 also represents an addition over the earlier constructor.
Here we increase the superiority of cShape with respect to double because the interface
definition overloads the associative operator, mtimes.
The change to subsref is almost as simple and is completely isolated inside the ColorRgb
case. The modified ColorRgb case code is shown in Code Listing 16. Line 2 uses hsv2rgb
Code Listing 14, Public Variable Names in subref’s Dot-Reference Case
1 switch index(1).type
2 case '.'
3 switch index(1).subs
4 case 'Size'
5 varargout = {this.mSize};
6 case 'ColorRgb'
7 varargout = {this.mColorRgb};
8 otherwise
9 error(['??? Reference to non-existent field ' ...
10 index(1).subs '.']);
11 end
12 case '()'
13 % code to deal with cell array of index values
14 case '{}'
15 % code to deal with cell array of index values
16 otherwise
17 error(['??? Unexpected index.type of ' index(1).type]);
18 end
Code Listing 15, Modified Constructor Using mColorHsv Instead of mColorRgb
1 function this = cShape
2 this = struct( ...
3 'mSize', ones(2,1), ... % scaled [width height]’ of
bounding box
4 'mScale', ones(2,1), ... % [width height]’ scale factor
5 'mColorHsv', rgb2hsv([0 0 1])' ... % [H S V]’ of border,
default, blue
6 );
7 this = class(this, 'cShape');
8 superiorto('double')
Code Listing 16, Converting HSV Values to RGB Values
1 case 'ColorRgb'
2 rgb = hsv2rgb([this.mColorHsv]')';
3 varargout = mat2cell(rgb, 3, ones(1, size(rgb,2)));
C911X_C004.fm Page 54 Friday, March 30, 2007 11:23 AM
Changing the Rules … in Appearance Only 55
to convert private HSV values into public RGB values. The function will convert multiple HSV
vectors by packaging each HSV 3-tuple as a row of the input matrix. Similarly, each output RGB
3-tuple is returned as a row of the output matrix. In Line 2, [this.mColorHsv] supports a
nonscalar this by concatenating HSV columns. The concatenated columns are transposed before
they are passed into hsv2rgb, and the result is transposed so that each column contains an RGB
3-tuple. Line 3 converts the combined RGB array into a cell array of 3 × 1 RGB vectors and assigns
the cell array into varargout. Now, just like all the other cases, a nonscalar this returns multiple
arguments.
To a client familiar with dot-reference and structures, dot-reference and objects looks identical.
While the outward appearance is the same, inside the private implementation we can do whatever
we want. As with Size, the public name might refer to a private member variable, but the public
name can easily refer to a data conversion or a combination of several private variables. The public
names are included in the interface specification and the client doesn’t need to know what is really
happening behind the interface.
4.1.2.6 subsref Dot-Reference, Attempt 4: Multiple Indexing Levels
If the length of the substruct index array is greater than one, index includes reference
operators beyond the initial dot-reference operator. The length is unlimited; however, certain
combinations of nested reference operators are illegal. For example, when the length of the indexed
variable is greater than one, a second dot-reference operator generates an error. That is, when a is
nonscalar, a.level_1 is allowed but a.level_1.level_2 is not. MATLAB already lives by
these rules so it would be very convenient to coerce MATLAB to handle all of these details.
Code Listing 17 shows an improved version of the dot-reference case that can handle multiple
indexing levels. This version is not as compact as before primarily due to the addition of errorchecking code. Each public name case adds a check for an empty object… If the object is empty
the function’s return value is also empty. Lines 4–5 and 10–11 are examples. Exactly how an empty
object can occur is discussed in the array-reference-operator section. When an empty object does
appear, the correct return is an empty cell. The nonempty else code is identical to the code already
discussed. Lines 20–35 implement multiple-level indexing.
Code Listing 17, An Improved Version of the subsref Dot-Reference Case
1 case '.'
2 switch index(1).subs
3 case 'Size'
4 if isempty(this)
5 varargout = {};
6 else
7 varargout = {this.mSize};
8 end
9 case 'ColorRgb'
10 if isempty(this)
11 varargout = {};
12 else
13 rgb = hsv2rgb([this.mColorHsv]')';
14 varargout = mat2cell(rgb, 3, ones(1, size(rgb,2)));
15 end
16 otherwise
C911X_C004.fm Page 55 Friday, March 30, 2007 11:23 AM