Why not choose both?
Indeed, the only thing that matters is the interface between your library and its internal elements. Or how your users will use the library. You can store information for the rectangle, but you want to, but it needs to be encapsulated far, far from the user, so they don’t need to worry about how their rectangle is stored, just that it is really a rectangle.
In other words, if you select both, if you write object-oriented code, you can save the rectangle as you want, and then let your user create the rectangle using either of these methods.
For example, your declaration might look something like this:
class Rectangle { public: Rectangle(Point p1, Point p2); Rectangle(Point origin, int width, int height); ... };
(C ++, as you noted this)
Where Point is some class:
class Point { public: Point(int x, int y) : mX(x), mY(y) {} private: int mX; int mY; };
Thus, your library is not limited to supporting only one type of specification for creating a rectangle.
As for the implementation specifically, it really doesn't matter. They both work and can be easily converted to each other and use the same amount of memory, and therefore there will be no significant consequences for using one on top of the other.
For simple development simplicity, consider what are the options for using your rectangle. Take a look at each member function that you will need to write for this class, and consider which format will make it easier to write these functions.
If it were me, I would probably use it with two dots.
Edit: An academic approach to why I think that implementing it in any case will have absolutely no meaning in most cases.
Let there be a member function or operation on our Rectangle class that works on our rectangle or does some calculations. Suppose that one implementation method (width / height / start or two points) will perform this operation much faster than the other implementation.
We can convert from width to implementation / height / origin using the following:
// assuming x0,y0 is top left and x1,y1 is bottom right x0 = originX; y0 = originY; x1 = originX + width; y1 = originY + height;
And we can convert two points from the implementation with the following:
// assuming x0,y0 is top left and x1,y1 is bottom right originX = x0; originY = y0; width = x1 - x0; height = y1 - y0;
Therefore, an implementation that performs this operation is much slower / worse than another implementation can be converted to another implementation at O (1) runtime, so that another implementation cannot be much better than the first implementation.
If you do not perform this operation several thousand times per second or on a device with very high bandwidth, I am very sure that there will not be a difference in performance. There is no longer any difference in memory, because both implementations pretty much just store 4 float / ints.
This leaves a lot of coding convenience, and, as I said above, in my original post, you can simply “consider what options for using your rectangle are. Look at each member function that you will need to write a class for this and think about which format makes writing these features easier. "