Книга: C# для профессионалов. Том II

Преобразования координат

Преобразования координат

В этом разделе мы рассматриваем реализацию вспомогательных методов, которые были использованы в примере CapsEditor, чтобы выполнить преобразование координат. Это методы WorldYCoordinateToLineIndex() и LineIndexToWorldCoordinates(), на которые мы ссылались в предыдущем разделе, а также некоторые другие методы.

Первое. LineIndexToWorldCoordinates() получает заданный индекс строки и определяет мировые координаты верхнего левого угла строки с помощью известных ширины поля и высоты строки:

private Point LineIndexToWorldCoordinates(int index) {
 Point TopLeftCorner =
  new Point((int)margin, (int)(lineHeight*index + margin));
 return TopLeftCorner;
}

Мы также используем метод, который делает приблизительно обратное преобразование в OnPaint(). WorldYCoordinateToLineIndex() определяет индекс строки, но он принимает в расчет только вертикальную мировую координату. Это связано с тем, что метод используется для определения индекса строки, соответствующего верху и низу области вырезания:

private int WorldYCoordinateToLineIndex(int у) {
 if (у < margin) return -1;
 return (int)((y - margin)/lineHeight);
}

Существуют еще три метода, вызываемые из процедуры обработки, которые отвечают на двойной щелчок пользователя мышью. Прежде всего — метод, определяющий индекс строки, которая выведется в заданных мировых координатах. В отличие от WorldYCoordinateToLineIndex() этот метод берет в расчет позиции x- и y- координат. Он возвращает -1, если нет строки текста с заданными координатами.

private int WorldCocrdinatesToLineIndex(Point position) {
 if (!documentHasData) return -1;
 if (position.Y < margin || position.X < margin) return -1;
 int index = (int) (position.Y - margin) / (int) this.lineHeight;
 // проверить, что позиция находится не ниже документа
 if (index >= documentLines.Count) return -1;
 // теперь проверим, что горизонтальная позиция располагается
 // внутри строки
 TextLineInformation theLine =
  (TextLineInformation)documentLines[index];
 if (position.X > margin * theLine.Width)
 return -1;
 // все хорошо. Можно вернуть ответ.
 return index;
}

Наконец, иногда необходимо делать преобразование между индексом строки и координатами страницы, а не мировыми координатами. Это делает следующий метод:

private Point LineIndexToPageCoordinates(int index) {
 return LineIndexToWorldCoordinates(index) + new Size(AutoScrollPosition);
}
private int PageCoordinatesToLineIndex(Point position) {
 return WorldCoordinatesToLineIndex(position - new Size(AutoScrollPosition));
}

Эти методы сами по себе не кажутся особенно интересными, они иллюстрируют общую технику, которую, по всей видимости, вам придется часто использовать. Применяя GDI+, мы иногда оказываемся в ситуации где заданы некоторые координаты (например, координаты места, где пользователь щелкнул мышью) и требуется определить, какой элемент изображен в этом месте. Или наоборот, для заданного определенного элемента вывода необходимо приблизительно определить, где он должен быть выведен. Следовательно, при создании приложений GDI+ может оказаться полезным умение написать методы, эквивалентные методам преобразований координат, проиллюстрированным здесь.

Оглавление книги


Генерация: 5.891. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз