Results 1 to 6 of 6

Thread: Möbius strip

  1. #1

    Möbius strip

    Mobius strip is a paper strip in which A connect to D and B connect to C.
    A------------------------C
    ........................
    B------------------------D


    it is a strange entity , we can't determine its up or down so it is causing confusion, look its lighting on the following demos which are the same demos but done in 2 ways
    the first demo depends on lesson 4
    http://psch.thinbasic.com/old/tbgl_lesson4.html
      Uses "TBGL"
      Uses "UI" 
      Uses "math"
      
      DIM hWnd      as dword
      Dim x, y, z, u, v As Single 
      Dim wireframe As Long
      
      ' We will initialize OpenGL and internal buffers
      ' Function also returns window handle
      hWnd = TBGL_CreateWindowEx("Mobius Strip - press 'W' for wire/solid frame...... press ESC to quit", 640, 480, 32, %TBGL_WS_WINDOWED )      
                                    
      tbgl_ShowWindow               ' This will display the window on the screen
      TBGL_BackColor 255,255,255
      TBGL_UseLighting(%TRUE)
      TBGL_UseLightSource(%GL_LIGHT0, %TRUE)  
      
      TBGL_GetAsyncKeyState(-1)  ' Reset status of the all keys to prevent immediate quit  
      'TBGL_PolygonLook %GL_LINE
      while TBGL_IsWindow(hWnd)          ' While window exists, we will draw and check for ESCAPE
       If TBGL_GetWindowKeyOnce( hWnd, %VK_W) Then 'display wireFrame or solid frame
        If wireframe = 0 Then
          TBGL_PolygonLook %GL_LINE
          wireframe = 1
          Else
          TBGL_PolygonLook %GL_FILL
          wireframe = 0
        End If
       End If 
       
        tbgl_ClearFrame             ' This clears the frame and prepares it for drawing
            
        TBGL_Camera 0,2,4,0,0,0    ' We will look from point 0,0,10 to 0,0,0 ( origin of coordinates )
       
        TBGL_Color 0, 255, 0
        TBGL_PushMatrix 
          TBGL_Rotate 90, 1, 0, 0 
          TBGL_Rotate GetTickCount/50, 0, 0, 1 
          DrawQuads   
        tbgl_PopMatrix       
    
        
        tbgl_DrawFrame              ' This will display the scene
        
        ' When ESCAPE is pressed, we will leave the main loop
        IF TBGL_GetWindowKeyState( hWnd, %VK_ESCAPE ) THEN EXIT while
        
      Wend  
      
      tbgl_DestroyWindow            ' This will destroy the window
    
    Sub DrawQuads( )
    u=0
    TBGL_BeginPoly %GL_QUAD_STRIP
        
    While u <= 2*Pi
    v = -0.5
    While v<= 0.5
           x = Cos(u) * ( 1 + (v/2 * Cos(u/2)) )
    			 y = Sin(u) * ( 1 + (v/2 * Cos(u/2)) )
    			 z = v/2 * Sin(u/2)
    			 TBGL_Vertex x,y,z
           v+1
    Wend 
    v = -0.5
    u + 0.1
    Wend
    'connect the last 2 points to the first 2 points in reverse 
    v = 0.5 :u=0
    While v>= -0.5
           x = Cos(u) * ( 1 + (v/2 * Cos(u/2)) )
    			 y = Sin(u) * ( 1 + (v/2 * Cos(u/2)) )
    			 z = v/2 * Sin(u/2)
    			 TBGL_Vertex x,y,z
           v-1
    Wend 
    TBGL_EndPoly               
    
    end sub
    
    the second demo is using the GBuffer
    Uses "TBGL"
    Uses "math"
    
    Function TBMain()
      Local hWnd      As DWord 
      Local i,wireframe As Long
      Local FrameRate As Double
      ' -- Create and show window
      hWnd = TBGL_CreateWindowEx("Mobius strip using GBuffers - press 'W' for wire/solid Frame,...press ESC to quit", 600, 600, 32, %TBGL_WS_WINDOWED Or %TBGL_WS_CLOSEBOX) 
      TBGL_ShowWindow 
      TBGL_BackColor 255,255,255 
      'TBGL_PolygonLook %GL_LINE
      ' -- Create 3D points buffer
      Dim gbQuad As DWord = TBGL_GBufferCreate(%TBGL_QUADSTRIP, %TBGL_3D)
      Global Nb As DWord = 128 
      ' -- Define data for it
      Global VertexA(Nb) As TBGL_TVECTOR3F
      Global ColorA(Nb)  As TBGL_TRGB  
      Global NormalA(Nb)    As TBGL_TVECTOR3F   
      
       FillArrays ' call the sub to fill VertexA , ColorA  arrays
       For i = 1 To Nb
        ColorA(i).r = Rnd(128, 255)'0
        ColorA(i).g = Rnd(128, 255)'255
        ColorA(i).b = Rnd(128, 255)'0
       Next 
      
      For i = 1 To Nb
        NormalA(i).x = 0
        NormalA(i).y = 1
        NormalA(i).z = 0
      Next   
          
      ' -- Create buffer dynamically linked to the arrays above
      TBGL_GBufferDefineFromArray(gbQuad, %TBGL_DYNAMIC, CountOf(VertexA), VertexA(1), ColorA(1), NormalA(1))
      TBGL_UseLighting(%TRUE)
      TBGL_UseLightSource(%GL_LIGHT0, %TRUE)                
      
      ' -- Resets status of all keys 
      TBGL_ResetKeyState() 
      
        ' -- Main loop
      While TBGL_IsWindow(hWnd)
    If TBGL_GetWindowKeyOnce( hWnd, %VK_W) Then
    If wireframe = 0 Then
    TBGL_PolygonLook %GL_LINE
    wireframe = 1
    Else
    TBGL_PolygonLook %GL_FILL
    wireframe = 0
    End If
    End If
      'init 
        FrameRate = TBGL_GetFrameRate
        TBGL_ClearFrame
          TBGL_Camera(0, 10, 20, 0, 0, 0)
          TBGL_Rotate 90, 1, 0, 0
          TBGL_Rotate GetTickCount/50, 0, 0, 1
                ' -- Render it                              
          TBGL_GBufferRender(gbQuad)   
          TBGL_DrawFrame
         ' -- ESCAPE key to exit application
        If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While
      Wend       
      
      ' -- Destroy window
      TBGL_DestroyWindow
    End Function 
     
    Sub FillArrays() 
    
    Dim x, y, z, u, v As Single
    v = -0.5 
    Dim N As DWord = 1
    While u <= 2*Pi
    v = -0.5
    While v<= 0.5
           x = Cos(u) * ( 1 + (v/2 * Cos(u/2)) )
    			 y = Sin(u) * ( 1 + (v/2 * Cos(u/2)) )
    			 z = v/2 * Sin(u/2)
    			
              VertexA(N).x = x*6
              VertexA(N).y = y*6
              VertexA(N).z = z*6
                   
        v+1 : N + 1
    Wend 
    
    v = -0.5
    u + 0.1
    Wend 
    
    VertexA(N).x = VertexA(2).x
    VertexA(N).y = VertexA(2).y
    VertexA(N).z = VertexA(2).z
    N+1
    VertexA(N).x = VertexA(1).x
    VertexA(N).y = VertexA(1).y
    VertexA(N).z = VertexA(1).z
    
    End Sub
    
    mobius.PNG
    Last edited by primo; 14-08-2016 at 10:55.

  2. #2
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732
    Very cool example! Would you like some help with calculating proper normals?


    Petr
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  3. #3
    Yes Petr of course i need help for better Normals and lighting for all parts of Mobius strip, i thought first it is not possible.
    the lighting of this kind of shapes cause confusion, it is suitable as a question in computer Lab exam .
    i have tried it again and the best result i can get is this (in the second demo)
    For i = 1 To Nb
    NormalA(i).x = Rnd(-1,1)
    NormalA(i).y = Rnd(-1,1)
    NormalA(i).z = Rnd(-1,1)
    Next

    at least the strip will not darken totaly for some moments while rotating

  4. #4
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732
    The normal calculation should be deterministic, I will dive into it this weekend


    Stay tuned,
    Petr
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  5. #5
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732
    One of the possible approaches, based on: http://psch.thinbasic.com/old/tbgl_lesson6.html

    Uses "TBGL", "math"
     
    Function TBMain()
      long  i, wireframe 
      double FrameRate 
      ' -- Create and show window
      dword hWnd = TBGL_CreateWindowEx("Mobius strip using GBuffers - press 'W' for wire/solid Frame,...press ESC to quit", 600, 600, 32, %TBGL_WS_WINDOWED Or %TBGL_WS_CLOSEBOX) 
      TBGL_ShowWindow
      TBGL_BackColor 255,255,255 
      
      ' -- Create 3D points buffer
      Dword gbQuad = TBGL_GBufferCreate(%TBGL_QUADSTRIP, %TBGL_3D)
      
      single detail = 0.01
      dword Nb = CalculateBufferSize(detail)
      ' -- Define data for it
      dim VertexA(Nb) As TBGL_TVECTOR3F
      dim ColorA(Nb)  As TBGL_TRGB  
      dim NormalA(Nb) As TBGL_TVECTOR3F   
       
      BuildGeometry(vertexA, detail)
      CalculateNormals(vertexA, normalA)
      PaintGeometry(colorA) 
           
      ' -- Create buffer dynamically linked to the arrays above
      TBGL_GBufferDefineFromArray(gbQuad, %TBGL_DYNAMIC, CountOf(VertexA), VertexA(1), ColorA(1), NormalA(1))
      TBGL_UseLighting(%TRUE)
      TBGL_UseLightSource(%GL_LIGHT0, %TRUE)                
       
      ' -- Resets status of all keys 
      TBGL_ResetKeyState() 
      single time
        ' -- Main loop
      While TBGL_IsWindow(hWnd)
        If TBGL_GetWindowKeyOnce( hWnd, %VK_W) Then
          If wireframe = 0 Then
            TBGL_PolygonLook %GL_LINE
            wireframe = 1
          Else
            TBGL_PolygonLook %GL_FILL
            wireframe = 0
          End If
        End If  
            
        FrameRate = TBGL_GetFrameRate
        TBGL_ClearFrame
          TBGL_Camera(0, 10, 20, 0, 0, 0)
          TBGL_Rotate 90, 1, 0, 0
          TBGL_Rotate time/50, 0, 0, 1
          ' -- Render it                              
          TBGL_GBufferRender(gbQuad)   
        TBGL_DrawFrame
        
         ' -- ESCAPE key to exit application
        If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While
        time+= 1/FrameRate*1000
      Wend      
       
      ' -- Destroy window
      TBGL_DestroyWindow
    End Function
    
    
    function CalculateBufferSize(detail as single) as long
      single u, v
      
      dword N = 1
      While u <= 2 * Pi
        v = -0.5
        While v <= 0.5          
          v+1 : N + 1
        Wend
        u + detail
      Wend
      return n+1
    end function
    
    
    Sub BuildGeometry(byref vertexA() As tbgl_tVector3F, detail as single) 
     
      single x, y, z, u, v
      
      dword N = 1
      While u <= 2 * Pi
        v = -0.5
        While v <= 0.5
          x = Cos(u) * ( 1 + (v/2 * Cos(u/2)) )
          y = Sin(u) * ( 1 + (v/2 * Cos(u/2)) )
          z = v/2 * Sin(u/2)
               
          vertexA(N).x = x*6
          vertexA(N).y = y*6
          vertexA(N).z = z*6
                        
          v+1 : N + 1
        Wend
        u + detail
      Wend
       
      VertexA(N).x = VertexA(2).x
      VertexA(N).y = VertexA(2).y
      VertexA(N).z = VertexA(2).z
      N+1
      VertexA(N).x = VertexA(1).x
      VertexA(N).y = VertexA(1).y
      VertexA(N).z = VertexA(1).z
    End Sub           
    
    
    sub CalculateNormals(byref vertexA() as tbgl_tVector3F, byref normalA() as tbgl_tVector3F) 
      single ux, uy, uz,
             vx, vy, vz,
             nx, ny, nz
             
      long i, j
      For i = 1 To countOf(NormalA)-3 step 4
        ux = vertexA(i+1).x - vertexA(i).x
        uy = vertexA(i+1).y - vertexA(i).y
        uz = vertexA(i+1).z - vertexA(i).z
    
    
        vx = vertexA(i+2).x - vertexA(i).x
        vy = vertexA(i+2).y - vertexA(i).y
        vz = vertexA(i+2).z - vertexA(i).z
        
        nx =   uy * vz - uz * vy
        ny = -(ux * vz - uz * vx)
        nz =   ux * vy - uy * vx
        
        for j = 0 to 3
          NormalA(i+j).x = nx
          NormalA(i+j).y = ny
          NormalA(i+j).z = nz
        next
      Next
      
    end sub           
    
    
    sub PaintGeometry(byref colorA() as tbgl_tRGB)
      long i
      For i = 1 To countOf(ColorA)
        ColorA(i).r = 255
        ColorA(i).g = 128
        ColorA(i).b =  64
      Next
    end sub
    
    Petr
    Last edited by Petr Schreiber; 21-08-2016 at 11:49.
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  6. #6
    Thanks Petr for this impressive example, also the lesson 6 is very useful.
    i though first that you will use a continuous calculations of Normals while the strip rotating but you have used a fixed values and it works.
    a very little talk in the web about the normals of not orientable objects, so this adds more to the available literature .

Similar Threads

  1. Strip a set of characters from a string
    By zak in forum Rosetta Code
    Replies: 3
    Last Post: 04-04-2015, 10:10

Members who have read this thread: 0

There are no members to list at the moment.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •