Rectangle::getSize() missing

Just stumbled across this and wonder why this basic function is missing. It is absolutely useful to get the extent of a Rectangle as a Point, so it can be passed on to other functions more easily:

Point<ValueType> getSize() const noexcept { return { w, h }; }

Please consider adding it, TIA

The problem with this to me is that a Point is semantically different to a “size”.
Personally I’d like to see a juce::Size class where a Rectangle contains Point and Size members.

When I’ve had to return sizes of things that don’t have a location, I’ve always used a Rectangle with zero origin as the methods of Rectangle are much better for making the size bigger or smaller.

1 Like

IIRC the reason I didn’t do that was some kind of symbol clash (this was many years ago). Probably would be something we could add now without any problem though, and yes, agreed that it’d be nice.

How would a Size class be different to the Rectangle class?

Surely a rectangle with 0, 0 position would work exactly the same?

Kind of, but it would be a smaller interface as wouldn’t have all the origin stuff.

It’s more so you can be more expressive about the intent and inform callers that you’re not interested in the origin of a Rectangle or a returned object doesn’t have any relevance.

Also, if you add a setSize (Rectangle<Type>) method, it would be ambiguous, if the origin is taken into account or not (kind of what @dave96 said already).

I wouldn’t look at this too philosophically. Even then, the size of a Rectangle is equivalent to the local coordinate of its bottom-right corner. And that’s a Point.

Oh, and Point does not necessarily denote ‘location’ (e.g. unity vectors, matrices)

It would be an issue if width and height used different base types, but AFAIK that’s not the case.

But you’ve hit one of the main objections there - what set of basis vectors are the coordinates of your point based on? ([1, 0], [0, 1]) or ([1, 0], [0, -1])? A point can have a negative extent in each direction, but what does a negative size mean?

I’d argue that Point is very much ‘location’. How are Points used with vectors and matrices where they don’t represent offsets in each dimension from an origin?

Getting this stuff right is very important when you’re providing an API.

Also methods like expand, withWidth etc. have no meaning to a Point.

Exactly what I was talking about: Size is the offset from the origin. Negative size is not defined and can be eliminated easily. A rectangle with negative size is invalid anyway (corners swappend)

I think we’re talking at cross-purposes. It’s obvious, mechanically, how you can use a Point as a size, but you’ve needed to use the words “Size is the offset from the origin” to explain how to go from an inherently Point-y thing to a Size.

2 Likes

Ok. Maybe the term ‘size’ is misleading.

How about ‘extent’ ?

Just checked Smalltalk and there are several hundred senders and several dozen implementors of ‘extent’. So, if the sacred mothership of OO used it for decades, in a world of philosophical purity where the null pointer is an instance of class UndefinedObject, it can’t possibly be wrong :wink:

I think the term size is just perfect, no need to find a different one. The objection was to express a size using a Point or a zero positioned Rectangle.

Maybe it could be reassessed, if Size still collides. FWIW, I defined a struct Size in my engine with no problems.

Actually both Point and Size are subclasses of Pair<x,y>, which is the purely ‘mechanical’ thing they are based on, only that Point and Size slightly differ in semantics.

Whether, in the context of the Juce library, making Size a class of its own is useful, I don’t know. So yes, temporarily superimposing ‘Size’ semantics on a Point for the sake of being able to return a function result, means bending the ontology a bit.

Another solution would be to make getSize() return a pair and have it implicitly convert to Point when used as such?

I would agree, if it was explicitly, like the Point<int>.toFloat() doing a
Point<Type> Size<Type>::fromOrigin() or Size<Type> Point<Type>::asSize().

Or whatever the linguists would prefer.