simple way to plot with a grid connecting the points

Everything related to 3D programming
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

simple way to plot with a grid connecting the points

Post by applePi »

1-prepare your data generated from a function or real data, and store it in cartesian 2D structured array which have vertex positions info and color info (such as color red upon condition ... .
2-prepare one dimensional indices array so every index refer to one vertex in a way that it makes a grid, in a way described near the end of this page: http://en.wikibooks.org/wiki/OpenGL_Pro ... utorial_04

these 3 lines play the major maestro

Code: Select all

glVertexPointer_(3, #GL_FLOAT,SizeOf(Point3D),@Vertex(0,0)\x)
glColorPointer_(3, #GL_FLOAT, SizeOf(Point3D), @Vertex(0,0)\r) 
;glDrawElements_(mode,count,type, indices address) ; from doc
glDrawElements_(#GL_LINES ,2*Nb*(Nb+1)*2,#GL_UNSIGNED_INT, @indices(0))
i have provided several commented functions , just uncomment any function line to display it, but beware of the functions which may have divide by zero at certain points like :y.f = 0.7/Log(x*x+z*z)+0.6 it is your responsibility to put conditions to bypass the black hole error.

there are many possible additions like that in the above link such as hiding the other side lines from our front sight, i find it difficult to implement since it uses shaders which i dislike it totaly. my knowledge in opengl about 0.0001 and i use only these 0.0001 and it is enough to draw things easily, (not making games), and what we don't understand we choose another way, it is not obligatory to know everything in this large library.

change Nb to increase/decrease the points and grid lines, and to follow what happened use Nb=3 , ie 3*3 squared grid with 4*4 points

Edit:if you don't like your eye position change this:
gluLookAt_( 0, 2, 1,
0, 1, 0,
0, 1, 0 )

the first 3 numbers is your eye position
the second 3 numbers is the object we look at position
the third 3 numbers is vectors
Image

Code: Select all

Structure Point3D
  x.f
  y.f
  z.f
  r.f
  g.f
  b.f
EndStructure


Define event, quit

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "OpenGL..3D Curve with Grid , using glDrawElements... Keys Up/Down to increase/dec the Graphics Y scale")
SetWindowColor(0, RGB(200,220,200))
OpenGLGadget(0, 20, 10, WindowWidth(0)-40 , WindowHeight(0)-20, #PB_OpenGL_Keyboard )
SetActiveGadget(0) 

glMatrixMode_(#GL_PROJECTION)
glLoadIdentity_();
gluPerspective_(45.0, 800/600, 1.0, 60.0)
glMatrixMode_(#GL_MODELVIEW)
glTranslatef_(0, 1, -5)
glShadeModel_(#GL_SMOOTH) 
glEnable_(#GL_DEPTH_TEST)


Nb=40 ; grid lines+1 over x or z axis

size = (Nb+1)*(Nb+1)
Dim Vertex.Point3D(Nb,Nb)

xMin.f = -1 : yMin.f = -1: zMin.f = -1 : xMax.f = 1: yMax = 1 : zMax = 1
;xMin.f = -2 : yMin.f = -2: zMin.f = -2 : xMax.f = 2: yMax = 2 : zMax = 2
;xMin.f = -10 : yMin.f = -10: zMin.f = -10 : xMax.f = 10: yMax = 10 : zMax = 10
;xMin.f = -0.5 : zMin.f = -0.5 : xMax.f = 0.5: zMax = 0.5
  range = xMax - xMin
  step1.f = range / Nb
  x.f = xMin: z.f = zMin : y.f = yMin : v.l = 0
  For b=0 To Nb
   
    For a=0 To Nb
    
      y.f = Sin(10*(x*x+z*z))/5
      ;y.f =(1 - x*x -z*z) * Exp(-1/2 * (x*x + z*z)) ; Mexican Hat
      ;y.f = 1/(15*(x*x+z*z))
      ;y.f = Sin(5*x)*Cos(5*z)/5
      ;y.f = 0.75/Exp((x*5)*(x*5)*(z*5)*(z*5))
      ;y.f = ATan ((z*z*z)/4 - (x*x))
      ;y.f = 0.2 ; just a flat plane
      ; 3D 'A' letter:
      ;y.f = ((1-Sign(-x-0.9+Abs(z*2)))/3*(Sign(0.9-x)+1)/3)*(Sign(x+0.65)+1)/2 -((1-Sign(-x-0.39+Abs(z*2)))/3*(Sign(0.9-x)+1)/3) + ((1-Sign(-x-0.39+Abs(z*2)))/3*(Sign(0.6-x)+1)/3)*(Sign(x-0.35)+1)/2 
      ;y.f = 0.7/Log(x*x+z*z)+0.6 ; here you must bypass the divide by zero error
      ;y.f = Pow((x*x+z*z), 0.5); cone
      ;(0.4^2-(0.6-(x^2+y^2)^0.5)^2)^0.5  -->  this is the following torn torus:
      ;y.f = Pow((Pow(0.4,2)-Pow((0.6-Pow((Pow(x,2)+Pow(z,2)),0.5)),2)),0.5);
      
      Vertex(a,b)\x = x
      Vertex(a,b)\y = y
      Vertex(a,b)\z = z
      
      If y>=0
        Vertex(a,b)\r = 1.0 :Vertex(a,b)\g = 0.3 :Vertex(a,b)\b = 0 
        Else
        Vertex(a,b)\r = 0.2 :Vertex(a,b)\g = 0.8 :Vertex(a,b)\b = 1 
      EndIf
      
      x.f + step1
      
    Next a
    
    x = xMin
    z.f + step1
  Next b
  
;=================================================================================
 
Dim indices(2 * Nb * (Nb+1) * 2)
i = 0;
;Horizontal grid lines
For yy = 0 To Nb
  For xx = 0 To Nb-1
    indices(i) = yy * (Nb+1) + xx;
    i+1
    indices(i) = yy * (Nb+1) + xx + 1;
    i+1
  Next
Next

; Vertical grid lines
For xx = 0 To Nb
  For yy = 0 To Nb-1
    indices(i) = yy * (Nb+1) + xx;
    i+1
    indices(i) = (yy + 1) * (Nb+1) + xx;
    i+1
  Next
Next

glScalef_(2,2,2) ; amplify the graphics size by 2
;the following is the camera or your eye, 0,2,1 your eys__0,1,0; the object__0,1,0 direction
gluLookAt_( 0, 2, 1,
           0,  1, 0,
            0, 1,  0 )

Repeat
 glRotatef_(1, 0, 1, 0); speed rot=1 -- 0,1,0 rotate around Y
    
 glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
 glClearColor_(0.9, 0.9, 0.9, 1)

  glEnableClientState_(#GL_VERTEX_ARRAY )
  glEnableClientState_(#GL_COLOR_ARRAY)
    
  glVertexPointer_(3, #GL_FLOAT,SizeOf(Point3D),@Vertex(0,0)\x)
  glColorPointer_(3, #GL_FLOAT, SizeOf(Point3D), @Vertex(0,0)\r) 
  
  ;glDrawElements_(mode,count,type, indices address) 
   glDrawElements_(#GL_LINES ,2*Nb*(Nb+1)*2,#GL_UNSIGNED_INT, @indices(0))

  glDisableClientState_(#GL_VERTEX_ARRAY);
  glDisableClientState_(#GL_COLOR_ARRAY)
  
  event = WindowEvent()
   If Event = #PB_Event_Gadget And EventGadget() = 0 
      If EventType() = #PB_EventType_KeyDown
      
        key = GetGadgetAttribute(0,#PB_OpenGL_Key )
        Select key
          
          Case #PB_Shortcut_Up 
            For b=0 To Nb
              For a=0 To Nb
                Vertex(a,b)\y * 1.03 ; increase the vertical graphics dimension
              Next
            Next
          Case #PB_Shortcut_Down 
            For b=0 To Nb
              For a=0 To Nb
                Vertex(a,b)\y * 0.95 ; flatten the vertical graphics dimension 
              Next
              
            Next
            
          Case #PB_Shortcut_Escape
            quit = 1
        EndSelect
           
      EndIf
   EndIf   
     
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
  
  Delay(2)
Until quit = 1 Or Event = #PB_Event_CloseWindow

Last edited by applePi on Mon May 09, 2016 7:18 am, edited 1 time in total.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: simple way to plot with a grid connecting the points

Post by applePi »

here is the same above program but in purebasic 3D engine (Ogre), it is exactly produce the same graphics, and i have used the same indices array to connect vertices with lines
just uncomment any function line to plot it
i have added If IsNAN(y): y=0:EndIf because the last function produce NaN error. in opengl somehow it bypasses this error.
Image

note that this version is simpler than the opengl version above, i have used as a container and have consulted MeshManual2.pb from PureBasic\Examples\3D

Code: Select all

;
; ------------------------------------------------------------
;
;   PureBasic - MeshManual 
;
;    (c) Fantaisie Software
;
; ------------------------------------------------------------
;

#CameraSpeed = 1
#scale = 3

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

Define.f KeyX, KeyY, MouseX, MouseY

If InitEngine3D()
  
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/fonts", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts", #PB_3DArchive_FileSystem)
  Parse3DScripts()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    
Nb=40 ; grid lines+1 over x or z axis
xMin.f = -1 : yMin.f = -1: zMin.f = -1 : xMax.f = 1: yMax = 1 : zMax = 1
;xMin.f = -2 : yMin.f = -2: zMin.f = -2 : xMax.f = 2: yMax = 2 : zMax = 2
;xMin.f = -10 : yMin.f = -10: zMin.f = -10 : xMax.f = 10: yMax = 10 : zMax = 10
;xMin.f = -0.5 : zMin.f = -0.5 : xMax.f = 0.5: zMax = 0.5
  range = xMax - xMin
  step1.f = range / Nb
  x.f = xMin: z.f = zMin : y.f = yMin : v.l = 0 
  CreateMesh(3, #PB_Mesh_LineList, #PB_Mesh_Static)
  For b=0 To Nb
   
    For a=0 To Nb
    
      ;y.f = Sin(10*(x*x+z*z))/5
      ;y.f =(1 - x*x -z*z) * Exp(-1/2 * (x*x + z*z)) ; Mexican Hat
      ;y.f = 1/(15*(x*x+z*z))
      y.f = Sin(5*x)*Cos(5*z)/5
      ;y.f = 0.75/Exp((x*5)*(x*5)*(z*5)*(z*5))
      ;y.f = ATan ((z*z*z)/4 - (x*x))
      ;y.f = 0.2 ; just a flat plane
      ; 3D 'A' letter:
      ;y.f = ((1-Sign(-x-0.9+Abs(z*2)))/3*(Sign(0.9-x)+1)/3)*(Sign(x+0.65)+1)/2 -((1-Sign(-x-0.39+Abs(z*2)))/3*(Sign(0.9-x)+1)/3) + ((1-Sign(-x-0.39+Abs(z*2)))/3*(Sign(0.6-x)+1)/3)*(Sign(x-0.35)+1)/2 
      ;y.f = Pow((x*x+z*z), 0.5); cone
      ;(0.4^2-(0.6-(x^2+y^2)^0.5)^2)^0.5  -->  this is the following torn torus:
      ;y.f = Pow((Pow(0.4,2)-Pow((0.6-Pow((Pow(x,2)+Pow(z,2)),0.5)),2)),0.5)
      If IsNAN(y): y=0:EndIf ; y=0 just a suggestion in case y=square root of -1 
      
      MeshVertexPosition(x, y, z) 
      
      If y>=0
        
        MeshVertexColor(RGB(255,76,0))
         Else
           MeshVertexColor(RGB(51,204,255))
        
      EndIf
      
      x.f + step1
      
    Next a
    
    x = xMin
    z.f + step1
  Next b
  
 
  ;;wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
  Dim indices(2 * Nb * (Nb+1) * 2)
i = 0;
;Horizontal grid lines
For yy = 0 To Nb
  For xx = 0 To Nb-1
    indices(i) = yy * (Nb+1) + xx;
    i+1
    indices(i) = yy * (Nb+1) + xx + 1;
    i+1
  Next
Next

; Vertical grid lines
For xx = 0 To Nb
  For yy = 0 To Nb-1
    indices(i) = yy * (Nb+1) + xx;
    i+1
    indices(i) = (yy + 1) * (Nb+1) + xx;
    i+1
  Next
Next

;;wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
    ;- Material
    CreateMaterial(0, LoadTexture(0, "White.jpg"))
    DisableMaterialLighting(0, #True)
    ;Define usage of vertices by referring To the indexes
    For i=0 To 2 * Nb * (Nb+1) * 2
      MeshIndex(indices(i))
    Next  
    FinishMesh(#False)
    
    SetMeshMaterial(3, MaterialID(0))
    Grid = CreateNode(#PB_Any, 0, 0, 0)
    AttachNodeObject(Grid, MeshID(3))
    ;ScaleNode(Grid, 2, 2, 2)
    
    ;-Camera
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 0, 3, 4, #PB_Absolute)
    CameraFOV(0, 40)
    CameraLookAt(0, NodeX(Grid),  NodeY(Grid),  NodeZ(Grid))
    CameraBackColor(0, RGB(0, 0, 40))
    
    ;-Light
    CreateLight(0, RGB(255,255,255), -10, 60, 10)
    AmbientColor(RGB(90, 90, 90))
    
    Repeat
      Screen3DEvents()
      
      ExamineKeyboard()

      RotateNode(Grid, 0.0, 0.5, 0.0, #PB_Relative) 
 
      RenderWorld()
      
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf

End



Last edited by applePi on Mon May 09, 2016 7:17 am, edited 1 time in total.
User avatar
em_uk
Enthusiast
Enthusiast
Posts: 366
Joined: Sun Aug 08, 2010 3:32 pm
Location: Manchester UK

Re: simple way to plot with a grid connecting the points

Post by em_uk »

Very nice work :)
----

R Tape loading error, 0:1
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: simple way to plot with a grid connecting the points

Post by davido »

@applePie,
Very nice examples, thank you for sharing. :D
DE AA EB
Post Reply