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

311
22 марта 2017, 14:29

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

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

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

Answer 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 другая.

Answer 2

Алгоритм вычисления крайних точек следующий:

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)+")");
Answer 3

Задайте клип регион в виде прямоугольника за вычетом кругов и рисуйте как рисовали - от центра к центру.

https://msdn.microsoft.com/en-us/library/system.drawing.graphics.clip(v=vs.110).aspx

READ ALSO
Какой инструмент выбрать для клиента и для работы с базой данных используя C#?

Какой инструмент выбрать для клиента и для работы с базой данных используя C#?

Какой инструмент выбрать для клиента и для работы с базой данных используя C#?

297
Подписаться на событие внутри job

Подписаться на событие внутри job

Используется QuartzNET

225
C# Invoke Chart

C# Invoke Chart

Нужно сделать так чтобы было видно построение объекта в Chart, но при это не зависала программаЕсть код без Invoke устраивает скорость, но зависает...

270
Упорядочить по убыванию 4 числа [требует правки]

Упорядочить по убыванию 4 числа [требует правки]

Написать программу которая упорядочивает 4 числа по убыванию используя только конструкцию if

467