Страницы

Поиск по вопросам

воскресенье, 16 февраля 2020 г.

Как соединить две окружности прямой

#c_sharp #графика


Имеются две окружности одного радиуса R с центрами в точках x1, y1; x2, y2, с произвольным
расположением.

Вопрос: как провести прямую, которая соединяла бы эти окружности, но при этом не
пересекала их? 
Вариант с перерисовыванием окружностей поверх прямой не годится.
Прямую рисую вот так:

Brush red = new SolidBrush(Color.Red);
Pen redPen = new Pen(red, 2);         
gr.DrawLine(redPen, x1, y1, x2, y2);




    


Ответы

Ответ 1



У вас есть окружности с центрами в O1 = (x1, y1) и O2 = (x2, y2), радиуса r. Заведём вектор C, указывающий из центра первой окружности в центр второй: классическое "конечные минус начальные": C = O2 - O1 = (x2 - x1, y2 - y1). Но это смещение, лишённое "базовой точки". Для чего оно? Для того, чтобы вычислить смещение каждого из двух концов искомого отрезка относительно центров окружностей. Если присмотреться, видно, что смещения одинаковы, просто выполнены в прямо противоположные стороны. И направлены они параллельно (коллинеарно, в векторных терминах) C. У нас есть правильно направленный вектор, но неправильной длины. Но длину можно исправить, умножив вектор на число m = r / length(C). Получится вектор S = C * m = (C.x * m, C.y * m). O1 + S это одна точка отрезка, O2 - S другая.

Ответ 2



Я разобрался и нашел более простое решение: double theta = Math.Atan2(y2 - y1, x2 - x1); x1 = x1 + r * cos(theta) y1 = y1 + r * sin(theta) Вторая координата (x2, y2) находится аналогично, только радиус вычитается

Ответ 3



Алгоритм вычисления крайних точек следующий: int x1 = 0, y1 = 0, r1 = 1, x2 = 3, y2 = 4, r2 = 1; // получаем единичный вектор направленный от центра первой окружности ко второй Vector2 norm = Vector2.Normalize(new Vector2(x2-x1, y2-y1)); // удлиняем его на радиусы окружностей Vector2 v1 = Vector2.Multiply(r1, norm); // для конца линии умножаем на отрицательный скаляр - получаем вектор в обратном направлении Vector2 v2 = Vector2.Multiply(-r2, norm); // Искомые точки получаем простым суммированием: Console.WriteLine("(" + (x1+v1.X) +", "+ (y1+v1.Y)+") - (" + (x2+v2.X) +", "+ (y2+v2.Y)+")");

Комментариев нет:

Отправить комментарий