Drawing Curves with Lagrange Interpolation (Javascript + HTML5)

Publicado em 20/12/2011

2


Olá pessoal. Tudo certo?!

Nesse post, mostro como desenhar curvas, usando Lagrange Interpolation, usando Javascript.

Há um live demo disponível. Também está disponível o código-fonte completo.

image

UPDATE: Também há um live demo mais interativo, que permite ao usuário definir os pontos que pertencem a curva em http://users.cjb.net/livedemoelemarjr/lagrange2.html. Observe:

image

 

Mais adiante, vou usar esse método para “suavizar” rotas nas animações que estou desenvolvendo na série sobre XNA.

Definindo os pontos da curva

Para esse exemplo simples, optei por selecionar poucos pontos. Observe:


              
var initializePoints = function () {
    var offsetX = canvasWidth / 5;
    points = [];
    points.push({ x: offsetX, y: canvasHeight / 2 });
    points.push({ x: offsetX * 2, y: canvasHeight / 2 - canvasHeight / 4 });
    points.push({ x: offsetX * 3, y: canvasHeight / 2 + canvasHeight / 4 });
    points.push({ x: offsetX * 4, y: canvasHeight / 2 });
};

            

Optei por pegar pontos observando alguma proporcionalidade com  o tamanho da janela.

Implementando Lagrange

As equações matemáticas apresentadas para interpolação usando Lagrange, são implementáveis, em Javascript, assim:


              
var lagrange = function (n, k, t) {
    var l = 1.0, ti, tk;
    tk = k / (n - 1.0);
    for (var i = 0; i < n; i++) {
        if (i != k) {
            ti = i / (n - 1.0);
            l *= ((t - ti) / (tk - ti));
        }
    }
    return l;
};

var evaluate = function (t) {
    var result = { x: 0, y: 0 };
    for (var i = 0; i < points.length; i++) {
        var l = lagrange(points.length, i, t);
        result.x += l * points[i].x;
        result.y += l * points[i].y;
    }
    return result;
};

            

Perceba como o produtório e somatório são calculados dentro do loop.

Desenhando…

Já temos os pontos de referência e a implementação da “lagrange interpolation”. Agora, vamos ver como fazer o desenho da curva. Veja:


              
var draw = function () {
    context.moveTo(points[0].x, points[0].y);
    var t = 0.0;
    for (var t = 0; t <= 1; t += 0.001) {
        var next = evaluate(t);
        context.lineTo(next.x, next.y);
    }
    context.stroke();

    for (var i = 0; i < points.length; i++) {
        context.beginPath();
        context.rect(
            points[i].x - 3, points[i].y - 3,
            6, 6
            );
        context.fillStyle = "#f00";
        context.fill();
        context.closePath();
    }
}

            

Há dois loops. No primeiro, desenho a curva propriamente dita. No segundo, desenho os pontos de referência.

Era isso.

Smiley piscando

Etiquetado:,
Publicado em: Post