Найти точку пересечения кривой безье и перпендикуляром к оси абсцисс

У меня есть следующие параметры: x - координаты точки через которую проведен перпендикуляр к оси абсцисс, cx1, cy1, cx2, cy2 - координаты контрольных точек кубической кривой безье. Начало кривой - в точке (0:0), конец - в точке (1:1). Как мне по этим значениям найти точку пересечения перпендикуляра и кривой (гарантированно, что форма кривой такова, что такая точка всего одна)?

Я сделал следующее:

const curve = function (x, x1, y1, x2, y2) {
    if (x === 0 || x === 1) return x;

    let c1 = new Vector(x1, y1);
    let c2 = new Vector(x2, y2);
    
    const getDot = (step) => {
        let dot1 = calcVector.mult(c1, step);
        let dot2 = calcVector.mult(calcVector.sub(c2, c1), step).add(c1);
        let dot3 = calcVector.mult(calcVector.sub(new Vector(1, 1), c2), step).add(c2);
        let dot21 = calcVector.mult(calcVector.sub(dot2, dot1), step).add(dot1);
        let dot22 = calcVector.mult(calcVector.sub(dot3, dot2), step).add(dot2);
        return calcVector.mult(calcVector.sub(dot22, dot21), step).add(dot21);
    };

    const step = 0.001;

    for (let i = 0; i < 1; i += step) {
        let dot1 = getDot(i);
        let dot2 = getDot(i + step);

        if (dot1.x === x) return dot1.y;
        if (dot2.x === x) return dot2.y; 
        if (dot1.x < x && x < dot2.x) return dot1.add(dot2).div(2).y;
    }
};

Этот код перебирает точки получаемые по алгоритму де Кастельжо и ищет те, которые попали наиболее близко к искомой. Он работает, но конечно не очень это приятно: как-то костыльно. Если кто-нибудь знает способ лучше - подскажите.


Ответы (0 шт):