Eu tenho um jogo que exige que cada jogador se mova ao longo de um caminho especificado. Eu desenho o caminho usando curvas de Bézier. Como posso determinar o comprimento total real (não linear) do caminho e a distância que cada jogador fez? (A distância entre o ponto inicial e um ponto especificado no caminho.)
ATUALIZAR:
O caminho é representado em um plano cartesiano (2D).
Respostas:
Como as respostas anteriores disseram, calcular o comprimento de uma curva de Bezier é difícil ( impossível ?). Eu diria que 100% dos jogos usam uma aproximação da duração, o que é quase sempre preciso o suficiente.
Há alguns meses, eu o implementei usando a abordagem proposta de quebrar a curva em segmentos "pequenos" e adicionar seu comprimento. Há um exemplo de implementação em C ++ aqui .
fonte
Medir o comprimento de uma curva de Bezier é difícil. Se você não se importa com uma pequena imprecisão, uma solução simples seria aproximar as curvas de Bezier com linhas retas e calcular a soma dos comprimentos das linhas. Quanto mais segmentos você criar, melhor será a aproximação.
fonte
A parametrização do comprimento da spline de ordem superior (ou seja, superior à 1ª ordem) deve ser aproximada; não pode ser representado diretamente, daí o fato de não ser fácil encontrar soluções diretas para isso.
Algumas implementações existentes (código copiar e colar):
Usando aproximações de Chebyshev , de acordo com os autores, a precisão aumenta à medida que o tamanho da curva aumenta. Veja as p. 7-8 pseudocódigo, o restante é uma descrição de outros algoritmos nos quais eles basearam sua abordagem, que você pode ignorar. Várias referências online referem-se a esse método como uma boa.
Veja também essas abordagens concisas.
fonte
Isso começou como um comentário no comentário da resposta de @ bummzack, mas demorou demais.
Existem duas abordagens. O primeiro é apenas o algoritmo padrão para renderizar uma curva de Bézier: os pontos de controle formam uma caixa delimitadora da curva; portanto, se todos os pontos de controle estiverem dentro do epsilon do segmento de linha, do ponto inicial ao ponto final, você se aproxima como uma linha; caso contrário, você subdividirá usando o algoritmo de Casteljau. O Epsilon é escolhido de acordo com o erro que você deseja no resultado final. (Para renderização, geralmente são 0,5 pixels).
A outra abordagem é um refinamento da que usa aritmética de intervalo. Pegue o comprimento da linha do início ao fim como o limite inferior e a soma dos comprimentos das linhas através dos pontos de controle como o limite superior. Mais uma vez, subdividir conforme exigido pelos seus requisitos finais de erro.
Normalmente, um subdivide em t = 0,5, mas o algoritmo de Casteljau permite a divisão em qualquer ponto; portanto, se você tiver um Bézier cúbico com pontos de controle C_0 a C_3 e C_2 estiver muito mais próximo do segmento de linha entre os pontos de extremidade do que C_1, poderá encontrar essa divisão em um de 1/3 ou 2/3 fornece limites mais apertados. Eu não trabalhei na álgebra para justificar qual seria melhor, mas você pode experimentar e informar, se quiser. Se nada mais, eu queria salientar que a opção está lá.
fonte
O cálculo do comprimento de uma curva parametrizada pode ser feito considerando a integral de sqrt ((dx / dt) ² + (dy / dt) ²), onde dx / dt é a derivada do componente x da curva e dy / dt é a derivada do componente y da curva. No caso de uma spline de Bézier, esses dois são iguais, pois a equação pode ser estendida para qualquer dimensão.
A fórmula para uma spline de Bézier cúbica é a seguinte: B (t) = (1 - t³) * P0 + 3 (1 - t) ²t * P1 + 3 (1 - t) t² * P2 + t³ P3 em que P0 até P3 são os pontos de controle.
De acordo com Wolfram | Alpha, a derivada dessa fórmula é: d (B (t)) / dt = 3 (t (t (P3 - P0) + P2 (2 - 3t) + P1 (3t² - 4t + 1))
Agora você pode colocar isso de volta na equação pelo comprimento de uma curva e calcular a integral de t = 0 a t = 1. Infelizmente, Wolfram | Alpha expira quando tento fazer isso. Você pode fazer a integração numérica, no entanto.
fonte