function XYZ = MunsellSpecificationsInMunsellTree(MunsellSpecStrings);
% Purpose		Express a Munsell specification in Cartesian coordinates in the Munsell tree. 
%
% Description	The Munsell system specifies a local colour by giving its hue (H), value (V),
%				and chroma(C) in the form H V/C.  The value is a number between 0 and 10.  
%				The chroma is a positive number, whose bound depends on hue and value,
%				as given by the MacAdam limits.  The hue specification consists of a letter
%				designator (B, BG, G, GY, Y, YR, R, RP, P, PB), and a number designator 
%				which is greater than or equal to 0, and less than or equal to 10.  If chroma is
%				0, then the local colour has no hue, and is specified as NV, where N is the
%				string "N," and V is the value.  For example, 5.0R 9.0/2.0 is a light pastel
%				red, while N3 is a dark grey.
%
%				The Munsell system can be visualized geometrically as an irregular "tree,"
%				which is a subset of cylindrical three-dimensional space.  The vertical 
%				axis in this space is given by Munsell value.  The horizontal plane of the
%				space is in polar coordinates.  The distance r from the origin corresponds
%				to Munsell chroma.  The angle theta corresponds to hue.  Theta is chosen
%				to be 0 along the x-axis, which has Munsell hue 0R, and to increase 
%				counterclockwise, going evenly through YR, Y, etc. until reaching RP and
%				arriving back at R.  While r and theta are natural coordinates in some
%				circumstances, we will use standard Cartesian coordinates x and y, instead.
%
%				This routine takes as input a standard Munsell notation, such as 7Y 5/6, and
%				returns its Cartesian xyz coordinates, when that Munsell notation is placed
%				in the cylindrical Munsell tree.  The conversion details are straightforward.
%
%				MunsellSpecStrings		A list, using {}, of standard Munsell specifications,  
%								such as 5R 9/4.  Spaces are not required; 5R9/4 is also acceptable.
%								Rather than a list, this variable can also be a single string,
%								consisting of one Munsell specification
%				
% Author		Paul Centore (May 21, 2017)
%
% Copyright 2017 Paul Centore
%
%    This file is part of MunsellAndKubelkaMunkToolbox.
%
%    MunsellAndKubelkaMunkToolbox is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    MunsellAndKubelkaMunkToolbox is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with MunsellAndKubelkaMunkToolbox.  If not, see <http://www.gnu.org/licenses/>.

% Initialize the return variable.  
XYZ = []  ;

% Check that there are some inputs; otherwise, return with a message
if isempty(MunsellSpecStrings)
	disp(['Exiting routine MunsellSpecificationsInMunsellTree: no inputs'])	; 
	return	;
end

% Make an internal copy, as a list indexed by {}, of the input Munsell specifications
if ischar(MunsellSpecStrings)	% Input variable is a single string, with one Munsell specification
	InternalMunsellSpecStrings{1} = MunsellSpecStrings	;	% Convert string to one-item list
else	                        % Input variable is a list of Munsell specification strings
	InternalMunsellSpecStrings = MunsellSpecStrings		;
end

% Find the number of input Munsell specifications
NumberOfMunsellSpecs = length(InternalMunsellSpecStrings)	;

% Find the hues, values, and chromas of the input Munsell specifications.  Express the hue
% in ASTM format, as a number between 0 and 100, where 0 corresponds to 0R (and so does
% 100), and the 100 ASTM numbers go evenly through the Munsell hues in the same direction
% as the Munsell tree; ASTM 10, for instance, corresponds to 0YR, ASTM 20 corresponds to
% 0Y, and so on.
ASTMhues                        = ASTMHuesOfMunsellSpecifications(InternalMunsellSpecStrings)			;
[MunsellValues, MunsellChromas] = ValuesAndChromasOfMunsellSpecifications(InternalMunsellSpecStrings)	;

% Find the Munsell tree coordinates of each input Munsell specification
for ctr = 1:NumberOfMunsellSpecs
	ASTMhue = ASTMhues(ctr)			;
	Value   = MunsellValues(ctr)	;
	Chroma  = MunsellChromas(ctr)	;
	
	% When Munsell chroma is 0, the specification is on the vertical axis through the origin
	if Chroma == 0
		XYZ = [XYZ; 0 0 Value]	;
	else	% Otherwise, use the ordinary conversion from cylindrical to Cartesian coordinates
		ASTMhueInDegrees = ASTMhue * 3.6	;
		X = Chroma * cosd(ASTMhueInDegrees)	;
		Y = Chroma * sind(ASTMhueInDegrees)	;
		XYZ = [XYZ; X Y Value]				;
	end
end