Pergunta

Eu estou escrevendo um programa que vai chamar um sólido ao longo da curva de uma spline. Eu estou usando o Visual Studio 2005 e escrito em C ++ para OpenGL. Estou usando FLTK para abrir minhas janelas (rápido e kit de ferramentas de luz).

Actualmente tenho um algoritmo que irá desenhar uma Spline cúbica Cardinal, dado um conjunto de pontos de controle, quebrando os intervalos entre os pontos acima em subintervalos e desenho linesegments entre esses sub pontos. O número de subintervalos é variável.

O código desenho de linha funciona maravilhosamente, e funciona basicamente do seguinte modo: I gerar um conjunto de pontos ao longo da curva de ranhura, utilizando a equação spline e armazená-los em uma matriz (tal como uma estrutura de dados especial chamado Pnt3f, onde as coordenadas são 3 flutuadores e existem algumas funções úteis, tais como a distância, comprimento, ponto e CrossProduct). Então eu tenho um único laço que percorre o conjunto de pontos e chama-los assim:

glBegin(GL_LINE_STRIP);
for(pt = 0; pt<=numsubsegements ; ++pt) {
    glVertex3fv(pt.v());
}
glEnd();

Como foi dito, este código funciona muito bem. Agora o que eu quero fazer é, em vez de desenhar uma linha, eu quero expulsar um sólido. Minha exploração atual está usando um 'cilindro' quádrica para criar um tubo ao longo da linha. Este é um pouco mais complicado, como eu tenho que orientar openGL na direção que eu quero desenhar o cilindro. Minha idéia é fazer isso:

psuedocode:

Push the current matrix,
translate to the first control point
rotate to face the next point
draw a cylinder (length = distance between the points)
Pop the matrix
repeat

O meu problema é conseguir os ângulos entre os pontos. Eu só preciso de guinada e inclinação, rotação is not importante. Eu sei tomar o arco-cosseno do produto escalar dos dois pontos dividido pelo magnitude de ambos os pontos, irá retornar o ângulo entre eles, mas isso não é algo que eu possa alimentar para OpenGL para girar com. Eu tentei fazer isso em 2D, usando o plano XZ para obter x rotação e tornando os vetores de pontos desde a origem, mas ele não retorna o ângulo correto.

Minha abordagem atual é muito mais simples. Para cada plano de rotação (X e Y), o ângulo encontra por:

arco-co-seno ((diferença de valores 'x') / distância entre os pontos)

o 'x' valor depende de como o seu conjunto o avião para cima, embora para os meus cálculos eu sempre uso mundial x.

Exceto algumas questões dele tornando-se desenhar no quadrante correto que Eu ainda não funcionou ainda, eu quero começar o conselho para ver se isso era uma boa implementação, ou para ver se alguém sabia uma maneira melhor.

Foi útil?

Solução

Você está correto em formando dois vetores dos três pontos em dois segmentos de linha adjacentes e, em seguida, usando o arco cosseno do produto de ponto para obter o ângulo entre eles. Para fazer uso deste ângulo que você precisa para determinar o eixo em torno do qual deve ocorrer a rotação. Leve o produto cruzado dos mesmos dois vetores para obter esse eixo. Você pode então construir uma matriz de transformação usando este eixo de ângulo ou passá-lo como parâmetros para glRotate .

Outras dicas

Algumas notas:
em primeiro lugar, o seguinte:

for(pt = 0; pt<=numsubsegements ; ++pt) {
  glBegin(GL_LINE_STRIP);
    glVertex3fv(pt.v());
}
glEnd();

não é uma boa maneira de desenhar qualquer coisa. Você deve ter um glEnd () para cada glBegin (). você provavelmente vai querer obter o glBegin () fora do circuito. o fato de que isso funciona é pura sorte.

segunda coisa

Meu exploração atual é usando um 'Cilindro' quádrica para criar um tubo ao longo da linha

Isso não vai funcionar como você espera. o 'cilindro' quádrica tem uma base de topo plano e uma base de fundo plano. Mesmo se você sucesso em fazer as rotações corretas de acordo com o spline as bordas dos topos planos estão indo estalar fora do volume do seu tubo destina e não será suave. Você pode experimentá-lo em 2D com apenas uma caneta e um papel. Tente desenhar um tubo liso utilizando tubos única mais curtos com bases planas. Isso é impossível.

Em terceiro lugar, a sua pergunta real, A ferramenta definitiva para essas rotações são quaternions . É um pouco complexo para explicar neste âmbito, mas você pode encontrar informações plentyful qualquer lugar que você olhar.
Se você tivesse usado QT em vez de FLTK você poderia também ter usado libQGLViewer . Ele tem uma classe Quaternion integrada que permitiria poupar-lhe a implementação. Se você ainda tem uma escolha que eu recomendo fortemente de se mudar para QT.

Você considerou gluLookAt ? Coloque o ponto de controle como o ponto de olho, o próximo ponto como ponto de referência, e fazer o vetor perpendicular à diferença entre os dois.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top