Для нахождения координат точки эллипса по углу существует простое и элегантное решение. Понимаю, что для маститого математика это решение является очевидным. Однако, для меня в то далекое время, когда инет был диким, связь модемной, а я сильно молодым, это таковым не являлось.
ВНИМАНИЕ! Если Вы искали как найти координаты точки по углу от произвольной прямой и совсем не подразумевали эллипс, то Вам сюда.
Калькулятор точки на эллипсе
Давайте посмотрим, как это выглядит на практике. Потом теория. Оранжевый маркер отвечает за угол, на основании которого считаем координаты. Красный — параметрический угол, о котором ниже.
Параметрическое уравнение эллипса
Обратимся, как обычно, к Википедии. Находим там следующее:
Каноническое уравнение эллипса может быть параметризовано:

Очевидно, что t — это угол, и это не «наш» угол. Это какой-то другой угол, который функционально связан с «нашим». «Нашим» называю угол, от которого требуется посчитать координаты.
Таким образом, задача нахождения координат точки эллипса по углу сводится к задаче нахождения угла t, зависящим от требуемого. Нахождением этой зависимости и займемся.
Подготовка

У нас есть эллипс, описанный двумя полуосями a и b. Представим две окружности, имеющих общий центр. Меньшая окружность (зеленая) имеет радиус b. Большая окружность (синяя) имеет радиус a.
Проведем прямую из общего центра [X0;Y0] в произвольную точку плоскости [X;Y]. В результате пересечения с этими окружностями получаются две точки [X1;Y1] и [X2;Y2].
α – угол между прямой и осью X.
Малая окружность | X1 = b × cos α | Y1 = b × sin α |
Большая окружность | X2 = a × cos α | Y2 = a × sin α |
Нахождение зависимости

Используя уравнение (1) посчитаем координаты точки на эллипсе [X’;Y’] для угла α. Проведем прямую из центра [X0;Y0] в точку [X’;Y’]. Угол β – угол между этой прямой и осью X.
Задача сводится к тому, чтобы найти такой α, при котором β был бы равен интересующему нас углу. Таким образом, угол α будет являться параметром в уравнении (1) для требуемого угла β.
Найдем зависимость между получившимся углом β и углом α. На рисунке видно, что прилегающий к углу катет (синий) равен ранее рассчитанному X2, а противолежащий (зеленый) равен Y1:
X’ = X2 = a × cos α
Y’ = Y1 = b × sin α
Опыт показывает, что тут зачастую возникает легкий ступор. Возможно, рисунок вводит в некое заблуждение. Видим треугольник, и если с синим катетом вопросов нет, то с зеленым — масса. Почему синус от α? Угол «вона где», тут синус вообще не от того угла и т.д.
Смотрим на пересечение прямой и малой (зеленой) окружности. Зеленый катет прилетает именно оттуда. Именно так координату Y’ и рассчитывали, согласно уравнению(1). Рисунок — это иллюстрация, не метод решения.
Тангенс угла β в этом случае равен:
(3) Тангенс угла β
Используя формулу тангенса произведем дальнейшие преобразования:
(4) Зависимость тангенса α от тангенса β
Таким образом, видим прямую зависимость угла α, который нужен нам в качестве параметра в уравнении(1), от угла β, координаты точки от которого хотим получить.
Нахождение координат
Угол α находим через арктангенс. В Delphi (и не только) для этих целей используется функция ArcTan2 из модуля math. Она корректно возвращает знак ± угла в зависимости от квадранта, а также предусмотрительно нечувствительна к возможным коллизиям, типа деления на 0.
Находим синус и косинус от требуемого угла β и подставляем в параметры функции ArcTan2, согласно последней формуле (4):
1 2 3 |
//-- находим параметр (некий угол) для уравнения --- SinCos(Angle,sn,cs); t := ArcTan2(a*sn, b*cs); |
Получившийся в результате вызова ArcTan2 угол есть ничто иное, как параметр t в параметрическом уравнении (1). Подставив его в уравнение, находим координаты точки на эллипсе, отстоящей на заданный угол от оси X.
О параметре
Практический смысл параметра t состоит в том, что это угол окружности до «сплющивания». Этот тот угол окружности, который будет соответствовать точке эллипса при заданном угле. Попытаюсь на практике показать.
В JavaScript’е нет понятия эллипс. Тем более нет понятия дуги эллипса. Но можно нарисовать окружность (через дугу) и «сплющить». Может быть такой номер пройдет и с дугой?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// рисует дугу эллипса function drawArcEllipse(ctx, center, a, b, start, finish, colorLine='none', widthLine=0.0, angle=0.0) { if (a==0.0) return; var t1 = start; var t2 = finish; ctx.beginPath(); // сохраняем контекст ctx.save(); // перемещение координат в центр эллипса ctx.translate(center.x, center.y); // поворот плоскости на угол, если требуется if (angle!=0.0) ctx.rotate(angle); // сжимаем по вертикали ctx.scale(1, b/a); // рисуем дугу ctx.arc(0, 0, a, t1, t2); // восстанавливает контекст ctx.restore(); if (colorLine!='none') ctx.strokeStyle = colorLine; if (widthLine>0.0) ctx.lineWidth = widthLine; ctx.stroke(); ctx.closePath(); } |

На рисунке слева видим, что дуга расположена совершенно неправильно. Очевидно, что надо использовать какие-то другие углы. Вот тут на помощь приходит параметр эллипса. Это как раз тот самый угол, который обеспечивает «попадание» в нужный нам угол при «сплющивании» окружности.
Перепишем функцию с учетом нахождения параметра:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
// рисует дугу эллипса function drawArcEllipse(ctx, center, a, b, start, finish, colorLine='none', widthLine=0.0, angle=0.0) { if (a==0.0) return; var sn = Math.sin(start); var cs = Math.cos(start); var t1 = Math.atan2(a*sn, b*cs); sn = Math.sin(finish); cs = Math.cos(finish); var t2 = Math.atan2(a*sn, b*cs); ctx.beginPath(); // сохраняем контекст ctx.save(); // перемещение координат в центр эллипса ctx.translate(center.x, center.y); // поворот плоскости на угол, если требуется if (angle!=0.0) ctx.rotate(angle); // сжимаем по вертикали ctx.scale(1, b/a); // рисуем дугу ctx.arc(0, 0, a, t1, t2); // восстанавливает контекст ctx.restore(); if (colorLine!='none') ctx.strokeStyle = colorLine; if (widthLine>0.0) ctx.lineWidth = widthLine; ctx.stroke(); ctx.closePath(); } |
На рисунке справа видим, что все встало на свои места. Идеальная дуга )
Координаты точки наклонного эллипса

Перенесено в отдельную статью.
Практика
Две функции. Первая находит параметр t по углу. Вторая производит расчет координат. Из второй не вызываю первую, т.к. получится двойное вычисление полуосей. Код не настолько велик, чтобы его нельзя было продублировать.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//****************************************************************** // Найти угол, который будет использован в расчете точки на элипсе // Т.е. тот самый параметр t в параметрическом уравнении эллипса: // x = a * cos t // y = b * sin t //****************************************************************** function GetEllipseAngleParam(ARect : TRectF; Angle : Extended) : Extended; var sn,cs : Extended; // синус/косинус a,b : Extended; // полуоси по X/Y begin a := ARect.Width/2; b := ARect.Height/2; SinCos(Angle,sn,cs); result := ArcTan2(a * sn, b * cs); end; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
//******************************************************************** // Найти координату точки на эллипсе по углу отклонения //******************************************************************** function CalcEllipsePointCoord(ARect : TRectF; Angle : extended) : TPointF; var sn,cs : Extended; // синус/косинус a,b : Extended; // полуоси по X/Y cnt : TPointF; // центр t : Extended; // параметр для уравнения эллипса begin // инициализация полуосей a := ARect.Width/2; b := ARect.Height/2; // центр эллипса cnt := ARect.CenterPoint; // находим параметр (некий угол) для уравнения SinCos(Angle,sn,cs); t := ArcTan2(a * sn, b * cs); // считаем результат по параметрическому уравнению SinCos (t, sn, cs); result.X := cnt.x + a * cs; result.Y := cnt.Y + b * sn; end; |
Скачать исходник + исполнямый файл
Друзья, спасибо за внимание!
Надеюсь, материал после правок стал понятней.
Подписывайтесь на телегу.
Если есть вопросы, с удовольствием отвечу )
Подскажите пожалуйста,я пытаюсь сделать примерную операцию в экселе, но по формуле atan2, оно не выводит значение, которое аналогично вашему в данной статье, а в разы меньше.
Булат, тут не «блокирует», просто комментарий требует одобрения для новых пользователей. Следующий ваш комментарий проскочит уже сразу, без одобрения.
В итоге, разобрались в группе телеграм-канала.
Для читателей вкратце обрисую проблему. Возможно, у кого-то есть аналогичный трабл.
Необходимо найти параметрических угол, но в Excel.
1) «в разы меньше» — вечная проблема радианов в градусы.
НО! Цитата из телеги: «Булат, [16.03.2022 15:45]
Если быть точнее, у меня получается 0,79818, что равняется 45,732 в градусах, а у вас 44,2
Достаточно большая погрешность»
2) оказалось, что функция ATAN2 в Excel (в отличие от Delphi, JS, C#) первым параметром берет X, вторым Y. Когда аргументы были поменены местами, результат стал тот, который ожидался.
Мне кажется что на диаграмме неправильно строиться, по координате У с положительным значением точка с низу.
Ось Y направлена вниз. Это нормально. И настолько привычно, что не сразу увидел в своё время, что неплохо бы знак поменять. Разницу между направлениями Y можно тут глянуть