Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Система координат в GDI+

1.9K
03 апреля 2009 года
GreenRiver
451 / / 20.07.2008
Всем привет!

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

Нашел вот такие вот API-функции для изменения системы координат:
SetMapMode
SetWindowOrg
SetViewportOrg
[их описание]

Есть ли этому какие-либо аналоги в .Net? Может быть как-то можно через Graphics? Гугл и MSDN молчат по этому поводу :(
5
03 апреля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: GreenRiver
Возникла такая проблема: очень желательно направить ось Y вверх, а не вниз, как по-умолчанию в GDI. Игры с матрицами, ни к чему не приводят, т.к. в результате текст выводится вверх ногами...

Попытка номер два:

Код:
private void DrawText(Graphics gfx, string text, float x, float y) {
            SizeF text_size = gfx.MeasureString(text, this.Font);
            Matrix current = gfx.Transform;            
            Matrix new_matrix = current.Clone();
            new_matrix.Multiply(new Matrix(1.0f, 0.0f, 0.0f, -1.0f, x, text_size.Height + y));
            gfx.Transform = new_matrix;
            gfx.DrawString(text, this.Font, Brushes.Red, 0.0f, 0.0f);
            gfx.Transform = current;
        }

        private void Form1_Paint(object sender, PaintEventArgs e) {
            Graphics gfx = e.Graphics;
            Matrix mirror = new Matrix(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, (float)ClientRectangle.Height);

            gfx.Transform = mirror;
            gfx.DrawLine(Pens.Blue, new Point(10, 10), new Point(100, 100));

            DrawText(gfx, "Sample text", 100.0f, 100.0f);
        }

Но, придется использовать отдельную функцию для вывода текста использовать. При вращении координат вроде работает...
1.9K
03 апреля 2009 года
GreenRiver
451 / / 20.07.2008
hardcase, респект! Я попробую, этот способ, результат выложу!

Большой спасибо, особенно за оперативность!!! :)
Ну и +1 в карму :)
40K
03 апреля 2009 года
Freya
11 / / 04.11.2008
а не проще просто преобразовывать координаты?!

y0 = Width - y1;

y0 - координата в обычной системе, где y изменяется сверху вниз
Width - высота экрана (или области вывода)
y1 - координата в обратной системе, где y изменяется снизу вверх
5
03 апреля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Freya
а не проще просто преобразовывать координаты?!

Матрица преобразования именно для этого и служит, только преобразованием занимается сама система - в идеале это делает графический ускоритель (но в GDI+ покачто этим занимается центральный процессор). К тому же она удобнее - задали один раз и погнали рисование в наших координатах :) А еще возможно масштабирование изображения и поворот. Вы хотите вспоминать ту систему уравнений с синусами и косинусами для поворота точки?

Кстати, Width - это ширина, будем считать, что вы имели в виду Height.

397
03 апреля 2009 года
SergPas
527 / / 03.02.2007
Согласен с Freya. Вначале так и написал, но потом почему то удалил сообщение...
Цитата:
Вы хотите вспоминать ту систему уравнений с синусами и косинусами для поворота точки?


А Вы как-то по-другому представляете себе матрицу поворота, без синусов и косинусов?

5
03 апреля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: SergPas
А Вы как-то по-другому представляете себе матрицу поворота, без синусов и косинусов?

У класса System.Drawing.Drawing2D.Matrix есть клевый метод Rotate. ;)

40K
03 апреля 2009 года
Freya
11 / / 04.11.2008
Думаю, операция преобразования в данном случае будет занимать больше времени, чем мгновенная операция вычитания, выполненная несколько раз.
А по вопросу поворота или масштабирования, система уравнений, скорее всего, будет проигрывать преобразованию матрицы.
397
03 апреля 2009 года
SergPas
527 / / 03.02.2007
Цитата:
У класса System.Drawing.Drawing2D.Matrix есть клевый метод Rotate. ;)


Который использует матрицу поворота с синусами и косинусами... :)
Иногда спускаюсь на более низкий уровень, и думаю в терминах матриц преобразований... Просто не совсем вижу смысл удобства такого изменения системы координат... Формировать матрицу, передавать её графическому конвейеру... Хотя... Наверно, Вы правы - одним преобразованием меньше, одним больше - производительность наверняка не пострадает, всё равно производит умножение...

5
03 апреля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Freya
Думаю, операция преобразования в данном случае будет занимать больше времени, чем мгновенная операция вычитания, выполненная несколько раз.

Зависит от того - сколько раз. Ведь через подобный "фильтр" придется пропускать все точки, участвующие в построении сцены. Не слишком ли это большая цена за скорость? Тем более, еще не известно, сколько линий нужно построить. Если не больше 1000, то разницы не почуствовать.

5
03 апреля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: SergPas
Который использует матрицу поворота с синусами и косинусами... :)

Естественно, только не придется открывать учебник Линейной Алгебры.

Цитата: SergPas
Просто не совсем вижу смысл удобства такого изменения системы координат...

Зависит от задачи.

1.9K
04 апреля 2009 года
GreenRiver
451 / / 20.07.2008
Цитата: Freya
а не проще просто преобразовывать координаты?!
y0 = Width - y1;


Хоть и не очень элегантный, но вариант. Да, порой стоит спуститься с небес на землю... о самом простом, я и не подумал :) Спасибо! :)

Цитата: Freya
Думаю, операция преобразования в данном случае будет занимать больше времени, чем мгновенная операция вычитания, выполненная несколько раз.
А по вопросу поворота или масштабирования, система уравнений, скорее всего, будет проигрывать преобразованию матрицы.


Мне не самоцель развернуть систему координат, потом нужно и дальше трансформировать координаты: смещение + масштабирование (точка обзора над картой). И лучше один раз "собрать" матрицу содержащую все нужные преобразования... чем делать последовательность маленьких преобразований... Да и удобнее матрицами это делать!

Цитата: SergPas
Который использует матрицу поворота с синусами и косинусами... :)
... Просто не совсем вижу смысл удобства такого изменения системы координат...

Можно ведь и синус вычислять вручную до меньшей точности, чем стандартный, быстрее будет :) Сейчас мне важно чтобы работало - а оптимизировать всегда можно!

1.9K
04 апреля 2009 года
GreenRiver
451 / / 20.07.2008
Цитата: hardcase
но в GDI+ покачто этим занимается центральный процессор...


Угу... и это заставляет глядеть в сторону чего-нибудь ускоренного, но DirectX не знаю совсем, а с OpenGL нет опыта работы в C#... нет времени разбираться - надо чтобы уже работало :)
Вот и приходится связываться со всякими GDI...

15K
16 апреля 2009 года
Vertecs
116 / / 21.06.2008
Вопрос очень интересный. И сам я попытался разобраться...
А нельзя ли просто все буквы шрифта при инициации перевернуть по вертикали?
В CreateFont экспериментировал со всеми углами. Не выходит...

Googlил, ничего не нашёл.

Есть соображение сам шрифт взять бинарно каждую букву отразить вертикально. Но, как это сделать?
В HTML-фильтрах шрифт можно делать зеркально отражённым. Но, неужели это делается не через преобразование матриц и шрифта, а блиттингом???
5
16 апреля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: GreenRiver
Угу... и это заставляет глядеть в сторону чего-нибудь ускоренного, но DirectX не знаю совсем, а с OpenGL нет опыта работы в C#... нет времени разбираться - надо чтобы уже работало :)
Вот и приходится связываться со всякими GDI...

Есть Windows Presentation Foundation (WPF). Он аппаратно ускоряется.

5
16 апреля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Vertecs
А нельзя ли просто все буквы шрифта при инициации перевернуть по вертикали?

При инициализации чего?

Шрифт тут существует не зависимо от нас, это не OpenGL, где его нужно руками загружать и конструировать визуальные объекты. Здесь он уже встроен в графическую подсистему. Кроме того, шрифты сейчас используютс не растровые, а векторные - простым блитингом его не перевернешь (конечно, можно отрендерить текст и уже его вращать как хочется, видимо так HTML фильтр поступает).

Остается наиболее универсальный метод - аффинные преобразования.

15K
18 апреля 2009 года
Vertecs
116 / / 21.06.2008
Цитата: hardcase
При инициализации чего?

Шрифт тут существует не зависимо от нас, это не OpenGL, где его нужно руками загружать и конструировать визуальные объекты. Здесь он уже встроен в графическую подсистему. Кроме того, шрифты сейчас используютс не растровые, а векторные - простым блитингом его не перевернешь (конечно, можно отрендерить текст и уже его вращать как хочется, видимо так HTML фильтр поступает).

Остается наиболее универсальный метод - аффинные преобразования.

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

Знаете кого-то, кто может ответить? Поделитесь с ним ссылкой.

Ваш ответ

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог