2012-04-05 2 views
6

Это вопрос, который возник несколько раз в моей карьере и который разбивает меня и моих коллег на два лагеря. Я думал, что на этот сайт лучше всего ответить, раз и навсегда.Определите прямоугольник как две точки или происхождение/размер?

Почти все библиотеки графики пользовательского интерфейса реализовать структуру Rectangle, но так, как они делают это, как правило, делится по двум возможным вариантам:

  1. Прямоугольник определяется как два 2D точек в пределах одной и той же системе координат, обычно называется р0 и p1, или с отдельными компонентами, как x0, y0, x1, y1.
  2. Прямоугольник определяется как двумерные векторы происхождения и размера, обычно называемые положением и размером, или, индивидуально, x, y, ширина, высота.

Теперь скажите, что я должен написать библиотеку пользовательского интерфейса, какой из двух вариантов выбрать?

Обновление: Вопрос касается реализации, а не интерфейса. Конечно, интерфейс прямоугольника мог бы поддерживать оба подхода, но как бы сохранить данные в прямоугольнике?

+3

Я думаю, что этот вопрос получит окончательный ответ, если мы определим а), где должны быть фигурные фигурные скобки, и б) использовать ли vi или emacs. – molbdnilo

ответ

8

Почему бы не выбрать обе?

Действительно, единственное, что имеет значение, это интерфейс между вашей библиотекой и ее внутренними элементами. Или, как ваши пользователи будут использовать библиотеку. Вы можете хранить информацию для прямоугольника, но хотите, но это должно быть инкапсулировано далеко, далеко от пользователя, так что им не нужно беспокоиться о том, как их прямоугольник хранится, просто что это действительно прямоугольник.

Другими словами, при выборе обоих, если вы пишете объектно-ориентированный код, вы можете сохранить прямоугольник, как хотите, а затем позволить своему пользователю создать прямоугольник с помощью любого из методов.

Например, ваше объявление может выглядеть примерно так:

class Rectangle 
{ 
public: 
    Rectangle(Point p1, Point p2); 
    Rectangle(Point origin, int width, int height); 
    ... 
}; 

(C++, так как вы помечено, что)

Где точка некоторый класс:

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) время работы, так что другая реализация не может быть , что намного лучше, чем th первая реализация.

Если вы не выполняете эту операцию несколько тысяч раз в секунду или на устройстве с ограниченной производительностью, я очень уверен, что разница в производительности не будет. Уже нет разницы в памяти, потому что обе реализации в значительной степени просто хранят 4 float/ints.

Это в значительной степени оставляет удобство кодирования, и, как я сказал выше в своем оригинальном посте, вы можете просто «рассмотреть, какие варианты использования вашего прямоугольника есть. Посмотрите на каждую функцию-член, которую вам нужно будет написать для этот класс и подумайте о том, какой формат облегчит запись этих функций ».

+1

Это только дает намеки на то, как должен выглядеть интерфейс, и я согласен. Однако вопрос был о реализации. Я расширяю исходный вопрос, чтобы сделать это более ясным. – paniq

+0

Разве последние три блока текста не отвечали на ваш вопрос об осуществлении? Я буду следить за тем, чтобы ваш вопрос обновлялся. –

+0

О да, я пропустил это, извините. Я не уверен, что это не имеет значения. – paniq

1

Без всякого сомнения, это, конечно, зависит исключительно от проблемы, с которой вы сталкиваетесь.

Для алгоритма графического рисования второй вариант, похоже, имеет очень незначительное преимущество ИМХО. В то время как для общих «геометрических» алгоритмов, определенных на евклидовой плоскости, 1-й вариант несколько более удобен.

Кроме того, как только я работал над алгоритмом, определенным на поверхности Земли. Значения, координаты x, y представляют собой долготу/широту соответственно. Координата x, очевидно, циклическая. В этом конкретном случае, чтобы определить (вид) rect - этого недостаточно, чтобы определить только углы, вам также необходимо направлении. Это может быть достигнуто соглашением о том, что первая точка (p0) является самой левой точкой, тогда как вторая точка (p1) - самая правая. Но вместо этого я предпочел переключиться на второе соглашение, где у вас есть, естественно, угол и вектор смещения.

+0

Это интересный момент, который вы делаете. – paniq

Смежные вопросы