Search code examples
arraysmatlabvectorcolorsenumeration

Non-scalar enumeration in Matlab


Is it possible to have enumeration member that are non-scalar?

For example, how can I enumerate colors such that each color is a 1x3 double (as needed for plots), without using methods?

With the following class definition

classdef color
    properties
        R, G, B
    end
    methods
        function c = color(r, g, b)
            c.R = r;
            c.G = g;
            c.B = b;
        end
        function g = get(c)
            g = [c.R, c.G, c.B];
        end
    end
    enumeration
        red (1, 0, 0)
        green (0, 1, 0)
    end
end

I can write color.green.get() to get [0 1 0], but I would like the same result with color.green to make the code cleaner.

A different solution may be setting color as a global struct, but it's not practical because global variables can cause confusion and I have to write global color; in each script/function.


Solution

  • I'm not sure exactly what you're asking here, but I think the main answer is that you're currently doing basically the right thing (although I'd suggest a few small changes).

    You can certainly have non-scalar arrays of enumeration values - using your class, for example, you could create mycolors = [color.red, color.green]. You can also have an enumeration with non-scalar properties, such as the following:

    classdef color2
        properties
            RGB
        end
        methods
            function c = color2(r, g, b)
                c.RGB = [r,g,b];
            end
        end
        enumeration
            red (1, 0, 0)
            green (0, 1, 0)
        end
    end
    

    and then you could just say color2.red.RGB and you'd get [1,0,0].

    But I'm guessing that neither of those are really what you want. The thing that I imagine you're aiming for, and unfortunately what you explicitly can't do, is something like:

    classdef color3 < double
        enumeration
            red ([1,0,0])
            green ([0,1,0])
        end
    end
    

    where you would then just type color3.red and you'd get [1,0,0]. You can't do that, because when an enumeration inherits from a built-in, it has to be a scalar.

    Personally, I would do basically what you're doing, but instead of calling your method get I would call it toRGB, so you'd say color.red.toRGB, which feels quite natural (especially if you also give it some other methods like toHSV or toHex as well). I'd also modify it slightly, so that it could accept arrays of colors:

    function rgb = toRGB(c)
            rgb = [[c.R]', [c.G]', [c.B]'];
    end
    

    That way you can pass in an array of n colors, and it will output an n-by-3 array of RGB values. For example, you could say mycolors = [color.red, color.green]; mycolors.toRGB and you'd get [1,0,0;0,1,0].

    Hope that helps!