Eu olhei em volta por um tempo e não consigo encontrar uma solução para esse problema. Digamos que eu tenho uma curva cúbica de bezier (definida por 4 pontos) e desejo obter um conjunto de pontos espaçados uniformemente ao longo da curva. Pense em colocar um texto ao longo de uma curva, por exemplo.
Agora, o problema é que, se eu inserir t
(valor de interpolação de 0-1) com um incremento constante, os pontos não serão espaçados uniformemente. A distância ao longo da curva é menor quando a curva faz uma curva e maior quando a curva é reta.
Então, como coloco pontos uniformemente ao longo de uma curva de bezier?
interpolation
curves
beziers
Potrus
fonte
fonte
t
, digamos, 100 passos e meça as distâncias entre os pontos resultantes. Em seguida, interpole ao longo dessa polilinha, conforme desejado.Respostas:
É mais uma questão de matemática. Assim, uma curva de Bezier tem a seguinte fórmula , tanto no
x
ey
componente.O comprimento percorrido ao
t
longo de uma curvagamma
é dado por:Não há solução gravável em humanos para a integral, então você precisa se aproximar.
Substitua
gamma(t)
by pela expressãoB(t)
para obter o comprimentolength_B
percorrido aot
longo do segmento bezier. Digamos que ele viaja de0
paraL
.Agora escolha
n
valores entre0
eL
que correspondam aos pontos espaçados igualmente. Por exemplo, comprimentos do formuláriok*L/n
parak
de0
atén
.Agora você precisa inverter a função
length_B
, para poder calcular ast
costas a partir do comprimentol
. É muita matemática e eu sou preguiçoso como o inferno, tente fazer isso sozinho. Se não puder, pode ir para a troca de pilha matemática . Para uma resposta mais completa, você pode ir para lá de qualquer maneira.Depois de ter essa
length_B
função inversa (ou uma aproximação razoável), o processo é bastante simples.l[k]
de distância do caminho especificado longe da origem(P0_x,P1_x)
.t[k]
uso correspondentelength_B_inverse
.(B_x(t[k]),B_y(t[k]))
.fonte
Bem, já faz algum tempo ...
Mas finalmente consegui resolver esse problema!
Tudo o que você precisa está neste post: Movendo naves entre dois planetas ao longo de um bezier, faltando algumas equações para aceleração
fonte
Apenas para expandir o que Marco disse, uma técnica comum para fazer isso é descer a curva em incrementos muito menores do que os passos de comprimento fixo que você deseja executar e armazenar o ponto de saída resultante (e talvez a distância?) Em uma tabela.
Em seguida, você percorre a tabela e descarta todas as entradas, exceto os pontos mais próximos dos múltiplos inteiros das distâncias que deseja percorrer.
Você fica com uma tabela que pode indexar diretamente em tempo de execução muito rapidamente. Se você quiser ir para o ponto que é 5 vezes o tamanho da sua distância, procure na tabela no índice [5].
Observe que você pode executar as duas etapas em uma e não armazenar os itens extras na tabela para começar, mas é mais fácil visualizar e entender em duas etapas.
Certa vez, vi uma técnica para calcular isso rapidamente, sem pré-calcular uma tabela (também não usava iteração / localização de raiz!), Mas, infelizmente, não me lembro dos detalhes:
Se eu me lembrar ou encontrar, postarei as informações!
fonte
Etapa 1 - Gere N + 1 pontos interpolando a curva em incrementos de 1 / N. N deve ser grande o suficiente para obter bons resultados visuais, mas pequeno o suficiente para ser facilmente calculado. Um valor de 50 deve ser bom para a maioria das situações, mas deve ser ajustado para o seu caso específico. Vou chamar isso de "pontos interpolados".
Como alternativa, você pode gerar uma lista curta de segmentos e interromper recursivamente cada segmento maior que o comprimento máximo desejado do segmento (inicialmente você deve gerar pelo menos quatro segmentos para contabilizar as curvas S, onde o início está muito próximo do fim).
Etapa 2 - "Ande na linha" usando os pontos interpolados e o espaçamento desejado entre cada ponto.
Vou deixar aqui meu código do Unity:
fonte
Aqui está um algoritmo que fornece bons resultados:
fonte