Godot: Allow clamping for more than just floats/ints

Created on 3 Dec 2017  路  15Comments  路  Source: godotengine/godot

While doing a tutorial from KidsCanCode, it dawned upon me that the clamp() function allows for floats/ints to be clamped, but not other variable types like Vector2s, Vector3s, or Colors that one might want to clamp to a range. What I'm proposing is to allow just that, as I don't imagine it would be too hard to implement and it would allow for code to be condensed a little more.

For example, for a Vector2 named position, this functionality would allow this code snippet:

position.x = clamp(position.x, 0, get_viewport_rect().size.x)
position.y = clamp(position.y, 0, get_viewport_rect().size.y)

to be simplified to this:

position = clamp(position, Vector2(), get_viewport_rect().size)

(You can see how this might be useful for a Color, where there might be a lot more values to clamp.)

Ideally, I would like to see clamp() allowed for Vector2, Vector3, and Color, at the least. (Though other types similar in nature to those three might be nice to allow clamping for too!)

Hope this isn't too much to ask for. :)

enhancement core

Most helpful comment

API proposal:

  • Rename Vector2.clamped to Vector2.limit_length.

  • Add Vector3.limit_length to be consistent with Vector2.

  • Add Vector2.clamp(min, max) where min and max are of type Vector2.

  • Add Vector3.clamp(min, max) where min and max are of type Vector3.

  • Add Color.clamp(min, max) where min and max are of type Color.

    • Bonus idea: We could allow Color.clamp to have default values of min = Color(0, 0, 0, 0) and max = Color(1, 1, 1, 1), since clamping a color to this range seems like it would be a relatively common operation.

    • Bonus idea part 2: With the above, you could override only min to Color.black, which would clamp to non-transparent colors, since black is Color(0, 0, 0, 1).

Thoughts?

All 15 comments

Similar to #8071

Not sure whether to close this then or leave it open, if it's just similar and not a duplicate. :/

It's not a duplicate in my opinion.

If https://github.com/godotengine/godot/issues/8071 were implemented, wouldn't it cover this issue? If the API is to be consistent then it shouldn't just cover the clamp function, but should cover as many math functions as possible, right? It does seem like a duplicate to me. :)

@NathanWarden I agree, but than there's Godot's reality, that the more you ask for, the less you generally get into the core :-)

@poke1024 I suppose in some cases that's true, it is easier to ask for one thing (and it be implemented) than to ask for an entire library to be extended :)

@NathanWarden Adding onto what poke1024 said, I feel clamp() would be more useful than any of the other math functions. Not to mention, this would be a great short-term improvement, with the rest of the math functions being a long-term improvement.

@LikeLakers2 Thanks for pointing that out, I can see some functions being more useful than others on a regular basis with other data types.

So, Vector2 already has a function called clamped(), but this doesn't do the same as clamping a float or int. Vector2's clamped is basically if vector.length() > val: vector = vector.normalized() * val. What should be done about this? It would be confusing to have both Vector2.clamp() and Vector2.clamped() since they are similar names. Note: Vector3 does not have clamped (https://github.com/godotengine/godot/issues/30058).

I think the existing method might make more sense as "limit" or something, since it effectively puts a cap on the length of the vector. But changing this breaks compat and would probably need to wait until Godot 4.0. We can keep clamped as an alias but add "limit" or similar in 3.2, but again, having both clamp and clamped would be confusing, so adding clamp should wait until 4.0. #16863

I'd vote for renaming the existing method .. limit sounds good or maybe limit_length. The old method is so specific I doubt it is used much outside the 2 mentions in the godot source. In fact there's an argument to get rid of the old method altogether.

Since discovering it a few months ago I've used Vector2's clamped in every project I have, so if there's an argument to get rid of it altogether I'd like to hear it

I'm not sure limit conveys better info than clamp. Both sound the same and expect the user to "guess" they are referring to length, which is not directly a value of the vector. I'd just name this clamp_length, or limit_length (besides it would otherwise occupy the space for a memberwise clamp which in my sense would be the consistent/standard way of calling such function, however Vector2/Vector3 don't have it, so....).

API proposal:

  • Rename Vector2.clamped to Vector2.limit_length.

  • Add Vector3.limit_length to be consistent with Vector2.

  • Add Vector2.clamp(min, max) where min and max are of type Vector2.

  • Add Vector3.clamp(min, max) where min and max are of type Vector3.

  • Add Color.clamp(min, max) where min and max are of type Color.

    • Bonus idea: We could allow Color.clamp to have default values of min = Color(0, 0, 0, 0) and max = Color(1, 1, 1, 1), since clamping a color to this range seems like it would be a relatively common operation.

    • Bonus idea part 2: With the above, you could override only min to Color.black, which would clamp to non-transparent colors, since black is Color(0, 0, 0, 1).

Thoughts?

@aaronfranke I would of preferred to have it under the global clamp() function, but at the same time, your proposal is probably miles easier to implement. So no complaints from me. It sounds like a fine proposal.

@aaronfranke I really like the idea and I think that is how it has to be implemented. But however it will break the current API maybe for 4.0 as already a lot is broken in 4.0 API.

Was this page helpful?
0 / 5 - 0 ratings