这个问题在我的职业生涯中多次提出,并将我和我的同事分成两个阵营。我认为这个网站上的答案可能是最好的,一劳永逸。
几乎所有的图形UI库都实现了Rectangle结构,但它们的工作方式通常分为两个可能的选项:
现在,我说我要编写一个UI库,我应该选择哪两种选择?
更新:问题涉及实施,而不是界面。当然矩形的界面可以很好地支持两种方法,但是如何将数据存储在矩形中?
答案 0 :(得分:8)
为什么不选择两者?
真的,唯一重要的是你的库和它的内部之间的接口。或者,您的用户使用库的方式。您可以存储您想要的矩形信息,但是应该将其封装在远离用户的地方,这样他们就不必担心矩形的存储方式,只需它确实是一个矩形。
换句话说,如果您正在编写面向对象的代码,则可以根据需要存储矩形,然后让用户使用任一方法创建矩形。
例如,您的声明可能如下所示:
class Rectangle
{
public:
Rectangle(Point p1, Point p2);
Rectangle(Point origin, int width, int height);
...
};
(C ++,因为你标记了它)
Point是某类:
class Point
{
public:
Point(int x, int y) : mX(x), mY(y) {}
private:
int mX;
int mY;
};
这样,您的库不仅限于支持一种类型的规范来创建矩形。
具体实施,确实没关系。它们都可以工作并且可以很容易地相互转换并使用相同数量的内存,因此使用一个而不是另一个会产生重大的性能影响。
为了简化开发,请考虑矩形的用例。看看你需要为该类编写的每个成员函数,并考虑哪种格式可以更容易地编写这些函数。
如果是我,我可能会用两点来实现它。
编辑:为什么我认为以这种方式实施它的学术方法在大多数情况下绝对没有区别。
让我们的Rectangle类上有成员函数或操作,它对矩形起作用或进行一些计算。假设一种实现方法(宽度/高度/原点或两点)将比其他实现快得多地执行此操作。
我们可以使用以下内容从实现宽度/高度/原点转换:
// assuming x0,y0 is top left and x1,y1 is bottom right
x0 = originX;
y0 = originY;
x1 = originX + width;
y1 = originY + height;
我们可以通过以下方式从实现转换为两点:
// assuming x0,y0 is top left and x1,y1 is bottom right
originX = x0;
originY = y0;
width = x1 - x0;
height = y1 - y0;
因此,执行此操作的实现比其他实现更慢/更差可以在O(1)运行时转换为其他实现,因此其他实现不能 更好比第一次实施。
除非你每秒进行几千次这样的操作或者性能极限的设备,否则我非常确信没有性能差异。已经没有内存差异,因为这两个实现几乎只存储4个浮点数/整数。
这几乎留下了编码的便利性,就像我在上面的原帖中所说的那样,你可以简单地“考虑一下你的矩形的用例。看看你需要为它编写的每个成员函数。上课并考虑哪种格式可以更容易地编写这些函数。“
答案 1 :(得分:2)
毫无疑问,这当然只取决于你所面临的问题。
对于图形绘制算法,第二个选项似乎具有非常小的优势恕我直言。而对于在欧几里得平面上定义的一般“几何”算法 - 第一种选择更方便。
此外,一旦我正在研究地球表面定义的算法。平均值,x,y坐标分别表示经度/纬度。 x坐标显然是循环。在这个特定的情况下,为了定义一个(某种)矩形 - 它不足以定义角落,你还需要一个方向。这可以通过第一点(p0)是最左边的点,而第二点(p1) - 最右边的约定来处理。但我更倾向于切换到第二个约定,你自然会有一个角和一个偏移向量。