Как рассчитать гладкую кривую между двумя точками, где траектория кривой должна начинаться и заканчиваться под двумя заданными углами

У меня есть 2 точки на пути (x1, y1) и (x2, y2). Обе точки имеют значение угла в градусах (a1 и a2 соответственно). Это углы, которые кривая, пересекающая эти точки, должна составлять с осью y, когда она пересекает соответствующее значение (x, y).

Например, кривая, пересекающая точки (x1, y1) и (x2, y2), должна иметь траекторию a1 градусов в точке (x1, y1), а также траекторию a2 градусов в точках (x2, y2 ).

Я хочу написать функцию, которая находит кривую, соответствующую приведенному выше сценарию, но не знаю, с чего начать. Любая помощь вообще будет оценена по достоинству.


person Jailan    schedule 25.08.2017    source источник
comment
это математический вопрос без кода, вы пытались.   -  person Nina Scholz    schedule 25.08.2017
comment
Кривая Безье   -  person ASDFGerte    schedule 25.08.2017
comment
Вы можете сделать такую ​​кривую из отрезков прямых и дуг окружностей, при этом прямые касаются дуг в месте их соединения.   -  person dmuir    schedule 25.08.2017


Ответы (1)


Вы можете использовать кривую Безье, чтобы создать нужную вам кривую. Контрольные точки определяют касательную кривой в начальной и конечной точках. Таким образом, чтобы установить угол в начале и конце, просто определите контрольные точки вдоль углов.

Данные

var x1 = ?;  // in pixels
var y1 = ?;
var x2 = ?
var y2 = ?;
var ang1 = ?;  // in radians
var ang2 = ?

Получить длину линии

var len =  Math.hypot(x2-x1,y2-y1);

Получите векторы для углов и расширьте примерно до 1/3 len

var ax1 = Math.cos(ang1) * len * (1/3); 
var ay1 = Math.sin(ang1) * len * (1/3);

var ax2 = Math.cos(ang2) * len * (1/3); 
var ay2 = Math.sin(ang2) * len * (1/3);

Затем нарисуйте

ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.bezierCurveTo(
    x1 + ax1, y1 + ay1,
    x2 - ax1, y2 - ay2,
    x2, y2
);
ctx.stroke();

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

person Blindman67    schedule 25.08.2017
comment
Спасибо, это было полезно. Почему вы выбрали 1/3 длины? - person Jailan; 26.08.2017
comment
@Jailan Нет причин, по которым значение является произвольным и может быть любой длины, если оно равно › 0 - person Blindman67; 26.08.2017