Нарисовать коло

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

Ответить
romanu416
Сообщения: 6
Зарегистрирован: 29 окт 2013, 02:04

Есть функция для рисования триугольника , а как нарисовать коло ?

Код: Выделить всё

void Triangle::Plump()
{
    MoveToEx(dc, x, y, NULL);
    LineTo(dc, x1, y1);
    MoveToEx(dc, x1, y1, NULL);
    LineTo(dc, x2, y2);
    MoveToEx(dc, x2, y2, NULL);
    LineTo(dc, x, y);
    
}
мне надо потом описать круг вокруг этого треугольника.
я как это сделать через эллипс хз так как там водят крайние координаты прямоугольника.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Ангем тебе в помощь. Возможно есть более простой способ, но мне сразу пришёл в голову вот такой:

1. Вычисляем радиус описанной окружности (вариантов масса, формулы вот тут).
2. Выбираем любую сторону (a) и находим длину серединного перпендикуляра к этой стороне (по формуле Пифагора это получается корень из (R*R - a*a/4)).
3. Строим орт к нашей выбранной стороне a, точнее к вектору, представляющему нашу сторону (меняем местами координаты, добавляя к одной из них минус и делим координаты на длину вектора).
4. Умножаем орт на длину вычисленной на шаге 2 серединной высоты.
5. Устанавливаем полученный вектор в середину стороны а, и, зная все координаты, получаем координаты центра описанной окружности.
6. Теперь, зная координаты центра описанной окружности (Xc, Yx) и радиус описанной окружности (R), несложно вычислить квадрат, ограничивающего эту окружность (Xc - R, Yc - R, Xc + R, Yc + R).

P.S. Небольшая заметочка для сообразительных. На шаге 3 мы могли сменить знак либо у одной, либо у другой координаты, чтобы получить орт. Оба орта будут правильными (перпендикулярны исходному вектору-стороне), но при этом будут торчать в разные стороны от нашей стороны. Вопрос, как правильно выбрать нужный из этих двух ортов? Вопрос лежит на поверхности. Если угол треугольника, противолежащей нашей стороне, острый, то радиус описанной окружности лежит внутри треугольника, если же тупой, то снаружи. Острый угол или тупой, можно определить через косинус, который несложно вычисляется через скалярное произведение двух оставшихся сторон.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Тогда ещё надо определять, куда отложен каждый из ортов (и не стороны, орт стороны - это просто её координаты, делённые на длину без обмена местами и смены знака, а это орт нормали): внутырь, или наружу. А как? Визуально не проблема. А какой формальный признак взять для программирования? Не сразу ведь и сообразишь, как формализовать нахождение точки внутри многоугольника. Зато у описанной окружности есть одно хорошее свойство: расстояния от её центра до всех вершин многоугольника (в данном случае треугольника) равны радиусу, а квадраты, соответственно, - квадрату радиуса. Ну а квадрат расстояния есть сумма квадратов разностей координат.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

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

А какой формальный признак взять для программирования? Не сразу ведь и сообразишь, как формализовать нахождение точки внутри многоугольника.
Не совсем так. Задачу можно переформулировать и тогда никаких проблем с формализацией не возникнет. Наша задача определить находится ли вычисленная точка и свободная вершина треугольника по одну сторону от прямой, проведённой через нашу строну, или по разные. Это проверяется достаточно легко. Следует определить имеет ли один и тот же знак выражение y - f(x), где f(x) - уравнение прямой проходящей через нашу сторону (тогда точки лежат по одну сторону), или разный знак (тогда они лежат по разные стороны).
Ещё вариант: можно отложить орты нормалей ото всех сторон, каждый домножить на длину её серединного перпендикуляра (согласно формуле из пункта 2) и выбрать тройку максимально близких точек, все эти точки будут с некоторой погрешностью отмечать центр окружности.
Совершенно верно, это альтернатива для тех, кому лень вычислять косинус противолежащего угла и построить уравнение прямой, проходящей через две точки. Кстати, достаточно рассмотреть не три, а две стороны - этого будет достаточно.

И да, на счёт терминологии, совершенно верно, я имел в виду построение нормаля, и затем вычисление орта нормаля. Десять лет уже этим термином не пользовался. Формулы все помню, а термин спутал :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ответить