Help on an error - bgi graphics, function plot modules

Just starting out? Need help? Post your questions and find answers here.
startup
Enthusiast
Enthusiast
Posts: 105
Joined: Wed Feb 25, 2015 5:55 pm

Re: Help on an error - bgi graphics, function plot modules

Post by startup »

Code: Select all

XIncludeFile "MINIBGI.pbi"

DeclareModule MINIPLOT
  EnableExplicit  
  
#MAXINTEGER = 65535
  


;   sets clipping of plotting on: i.e. only within actual plot region
;   delimited by XMin->XMax And YMin->YMax
Declare SetClipOn()

;   sets clipping of plotting off: i.e. can plot anywhere on the screen,
;   but window is still delimited by XMin->XMax And YMin->YMax
Declare SetClipOff()

;   clears a status line at the very top of the screen;
;   you have To be in graphics mode For this To work.
Declare Clear_StatusLine()


;   writes out a status line "Message" after clearing the status line
;   you have To be in graphics mode For this To work.
Declare Write_StatusLine(Message.s)


;   defines constants (XAxisScale,YAxisScale,ConstX,ConstY) which are used
;   To convert To And from world And window coordinate systems.
Declare Setscale(WXMin.d,WXMax.d,WYMin.d,WYMax.d)

;performs transformation from world coordinates to window (screen) coordinates
Declare World_to_Window(x.d,y.d, *XScreen.integer, *YScreen.integer)


;   performs transformation from window (screen) coordinates To world
;   coordinates
Declare Window_to_World(XScreen.i,YScreen.i, *x.double, *y.double)

;  move graphics cursor To world coordinate X,Y
Declare Move(X.d,Y.d)

;   draw line from present position of graphics cursor To world
;   coordinate X,Y; use BGI Declare SetLineStyle to change from
;   solid To dotted, dashed, etc
Declare Draw(X.d,Y.d)

;   move graphics cursor a relative distance (in world coordinates) from
;   present position
Declare RelMove(X.d,Y.d)


;   draw line from present position of graphics cursor To a new
;   position given by the relative distance X,Y (in world coordinates)
;   use BGI Declare SetLineStyle To change from solid To dotted,
;   dashed, etc
Declare RelDraw(X.d,Y.d)


;   Draws tick marks For "axes" And "frame" With minor tick intervals
;   every XTick,YTick, And major ticks every XMajor,YMajor minor ticks.
;   Tick_Proc checks If x And y axes are running the conventional directions
;   (i.e. xmin->max is left To right And ymin->ymax is up) And acts accordingly;
;   This routine is only used internally by HiGraf.
;Declare Tick_Proc(Xarg.d,Yarg.d,XTick.d,YTick.d, XMajor.i,YMajor.i, GridOn.b)
Declare  Tick_Proc(Xarg.d, Yarg.d, XTick.d, YTick.d, XMajor.i, YMajor.i, GridOn.i)


;   draws a frame around box determined by XMin,XMax And YMin,YMax;
;   put minor ticks every XTick,YTick interval With major ticks every
;   XMajor,YMajor multiples of XTick,YTick; if GridOn = TRUE a grid
;   is drawn
Declare Frame(XTick.d,YTick.d, XMajor.i,YMajor.i, GridOn.b)


;  puts STRING Labl at the top of the plot
Declare TopTitle(Labl.s)

;   labels x axis With STRING Labl; Label_Axes sets up variable MaxLabHeight
;   which is used For XAxisTitle offset; if you haven't called Label_Axes,
;   Setup_Graph has initialized MaxLabHeight To 0;
Declare XAxisTitle(Labl.s)

;   labels y axis With STRING Labl; Label_Axes sets up variable MaxLabLength
;   which is used For YAxisTitle offset; if you haven't called Label_Axes,
;   Setup_Graph has initialized MaxLabLength To 0;
Declare YAxisTitle(Labl.s)

;   This Declare draws a label at position X,Y in world coordinates;
;   the variables "Font,Direction,Size,XJust,YJust" are just As in the
;   BGI description For Turbo Pascal graphics:
;   Font,Direction, And Size are set by a BGI proc "SetTextStyle" And
;   XJust,YJust are set by a BGI proc "SetTextJustify"
Declare Draw_Label(X.d,Y.d, Strng.s,Font.i,Direction.i,Size.i, XJust.i,YJust.i)

;   Draws a pair of axes through XOrg,YOrg With minor tick intervals
;   XTick,YTick, And major ticks every XMajor,YMajor minor tick
;   intervals; if the flag GridOn = TRUE then a grid is drawn
Declare Axes(XOrg.d,YOrg.d,XTick.d,YTick.d, XMajor.i,YMajor.i, GridOn.b)

;   Labels axes at intervals LabelX, LabelY; by convention you may
;   want this To be :
;       LabelX = XMajor*XTick
;       LabelY = YMajor*YTick
;   in your program
Declare Label_Axes(LabelX.d,LabelY.d)

;   Plots a Symbol, scaled by SymSize, centered at world coordinates
;   X,Y; available Symbols are:
;     1  - plus
;     2  - box
;     3  - cross (x-like)
;     4  - triangle
;     5  - inverted triangle
;     6  - open circle
;     7  - filled circle
;     8  - dot
Declare PlotPoint(X.d,Y.d, Symbol.i, SymSize.i, color.i)

;   Declare To set up the graph limits.
;   The world coordinate limits are XMin, XMax, YMin, And YMax.
;   The window limits are WXMin, WXMax, WYMin, WYMax expressed As
;   fractions (of 1,i.e. 0.95 etc) of the maximum screen limits.
Declare Setup_Graph(XMin.d,XMax.d,YMin.d,YMax.d, WXMin.d,WXMax.d,WYMin.d,WYMax.d,logx.b,logy.b)

;   Plots a Symbol, scaled by SymSize, centered at world coordinates
;   X,Y; error bar on X,Y are sigx and sigy; available Symbols are:
;     1  - plus
;     2  - box
;     3  - cross (x-like)
;     4  - triangle
;     5  - inverted triangle
;     6  - open circle
;     7  - filled circle
;     8  - dot
Declare PlotData(x.d,sigx.d,y,sigy.d, Symbol.i, SymSize.i, color.i)
  
EndDeclareModule

Module MINIPLOT
EnableExplicit

UseModule MINIBGI
Global.l Dim Custom_LineStyle(5)
Global.d XWorldMin, XWorldMax,YWorldMin, YWorldMax ; global variables for world limits 
Global.i XWindMin, XWindMax, YWindMin, YWindMax ; global variables for window limits 
Global.i XViewMax,YViewMax ; viewport limits 
Global.d XAxisScale, YAxisScale ; factors for converting 
Global.i ConstX, ConstY       ; to screen coordinates 
Global.b XAxisLog, YAxisLog ; global variables for axis type 
Global.i MaxLabLength ; y axis label length in pixels; used To calculate y axis title offset 
Global.i MaxLabHeight ; x axis label height in pixels; used To calculate x axis title offset 
Global.i MaxColor ; store GetMaxColor value 

;   sets clipping of plotting on: i.e. only within actual plot region
;   delimited by XMin->XMax And YMin->YMax
Procedure SetClipOn()
  SetViewPort(XWindMin,YWindMin,XWindMax,YWindMax,#ClipOn)
EndProcedure

;   sets clipping of plotting off: i.e. can plot anywhere on the screen,
;   but window is still delimited by XMin->XMax And YMin->YMax
Procedure SetClipOff()
  SetViewPort(XWindMin,YWindMin,XWindMax,YWindMax,#ClipOff)
EndProcedure

;   clears a status line at the very top of the screen;
;   you have To be in graphics mode For this To work.
Procedure Clear_StatusLine()
  Protected.i Status_Width = 12 ; is status line 12 pixels tall? 
  SetViewPort(0,0,GetMaxX(),GetMaxY(),#ClipOff)
  SetFillStyle(#EmptyFill,GetMaxColor())
  Bar(0,0,GetMaxX(),Status_Width)
  SetClipOn()
EndProcedure


;   writes out a status line "Message" after clearing the status line
;   you have To be in graphics mode For this To work.
Procedure Write_StatusLine(Message.s)
  Clear_StatusLine()
  SetViewPort(0,0,GetMaxX(),GetMaxY(),#ClipOff)
  SetTextStyle(#ArialFont,#HorizDir,6)
  SetTextJustify(#LeftText,#TopText)
  MoveTo(0,0)
  OutText(Message)
  SetClipOn()
  MoveTo(1,2)
EndProcedure


;   defines constants (XAxisScale,YAxisScale,ConstX,ConstY) which are used
;   To convert To And from world And window coordinate systems.
Procedure Setscale(WXMin.d,WXMax.d,WYMin.d,WYMax.d)
  XWindMin = Round(WXMin*GetMaxX()/100.0, #PB_Round_Down)
  XWindMax = Round(WXMax*GetMaxX()/100.0, #PB_Round_Down)
  YWindMin = Round(WYMin*GetMaxY()/100.0, #PB_Round_Down)
  YWindMax = Round(WYMax*GetMaxY()/100.0, #PB_Round_Down)
  XViewMax = XWindMax-XWindMin
  YViewMax = YWindMax-YWindMin
  If XAxisLog
    XAxisScale = XViewMax /(Log10(XWorldMax)-Log10(XWorldMin))
    ConstX = -Round(Log10(XWorldMin)*XAxisScale, #PB_Round_Down)
  Else
    XAxisScale = XViewMax/(XWorldMax-XWorldMin)
    ConstX = -Round(XWorldMin*XAxisScale, #PB_Round_Down)
  EndIf
  If YAxisLog
    YAxisScale = YViewMax/(Log10(YWorldMin)-Log10(YWorldMax))
    ConstY = -Round(Log10(YWorldMax)*YAxisScale, #PB_Round_Down)
  Else
    YAxisScale = YViewMax/(YWorldMin-YWorldMax)
    ConstY = -Round(YWorldMax*YAxisScale, #PB_Round_Down)
  EndIf
EndProcedure

;performs transformation from world coordinates to window (screen) coordinates
Procedure World_to_Window(x.d,y.d, *XScreen.integer, *YScreen.integer)
  Protected.d temp
  Protected.i isign
  If XAxisLog
    If (x > 0.0) 
      x = Log10(x)
    Else
      x = Log10(XWorldMin)
    EndIf
  EndIf
  If YAxisLog
    If (y > 0.0) 
      y = Log10(y)
    Else
      y = Log10(YWorldMin)
    EndIf
  EndIf
  temp = x * XAxisScale + ConstX
  isign = Sign(temp)
  
  If isign*temp < #MAXINTEGER
    *XScreen\i = Round(temp, #PB_Round_Down)
  Else
    *XScreen\i = isign*#MAXINTEGER
  EndIf
  
  temp = y * YAxisScale + ConstY
  isign = Sign(temp)
  
  If isign*temp < #MAXINTEGER
    *YScreen\i = Round(temp, #PB_Round_Down)
  Else
    *YScreen\i = isign*#MAXINTEGER
  EndIf
EndProcedure


;   performs transformation from window (screen) coordinates To world
;   coordinates
Procedure Window_to_World(XScreen.i,YScreen.i, *x.double, *y.double)
  *x\d = (1.0*XScreen-ConstX)/XAxisScale
  *y\d = (1.0*YScreen-ConstY)/YAxisScale
  If XAxisLog
    *x\d = Pow(10.0,*x\d) 
  EndIf
  If YAxisLog
    *y\d = Pow(10.0,*y\d) 
  EndIf
EndProcedure

;  move graphics cursor To world coordinate X,Y
Procedure Move(X.d,Y.d)
  Protected xs.i,ys.i
  World_to_Window(X,Y,@xs,@ys)
  MoveTo(xs,ys)
EndProcedure

;   draw line from present position of graphics cursor To world
;   coordinate X,Y; use BGI procedure SetLineStyle to change from
;   solid To dotted, dashed, etc
Procedure Draw(X.d,Y.d)
  Protected xs.i,ys.i
  World_to_Window(X,Y,@xs,@ys)
  LineTo(xs,ys)
EndProcedure

;   move graphics cursor a relative distance (in world coordinates) from
;   present position
Procedure RelMove(X.d,Y.d)
  Protected xs.i,ys.i
  World_to_Window(X,Y,@xs,@ys)
  MoveRel(xs,ys)
EndProcedure


;   draw line from present position of graphics cursor To a new
;   position given by the relative distance X,Y (in world coordinates)
;   use BGI Procedure SetLineStyle To change from solid To dotted,
;   dashed, etc
Procedure RelDraw(X.d,Y.d)
  Protected xs.i,ys.i
  World_to_Window(X,Y,@xs,@ys)
  LineRel(xs,ys)
EndProcedure

;   Draws tick marks For "axes" And "frame" With minor tick intervals
;   every XTick,YTick, And major ticks every XMajor,YMajor minor ticks.
;   Tick_Proc checks If x And y axes are running the conventional directions
;   (i.e. xmin->max is left To right And ymin->ymax is up) And acts accordingly;
;   This routine is only used internally by HiGraf.


Procedure Tick_Proc(Xarg.d,Yarg.d,XTick.d,YTick.d, XMajor.i,YMajor.i, GridOn.i)
  Protected.d XTick_scale = 0.015     ; scale factors for tick lengths 
  Protected.d YTick_scale = 0.005
  Protected.d x, y, decade, tempmin, tempmax
  Protected.i ticklen, i
  ; draw x axis tick marks 
  ticklen = Round(XTick_scale*GetMaxY(), #PB_Round_Down)
  If XWorldMin <= XWorldMax  ; normal axis direction 
    tempmin = XWorldMin
    tempmax = XWorldMax
  Else ; axis is reversed from normal 
    tempmin = XWorldMax
    tempmax = XWorldMin
  EndIf
  If XAxisLog  ; x axis is logarithmic
    decade = Pow(10.0,Log(tempmin)) ; get next lower decade 
    While (decade <= tempmax)
      Move(decade, Yarg)
      LineRel(0, 2 * ticklen)
      LineRel(0, -4 * ticklen)
       If GridOn
         Move(decade, YWorldMin)
         Draw(decade, YWorldMax)
       EndIf
       For i = 3 To 9
        x = decade * i
        If GridOn = #True
          SetLineStyle(#DottedLn, 0, 1) ; fine dotted line 
          Move(x, YWorldMin)
          Draw(x, YWorldMax)
          SetLineStyle(#SolidLn,0,#NormWidth)
        EndIf
        If x <= tempmax
          Move(x,Yarg)
          LineRel(0, ticklen)
          LineRel(0, -2 * ticklen)
        EndIf
       Next
      decade = decade * 10.0
    Wend
  ElseIf XTick > 0.0  ; x axis is linear 
    x = tempmin+XTick
    i = 1
    Repeat
      Move(x,Yarg)
      If (i % XMajor) = 0
        LineRel(0,2*ticklen)
        LineRel(0,-4*ticklen)
      Else
        LineRel(0,ticklen)
        LineRel(0,-2*ticklen)
      EndIf
      If GridOn = #True
        If (i % XMajor) <> 0
          SetLineStyle(#DottedLn,0,1)  
        EndIf ; fine dotted line 
        Move(x,YWorldMin)
        Draw(x,YWorldMax)
        SetLineStyle(#SolidLn,0,#NormWidth)
      EndIf
      INC(x, XTick)
      INC(i)
    Until (x > tempmax)
  EndIf ; ELSE IF (XTick... 
  ; draw y axis tick marks 
  ticklen = Round(YTick_scale*GetMaxX(), #PB_Round_Down)
  If YWorldMin <= YWorldMax  ; normal axis direction 
    tempmin = YWorldMin
    tempmax = YWorldMax
  Else ; axis is reversed from normal 
    tempmin = YWorldMax
    tempmax = YWorldMin
  EndIf 
  If YAxisLog  ; y axis is logarithmic 
    decade = Pow(10.0,Log(tempmin)) ; get next lowest decade 
    While (decade <= tempmax)
      Move(Xarg,decade)
      LineRel(-2*ticklen,0)
      LineRel(4*ticklen,0)
      If GridOn
        Move(XWorldMin,decade)
        Draw(XWorldMax,decade)
      EndIf
      For i = 3 To 9
        y = decade*i
        If y <= tempmax
          Move(Xarg,y)
          LineRel(-ticklen,0)
          LineRel(2*ticklen,0)
        EndIf
        If GridOn = #True
          SetLineStyle(#DottedLn,0,1) ; fine dotted line 
          Move(XWorldMin,y)
          Draw(XWorldMax,y)
          SetLineStyle(#SolidLn,0,#NormWidth)
        EndIf
      Next
      decade = decade*10.0
    Wend
  ElseIf YTick > 0.0  ; y axis is linear 
    y = tempmin+YTick
    i = 1
    Repeat
      Move(Xarg,y)
      If (i % YMajor) = 0
        LineRel(-2*ticklen,0)
        LineRel(4*ticklen,0)
      Else
        LineRel(-ticklen,0)
        LineRel(2*ticklen,0)
      EndIf
      If GridOn = #True
        If (i % YMajor) <> 0
          SetLineStyle(#DottedLn,0,1) 
        Else
        EndIf ; fine dotted line 
        Move(XWorldMin,y)
        Draw(XWorldMax,y)
        SetLineStyle(#SolidLn,0,#NormWidth)
      EndIf
      INC(y,YTick)
      INC(i)
    Until y > tempmax
  EndIf
EndProcedure


;   draws a frame around box determined by XMin,XMax And YMin,YMax;
;   put minor ticks every XTick,YTick interval With major ticks every
;   XMajor,YMajor multiples of XTick,YTick; if GridOn = TRUE a grid
;   is drawn
Procedure Frame(XTick.d,YTick.d, XMajor.i,YMajor.i, GridOn.b)
  SetClipOff()
  ; draw frame around world 
  Move(XWorldMin,YWorldMin)
  Draw(XWorldMax,YWorldMin)
  Draw(XWorldMax,YWorldMax)
  Draw(XWorldMin,YWorldMax)
  Draw(XWorldMin,YWorldMin)
  SetClipOn()
  ; add tick marks 
  Tick_Proc(XWorldMin,YWorldMin,XTick,YTick,XMajor,YMajor,GridOn)
  Tick_Proc(XWorldMax,YWorldMax,XTick,YTick,XMajor,YMajor,GridOn)
EndProcedure


Procedure.s Remove_Zeros(Strng.s)
  Protected.i i,j,z
  Protected.s tmp1,tmp2
  Protected.s signs
  Strng = Trim(Strng)
  i = Len(Strng)
  If (Mid(Strng,i-3,i) = "E+0") Or (Mid(Strng,i-3,i) = "E-0")
    Strng = Mid(Strng,0,i-4)
    i = Len(Strng)
  ElseIf (Mid(Strng,i-4,i) = "E+00") Or (Mid(Strng,i-4,i) = "E-00")
    Strng = Mid(Strng,0,i-5)
    i = Len(Strng)
  ElseIf (Mid(Strng,i-5,i) = "E+000") Or (Mid(Strng,i-5,i) = "E-000")
    Strng = Mid(Strng,0,i-6)
    i = Len(Strng)
  ElseIf (Mid(Strng,i-6,i) = "E+0000") Or (Mid(Strng,i-6,i) = "E-0000")
    Strng = Mid(Strng,0,i-7)
    i = Len(Strng)
  EndIf
  z = FindString(Strng, "E", 1, #PB_String_NoCase)
  If z > 0 
    tmp1 = Mid(Strng,0,z-1)
    If Mid(Strng,z+1,1) = "+" 
      signs = "E+"
      tmp2 = Mid(Strng,z+2,i)
    ElseIf Mid(Strng,z+1,1) = "-" 
      signs = "E-"
      tmp2 = Mid(Strng,z+2,i)
    Else
      tmp2 = Mid(Strng,z+1,i)
    EndIf
    i = Len(tmp1)
    If i > 0 
      While i > 0
        If (Mid(tmp1,i-1,1) = " ") Or (Mid(tmp1,i-1,1) = "0") 
          ;tmp1[i-1] = Chr(0)
          tmp1 = Mid(tmp1,0,i)
          DEC(i)
        Else
          Break
        EndIf
      Wend
    EndIf
    i = Len(tmp1)
    If Mid(tmp1,i-1,1) = "." 
      tmp1 = Mid(tmp1,0,i-2)
    EndIf
    ; start exponent 
    i = -1
    j = Len(tmp2)
    If j > 0 
      While i < j
        If (Mid(tmp2,i+1,1) = " ") Or (Mid(tmp2,i+1,1) = "0") 
          INC(i)
        Else
          Break
        EndIf
      Wend
    EndIf
    If i >= 0 
      tmp2 = Mid(tmp2,i+1,j)
    EndIf
    tmp1 = tmp1 + signs
    tmp1 = tmp1 + tmp2
    Strng = tmp1;
  Else          ; regular number such as 20.0000
    z = FindString(Strng, ".", 1, #PB_String_NoCase)
    If z > 0 
      i = Len(Strng)
      If i > 0 
        While i > 0
          If (Mid(Strng,i,1) = " ") Or (Mid(Strng,i,1) = "0") 
            Strng = Mid(Strng,0,i-1)
            DEC(i)
          Else
            Break
          EndIf
        Wend
      EndIf
      i = Len(Strng)
      If z > 0
        ;check for numbers such as -0.302
        tmp1 = Mid(Strng,1,z-1)   ;-0
        tmp2 = Mid(Strng,z+1,i)   ; 302
        i = Len(tmp1)
        While i > 0
          If (Mid(tmp1,i,1) = " ") Or (Mid(tmp1,i,1) = "0") 
            tmp1 = Mid(tmp1, 0, i-1)
            DEC(i)
          Else
            Break
          EndIf
        Wend
        i = Len(tmp2)
        While i > 0
          If (Mid(tmp2,i,1) = " ") Or (Mid(tmp2,i,1) = "0") 
            tmp2 = Mid(tmp2,0,i-1)
            DEC(i)
          Else
            Break
          EndIf
        Wend
        If tmp2 <> ""
          Strng = tmp1 + "." + tmp2
        Else
          Strng = tmp1
        EndIf
        If Strng = ""
          Strng = "0"
        EndIf
      EndIf
    EndIf
  EndIf
  ProcedureReturn Strng
EndProcedure

;  puts STRING Labl at the top of the plot
Procedure TopTitle(Labl.s)
  Protected.i scale = 24
  Protected.i xw,yw
  SetClipOff()
  xw = Int(XViewMax / 2)  - (Len(Labl)/2)
  yw = -scale
  SetTextStyle(#CourierNewFont,#HorizDir, 16)
  SetTextJustify(#CenterText,#BottomText)
  OutTextXY(xw, yw, Labl)
  SetClipOn()
EndProcedure

;   labels x axis With STRING Labl; Label_Axes sets up variable MaxLabHeight
;   which is used For XAxisTitle offset; if you haven't called Label_Axes,
;   Setup_Graph has initialized MaxLabHeight To 0;
Procedure XAxisTitle(Labl.s)
  Protected.i scale = 12
  Protected.i xw,yw
  SetClipOff()
  xw = Int(XViewMax / 2)
  yw = YViewMax+MaxLabHeight+scale+16;
  SetTextStyle(#CourierNewFont,#HorizDir,16)
  SetTextJustify(#CenterText,#TopText)
  OutTextXY(xw,yw,Labl)
  SetClipOn()
EndProcedure

;   labels y axis With STRING Labl; Label_Axes sets up variable MaxLabLength
;   which is used For YAxisTitle offset; if you haven't called Label_Axes,
;   Setup_Graph has initialized MaxLabLength To 0;
Procedure YAxisTitle(Labl.s)
  Protected.i scale = 40
  Protected.i xw,yw
  SetClipOff()
  xw = -MaxLabLength-scale ; adjust position for length of y axis number labels 
  yw = Int(YViewMax / 2)
  SetTextStyle(#CourierNewFont, #VertDir, 16)
  SetTextJustify(#RightText, #CenterText)
  OutTextXY(xw,yw,Labl)
  SetClipOn()
EndProcedure

;   This Procedure draws a label at position X,Y in world coordinates;
;   the variables "Font,Direction,Size,XJust,YJust" are just As in the
;   BGI description For Turbo Pascal graphics:
;   Font,Direction, And Size are set by a BGI proc "SetTextStyle" And
;   XJust,YJust are set by a BGI proc "SetTextJustify"
Procedure Draw_Label(X.d,Y.d, Strng.s,Font.i,Direction.i,Size.i, XJust.i,YJust.i)
  Protected.i xw,yw
  SetTextJustify(XJust,YJust)
  SetTextStyle(Font,Direction,Size)
  World_to_Window(X,Y,@xw,@yw)
  OutTextXY(xw,yw,Strng)
EndProcedure

;   Draws a pair of axes through XOrg,YOrg With minor tick intervals
;   XTick,YTick, And major ticks every XMajor,YMajor minor tick
;   intervals; if the flag GridOn = TRUE then a grid is drawn
Procedure Axes(XOrg.d,YOrg.d,XTick.d,YTick.d, XMajor.i,YMajor.i, GridOn.b)
  SetClipOn()
  Move(XOrg,YWorldMin) 
  Draw(XOrg,YWorldMax)  ; x axis 
  Move(XWorldMin,YOrg) 
  Draw(XWorldMax,YOrg)  ; y axis 
  Tick_Proc(XOrg,YOrg,XTick,YTick,XMajor,YMajor,GridOn) ; draw tick marks 
EndProcedure

;   Labels axes at intervals LabelX, LabelY; by convention you may
;   want this To be :
;       LabelX = XMajor*XTick
;       LabelY = YMajor*YTick
;   in your program
Procedure Label_Axes(LabelX.d,LabelY.d)
  Protected.i x_location = 8  ; factors for positioning labels 
  Protected.i y_location = 8
  Protected.i xloc,yloc,templength,tempheight
  Protected.d tempminx,tempmaxx,tempminy,tempmaxy
  Protected.d x,y
  Protected.s labl
  SetClipOff()
  SetTextStyle(#TimesNewRomanFont,#HorizDir,2)
  If XWorldMin <= XWorldMax  ; regular axis direction 
    If XAxisLog
    ; adjust limits to ensure end labels are shown 
      World_to_Window(XWorldMin,YWorldMin,@xloc,@yloc)
      Window_to_World(xloc-1,yloc,@tempminx,@y)
      World_to_Window(XWorldMax,YWorldMin,@xloc,@yloc)
      Window_to_World(xloc+1,yloc,@tempmaxx,@y)
    Else ; X axis is linear 
      tempminx = XWorldMin
      tempmaxx = XWorldMax
    EndIf
  Else ; reversed axis direction 
    If XAxisLog
    ; adjust limits to ensure end labels are shown 
      World_to_Window(XWorldMax,YWorldMin,@xloc,@yloc)
      Window_to_World(xloc+1,yloc,@tempminx,@y)
      World_to_Window(XWorldMin,YWorldMin,@xloc,@yloc)
      Window_to_World(xloc-1,yloc,@tempmaxx,@y)
    Else ; X axis is linear 
      tempminx = XWorldMax
      tempmaxx = XWorldMin
    EndIf
  EndIf

  If YWorldMin <= YWorldMax  ; regular axis direction 
    If YAxisLog
    ; adjust limits to ensure end labels are shown 
      World_to_Window(XWorldMin,YWorldMin,@xloc,@yloc)
      Window_to_World(xloc,yloc+1,@x,@tempminy)
      World_to_Window(XWorldMin,YWorldMax,@xloc,@yloc)
      Window_to_World(xloc,yloc-1,@x,@tempmaxy)
    Else ; Y axis is linear 
     tempminy = YWorldMin
     tempmaxy = YWorldMax
    EndIf
  Else ; reversed axis direction 
    If YAxisLog
    ; adjust limits to ensure end labels are shown 
      World_to_Window(XWorldMin,YWorldMax,@xloc,@yloc)
      Window_to_World(xloc,yloc-1,@x,@tempminy)
      World_to_Window(XWorldMin,YWorldMin,@xloc,@yloc)
      Window_to_World(xloc,yloc+1,@x,@tempmaxy)
    Else ; Y axis is linear 
      tempminy = YWorldMax
      tempmaxy = YWorldMin
    EndIf
  EndIf
  ; label x axis 
  MaxLabHeight = 0; ; initialize this offset for XAxisTitle 
  tempheight = 0;
  SetTextJustify(#CenterText, #TopText) ; do this just once for linear axis 
  x = tempminx
  If XAxisLog 
    x = Pow(10.0,Log10(tempminx))
  EndIf
  While x <= tempmaxx
    If XAxisLog
      labl = StrD(Log10(x), 3) ; was 6
    Else
      labl = StrD(x, 3) ; was 5
    EndIf
    labl = Remove_Zeros(labl)
    World_to_Window(x,YWorldMin,@xloc,@yloc)
    If XAxisLog  ; do an exponentiated label 
      If (x >= tempminx) And (x <= tempmaxx)
        SetTextJustify(#CenterText, #TopText)
        INC(yloc, y_location+13) ; position the "10" 
        OutTextXY(xloc,yloc,"10")
        tempheight = TextHeights("10") + Int(TextHeights(labl)-4)
        DEC(yloc, Int(tempheight / 2))
        INC(xloc, Int(TextWidths("10") / 2) + 3)
        tempheight = Int(tempheight / 2) + Int(TextHeights(labl)) ; pixel height of label 
        SetTextJustify(#LeftText,#TopText)
        OutTextXY(xloc,yloc,labl)
      EndIf ; IF ((x >= tempminx... 
      x = x*10.0
    Else ; straight linear label 
      INC(yloc,y_location)
      OutTextXY(xloc,yloc,labl)
      tempheight = TextHeights(labl)
      INC(x+LabelX)
    EndIf ; IF (XAxisLog)... 
    If tempheight > MaxLabHeight
      MaxLabHeight = tempheight
    EndIf
  Wend ; WHILE 
  ; label y axis 
  MaxLabLength = 0 ; initialize this offset for YAxisTitle 
  templength = 0
  SetTextJustify(#RightText,#CenterText)
  y = tempminy
  If YAxisLog 
    y = Pow(10.0,Log10(tempminy))
  EndIf
  While y <= tempmaxy
    If YAxisLog
      labl = StrD(Log10(y), 3) ; was 6
    Else
      labl = StrD(y, 3) ; was 5
    EndIf
    labl = Remove_Zeros(labl)
    World_to_Window(XWorldMin,y,@xloc,@yloc)
    If YAxisLog  ; do an exponentiated label 
      If (y >= tempminy) And (y <= tempmaxy)
        SetTextJustify(#RightText,#CenterText)
        templength = TextWidths("10") + Int(TextWidths(labl)/2)
        DEC(xloc,x_location-templength) ; position the "10" 
        OutTextXY(xloc,yloc,"10")
        templength = templength + Int(TextWidths(labl)) ; pixel width of label 
        DEC(yloc,Int(TextHeights("10") / 2))
        INC(xloc,2)
        SetTextJustify(#LeftText,#CenterText)
        OutTextXY(xloc,yloc,labl)
      EndIf ; IF ((y >= tempminy... 
      y = y * 10.0
    Else ; straight linear label 
      DEC(xloc,x_location)
      OutTextXY(xloc,yloc,labl)
      templength = TextWidths(labl)
      INC(y,LabelY)
    EndIf
    If (templength > MaxLabLength)  
      MaxLabLength = templength 
    EndIf
  Wend
  ; restore defaults 
  SetClipOn()
EndProcedure

;   Plots a Symbol, scaled by SymSize, centered at world coordinates
;   X,Y; available Symbols are:
;     1  - plus
;     2  - box
;     3  - cross (x-like)
;     4  - triangle
;     5  - inverted triangle
;     6  - open circle
;     7  - filled circle
;     8  - dot
Procedure PlotPoint(X.d,Y.d, Symbol.i, SymSize.i, color.i)
  Protected.i del = 1
  Protected.i xs,ys,delta,x1,y1
  Protected.i curcol
  x1 = GetX() 
  y1 = GetY()
  curcol = GetColor()
  SetColor(color)
  World_to_Window(X,Y,@xs,@ys)
  delta = del*SymSize;
  Select Symbol
    Case 1   ; plus 
         MoveTo(xs-delta,ys)
         LineRel(2*delta,0)
         MoveRel(-delta,-delta)
         LineRel(0,2*delta)
    Case 2   ; box 
         MoveTo(xs-delta,ys-delta)
         LineRel(2*delta,0)
         LineRel(0,2*delta)
         LineRel(-2*delta,0)
         LineRel(0,-2*delta)
    Case 3   ; cross 
         MoveTo(xs-delta,ys-delta)
         LineRel(2*delta,2*delta)
         MoveRel(-2*delta,0)
         LineRel(2*delta,-2*delta)
    Case 4:   ; triangle 
         MoveTo(xs,Int(ys-delta-delta / 3))
         LineRel(-delta,2*delta)
         LineRel(2*delta,0)
         LineRel(-delta,-2*delta)
    Case 5   ; inverted triangle 
         MoveTo(xs,Int(ys+delta+delta / 3))
         LineRel(-delta,-2*delta)
         LineRel(2*delta,0)
         LineRel(-delta,2*delta)
    Case 6 
         Circles(xs,ys,delta) ; open circle 
    Case 7 
      FillEllipse(xs,ys,delta,delta, color) ; closed circle 
    Case 8 
      PutPixel(xs,ys,GetMaxColor()) ; unscaled point 
  Default
  EndSelect
  MoveTo(x1,y1)
  SetColor(curcol)
EndProcedure

;   Procedure To set up the graph limits.
;   The world coordinate limits are XMin, XMax, YMin, And YMax.
;   The window limits are WXMin, WXMax, WYMin, WYMax expressed As
;   fractions (of 1,i.e. 0.95 etc) of the maximum screen limits.
Procedure Setup_Graph(XMin.d,XMax.d,YMin.d,YMax.d, WXMin.d,WXMax.d,WYMin.d,WYMax.d,logx.b,logy.b)
   If logx = #True
     XAxisLog = #True
   Else 
     XAxisLog = #False 
   EndIf
   If logy = #True
     YAxisLog = #True
   Else 
     YAxisLog = #False 
   EndIf
  ; set global variables for other graphics routines. 
  XWorldMin = XMin
  XWorldMax = XMax
  YWorldMin = YMin
  YWorldMax = YMax
  Setscale(WXMin,WXMax,WYMin,WYMax)
  ; initialize some global constants just in case Label_Axes is not called 
  MaxLabLength = 0
  MaxLabHeight = 0
  ; set up defaults for graphics parameters 
  SetClipOn()
  Custom_LineStyle(0) = $0FFFF
  Custom_LineStyle(1) = $5555
  Custom_LineStyle(2) = $0F0F
  Custom_LineStyle(3) = $1111
  Custom_LineStyle(4) = $1010
EndProcedure

;   Plots a Symbol, scaled by SymSize, centered at world coordinates
;   X,Y; error bar on X,Y are sigx and sigy; available Symbols are:
;     1  - plus
;     2  - box
;     3  - cross (x-like)
;     4  - triangle
;     5  - inverted triangle
;     6  - open circle
;     7  - filled circle
;     8  - dot
Procedure PlotData(x.d,sigx.d,y,sigy.d, Symbol.i, SymSize.i, color.i)
  Protected.i del = 1
  Protected.i xs,ys,delta,xx,yy
  PlotPoint(x,y,Symbol,SymSize, color)
  delta = del*SymSize
  xx = GetX() 
  yy = GetY()
  If (sigx > 0.0)  ; do x error bar 
    Move(x+sigx,y)
    Draw(x-sigx,y)
    World_to_Window(x+sigx,y,@xs,@ys)
    MoveTo(xs,ys-delta)
    LineRel(0,2*delta)
    World_to_Window(x-sigx,y,@xs,@ys)
    MoveTo(xs,ys-delta)
    LineRel(0,2*delta)
  EndIf
  If (sigy > 0.0)  ; do y error bar 
    Move(x,y+sigy)
    Draw(x,y-sigy)
    World_to_Window(x,y+sigy,@xs,@ys)
    MoveTo(xs-delta,ys)
    LineRel(2*delta,0)
    World_to_Window(x,y-sigy,@xs,@ys)
    MoveTo(xs-delta,ys)
    LineRel(2*delta,0)
  EndIf
  MoveTo(xx,yy)
EndProcedure

EndModule
infratec
Always Here
Always Here
Posts: 7577
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Help on an error - bgi graphics, function plot modules

Post by infratec »

Hi,

weired :?:


Your latest version:
Image

With my Tick_Plot():
Image

Ok, the frame is something strange.
But in general the axis looks much better.

Bernd
startup
Enthusiast
Enthusiast
Posts: 105
Joined: Wed Feb 25, 2015 5:55 pm

Re: Help on an error - bgi graphics, function plot modules

Post by startup »

crazy - i have frames

i use:

Code: Select all

XIncludeFile "MINIPLOT.pbi"
XIncludeFile "MINIBGI.pbi"

UseModule MINIPLOT
UseModule MINIBGI
EnableExplicit 

Procedure.d sinc(x.d)
If x=0.0 
  ProcedureReturn 1.0 
Else 
  ProcedureReturn Sin(x/(x*x))
EndIf
EndProcedure

Global x.d,xwin=800, ywin=800
Global Event.i, Quit.i, wnum.i,MaxX.i,MaxY.i,MaxRadius.i
wnum = OpenWindow(#PB_Any, 100, 200, xwin, ywin, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
If wnum
  InitGraph(wnum, xwin, ywin, "tester")
  Setup_Graph(-5.0, 20.0, -0.5, 2.5, 10.0, 85.0, 10.0, 85.0, #False, #False)
  SetColor(#Black)
  Frame(1.0,0.1,5,5,#True)
  SetColor(#Red)
  Axes(1.0,1.0,5.0,5.0,5,5,#False)
  SetColor(#Black)
  Label_Axes(1.0,0.5)
  TopTitle("Sinc Function")
  XAxisTitle("x (radians)")
  YAxisTitle("Sin(x/x*x)")

  x = -5
  SetColor(#PrussianBlue)
  Move(x,sinc(x))
  x = x + 0.5
  Repeat
    Draw(x,sinc(x)+1)
    INC(x, 0.5)
  Until x > 20


    
  Repeat
    Event = WaitWindowEvent()
    If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
      Quit = 1
    EndIf
  Until Quit = 1
EndIf

End   ; All the opened windows are closed automatically by PureBasic

craps, i don't know how to put a picture here

richard
infratec
Always Here
Always Here
Posts: 7577
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Help on an error - bgi graphics, function plot modules

Post by infratec »

Hi, hi,

I commented out the frame procedure since it looks not like you want.
But you can see that the axis are placed correct.

For pictures:
You have to upload the pictures to a 'picture hoster', then you can include here the link
in tags [img]....[/img]

Bernd
startup
Enthusiast
Enthusiast
Posts: 105
Joined: Wed Feb 25, 2015 5:55 pm

resolved - bgi graphics, function plot modules

Post by startup »

a correction. i am still trying to figure out the thing with the picture. maybe i am to old or to stupid.

Code: Select all

Procedure.s Remove_Zeros(Strng.s)
  Protected.i i,j,z
  Protected.s tmp1,tmp2
  Protected.s signs
  Strng = Trim(Strng)
  i = Len(Strng)
  If (Mid(Strng,i-3,i) = "E+0") Or (Mid(Strng,i-3,i) = "E-0")
    Strng = Mid(Strng,0,i-4)
    i = Len(Strng)
  ElseIf (Mid(Strng,i-4,i) = "E+00") Or (Mid(Strng,i-4,i) = "E-00")
    Strng = Mid(Strng,0,i-5)
    i = Len(Strng)
  ElseIf (Mid(Strng,i-5,i) = "E+000") Or (Mid(Strng,i-5,i) = "E-000")
    Strng = Mid(Strng,0,i-6)
    i = Len(Strng)
  ElseIf (Mid(Strng,i-6,i) = "E+0000") Or (Mid(Strng,i-6,i) = "E-0000")
    Strng = Mid(Strng,0,i-7)
    i = Len(Strng)
  EndIf
  z = FindString(Strng, "E", 1, #PB_String_NoCase)
  If z > 0 
    tmp1 = Mid(Strng,0,z-1)
    If Mid(Strng,z+1,1) = "+" 
      signs = "E+"
      tmp2 = Mid(Strng,z+2,i)
    ElseIf Mid(Strng,z+1,1) = "-" 
      signs = "E-"
      tmp2 = Mid(Strng,z+2,i)
    Else
      tmp2 = Mid(Strng,z+1,i)
    EndIf
    i = Len(tmp1)
    If i > 0 
      While i > 0
        If (Mid(tmp1,i-1,1) = " ") Or (Mid(tmp1,i-1,1) = "0") 
          ;tmp1[i-1] = Chr(0)
          tmp1 = Mid(tmp1,0,i)
          DEC(i)
        Else
          Break
        EndIf
      Wend
    EndIf
    i = Len(tmp1)
    If Mid(tmp1,i-1,1) = "." 
      tmp1 = Mid(tmp1,0,i-2)
    EndIf
    ; start exponent 
    i = -1
    j = Len(tmp2)
    If j > 0 
      While i < j
        If (Mid(tmp2,i+1,1) = " ") Or (Mid(tmp2,i+1,1) = "0") 
          INC(i)
        Else
          Break
        EndIf
      Wend
    EndIf
    If i >= 0 
      tmp2 = Mid(tmp2,i+1,j)
    EndIf
    tmp1 = tmp1 + signs
    tmp1 = tmp1 + tmp2
    Strng = tmp1;
  Else          ; regular number such as 20.0000
    z = FindString(Strng, ".", 1, #PB_String_NoCase)
    If z > 0 
      i = Len(Strng)
      If i > 0 
        While i > 0
          If (Mid(Strng,i,1) = " ") Or (Mid(Strng,i,1) = "0") 
            Strng = Mid(Strng,0,i-1)
            DEC(i)
          Else
            Break
          EndIf
        Wend
      EndIf
      i = Len(Strng)
      If z > 0
        ;check for numbers such as -0.302
        tmp1 = Mid(Strng,1,z-1)   ;-0
        tmp2 = Mid(Strng,z+1,i)   ; 302
        If tmp2 = ""
          ProcedureReturn tmp1
        EndIf
        i = Len(tmp1)
        While i > 0
          If (Mid(tmp1,i,1) = " ") Or (Mid(tmp1,i,1) = "0") 
            tmp1 = Mid(tmp1, 0, i-1)
            DEC(i)
          Else
            Break
          EndIf
        Wend
        i = Len(tmp2)
        While i > 0
          If (Mid(tmp2,i,1) = " ") Or (Mid(tmp2,i,1) = "0") 
            tmp2 = Mid(tmp2,0,i-1)
            DEC(i)
          Else
            Break
          EndIf
        Wend
        If tmp2 <> ""
          Strng = tmp1 + "." + tmp2
        Else
          Strng = tmp1
        EndIf
        If Strng = ""
          Strng = "0"
        EndIf
      EndIf
    EndIf
  EndIf
  ProcedureReturn Strng
EndProcedure
Post Reply