Domanda

Sto scrivendo un programma che disegnerà un solido lungo la curva di una spline. Sto usando Visual Studio 2005 e sto scrivendo in C ++ per OpenGL. Sto usando FLTK per aprire le mie finestre (toolkit veloce e leggero).

Attualmente ho un algoritmo che disegnerà una Spline cubica cardinale, data una serie di punti di controllo, spezzando gli intervalli tra i punti in sottointervalli e disegnando segmenti di linea tra questi punti secondari. Il numero di sottointervalli è variabile.

Il codice del disegno a tratteggio funziona meravigliosamente e sostanzialmente funziona nel modo seguente: Genero un insieme di punti lungo la curva della spline usando l'equazione della spline e li memorizzo in un array (come una speciale struttura di dati chiamata Pnt3f, dove le coordinate sono 3 float e ci sono alcune utili funzioni come distanza, lunghezza, punto e prodotto incrociato). Quindi ho un singolo ciclo che scorre attraverso la matrice di punti e li disegna in questo modo:

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

Come detto, questo codice funziona alla grande. Ora quello che voglio fare è, invece di disegnare una linea, voglio estrudere un solido. La mia attuale esplorazione sta usando un quadric "cilindro" per creare un tubo lungo la linea. Questo è un po 'più complicato, poiché devo orientare openGL nella direzione in cui voglio disegnare il cilindro. La mia idea è di fare questo:

psuedocodarlo:

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

Il mio problema è ottenere gli angoli tra i punti. Ho solo bisogno di imbardata e beccheggio, il rollio non è importante. So che prendere l'arco-coseno del prodotto punto dei due punti diviso per la grandezza di entrambi i punti, restituirà l'angolo tra di loro, ma questo non è qualcosa che posso alimentare con OpenGL con cui ruotare. Ho provato a farlo in 2d, usando il piano XZ per ottenere la rotazione x, e rendendo i punti vettori dall'origine, ma non restituisce l'angolo corretto.

Il mio approccio attuale è molto più semplice. Per ogni piano di rotazione (X e Y), trova l'angolo di:

arco-coseno ((differenza nei valori 'x') / distanza tra i punti)

il valore 'x' dipende da come imposti il ??tuo piano, anche se per i miei calcoli uso sempre il mondo x.

Salvo alcuni problemi di esso facendolo disegnare nel quadrante corretto che non ho ancora elaborato, voglio ottenere consigli per vedere se questa era una buona implementazione o per vedere se qualcuno conosceva un modo migliore.

È stato utile?

Soluzione

È corretto formare due vettori dai tre punti in due segmenti di linea adiacenti e quindi utilizzare l'arccosina del prodotto punto per ottenere l'angolo tra di essi. Per utilizzare questo angolo è necessario determinare l'asse attorno al quale deve avvenire la rotazione. Prendi il prodotto incrociato degli stessi due vettori per ottenere questo asse. Puoi quindi costruire una matrice di trasformazione utilizzando questo angolo dell'asse o passandolo come parametro a glRotate .

Altri suggerimenti

Alcune note:
prima di tutto, questo:

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

non è un buon modo per disegnare nulla. DEVI avere un glEnd () per ogni singolo glBegin (). probabilmente vorrai estrarre glBegin () dal ciclo. il fatto che funzioni è pura fortuna.

seconda cosa

  

La mia esplorazione attuale sta usando a   Quadric "cilindro" per creare un tubo   lungo la linea

Questo non funzionerà come previsto. il quadric "cilindro" ha una base superiore piatta e una base inferiore piatta. Anche se riesci a fare le rotazioni corrette in base alla scanalatura, i bordi delle parti superiori piane salteranno fuori dal volume del tubo previsto e non sarà liscio. Puoi provarlo in 2D con solo una penna e un foglio. Prova a disegnare un tubo liscio usando solo tubi più corti con una base piatta. Questo è impossibile.

Terzo, alla tua vera domanda, lo strumento definitivo per tali rotazioni sono quaternions . È un po 'complesso da spiegare in questo ambito, ma puoi trovare molte informazioni ovunque guardi.
Se avessi usato QT invece di FLTK avresti potuto usare anche libQGLViewer . Ha una classe Quaternion integrata che ti risparmierebbe l'implementazione. Se hai ancora una scelta, ti consiglio vivamente di passare a QT.

Hai considerato gluLookAt ? Metti il ??tuo punto di controllo come punto dell'occhio, il punto successivo come punto di riferimento e rendi il vettore up perpendicolare alla differenza tra i due.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top