Gdi

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Aram
Сообщения: 18
Зарегистрирован: 16 апр 2007, 14:07

Скажите пожалуйста существует ли в С++ библиотека для работы с линиями, квадратиками, окружностью? Т.е мне нужно знать, наприрмер, пересекаются ли две прямые, находится ли точка на прямой, Находится ли прямая в области (например в квадрате, в окружности), лежит точка в области? и т.д.
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

А при чём здесь графические функции (линии, квадратики, окружности)? Это чистой воды арифметика. Бери учебник по алгебре для средней школы и там все эти формулы есть.

Хотя в Win32API есть парочка функций. которые могут тебе существенно облегчить задачу - это PtInRect() и PtInRegion().

Функция PtInRegion() универсальная. В качестве области для неё может быть задана любая фигура. PtInRect() годится только для прямоугольника.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

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

По поводу API Helpers, могу ещё добавить функцию RectInRegion. Есть ещё набор функций для работы с прямоугольниками: объединение, пересечение, равенство и т.д., но они, как сам понимаешь, для истинных гурманов Win API :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Aram
Сообщения: 18
Зарегистрирован: 16 апр 2007, 14:07

WinMain писал(а):А при чём здесь графические функции (линии, квадратики, окружности)? Это чистой воды арифметика. Бери учебник по алгебре для средней школы и там все эти формулы есть.

Хотя в Win32API есть парочка функций. которые могут тебе существенно облегчить задачу - это PtInRect() и PtInRegion().

Функция PtInRegion() универсальная. В качестве области для неё может быть задана любая фигура. PtInRect() годится только для прямоугольника.
Я знаю что это из курса аналитической геометрии . Но зачем создавать велосипед заново , я подумал может есть уже готовые функции.
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

Библиотека GDI сама по себе слабенькая по части векторной графики, ориентирована в основном на работу с растром, поэтому математических функций в ней совсем мало. Их гораздо больше в OpenGL и Direct3D. Эти графические библиотеки наоборот в основном ориентированы на векторную графику, поэтому там математическая часть на порядок сильнее, чем в GDI.
Аватара пользователя
Decoder
Сообщения: 308
Зарегистрирован: 19 фев 2008, 23:11
Откуда: Moscow

Хорошая тема. Мне тут понадобилось определить, с какой стороны от прямой находится точка (или она лежит на прямой). Каким наиболее простым способом это можно сделать?
Поумнеть несложно, куда труднее от дури избавиться.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Если прямая строится по двум точкам (x1, y1) и (x2, y2), то её уравнение выглядит следующим образом:

(y - y1)/(y2 - y1) = (x - x1)/(x2 - x1)

Либо после приведения к более знакомому виду, который устанавливает зависимость y от x:

y = x * (x2 - x1) / (y2 - y1) - x1*(x2 - x1) + y1*(x2 - y1)

Таким образом, если точка лежит на прямой, то её координаты, будучи подставлены в уравнение, должны обратить его в тождество. Иными словами нам следует вычислить значение M:

M = (y - y1)/(y2 - y1) - (x - x1)/(x2 - x1)

Если M = 0, значит точка лежит на прямой. Если M > 0, то точка лежит в той полуплоскости относительно прямой, в сторону которой направлен нормаль прямой. Если M < 0, то в другой полуплоскости.

Из-за ошибок округления, а также из-за того, что на самом деле у нас мы имеем не классическую плоскость, а дискретную (две различные точки, расположенные достаточно близко друг к другу считаются одной точкой, так как отображаются одним и тем же пикселом экрана), именно из-за этих причин принято проверять не условие M == 0, а соотношение -1 < M < 1. Естественно, это соотношение должно проверяться только после перехода к экранным координатам.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

На эту тему можешь мою статью прочитать. Там как раз про это написано...

http://winmain.epage.ru/geom/page.html
Аватара пользователя
Decoder
Сообщения: 308
Зарегистрирован: 19 фев 2008, 23:11
Откуда: Moscow

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