color becomes vec4

I’m posting this here to see if any of the more advanced Codea users can see a problem with this change to the runtime.

The proposal is to make the color(r,g,b,a) function simply return a new vec4 object with the specified values. In practice this should behave identically, except vec4 exposes its metatable. In addition, it makes things like the equals (==) and arithmetic operators (add, normalize and so on) available for colors.

All existing functions that accept color will now accept vec4 — again, this should be transparent to you as a Codea user.

vec4 has .r, .g, .b, .a accessors, as color did.

Can any one see any issues with this proposal?

Edit: Alternatively we could make color a more fleshed out object, but it feels redundant as the data is identical to a vec4.

This is a neat idea. I just have one thing, but I’m not sure wether this would be a problem: I have a data serializer for codea, that also takes care or the userdata objects. It recognizes the type of userdata by its metatable. Clearly, there will be no color type after this change. As long as there is no “hidden” data stored in the vec4 representing a color, meaning that color(r,g,b,a) == vec4(r,g,b,a) for identical values of r,g,b,a , it should not make any difference.

Hi Simeon,

I only see benefits, but I’m not up on metatables yet so some of the implications may be lost to me.

On a trivial point - I assume that you aren’t changing the syntax and color(r,g,b,a) remains the same - it’s just the routines behind it change.

One thought - do you check that the values are within range for entry ? i.e. 0 to 255. Is there an out of range error? and would we still be allowed to pass variables and arrays in to simplify code?

Bri_G

:slight_smile:

Sorry, I can’t see any benefits except for the one that you can get rid of an extra data structure.

What you have to do, I think, is to explain (especially for beginners) the different meanings of a vector:

  1. The mathematical vector. It has x, y and perhaps more predefined components, there are functions to make useful special purpose calculations.

  2. The vector as a list (like std::vector in C++ is the dominant way of creating a list).

You should explain that a vec4-diguised color has nothing to do with a vec2 where you can calculate the length of it, whereas vec2 and vec3 share similarities.

I’m not a heavy user of colors, but it never occurred to me that I wanted to compare a color with an exact other color. Maybe painting programs want to do this in operations like “replace this red with green”, and even then I’d suppose that such painting programs rather offer “replace this red and anything within a certain shade of it with green”, and gone is the usefulness of color1 == color2. And if I modify a color, I work on its named parts, not on the color as an arbitrary list.

A vec4 with a special purpose interpretation as a color … well, I don’t want to speak against it, I just doesn’t make much sense to me. A color is a color, there is no similar context. A function that works on a color has little meaning for arbitrary vec4 values. A function that operates on arbitrary vec4 values … can you imagine one that has a meaning with respect to colors? Maybe for fractals.

Verdict: Use vec4, but explain the different purposes of vectors clearly.

I’ve had a bug by assuming that == worked for colors before. Took me a long time to find it too.

But thinking more about it: doesn’t == make it impossible to use that class as keys of tables in lua? You’d end with situations where obj1 == obj2 but table[obj1]~=table[obj2]. And as far as I know there would be no way to differentiate obj1 from obj2. Obviously a bigger issue than just color, but would be interested to hear your thoughts on it.

As for color, I see @codeslinger’s point that a color is not a vec4, and would rather keep the external interface separate. You could also implement color as a wrapper around vec4, and just fwd all methods to the vec4 methods?

I have (previously) added pages to the wiki about these userdata here and here and about Codea’s userdata more generally here.

Making color() return the same userdata as vec4() has one odd side-effect: colors will then have vector-like functionality. I would suggest, @Simeon, that Codea remain true to its philosophy: Is it simple, elegant or beautiful to be able to calculate the dot-product of two colours?

Thank you for the feedback.

Would you prefer color become a more fleshed out object of its own? Perhaps with a special color * color multiplication that normalizes to the 255 range, and addition/subtraction that clamps.

@ruilov it wasn’t so much about not adding the methods to color, but to simplify by removing one redundant data type. It felt more “pure” to have color be vec4

I didn’t even realize there was a color object until like a week ago. I was just doing the vec4() object thing.

@Deamos really? But how are you doing indexed coloring for your mesh?

Or are you steering clear of 3d altogether?

@Simeon I second the notion as for days I’ve been trying to figure out why I can’t seem to get it to so much as read the values from my tables associated with the r,g,b.
(I usually leave off a cause the first is the index so its usually: i,r,g,b)

As long as everything is in the same place they can be read but when you try modularizing everything then you run into some issues.

Guys, I mean pretending the problem does not exist now won’t eliminate it later.

As Codea userdata can be enhanced by individual users of the app, I think it is a difficult decision whether or not to extend the built-in functionality (and, consequently, complexity for users) of Codea’s userdata.

Some things are a chore (and it is a joy when somebody else has done your chores) and some things are a joy. You could imagine additional functionality for a color userdata but, if you build it in to the app, do you then deny some coder the joy of discovering and implementing that for himself or herself?

I’ve already done a fair bit of extension for colours. Not sure about “joy”, though.

My instinct is that this is a bad idea. I don’t see any gain, but lots of room for confusion. Of course, you could do stuff internally to make your lives easier, but I can’t think of a single operation where colour-is-vector would actually make life clearer for the user.

Take mixing. I want to blend red and blue, so I want to take 5 parts red to 2 parts blue. I want to write c = blend(red,5,blue,2). I don’t want to write c = (5*red + 2*blue)/7.

Yeah I’m unsure about this now. I’m thinking about just improving the colour type.

The biggest improvement would be to spell it correctly!

Ha! I am totally going to alias the color() function to be colour() from now on.

@Andrew_Stacey um actually spelling it correctly is a relative thing in England they do spell color that way.

To which I must ask
@Simeon are you english?

@GenobiJuan: I’m pretty sure he was just poking fun :wink:

Yes, we have joked about it before… TLL being Aussies and Andrew a Brit.

@GenobiJuan Australian, we follow English spelling for most things.

All Codea APIs will use US spelling — it’s just confusing otherwise.

Actually, the long list of colour definitions provided by @Andrew_Stacey in the example projects Roller Coaster and Anagrams, is an example of the sort of chore that I had in mind; I suspect everybody else is grateful that he took the time and trouble to do so.

Extending color() in the Codea API so that color(string) returns a userdata appropriately initialised based on the colour name in string might bring joy - say names based on the W3C extended color keyword names, but tolerant of the use of spaces and/or capital letters.

@mpilgrem If you look carefully at the licence for those files, you’ll see that I didn’t - strictly speaking - create those lists. One nice perl script plus someone else’s files was the limit of the chore for me.

But you’re right that such things are great when others do it and we can share code.