Какова идея определения прямоугольников с двумя точками? [закрыто

softwareengineering.stackexchange https://softwareengineering.stackexchange.com/questions/22643

Вопрос

Дело не в том, что это не имеет смысла, но это просто работает неловко в 99% случаев.

Часто в двухмерной графике прямоугольники инициализируются, хранятся и манипулируются как пара точек. Ни в каком конкретном языке,

class Rect:
   p1, p2: point

Есть больше смысла определять прямоугольник как два значения x и два значения Y, например, это:

class Rect
   xleft, xright: int
   ytop, ybottom: int

С двумя точками, если в каком -то месте в исходном коде вы хотите использовать значение y вершины, вы должны сказать rect.p1.y (хммм, остановитесь и подумайте, это P1 или P2), но но но С четырьмя значениями как простыми элементами данных это ясно и прямо: rect.ytop (не требуется мысли!) Использование двух точек означает, что при работе с вертикали вы должны запутаться горизонтальным; Есть посторонняя связь между независимыми элементами.

Как появилась эта идея с двумя точками и почему она сохраняется? Есть ли какая -то польза от координат x и y?

Добавлено примечание. Этот вопрос находится в контексте выравнивающих прямоугольников XY, таких как менеджеры Windows и наборы инструментов GUI, а не в контексте произвольных форм в приложении для рисования и живописи.

Это было полезно?

Решение

Вы считали, что это менее подвержено ошибкам?

Если вы используете (point1, point2), то тогда очень Очистите, что вы указываете. Если вы предоставляете 2 балла, то единственная возможная ошибка заключается в том, что пользователь смешал свой x и y при создании точек, поскольку порядок точек не имеет значения.

Если вы поставляете 4 целых числа, то если кто -то не обращает внимания, он может поставлять (x1, x2, y1, y2), когда вы хотели (x1, y1, x2, y2) или наоборот. Кроме того, некоторые API, такие как WCF Прямо Структура определяет прямоугольник как (x, y, ширина, высота), которая затем может вызвать путаницу из -за того, что означает (1, 2, 3, 4). Это (x, y, w, h) или (x1, y1, x2, y2) или (x1, x2, y1, y2)?

В общем, (Point1, Point2) кажется мне немного безопаснее.

Другие советы

Мне всегда нравилось определять прямоугольник как точку + ширина и высота, где точка-верхний левый угол прямоугольника.

class Rect {
  float x, y;
  float width, height;
}

А затем добавьте любые методы, которые вам нужны, чтобы получить другие метрики. Как Ява версия

На самом деле, прямаяглась не определяется 2 баллами. Прямоугольник может быть определен только двумя точками, если он параллелен оси.

Есть несколько способов представить прямоугольники, которые параллельны осям:

  1. Две диагонально противоположные точки
  2. Одна угловая точка, высота и ширина
  3. Центральная точка, половина высоты и ширина (необычная, но иногда полезная).
  4. Как два координата X и две координаты Y

Для (1) многие библиотеки используют соглашение, чтобы определить, какие две точки используются - например, Topleft и Bottomright.

Выбор представления может быть обусловлен первоначальной целью определения прямоугольника, но я представляю, что это часто произвольный. Анкет Представления эквивалентны в информации, которую они несут. Они, однако, отличаются по легкостью, с которой могут быть рассчитаны свойства прямоугольника, и удобство, с помощью которого операции могут выполняться на повторном рефлянте.

Преимущества определения (1) над другими включают:

  • Последовательность API с другими полигонами, линиями и т. Д.
  • Topleft, Bottomright может быть передана любому методу, который принимает точки
  • Методы точечного класса можно вызвать на Topleft, Bottomright
  • Большинство свойств можно легко получить, например. Notemleft, Top Right, ширина, высота, центр, диагональ и т. Д.

Что ж p1: Point а также p2: Point у каждого будет два int координаты В любом случае, в них нет того же класса.

И если вы храните эти два очка в качестве первоклассного Point Объекты, разве вы не получаете от них немного больше полезности? В большинстве графических систем координат, о которых я знаю, точки подкладываются таким образом, чтобы создать иерархию объектов: point -> circle -> ellipse и так далее.

Так что, если вы создаете объект, который не использует Point Класс, вы развелись с этим объектом с остальной части классовой иерархии.

Вот почему мне нравится Дельфи TRect. Анкет Он определяется как вариант записи (союз в C-Speak), который можно интерпретировать либо как топлфт и нижняя точка, либо верхняя, слева, нижняя и правая целые числа, в зависимости от того, что в настоящее время удобнее.

Конечно, если вы определите свой прямоугольник как:

class Rect
{
    Point bottomLeft;
    Point topRight;
}

Тогда вы сразу же знаете, какой точка есть.

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

Добавив преобразование в форму, вы можете ориентироваться на свой прямоугольник так, как вам нужно. Вам по -прежнему понадобится выравниваемая рамка оси для быстрого приема/отклонения проверок :)

Однако, если ваша модель допускает прямоугольники в какой -либо ориентации без применения преобразования, то «внизу левого» и «верхний правый» не имеют значения, что приводит к «P1» и «P2» (или что -то эквивалентное).

Я думаю, что для прямоугольника будет представлен прямоугольник, чтобы быть представленным X и Y и точкой; Вы могли бы даже сделать точку расположения центром прямоугольника, чтобы оно не зависело от вращения

Но, вероятно, было проще всего кодировать его как два очка!

Мне это не нравится, потому что мы выбросили потенциальную степень свободы, которая по сути допускает произвольное вращение. Общий 2D прямоугольник имеет пять неизвестных (степени свободы). Мы могли бы указать их как координаты точки, длина двух сторон, которые образуют вершину с этой точкой, и угол от горизонтальной первой линии (другой предполагается, что имеет угол на 90 градусов больше). Можно также использовать бесконечное количество других возможностей, но необходимо указать пять независимых величин. Некоторые варианты приведут к более легкой алгебре, чем другие, в зависимости от того, что с ними сделано.

Разве это не то же самое, что 2 очка? Как это неловко ... большинство процедур рисования требуют точек, а не отдельных компонентов x/y.

Определение прямоугольников как пары точек позволяет повторно использовать точку как вершину для другой формы. Просто мысль...

Я полагаю, что это в основном для установления единообразия между примитивами всех форм.

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

Все многоугольники могут быть определены по их точкам, с небольшим количеством логики, чтобы определить, что делать с точками.

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

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

Выполнение вращений на прямоугольнике, определяемом точками, также намного проще, чем определено с точкой плюс ширина и высота.

Я ожидаю, что инкапсуляция сделает эту дифференциацию не важной в качестве пользователя класса.

Прямоугольник должен быть определен как три точки, которые будут хорошо определены в 3 измерениях. Я не совсем уверен в требовании определения прямоугольника в 4 или более измерениях.

Это совершенно произвольно. Вам нужны четыре части информации, чтобы нарисовать прямоугольник. Дизайнер (ы) библиотеки решил представить его с двумя точками (каждая с координатой XY), но мог бы легко сделать это с x/y/w/h или вверху/внизу/слева/справа.

Я полагаю, реальный вопрос ОП: Почему Был ли этот конкретный выбор?

Выбор параметров важен только для дизайнеров / кодеров низкого уровня.

Пользователям высокого уровня нужно только думать:

  • ISpointInrect
  • Область
  • Пересечение (или отсечение)
  • Hasoverlap (так же, как recsection.area> 0)
  • Союз (становится списком прямоугольников)
  • Вычитание (список прямоугольников, которые представляют тот же набор точек, который находится в прямом эфире, но не в прямом b)
  • Преобразование
    • Сдвиги в x и y
    • Вращение (0, 90, 180, 270)
    • Масштабирование в x и y (смотрите примечание)
  • Простой синтаксис для свойств XMIN, XMAX, YMIN, YMAX, ширина, высота, так что пользователю не нужно знать точный выбор параметров.

ПРИМЕЧАНИЕ. Чтобы минимизировать потерю точности во время преобразования масштабирования, иногда уместно внедрить второй прямоугольный класс, в котором используются координаты с плавающей точкой, так что промежуточные результаты можно точно хранить в последовательности преобразований и только округлены до целого числа в последний шаг.

Как говорит @Steven, я думаю, что это должно быть с точки зрения одной (x, y) точки и (w, h) вектора размера. Это потому, что легко попасть в двусмысленность. Предположим, у вас есть следующий заполненный прямоугольник, начиная с точки (0,0).

  012
0 XXX
1 XXX
2 XXX

Очевидно, что это ширина, высота (3,3), но какова это вторая точка? Это (2,2) или (3,3)?

Эта двусмысленность может вызвать все виды проблем.

Я узнал много много лет назад, что лучше думать о графических координатах как о строках между Пиксели, а не как линии, которые пиксели наАнкет Таким образом, нет двусмысленности.

Pa(x,y)*-----------------------------------*Pb(x,y)
       |                                   |
       |                                   |
       |                                   |
       |                                   |
       |                                   |
       |                                   |
Pc(x,y)*-----------------------------------*Pd(x,y)

Таким образом, мы можем определить как PB и PC:

PB (PD (X), PA (Y))

а также

ПК (PA (X), PD (Y))

Таким образом, нет необходимости определять все четыре точки из -за симметрии

Лицензировано под: CC-BY-SA с атрибуция
scroll top