2011-10-17 11 views
7

MODIFICA: si tratta di un errore di libreria. I reported alla mailing list di HOpenGL.GLU NURBS reso in modo errato

Uso un metodo rettangolare a 9 punti per rappresentare un cerchio/ellisse come NURBS.

I punti sono p1, p2, ..., p9, p9 = p1. Posano come mostrato:

y2 | p2 p3 p4 
y1 | p1 p5 
y0 | p8 p7 p6 
------------- 
    | x0 x1 x2 

x1 = (x0 + x2)/2 
y1 = (y0 + y2)/2 

I.e. p1 = (x0, y1), p2 = (x0, y2) e così via.

e pesi sono:

  • 1 per punti medi (p1,p3,p5,p7)
  • sqrt(0.5) per punti angolo (p2,p4,p6,p8)

ho applicato pesi come coordinate omogenee, utilizzando due modi:

  • destra - (x,y) con il peso w diventa Vertex4 (w*x) (w*y) 0 w
  • sbagliato - diventa Vertex4 x y 0 w

I risultati (a destra prima, seconda sbagliato, scusate se sono troppo grandi): first second

Vedete, entrambi non sono cerchi giusti (anche se il secondo sembra bello) e non riesco a capire perché.

seguito riportata il codice, basato su Lines.hs dagli esempi GLUT:

import System.Exit (exitWith, ExitCode(ExitSuccess)) 
import Graphics.UI.GLUT 
import Foreign.Marshal.Array 
import Graphics.Rendering.OpenGL.GLU.NURBS 

myInit :: IO() 
myInit = do 
    clearColor $= Color4 0 0 0 0 

display :: DisplayCallback 
display = do 
    clear [ ColorBuffer, DepthBuffer ] 
    color (Color3 1.0 1.0 1.0 :: Color3 GLfloat) 

    withNURBSObj() $ \nurbsObj -> do 
    nurbsBeginEndCurve nurbsObj $ 
     withArrayLen knots $ \nKnots knots -> 
     withArray controls $ \controls -> do 
      nurbsCurve nurbsObj (fromIntegral nKnots) knots stride controls order 

    flush 

    where 
    order = 3 
    stride = 4 -- number of floats in Vertex 
    controls = zipWith mkControl points weights 
    mkControl (x, y) w = Vertex4 (x*w) (y*w) 0 w 
    -- mkControl (x, y) w = Vertex4 x y 0 w 
    knots = [0, 0, 0, 0.25, 0.25, 0.5, 0.5, 0.75, 0.75, 1, 1, 1] 
    weights = let a = sqrt 0.5 in [1, a, 1, a, 1, a, 1, a, 1] 
    points = [ 
     (x0, y1), (x0, y2), (x1, y2), 
     (x2, y2), (x2, y1), (x2, y0), 
     (x1, y0), (x0, y0), (x0, y1) 
     ] 

    y1 = (y0 + y2)/2 
    x1 = (x0 + x2)/2 
    (x0, x2) = (50, 450) 
    (y0, y2) = (x0, x2) 

reshape :: ReshapeCallback 
reshape [email protected](Size w h) = do 
    viewport $= (Position 0 0, size) 
    matrixMode $= Projection 
    loadIdentity 
    ortho2D 0 (fromIntegral w) 0 (fromIntegral h) 
    -- the following line is not in the original example, but it's good style... 
    matrixMode $= Modelview 0 

keyboard :: KeyboardMouseCallback 
keyboard (Char '\27') Down _ _ = exitWith ExitSuccess 
keyboard _ _ _ _ = return() 

-- Request double buffer display mode. 
-- Register mouse input callback functions 
main :: IO() 
main = do 
    (progName, _args) <- getArgsAndInitialize 
    initialDisplayMode $= [ SingleBuffered, RGBMode ] 
    initialWindowSize $= Size 500 500 
    initialWindowPosition $= Position 100 100 
    createWindow "Test" 
    myInit 
    displayCallback $= display 
    reshapeCallback $= Just reshape 
    keyboardMouseCallback $= Just keyboard 
    mainLoop 

EDIT: Ricontrollai coefficienti diverse volte, e prima rappresentazione rettangolare ho usato 7-point metodo triangolo, e c'erano distorsioni molto simili. Quindi non dovrebbe essere un problema con una rappresentazione concreta.

+0

Solo un suggerimento: si dovrebbe cambiare la visualizzazione in "Int -> Int -> DisplayCallback', con il primo in parametri che è la dimensione della finestra, impostando anche l'intera proiezione sul display. In risagoma, usa 'displayCallback $ = display w h'; questo rende molto più Haskell-ish, evitando impurità inutili. – datenwolf

+0

gah, tanti errori di battitura in un singolo commento e nessun modo per modificarlo. – datenwolf

risposta

5

Ok, con la mia prima risposta ho avuto un momentaneo errore. In ogni caso, non si dispone di un bug nel codice a tutti: Se io compilare ed eseguire il codice dato ottengo questo:

NURBS circle

Ho il sospetto, qualcosa nella tua installazione di Haskell è rotto.

EDIT causa di commentare:

Ora che è strano ...

sto usando Gentoo, quindi il mio sistema offre i moduli Haskell OpenGL attraverso il sistema Portage.Così ottengo questo:

loki ~ # for p in OpenGL OpenGLRaw GLURaw; do ghc-pkg latest $p; done 
OpenGL-2.2.1.1 
ghc-pkg: cannot find package OpenGLRaw 
ghc-pkg: cannot find package GLURaw 

Così ho installato l'OpenGL e GLUT moduli con cabala nel mio homedir:

[email protected] ~ $ for p in OpenGL OpenGLRaw GLURaw; do ghc-pkg latest $p; done 
OpenGL-2.4.0.1 
OpenGLRaw-1.1.0.1 
GLURaw-1.1.0.0 

E con quelli installati posso riprodurre la vostra prima immagine!

+0

Oh, è un grande WTF per me ora. Forse anche qualcosa non va con il driver della scheda grafica. Grazie mille, pubblicherò un aggiornamento quando ne saprò il motivo. – modular

+0

Puoi scrivere la tua piattaforma e le versioni dei pacchetti OpenGL, GLURaw e forse OpenGLRaw e GLUT? – modular

+0

È possibile eseguire: 'per p in OpenGL OpenGLRaw GLURaw; fare ghc-pkg latest $ p; done' – modular

Problemi correlati