Нахождение координат точки эллипса по углу

Я хочу знать координаты вершины эллипса при заданном угле. Центр эллипса находится на x = 0 и y = 0. Большая полуось равна x и имеет значение 1. Малая полуось - это y и имеет значение 0,38. Угол переменный.

Я перепробовал все в этом сообщении Stack Exchange, но ничего не получилось:

Вероятно, неправильные не данные решения, а моя интеграция их в JavaScript.

Например, это не работает:

a = 1
b = 0.38

function getAngle(x1, y1, x2, y2) {
    return Math.atan((y2 - y1) / (x2 - x1)) * 180 / Math.PI
}

angle = getAngle(0,0,0.3,0.7)

x = (a*b*Math.cos(angle))
/
Math.sqrt(
    (a*Math.cos(angle))**2 +
    (b*Math.sin(angle))**2
)

y = (a*b*Math.sin(angle))
/
Math.sqrt(
    (a*Math.cos(angle))**2 +
    (b*Math.sin(angle))**2
)

console.info({x,y})

Вывод:

{
    "x": -0.35112437558647797,
    "y": -0.3823646436315567
}

Как вы можете видеть на этом изображении, результат не является вершиной эллипса:

Как найти координаты точки эллипса на основе угла?

Отвечает ли это на ваш вопрос? OpenGL Ellipse с проблемами начального/конечного угла см. [Edit2] Быстрое аналитическое решение O (1) в моем ответе там

Spektre 21.11.2022 09:32
Как использовать API парсинга квитанций с помощью JavaScript за 5 минут?
Как использовать API парсинга квитанций с помощью JavaScript за 5 минут?
В этом руководстве вы узнаете, как использовать API парсинга квитанций за 5 минут с помощью JavaScript. Eden AI предоставляет простой и удобный для...
Хук useOnClickOutside в ReactJS
Хук useOnClickOutside в ReactJS
Как разработчик ReactJS, вы, возможно, сталкивались с ситуацией, когда вам нужно закрыть модальное или выпадающее меню, когда кто-то щелкает за его...
Хуки (часть-2) - useEffect
Хуки (часть-2) - useEffect
Хук useEffect - один из самых мощных и универсальных инструментов в арсенале разработчика React. Он позволяет вам управлять побочными эффектами в...
Простое руководство по тестированию взаимодействия с пользователем с помощью библиотеки тестирования React
Простое руководство по тестированию взаимодействия с пользователем с помощью библиотеки тестирования React
В предыдущем посте я показал вам на примерах, как писать базовые тесты в React. Важнейшей частью пользовательского интерфейса приложений является...
Как конвертировать HTML в PDF с помощью jsPDF
Как конвертировать HTML в PDF с помощью jsPDF
В этой статье мы рассмотрим, как конвертировать HTML в PDF с помощью jsPDF. Здесь мы узнаем, как конвертировать HTML в PDF с помощью javascript.
Создайте титры как в звездных войнах с помощью CSS и Javascript
Создайте титры как в звездных войнах с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
2
1
75
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Такой эллипс представляет собой просто окружность, масштабированную с коэффициентом 0,38 по оси Y.

Рассуждения, которые я бы применил, чтобы понять ответ, заключались бы в том, чтобы изменить масштабирование.

Если бы вы масштабировали всю ось Y чертежа с коэффициентом 1/0,38≈2,63, то эллипс выглядел бы как круг. Но тогда угол синей линии был бы другим. Потому что у него будет слот не 0,7/0,3, а 2,63×0,7/0,3.

И этот угол также будет углом пересечения точки этой синей линии и эллипса. Это параметрическая координата пересечения эллипса.

Поскольку эта параметрическая координата не зависит от масштабирования, она остается неизменной даже при текущем масштабе 0,38.

Итак, вывод такой

let angle = Math.atan((0.7/0.3)*a/b);
let x = a*Math.cos(angle);
let y = b*Math.sin(angle);

Демонстрация:

let a=1;
let b=0.38;

let canvas=document.getElementById('canvas');
let ctx = canvas.getContext("2d");
let y0=120;
let x0=100;
let sc=150;
ctx.strokeStyle='#000000';
// Axis
ctx.beginPath(); 
ctx.moveTo(0,y0);
ctx.lineTo(300,y0);
ctx.stroke();
ctx.moveTo(x0,0);
ctx.lineTo(x0,300);
ctx.stroke();
// Ellipse
ctx.strokeStyle='#ff0000';
ctx.beginPath();
ctx.moveTo(x0+sc*a,y0);
ctx.ellipse(x0,y0,sc*a, sc*b, 0, 0, 6.28);
ctx.stroke();
// Blue line
ctx.strokeStyle='#0000ff';
ctx.beginPath();
ctx.moveTo(x0,y0);
ctx.lineTo(x0+0.3*sc, y0-0.7*sc);
ctx.stroke();

// Intersection coordinate. The next 3 lines are my answer
// (all the lines before, and after the next 3, are just 
// what is needed for drawing)
let angle = Math.atan((0.7/0.3)*a/b);
let x = a*Math.cos(angle);
let y = b*Math.sin(angle);

// Draw a yellow box at this point. It should intersect both ellipse and line
ctx.fillStyle='#888800';
ctx.beginPath();
ctx.fillRect(x0+x*sc-5, y0-y*sc-5, 10, 10);
<canvas id=canvas width=300 height=200>
</canvas>

Теперь вы можете заметить, что он не отвечает строго на вопрос в заголовке вашего вопроса. Он не дает координаты точки эллипса на основе угла. Поскольку angle здесь не угол синей линии, а угол, который она имела бы, если бы мы масштабировали диаграмму так, чтобы эллипс выглядел как круг.

Но из тела вашего вопроса и, более того, из вашего кода кажется, что ваш реальный вопрос - это «поиск точки в эллипсе на основе наклона линии 0,7/0,3».

Но если вы действительно хотите найти точку по углу (угол синей линии, вам просто нужно использовать tan, чтобы получить наклон, прежде чем масштабировать и использовать atan, чтобы получить реальный угол, который нам нужен.

Так

let parametricAngle = Math.atan(Math.tan(inputAngle)*a/b);
let x=a*Math.cos(parametricAngle);
let y=b*Math.sin(parametricAngle);

Потрясающие! +1. Я пытался сделать это с помощью холста масштаба и перевода, но это тоже не сработало.

Yogi 21.11.2022 01:52

Удивительно и намного проще, чем другие решения, которые я нашел и которые я не мог заставить работать! Было бы просто добавить ограничение переменного центра эллипса? Если его центр не 0; 0, а, например, 0,5; 3, было бы просто применить это решение?

papillon 21.11.2022 09:32

@papillon Это ничего не меняет или почти не меняет. Кстати, вы можете видеть, что в моем фрагменте javascript в реальности центр не (0,0), а (x0,y0)=(100,120), поскольку (0,0) на холсте будет в углу холста . Итак, если у вас есть синяя линия, проходящая через центр (x0, y0) и другую точку (x1, y1), (x1-x0) становится новым 0,3 вашего примера, а (y1-y0) новым 0,7. Таким образом, угол точки равен atan((y1-y0)/(x1-x0)), а то, что я назвал parametricAngle (это угол, который вы должны передать cos и sin), равен atan((y1-y0)/(x1-x0)*a/b).

chrslg 21.11.2022 11:11

Затем из этого parametricAngle=Math.atan((y1-y0)/(x1-x0)*a/b) вы можете узнать точку пересечения, которая является x=x0+a*Math.cos(parametricAngle); и y=y0+b*Math.sin(parametricAngle);.

chrslg 21.11.2022 11:12

Примерно так, как я сделал во фрагменте. Где x0, y0 равно 100 и 120. А x1-x0 0,3, y1-y0 0,7. Единственная разница в том, что в сниппете я сказал y=y0-b*Math.sin(parametricAngle), поэтому - вместо +. Это потому, что в холсте ось y направлена ​​вниз, и я хотел сымитировать ваш график, где ось y по традиции направлена ​​вверх.

chrslg 21.11.2022 11:14

Обратите внимание, что в защиту решений, которые вы получили на Math.SE, они отвечают на первоначальный вопрос. Это не «как я нахожу пересечение эллипса и прямой», а «как я нахожу точку эллипса под углом angle». Мой ответ на это также проще (просто вычислить parametricAngle=Math.atan(Math.tan(angle)*a/b). А затем вычислить cos и sin этого. Что в конце приводит к выражению x=a*Math.cos(Math.atan(Math.tan(angle)*a/b)) и y=b*Math.sin(Math.atan(Math.tan(angle)*a/b))

chrslg 21.11.2022 11:20

Такие sin, cos, tan atan — операции достаточно высокого уровня. Это может быть проще понять, но компьютеру немного сложнее вычислить. А те sin(atan(tan(...))) и cos(atan(tan(...))) имеют более простую формулировку (с точки зрения компьютера, а не с вашей :D). Ответы формы Math.SE — это более простые выражения.

chrslg 21.11.2022 11:21

В вашем случае это будет означать, что директор синей линии dx,dy обозначен как dx=0.3; dy=0.7;, x и y можно вычислить как x=a*b*/Math.sqrt(b*b+a*a*dy*dy/dx/dx) и y=b*Math.sqrt(1-x*x/a/a)

chrslg 21.11.2022 11:33

Очень ясно, спасибо @chrslg! :)

papillon 21.11.2022 11:58

Просто инверсия из решения Math.SE (которое называет y тем, что я называю x, и x тем, что я называю y). Но вне этого они являются одними и теми же ценностями. И быстрее вычисляются. Даже если немного сложнее объяснить

chrslg 21.11.2022 11:59

Другие вопросы по теме