Gdi
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
Скажите пожалуйста существует ли в С++ библиотека для работы с линиями, квадратиками, окружностью? Т.е мне нужно знать, наприрмер, пересекаются ли две прямые, находится ли точка на прямой, Находится ли прямая в области (например в квадрате, в окружности), лежит точка в области? и т.д.
А при чём здесь графические функции (линии, квадратики, окружности)? Это чистой воды арифметика. Бери учебник по алгебре для средней школы и там все эти формулы есть.
Хотя в Win32API есть парочка функций. которые могут тебе существенно облегчить задачу - это PtInRect() и PtInRegion().
Функция PtInRegion() универсальная. В качестве области для неё может быть задана любая фигура. PtInRect() годится только для прямоугольника.
Хотя в Win32API есть парочка функций. которые могут тебе существенно облегчить задачу - это PtInRect() и PtInRegion().
Функция PtInRegion() универсальная. В качестве области для неё может быть задана любая фигура. PtInRect() годится только для прямоугольника.
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Верно, это элементарная геометрия, там всё достаточно просто. Графические функции по определению не умеют ничего подобного. Их предназначение - рисовать, а не давать вопросы по курсу школьной геометрии.
По поводу API Helpers, могу ещё добавить функцию RectInRegion. Есть ещё набор функций для работы с прямоугольниками: объединение, пересечение, равенство и т.д., но они, как сам понимаешь, для истинных гурманов Win API
По поводу API Helpers, могу ещё добавить функцию RectInRegion. Есть ещё набор функций для работы с прямоугольниками: объединение, пересечение, равенство и т.д., но они, как сам понимаешь, для истинных гурманов Win API

Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Я знаю что это из курса аналитической геометрии . Но зачем создавать велосипед заново , я подумал может есть уже готовые функции.WinMain писал(а):А при чём здесь графические функции (линии, квадратики, окружности)? Это чистой воды арифметика. Бери учебник по алгебре для средней школы и там все эти формулы есть.
Хотя в Win32API есть парочка функций. которые могут тебе существенно облегчить задачу - это PtInRect() и PtInRegion().
Функция PtInRegion() универсальная. В качестве области для неё может быть задана любая фигура. PtInRect() годится только для прямоугольника.
Библиотека GDI сама по себе слабенькая по части векторной графики, ориентирована в основном на работу с растром, поэтому математических функций в ней совсем мало. Их гораздо больше в OpenGL и Direct3D. Эти графические библиотеки наоборот в основном ориентированы на векторную графику, поэтому там математическая часть на порядок сильнее, чем в GDI.
Хорошая тема. Мне тут понадобилось определить, с какой стороны от прямой находится точка (или она лежит на прямой). Каким наиболее простым способом это можно сделать?
Поумнеть несложно, куда труднее от дури избавиться.
- 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. Естественно, это соотношение должно проверяться только после перехода к экранным координатам.
(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" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
На эту тему можешь мою статью прочитать. Там как раз про это написано...
http://winmain.epage.ru/geom/page.html
http://winmain.epage.ru/geom/page.html
Спасибо, WinMain.
Интересное решение и очень простое.
Поскольку в теле функции нет операции деления, то исключается ошибка деления на ноль и при этом нет потерь в точности вычислений из-за округления результата.
Интересное решение и очень простое.
Поскольку в теле функции нет операции деления, то исключается ошибка деления на ноль и при этом нет потерь в точности вычислений из-за округления результата.
Поумнеть несложно, куда труднее от дури избавиться.