How do you get smooth graphics?

Just starting out? Need help? Post your questions and find answers here.
rufusthedog
New User
New User
Posts: 7
Joined: Sat Nov 16, 2013 9:04 am

How do you get smooth graphics?

Post by rufusthedog »

Hi All,

I'm new to programing in general and hack my way through. I'm writing a graphing application that I would like to have realtime graphing so a circuit could be tuned. I'm using the serial port which is the hold up for speed but ignoring that for now. When I update the graph the image isn't very smooth. I would also appreciate any suggestion on improving just the general feel of the application. I have a couple of files that I use for storing data and setup that I also have attached. I have commented the serial port call so program won't hang.

Program:

Code: Select all

Sun, 20 Oct 2013 18:19:04
;/ by Bryan Pollock

;- Global Variables and Constants
Global BubbleTipStyle.l:BubbleTipStyle=0

;- Window Constants
Enumeration 1
  #Window_Form1
EndEnumeration
#WindowIndex=#PB_Compiler_EnumerationValue


;- Gadget Constants
Enumeration 1
  ;Window_Form1
  #Gadget_Form1_Run_NPR
  #Gadget_Form1_NPRRepeat
  #Gadget_Form1_Plt
  #Gadget_Form1_Image5
  #Gadget_Form1_NoiseLevel
  #Gadget_Form1_MinNPR
  #Gadget_Form1_NPRTx
  #Gadget_Form1_NoisePwr
  #Gadget_Form1_UpperLimit
  #Gadget_Form1_UpperLim
  #Gadget_Form1_LowerLimit
  #Gadget_Form1_LowerLim
  
  #Gadget_Form1_NPRScale
  #Gadget_Form1_NPRScaled
  #Gadget_Form1_minthreshold
  #Gadget_Form1_maxthreshold
  #Gadget_Form1_minimumthreshold
  #Gadget_Form1_maximumthreshold
  
 
 
  
EndEnumeration
#GadgetIndex=#PB_Compiler_EnumerationValue
Enumeration 1
  #MenuBar_Form1
EndEnumeration
#MenuBarIndex=#PB_Compiler_EnumerationValue

Procedure.l Window_Form1()
  If OpenWindow(#Window_Form1,30,25,1000,700,"Pollock Protosource NPR Tester",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_TitleBar|#PB_Window_ScreenCentered|#PB_Window_WindowCentered|#PB_Window_Invisible)
      ButtonGadget(#Gadget_Form1_Run_NPR,30,650,60,20,"NPR RUN")
      ButtonGadget(#Gadget_Form1_plt,100,650,60,20,"PLOT")
      ButtonGadget(#Gadget_Form1_nprrepeat,170,650,100,20,"CONTINUOUS",#PB_Button_Toggle)
      
    
  
      
      StringGadget(#Gadget_Form1_UpperLimit,5,360,30,20,"68")
      TextGadget(#Gadget_Form1_UpperLim,5,340,70,20,"UPPER LIMIT")
      StringGadget(#Gadget_Form1_NPRScale,5,415,30,20,"4")
      TextGadget(#Gadget_Form1_NPRScaled,5,395,50,20,"PER/DIV")
      StringGadget(#Gadget_Form1_LowerLimit,5,470,30,20,"0")
      TextGadget(#Gadget_Form1_LowerLim,5,450,80,20,"LOWER LIMIT")
      
      StringGadget(#Gadget_Form1_MinNPR,500,650,40,20,"41")
      TextGadget(#Gadget_Form1_NPRtx,415,650,80,20,"MIN. NPR",#PB_Text_Right)
      StringGadget(#Gadget_Form1_NOISELEVEL,400,650,40,20,"-65")
      TextGadget(#Gadget_Form1_NoisePwr,310,650,80,20,"NOISE PWR",#PB_Text_Right)
      
      StringGadget(#Gadget_Form1_minthreshold,675,650,40,20,"-60")
      TextGadget(#Gadget_Form1_minimumthreshold,570,650,100,20,"MIN. THRESHOLD",#PB_Text_Right)
      StringGadget(#Gadget_Form1_maxthreshold,815,650,40,20,"-55")
      TextGadget(#Gadget_Form1_maximumthreshold,710,650,100,20,"MAX THRESHOLD",#PB_Text_Right)
      
      
      HideWindow(#Window_Form1,0)
    ProcedureReturn WindowID(#Window_Form1)
  EndIf
EndProcedure


Declare Plt()       ;Prints the plot
Declare ReadNPR()   ;reads back in the file and splits into two arrays
Declare SerialRead();reads in the data from the serial port
Declare NprPlot()
Declare UpdatePlot(Win, w, h)

Define count = 63
Define MyLine$
Global Dim serie_x.f(64)
Global Dim serie_y.f(64)
Global  max_x.f, max_y.f, min_x.f = #MAXLONG, min_y.f = Infinity()
Global Dim test.f(64)
Global t.s
Global Peak.f
Global COM.s
Structure PlotData
  x.f  ;interger variable
  y.f  ;floating variable
EndStructure
Global Dim MyData.PlotData(count)

ReadFile(0, "C:\Program Files\NPR\com.txt" )
While Eof(0) = 0         ;loop as long the 'end of file' isn't reached
  COM.s = ReadString(0)   ;display line by line in the debug window
Wend

COM.S= InputRequester ("ENTER COM PORT" , "COM PORT" , COM.s )
If CreateFile(0,"C:\Program Files\NPR\com.txt",#PB_File_SharedRead) ; we create a new text file...
    
  WriteString(0,COM.s)  ;
            
  CloseFile(0)  
        
EndIf 

;- Main Loop
If Window_Form1()
  
 ;SerialRead()     
 ReadNPR()
 NprPlot()
 
 quitForm1=0
 
 Repeat
   EventID  =WaitWindowEvent()
   MenuID   =EventMenu()
   GadgetID =EventGadget()
   WindowID =EventWindow()
   
     Select EventID
      Case #PB_Event_CloseWindow
        If WindowID=#Window_Form1
          quitForm1=1
        EndIf

      Case #PB_Event_Gadget
        Select GadgetID
          Case #Gadget_Form1_Run_NPR
            StartTime = ElapsedMilliseconds()
            ;SerialRead()
            ReadNPR()
            NprPlot()
            Delay(1)
            t.s = Str(ElapsedMilliseconds()-StartTime)
            
          Case #Gadget_Form1_plt      
            Plt()
            
          Case #Gadget_Form1_nprrepeat
            Repeat
            StartTime = ElapsedMilliseconds()  
            ;SerialRead()
            ReadNPR()
            NprPlot()
            WaitWindowEvent(10);Added to allow time for state change
            t.s = Str(ElapsedMilliseconds()-StartTime)
            Delay(100)
            Until GetGadgetState( #Gadget_Form1_nprrepeat)=0  

          Case #Gadget_Form1_Image5
            Select EventType()
              Case #PB_EventType_LeftDoubleClick
              Case #PB_EventType_RightDoubleClick
              Case #PB_EventType_RightClick
                 
              Case #Gadget_Form1_NOISELEVEL
                Select EventType()
                  Case #PB_EventType_Change
                    
                EndSelect
              Default
            EndSelect
        EndSelect
    EndSelect
  Until quitForm1
  CloseWindow(#Window_Form1)
EndIf
End

;Procedures


Procedure NprPlot()
;defines the image window
  
  Define Win =  ImageGadget(#Gadget_Form1_Image5,30,25,950,650,0,#PB_Image_Border)
  
  w=850  ;The width of the image
  h=600  ;The Height of the image
  
  If Win
  
  UpdatePlot(Win, w, h)
  
    Define event = WaitWindowEvent()
    Select event
      Case #PB_Event_SizeWindow
        UpdatePlot(Win, WindowWidth(Win), WindowHeight(Win)) 
  SmartWindowRefresh(win,1)
    EndSelect
  
EndIf
EndProcedure 

Procedure Plt()
;Save the plot If the user wants To
If MessageRequester("Question", "Save it?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
  StandardFile.s = "C:\Users\Owner\Desktop\NPR"
  Pattern.s="png (*.png)|*.png"
  pat=0
  File.s=SaveFileRequester("You have to type the extension .png",StandardFile.s,Pattern.s,pat)
    UsePNGImageEncoder()


    SaveImage(1, File.s, #PB_ImagePlugin_PNG)
EndIf
  

  
 EndProcedure 
  
Procedure ReadNPR()
  
;Open the file and splits it into two arrays serie_x and serie_y
  OpenFile(0,"C:\Program Files\NPR\npr.txt",#PB_File_SharedRead)
  Peak.f=0  ;reset peak
  thenpr.f=0
  max_y.f = Val(GetGadgetText(#Gadget_Form1_UpperLimit))
  min_y.f = Val(GetGadgetText(#Gadget_Form1_LowerLimit))
    
  For i = 0 To 63
      MyLine$ = ReadString(0) ;reads in the NPR file
      
      Xcord.s = StringField(MyLine$,1,",") ;strips off the attenuator setting from the file
      Ycord.s = StringField(MyLine$,2,",") ;strips off the notch depth from the file
      X.f = ValF(Xcord.s)
      Y.f = ValF(Ycord.s)
      serie_x(i) = X 
      
      If serie_x(0)>=63: x = 0: EndIf
      If serie_x(63)<62: x = 63: EndIf
      serie_y.f(i) = Y.f
      If x > max_x: max_x = x:  EndIf
      If x < min_x: min_x = x:  EndIf
  
 
 ;picking the Peak NPR
      If serie_y.f(i)>=Peak.f
        Peak.f=serie_y.f(i)
      EndIf
           
   Next
 
 
EndProcedure
 
Procedure UpdatePlot(Win, w, h)
  
  
  Protected gblm = 100, gtrm = 50 ;graph's bottom-left and top-right margin
  
  Protected count = ArraySize(MyData())
  
  If w > gblm And h > gblm And count > 0
    
    Protected gw = w - gblm, gh.f = h - gblm ;graph's width and height gw=graph width, gblm=graph bottom left margin
    Protected i, yf.f, xf.f
    yf.f = (gh.f - gtrm) / (max_y.f)    ;gh= graph height, gtrm=graph top right margin
    xf.f = (gw - gtrm) / max_x
 
    CreateImage(1, w, h,32,$ffffff)
    Protected OutputID = ImageOutput(1)
    StartDrawing(OutputID)
    DrawingMode(#PB_2DDrawing_Transparent)
    Ns.f = ValF(GetGadgetText(#Gadget_Form1_NPRScale))
    GridStep.f = max_y.f
      
;- Draw Y grid
;NOTE: was for next loop but for next only can use constant for step
        
   While (s.f+min_y) <= GridStep.f 
     y.f = gh.f - max_y.f * (s.f+min_y) / GridStep * yf
     LineXY(gblm, y.f, w - gtrm, y.f, $89BA89)
            
;Y-scale
     x.f = gblm + max_x * (s.f+min_y) / count * xf
     y.f = gh.f- max_y.f * (s.f+min_y) / GridStep.f * yf
   DrawText(50, y.f-5, RSet(StrD((s.f+min_y) / GridStep * max_y.f, 2), 5),RGB(0, 0, 0))
   s.f+Ns.f
   
   Wend
;Draw X grid
   For i = 0 To count Step 5
     x.f = gblm + max_x * i / count * xf
     y.f = gh.f-min_y*yf 
     LineXY(x, y.f, x, gtrm, $89BA89)
        
;X-Scale
     If i: DrawText(x.f - 20, y.f + 5, RSet(StrD(i/2+ValF(GetGadgetText(#Gadget_Form1_NOISELEVEL))),6),RGB(0, 0, 0)): EndIf 
        
   Next
       
      DrawText(x-x/2, y.f +25, "dBv/Hz",6)   
      DrawText(15, y.f-y.f/2, "NPR",6) 
         
;Draw the minimum NPR line   
      minimumNPR.f=(500-ValF(GetGadgetText(#Gadget_Form1_MinNPR))*450/ max_y.f)
      
      LineXY(100, minimumNPR, 800, minimumNPR, $00EEC0) 
      LineXY(100, minimumNPR+1, 800, minimumNPR+1, $00EEC0)
      
      DrawText(650,550,"Minimum NPR="+ GetGadgetText(#Gadget_Form1_MinNPR),6)
;Draw the peak line   
      Peakdraw.f=(500-Peak.f*450/ max_y.f)
      
      LineXY(100, Peakdraw.f, 800, Peakdraw.f, $5FFF00)
      LineXY(100, Peakdraw.f+1, 800, Peakdraw.f+1, $5FFF00)
         
      DrawText(650,570,"Peak="+ StrF(Peak.f),6)
      
;Draw minimum thershold line, the extra lines make the line thicker
       LineXY(1544+ValF(GetGadgetText(#Gadget_Form1_minthreshold))*2*xf.f,minimumNPR.f-30,1544+ValF(GetGadgetText(#Gadget_Form1_minthreshold))*2*xf.f,minimumNPR.f+30,$000000)
       LineXY(1543+ValF(GetGadgetText(#Gadget_Form1_minthreshold))*2*xf.f,minimumNPR.f-30,1543+ValF(GetGadgetText(#Gadget_Form1_minthreshold))*2*xf.f,minimumNPR.f+30,$000000)
       LineXY(1545+ValF(GetGadgetText(#Gadget_Form1_minthreshold))*2*xf.f,minimumNPR.f-30,1545+ValF(GetGadgetText(#Gadget_Form1_minthreshold))*2*xf.f,minimumNPR.f+30,$000000)
       
;Draw maximum thershold line, the extra line make the line thicker
       
       LineXY(1544+ValF(GetGadgetText(#Gadget_Form1_maxthreshold))*2*xf.f,minimumNPR.f-30,1544+ValF(GetGadgetText(#Gadget_Form1_maxthreshold))*2*xf.f,minimumNPR.f+30,$000000)
       LineXY(1543+ValF(GetGadgetText(#Gadget_Form1_maxthreshold))*2*xf.f,minimumNPR.f-30,1543+ValF(GetGadgetText(#Gadget_Form1_maxthreshold))*2*xf.f,minimumNPR.f+30,$000000)   
       LineXY(1545+ValF(GetGadgetText(#Gadget_Form1_maxthreshold))*2*xf.f,minimumNPR.f-30,1545+ValF(GetGadgetText(#Gadget_Form1_maxthreshold))*2*xf.f,minimumNPR.f+30,$000000) 
      
      
;- Draw curve
 Protected ox = gblm + serie_x.f(0)*xf, oy.f = gh.f - serie_y.f(0)*yf
 If CreateFile(0,"C:\Program Files\NPR\test.txt",#PB_File_SharedRead)
  For i = 0 To count
    x = gblm + serie_x.f(i)*xf
    y.f = gh.f - serie_y.f(i)*yf
    LineXY(ox, oy.f, x, y.f, $376FED)
    ;LineXY(ox+0.1, oy.f+0.1, x+0.1, y.f+0.1, $376FED)
    ;LineXY(ox-0.2, oy.f-0.1, x-0.1, y.f-0.1, $376FED)
    
;finds where NPR crosses the minimum NPR
      sense.f=0.8  ;Change this number for larger capture range 
    If oy.f<minimumNPR.f+sense.f*yf And oy.f>=minimumNPR.f-sense.f*yf
       test.s = StrF(serie_x.f(i)/2+ValF(GetGadgetText(#Gadget_Form1_NOISELEVEL))-0.5)+"*"
       Line(ox, 50,1,gh.f-min_y*yf-gtrm, $FF3424)
       
       If ValF(test.s)<testmax.f:testmax.f=ValF(test.s):EndIf
       If ValF(test.s)<-1 And  ValF(test.s)<testmin.f:EndIf :testmin.f=ValF(test.s)
    
    EndIf

      ox = x: oy.f = y.f; creates line
        
    Next 
    testminmax.s=StrF(testmax.f)+"*"+StrF(testmin.f)
      WriteString(0,testminmax.s) ;we create a new text file... ;
  CloseFile(0)
EndIf

  ReadFile(0, "C:\Program Files\NPR\test.txt" )
  While Eof(0) = 0           ; loop as long the 'end of file' isn't reached
    test.s = ReadString(0)
    nprmin.s = StringField(testminmax.s,1,"*") ;strips off the attenuator setting from the file
    nprmax.s = StringField(testminmax.s,2,"*") ;strips off the notch depth from the file
    range.f=(ValF(nprmax.s)-ValF(nprmin.s))
    DrawText(100,550,"NPR Range = " + range.f,6)
   Wend
        
;measurement for test time
   ;DrawText(100,450,"Time for measurement="+  t.s + " Milliseconds",6)
   StopDrawing()
   ImageGadget(#Gadget_Form1_Image5,75,25,900,600,ImageID(1),#PB_Image_Border)
   LoadImage(#Gadget_Form1_Image5,"C:\Users\Owner\Desktop\pb.png")
    
  EndIf
EndProcedure

Procedure SerialRead()
  p = 0
    
  Shared Port$, *Byte, Text1.s
  b_size = 630
  
  Port.s = COM.s
  If OpenSerialPort(p, Port.s, 256000, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, b_size,b_size)=0 :  EndIf
    If IsSerialPort(p) :EndIf   
      If CreateFile(0,"C:\Program Files\NPR\npr.txt",#PB_File_SharedRead):EndIf:
  *Byte = AllocateMemory(b_size)
   Repeat   
       
     If IsSerialPort(0)
     Else
       MessageRequester("WRONG COM PORT OR CABLE NOT CONNECTED!",com.s):Break
     EndIf
    
      Bytes = AvailableSerialPortInput(0)
          
      Result = ReadSerialPortData(0, *Byte, Bytes)
            
      Text1.s = PeekS(*Byte, Result)
            
      endof.s = Left(Text1.s,3)
             
    Until  endof.s = "63,"  ;
              
       Result = ReadSerialPortData(0, *Byte, b_size)
       Text1.s = PeekS(*Byte, Result)
         
     If CreateFile(0,"C:\Program Files\NPR\npr.txt",#PB_File_SharedRead)          ; we create a new text file...
    
        WriteString(0,Text1.s)  ;
            
        CloseFile(0)  
        
     EndIf 
     
     If IsSerialPort(0)
         CloseSerialPort(0)
         FreeMemory(*Byte)
     EndIf       
    
   EndProcedure
   
NPR:
  • 0,22.27
    1,22.54
    2,23.89
    3,24.98
    4,26.07
    5,27.42
    6,28.51
    7,29.60
    8,30.14
    9,30.68
    10,31.23
    11,33.13
    12,34.48
    13,35.30
    14,35.57
    15,36.93
    16,37.20
    17,38.56
    18,39.10
    19,40.19
    20,40.73
    21,41.54
    22,42.36
    23,43.45
    24,45.07
    25,45.62
    26,45.89
    27,46.70
    28,47.79
    29,47.52
    30,48.60
    31,49.15
    32,49.15
    33,50.23
    34,50.23
    35,51.05
    36,51.86
    37,52.41
    38,53.49
    39,52.95
    40,53.76
    41,54.58
    42,54.85
    43,54.31
    44,55.12
    45,55.39
    46,56.48
    47,57.02
    48,57.29
    49,57.84
    50,58.92
    51,58.65
    52,60.28
    53,61.37
    54,61.91
    55,62.72
    56,62.72
    57,62.72
    58,63.00
    59,64.35
    60,63.81
    61,63.81
    62,63.27
    63,63.00
COM:
  • COM10
Test:
  • -55*-54.5
Thank You,

Bryan
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: How do you get smooth graphics?

Post by skywalk »

Search for anti aliasing lines.
You then change your LineXY() calls to one of the many AA_LineXY() routines available.
Also, simplify your example code to include a datasection with your data to plot. :wink:
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Post Reply