cyclometric circle

User avatar
Silvio.Falconi
Posts: 7104
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Post by Silvio.Falconi »

I tried to improve the class because the object is not centered now the circle is inside the object
practically creating the circumference I halved the measures as you can see in this picture


Image


But now I have problems with the small circles and the numbers because they are attached and I don't understand why

Image

numbers must be 1 to 90 and the number 1 must be located in the top center, the number 45 in the bottom center


even the circles are not all attached and instead should be drawn one behind the other, the position is bad

Image


is there someone can help me please ?

the test with new class

Code: Select all | Expand

#include "fivewin.ch"
#include "constant.ch"


Function Test()

      local oDlg,oFont,oBold
      local oBtnClose
      local nBottom   := 24
      local nRight    := 55
      local nWidth    := Max( nRight * DLG_CHARPIX_W, 180 )
      local nHeight   := nBottom * DLG_CHARPIX_H
      local oCicloMetric

   DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-10
   DEFINE FONT oBold NAME "TAHOMA" SIZE 0,-12  BOLD

   DEFINE DIALOG oDlg SIZE  nWidth, nHeight  ;
      PIXEL TRUEPIXEL  FONT oFont   ;  //RESIZABLE
      TiTle "Manage Ciclometric"

     oCicloMetric:=  TCyclometric():New( 1, 1, oDlg,  400, 300, CLR_HGRAY)


     @ 100,10 BUTTON oBtnClose PROMPT "Close" of oDlg  SIZE 80,22 ACTION oDlg:End()


   oDlg:bResized := <||
     local oRect := oDlg:GetCliRect()
        oBtnClose:nLeft    := oRect:nRight - 100
        oBtnClose:nTop     := oRect:nBottom - 45
    RETURN NIL
    >



                       ACTIVATE DIALOG oDlg CENTERED;
                       ON INIT (  Eval(oDlg:bResized))

   RELEASE FONT oFont, oBold
   Return nil

//------------------------------------------------------------------//

#define darkgray    nRgb(169,169,169)
#define darkorange  nRgb(255,140,0)
#define darkred     nRgb(139,0,0)
#define lightblue   nRgb(173,216,230)

#define TA_CENTER         6
#define COLOR_BTNFACE 15
#define PS_SOLID   0



Class TCyclometric From Tcontrol
   CLASSDATA lRegistered AS LOGICAL

    DATA nColorCirc
    DATA nColorText
    DATA oFont
    DATA lShowSmallCircles
    DATA lDrawBorder

    DATA nMedWidth,nMedHeight,nMedSide
    DATA nTopCir,nLeftCir
    DATA nRadiusExt
    DATA nRadiusInt


METHOD New( nRow, nCol, oWnd,  nWidth, nHeight) CONSTRUCTOR
METHOD Paint()
METHOD Display() INLINE ::BeginPaint(), ::Paint(), ::EndPaint(), 0
METHOD PaintCircle()
METHOD PaintNumbers()

ENDCLASS
//-----------------------------------------------------------------------//
METHOD New( nRow, nCol, oWnd,  nWidth, nHeight, nColorCirc,oFont,nColorText,;
            lPixel, lDesign,lShowSMallCircles,lDrawBorder) Class TCyclometric

   DEFAULT  nRow     := 0, nCol := 0, oWnd := GetWndDefault()
   DEFAULT  lPixel   := .f.
   DEFAULT  nColorCirc   := CLR_HGRAY

    DEFAULT nWidth := 50, nHeight := 50,;
           lDesign := .f.
   DEFAULT  lShowSMallCircles := .t.
   DEFAULT lDrawBorder := .t.   //test



   ::nTop      = If( lPixel, nRow, nRow * MTR_CHARPIX_H )  //14
   ::nLeft     = If( lPixel, nCol, nCol *  MTR_CHARPIX_W ) //8
   ::nBottom   = ::nTop  + nHeight
   ::nRight    = ::nLeft + nWidth
   ::oWnd      = oWnd
   ::lDrawBorder = lDrawBorder


   ::nId       = ::GetNewId()
  
   ::nColorCirc  =  nColorCirc
   ::lShowSMallCircles := lShowSMallCircles

   ::lDrag     = lDesign
   ::lCaptured = .f.
   ::ltransparent =.t.

    if oFont == nil
      DEFINE FONT ::oFont NAME "Verdana" SIZE 0, -10 BOLD
   else

      ::SetFont( oFont )

   endif
   ::nColorText  = nColorText

   ::nStyle  = nOr( WS_CHILD, WS_VISIBLE, WS_CLIPCHILDREN, WS_TABSTOP,;
                                 if( lDrawBorder, WS_BORDER, 0 ) )
   ::Register()

   if ! Empty( ::oWnd:hWnd )
      ::Create()
      ::Default()
      ::oWnd:AddControl( Self )
      if ::oWnd:oBrush != nil
         ::SetBrush( ::oWnd:oBrush )
      endif
   else
      ::oWnd:DefControl( Self )
   endif

   if lDesign
      ::CheckDots()
   endif

return Self
//------------------------------------------------------------//
METHOD Paint() Class TCyclometric
 local aInfo, aRect

   aInfo    := ::DispBegin()

   if ::lTransparent .or. ::nOpacity < 255
      aRect    := GetClientRect( ::hWnd )
      SetBrushOrgEx( ::hDC, -::nLeft, -::nTop )
      FillRect( ::hDC, aRect, ::oWnd:oBrush:hBrush )
      if ! ::lTransparent
         FillRectEx( ::hDC, aRect, nARGB( ::nOpacity, ::nClrPane ) )
      endif
   else
      ::PaintBack( ::hDC )
   endif

   ::PaintCircle()  //draw the main circle 

   ::PaintNumbers()  //draw the numbers and small circles

   if ValType( ::bPainted ) == "B"
      Eval( ::bPainted, ::hDC, ::cPS, Self )
   endif

   ::DispEnd( aInfo )

return nil
//------------------------------------------------------------------------//
METHOD PaintCircle() Class TCyclometric
   local aRect    := GetClientRect( ::hWnd )
   local oPen    := CREATEPEN( PS_SOLID, 2, darkgray )

    ::nTopCir    := ::nHeight / 2
    ::nLeftCir   := ::nWidth  / 2
    ::nMedWidth  := aRect[4]/2
    ::nMedHeight := aRect[3]/2
    ::nMedSide   := min( ::nMedWidth, ::nMedHeight ) - 10

      ellipse( ::hDC, ::nLeftCir - ::nMedSide,;
                      ::nTopCir  - ::nMedSide,;
                      ::nLeftCir + ::nMedSide,;
                      ::nTopCir  + ::nMedSide,oPen )


return 0
//------------------------------------------------------------------------//
METHOD PaintNumbers() Class TCyclometric
   local nI
   local  oPen := CREATEPEN( PS_SOLID, 1, CLR_BLUE )
   local  nTotalNumbers := 90
   local  step_fi := PI() / 4.5 / 10
   local aRect    := GetClientRect( ::hWnd )


  local  nYOffset := ::oFont:nHeight / 2
  local  nXOffset := ::oFont:nWidth / 2
  local  nDeltaR  := ::oFont:nHeight

  local nColor


    ::nRadiusExt := int( ::nMedSide ) * 0.98
    ::nRadiusInt := ::nRadiusExt      * 0.98

     //draw numbers and circles
       FOR nI = 1 TO nTotalNumbers
          nTop  := ::nTopCir  -  ( ::nRadiusInt * Cos( nI  ) )
          nLeft := ::nLeftCir +  ( ::nRadiusInt * Sin( nI  ) )

          Ellipse(::hDC, nLeft - 5, nTop  - 5, nLeft+ 5, nTop  + 5    )

         ::Say( nTop , nLeft , hb_ntoc( nI,0 ),CLR_RED , , ::oFont, .t.,.t., TA_CENTER )

       NEXT
 return 0
//------------------------------------------------------------------------//







 
with circles and numbers together

Image
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
Posts: 7104
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Post by Silvio.Falconi »

Now I correct the position of numbers but there is also some errors


Image

Code: Select all | Expand

METHOD PaintNumbers() Class TCyclometric
   local nI
   local  oPen := CREATEPEN( PS_SOLID, 1, CLR_BLUE )
   local  nTotalNumbers := 90


  local  nYOffset := ::oFont:nHeight / 2
  local  nXOffset := ::oFont:nWidth / 2
  local  nDeltaR  := ::oFont:nHeight

  local nColor
  local nAngolo


    ::nRadiusExt := int( ::nMedSide ) * 0.98
    ::nRadiusInt := ::nRadiusExt      * 0.98

     //draw numbers and circles
    FOR nI = 1 TO  nTotalNumbers
          nAngolo := 2* PI() / nTotalNumbers * ( nI - 1 )
          nTop  := ::nTopCir  -  ( ::nRadiusInt * Cos( nAngolo  ) )
          nLeft := ::nLeftCir +  ( ::nRadiusInt * Sin( nAngolo  ) )


         * Ellipse(::hDC, nLeft - 5, nTop  - 5, nLeft+ 5, nTop  + 5    )

         ::Say( nTop , nLeft , hb_ntoc( nI,0 ),CLR_RED , , ::oFont, .t.,.t., TA_CENTER )

       NEXT
 return 0
//------------------------------------------------------------------------//
the numbers must be outside the circumference


While the small circles seems run ok and right position

Image
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
Posts: 7104
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Post by Silvio.Falconi »

Perhaps I resolve but there is a small error


Image


Now the small circles are right and in their place and also the numbers only in the lower part touch the edge of the object
the numbers seem crooked to me i.e. there is no axis 90-> 45 the numbers are slightly off , How I can resolve ?

New code

Code: Select all | Expand

#include "fivewin.ch"
#include "constant.ch"


Function Test()

      local oDlg,oFont,oBold
      local oBtnClose
      local nBottom   := 24
      local nRight    := 55
      local nWidth    := Max( nRight * DLG_CHARPIX_W, 180 )
      local nHeight   := nBottom * DLG_CHARPIX_H
      local oCicloMetric

   DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-10
   DEFINE FONT oBold NAME "TAHOMA" SIZE 0,-12  BOLD

   DEFINE DIALOG oDlg SIZE  nWidth, nHeight  ;
      PIXEL TRUEPIXEL  FONT oFont   ;  //RESIZABLE
      TiTle "Manage Ciclometric"

     oCicloMetric:=  TCyclometric():New( 1, 1, oDlg,  400, 300, CLR_HGRAY)


     @ 100,10 BUTTON oBtnClose PROMPT "Close" of oDlg  SIZE 80,22 ACTION oDlg:End()


   oDlg:bResized := <||
     local oRect := oDlg:GetCliRect()
        oBtnClose:nLeft    := oRect:nRight - 100
        oBtnClose:nTop     := oRect:nBottom - 45
    RETURN NIL
    >



                       ACTIVATE DIALOG oDlg CENTERED;
                       ON INIT (  Eval(oDlg:bResized))

   RELEASE FONT oFont, oBold
   Return nil

//------------------------------------------------------------------//

#define darkgray    nRgb(169,169,169)
#define darkorange  nRgb(255,140,0)
#define darkred     nRgb(139,0,0)
#define lightblue   nRgb(173,216,230)

#define TA_CENTER         6
#define COLOR_BTNFACE 15
#define PS_SOLID   0



Class TCyclometric From Tcontrol
   CLASSDATA lRegistered AS LOGICAL

    DATA nColorCirc
    DATA nColorText
    DATA oFont
    DATA lShowSmallCircles
    DATA lDrawBorder

    DATA nMedWidth,nMedHeight,nMedSide
    DATA nTopCir,nLeftCir
    DATA nRadiusExt
    DATA nRadiusInt


METHOD New( nRow, nCol, oWnd,  nWidth, nHeight) CONSTRUCTOR
METHOD Paint()
METHOD Display() INLINE ::BeginPaint(), ::Paint(), ::EndPaint(), 0
METHOD PaintCircle()
METHOD PaintNumbers()
METHOD PaintSmallCircles()
ENDCLASS
//-----------------------------------------------------------------------//
METHOD New( nRow, nCol, oWnd,  nWidth, nHeight, nColorCirc,oFont,nColorText,;
            lPixel, lDesign,lShowSMallCircles,lDrawBorder) Class TCyclometric

   DEFAULT  nRow     := 0, nCol := 0, oWnd := GetWndDefault()
   DEFAULT  lPixel   := .f.
   DEFAULT  nColorCirc   := CLR_HGRAY
   DEFAULT  nColorText   := CLR_BLUE

    DEFAULT nWidth := 50, nHeight := 50,;
           lDesign := .f.
   DEFAULT  lShowSMallCircles := .t.
   DEFAULT lDrawBorder := .t.   //test



   ::nTop      = If( lPixel, nRow, nRow * MTR_CHARPIX_H )  //14
   ::nLeft     = If( lPixel, nCol, nCol *  MTR_CHARPIX_W ) //8
   ::nBottom   = ::nTop  + nHeight
   ::nRight    = ::nLeft + nWidth
   ::oWnd      = oWnd
   ::lDrawBorder = lDrawBorder


   ::nId       = ::GetNewId()

   ::nColorCirc  =  nColorCirc


   ::lShowSMallCircles := lShowSMallCircles

   ::lDrag     = lDesign
   ::lCaptured = .f.
   ::ltransparent =.t.

    if oFont == nil
      DEFINE FONT ::oFont NAME "TAHOMA" SIZE 0, -10
   else
      ::SetFont( oFont )
   endif

   ::nColorText  = nColorText

   ::nStyle  = nOr( WS_CHILD, WS_VISIBLE, WS_CLIPCHILDREN, WS_TABSTOP,;
                                 if( lDrawBorder, WS_BORDER, 0 ) )
   ::Register()

   if ! Empty( ::oWnd:hWnd )
      ::Create()
      ::Default()
      ::oWnd:AddControl( Self )
      if ::oWnd:oBrush != nil
         ::SetBrush( ::oWnd:oBrush )
      endif
   else
      ::oWnd:DefControl( Self )
   endif

   if lDesign
      ::CheckDots()
   endif

return Self
//------------------------------------------------------------//
METHOD Paint() Class TCyclometric
 local aInfo, aRect

   aInfo    := ::DispBegin()

   if ::lTransparent .or. ::nOpacity < 255
      aRect    := GetClientRect( ::hWnd )
      SetBrushOrgEx( ::hDC, -::nLeft, -::nTop )
      FillRect( ::hDC, aRect, ::oWnd:oBrush:hBrush )
      if ! ::lTransparent
         FillRectEx( ::hDC, aRect, nARGB( ::nOpacity, ::nClrPane ) )
      endif
   else
      ::PaintBack( ::hDC )
   endif

   ::PaintCircle()  //draw the main circle
   ::PaintSmallCircles()  //small circles
   ::PaintNumbers()  //draw the numbers

   if ValType( ::bPainted ) == "B"
      Eval( ::bPainted, ::hDC, ::cPS, Self )
   endif

   ::DispEnd( aInfo )

return nil
//------------------------------------------------------------------------//
METHOD PaintCircle() Class TCyclometric
   local aRect    := GetClientRect( ::hWnd )
   local oPen    := CREATEPEN( PS_SOLID, 2, darkgray )

    ::nTopCir    := ::nHeight / 2
    ::nLeftCir   := ::nWidth  / 2
    ::nMedWidth  := aRect[4]/2
    ::nMedHeight := aRect[3]/2
    ::nMedSide   := min( ::nMedWidth, ::nMedHeight ) - 10

      ellipse( ::hDC, ::nLeftCir - ::nMedSide,;
                      ::nTopCir  - ::nMedSide,;
                      ::nLeftCir + ::nMedSide,;
                      ::nTopCir  + ::nMedSide,oPen )


return 0
//------------------------------------------------------------------------//
METHOD PaintSmallCircles() Class TCyclometric
   local nI
   local  oPen := CREATEPEN( PS_SOLID, 1, CLR_BLUE )
   local  nTotalNumbers := 90


  local  nYOffset := ::oFont:nHeight / 2
  local  nXOffset := ::oFont:nWidth / 2
  local  nDeltaR  := ::oFont:nHeight


  local nAngolo


    ::nRadiusExt := int( ::nMedSide ) * 0.98
    ::nRadiusInt := ::nRadiusExt      * 0.98

     //draw circles
    FOR nI = 1 TO  nTotalNumbers
          nAngolo := 2* PI() / nTotalNumbers * ( nI - 1 )
          nTop  := ::nTopCir  -  ( ::nRadiusInt * Cos( nAngolo  ) )
          nLeft := ::nLeftCir +  ( ::nRadiusInt * Sin( nAngolo  ) )


          Ellipse(::hDC, nLeft - 5, nTop  - 5, nLeft+ 5, nTop  + 5    )


       NEXT
 return 0
//------------------------------------------------------------------------//

 METHOD PaintNumbers() Class TCyclometric
   local nI
   local  oPen := CREATEPEN( PS_SOLID, 1, CLR_BLUE )
   local  nTotalNumbers := 90


  local  nYOffset := ::oFont:nHeight / 2
  local  nXOffset := ::oFont:nWidth / 2
  local  nDeltaR  := ::oFont:nHeight

  local nColor
  local nAngolo
  local nMedSidetxt   := min( ::nMedWidth, ::nMedHeight )
  
    ::nRadiusExt := int( nMedSidetxt ) * 0.98


     //draw numbers and circles
    FOR nI = 1 TO  nTotalNumbers
          nAngolo := 2* PI() / nTotalNumbers * ( nI - 1 )
           nTop  := ::nTopCir  -  ( ::nRadiusExt * Cos( nAngolo  ) )
           nLeft := ::nLeftCir +  ( ::nRadiusExt * Sin( nAngolo  ) )

        ::Say( ntop - nYOffset  , nLeft  , hb_ntoc( nI,0 ),::nColorText , , ::oFont, .t.,.t., TA_CENTER )

       NEXT
 return 0
//------------------------------------------------------------------------//

 


as you can see here

Image

the number 90 is not in the center and consequently the number 45 is displaced

i don't know how to solve
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
Posts: 7104
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Post by Silvio.Falconi »

* correct the numbers text on the bottom

* when drawing the geometric shape corresponding to the xbrowse line, the lines are wrong because they don't point to the real xbrowse values

Image


New code

Code: Select all | Expand

#include "fivewin.ch"
#include "constant.ch"


Function Test()

      local oDlg,oFont,oBold
      local oBtnClose
      local nBottom   := 38
      local nRight    := 99
      local nWidth    := Max( nRight * DLG_CHARPIX_W, 180 )
      local nHeight   := nBottom * DLG_CHARPIX_H
      local cUrl:="http://www.televideo.rai.it/televideo/pub/solotesto.jsp?pagina=786"
      local adata:=TestUrl( cUrl )
      local oBrw
      local oCicloMetric

      local aColors:= {CLR_BLUE,;
                      CLR_GREEN,;
                      CLR_RED,;
                      CLR_MAGENTA,;
                      CLR_BROWN,;
                      CLR_HGRAY,;
                      CLR_LIGHTGRAY,;
                      CLR_HBLUE,;
                      CLR_HMAGENTA,;
                      METRO_VIOLET ,;
                      METRO_BROWN}

   DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-10
   DEFINE FONT oBold NAME "TAHOMA" SIZE 0,-12  BOLD

   DEFINE DIALOG oDlg SIZE  nWidth, nHeight  ;
      PIXEL TRUEPIXEL  FONT oFont RESIZABLE  ;  //
      TiTle "Manage Ciclometric"

     oCicloMetric:=  TCyclometric():New( 8, 1, oDlg,  500, 500, CLR_HGRAY)


       @ 200,600 XBROWSE oBrw OF oDlg SIZE 300,250 PIXEL NOBORDER;
      COLS 1,2,3,4,5,6;
      HEADERS "Ruota", "E1", "E2", "E3", "E4", "E5" ;
      SIZES  80,30,30,30,30,30  ;
      ARRAY adata ;
      CELL LINES

    WITH OBJECT oBrw
      :nRowHeight    := 20
      :nClrBorder := CLR_GRAY
      :lDrawBorder := .t.
      :nColorBox := CLR_HRED

      :lHeader             := .f.
      :lHscroll            := .f.
      :lvscroll            := .f.
      :l2007               := .F.
      :l2015               := .t.

      :nStretchCol         := STRETCHCOL_WIDEST
      :lAllowRowSizing     := .F.
      :lAllowColSwapping   := .F.
      :lAllowColHiding     := .F.
      :lRecordSelector     := .F.
      :nColDividerStyle    := LINESTYLE_LIGHTGRAY
      :nRowDividerStyle    := LINESTYLE_LIGHTGRAY
      :bClrStd := { || { CLR_BLACK, If( oBrw:KeyNo % 2 == 0, nRgb(173,216,230) , CLR_WHITE ) } }

      :bChange  := { ||Showform(oBrw:nArrayAt,oCicloMetric,aColors,oBrw) }

      :CreateFromCode()
   End




     @ 100,10 BUTTON oBtnClose PROMPT "Close" of oDlg  SIZE 80,22 ACTION oDlg:End()


   oDlg:bResized := <||
     local oRect := oDlg:GetCliRect()
        oBtnClose:nLeft    := oRect:nRight - 100
        oBtnClose:nTop     := oRect:nBottom - 45
    RETURN NIL
    >



                       ACTIVATE DIALOG oDlg CENTERED;
                       ON INIT (  Eval(oDlg:bResized))

   RELEASE FONT oFont, oBold
   Return nil
//----------------------------------------------------------------------//

 Function TestUrl( cUrl )
        local cRet:=""
        local cData:=""
        local cFile := "test.txt"
        local cBuff
        local nHndl
        local aShow:={}
        local nI

        IF IsInternet()
               cRet := WebPageContents( cUrl )
               cData := WebPageContents( cUrl )
        if Empty( cRet )
          ? "Invalid URL"
       else
            //per la data estrazione
            cData := subStr( cData, at( "ALMANACCO",  cData )+9 )
            cData := allTrim( subStr( cData, 1, at("BARI",  cData ) -1 ) )

            // per il blocco Bari - Nazionale
            cRet := subStr( cRet, at( "BARI", cRet ) )
            cRet := allTrim( subStr( cRet, 1, at( "Controlla", cRet ) - 1 ) )

            nHndl := fCreate( cFile )
            fWrite( nHndl, cRet )
            fClose( nHndl )
            IF ( nHndl := fOpen( cFile ) ) < 1
                msgStop( "UNABLE TO OPEN: " + cFile  )
            ELSE
                aShow := {}
                WHILE hb_fReadLine( nHndl, @cBuff, chr( 10 ) ) == 0
                    cBuff := allTrim( cBuff )
                    IF ! empty( cBuff )
                        aAdd( aShow, {} )
                        aAdd( aTail( aShow ), subStr( cBuff, 1, 11 ) )
                        FOR nI := 12 TO 28 STEP 4
                            aAdd( aTail( aShow ), subStr( cBuff, nI, 2 ) )
                        NEXT
                    ENDIF
                ENDDO
                * xBrowse( aShow )
                ferase(cfile)
                return aShow
            ENDIF
         endif
      else
         MsgAlert("Controlla la connessione su internet!","EasyLotto")
          endif
          return nil
//----------------------------------------------------------------------//

 Function Showform(nRecord,oCiclo,aColors,oBrw)
   local aNumeri:= {}
   local atemp:= {}
   local cText
   local num1,num2,num3,num4,num5


   nColor:=aColors[ nRecord ]

   AAdd(atemp,oBrw:aArrayData[ nRecord ] )

   cText:=atemp[1][1]  //text
   num1 :=atemp[1][2]
   num2 :=atemp[1][3]
   num3 :=atemp[1][4]
   num4 :=atemp[1][5]
   num5 :=atemp[1][6]

    aNumeri := {num1,num2,num3,num4,num5}

   ASort( aNumeri, nil, nil, { |x,y| x < y } )

   num1 :=aNumeri[1]
   num2 :=aNumeri[2]
   num3 :=aNumeri[3]
   num4 :=aNumeri[4]
   num5 :=aNumeri[5]

 *  oCiclo:Paint()
   oCiclo:Distance_Multiple(val(num1),val(num2),val(num3),val(num4),val(num5),nColor,oCiclo:aposition)

   Return nil
//-----------------------------------------------------------------------------------------/




















//------------------------------------------------------------------//

#define darkgray    nRgb(169,169,169)
#define darkorange  nRgb(255,140,0)
#define darkred     nRgb(139,0,0)
#define lightblue   nRgb(173,216,230)

#define TA_CENTER         6
#define COLOR_BTNFACE 15
#define PS_SOLID   0



Class TCyclometric From Tcontrol
   CLASSDATA lRegistered AS LOGICAL

    DATA nColorCirc
    DATA nColorText
    DATA oFont
    DATA lShowSmallCircles
    DATA lDrawBorder

    DATA nMedWidth,nMedHeight,nMedSide
    DATA nTopCir,nLeftCir
    DATA nRadiusExt
    DATA nRadiusInt

    DATA aPosition


METHOD New( nRow, nCol, oWnd,  nWidth, nHeight) CONSTRUCTOR
METHOD Paint()
METHOD Display() INLINE ::BeginPaint(), ::Paint(), ::EndPaint(), 0
METHOD PaintCircle()
METHOD PaintNumbers()
METHOD PaintSmallCircles()
METHOD Distance_Multiple(num1,num2,num3,num4,num5,nColor)
METHOD Say_distance(num1,num2)
METHOD Line( nTop, nLeft, nBottom, nRight, nColor, nDim )
ENDCLASS
//-----------------------------------------------------------------------//
METHOD New( nRow, nCol, oWnd,  nWidth, nHeight, nColorCirc,oFont,nColorText,;
            lPixel, lDesign,lShowSMallCircles,lDrawBorder) Class TCyclometric

   DEFAULT  nRow     := 0, nCol := 0, oWnd := GetWndDefault()
   DEFAULT  lPixel   := .f.
   DEFAULT  nColorCirc   := CLR_HGRAY
   DEFAULT  nColorText   := CLR_BLUE

    DEFAULT nWidth := 50, nHeight := 50,;
           lDesign := .f.
   DEFAULT  lShowSMallCircles := .t.
   DEFAULT lDrawBorder := .t.   //test



   ::nTop      = If( lPixel, nRow, nRow * MTR_CHARPIX_H )  //14
   ::nLeft     = If( lPixel, nCol, nCol *  MTR_CHARPIX_W ) //8
   ::nBottom   = ::nTop  + nHeight
   ::nRight    = ::nLeft + nWidth
   ::oWnd      = oWnd
   ::lDrawBorder = lDrawBorder


   ::nId       = ::GetNewId()

   ::nColorCirc  =  nColorCirc


   ::lShowSMallCircles := lShowSMallCircles

   ::lDrag     = lDesign
   ::lCaptured = .f.
   ::ltransparent =.t.
   ::aPosition := {}


    if oFont == nil
      DEFINE FONT ::oFont NAME "TAHOMA" SIZE 0, -10
   else
      ::SetFont( oFont )
   endif

   ::nColorText  = nColorText

   ::nStyle  = nOr( WS_CHILD, WS_VISIBLE, WS_CLIPCHILDREN, WS_TABSTOP,;
                                 if( lDrawBorder, WS_BORDER, 0 ) )
   ::Register()

   if ! Empty( ::oWnd:hWnd )
      ::Create()
      ::Default()
      ::oWnd:AddControl( Self )
      if ::oWnd:oBrush != nil
         ::SetBrush( ::oWnd:oBrush )
      endif
   else
      ::oWnd:DefControl( Self )
   endif

   if lDesign
      ::CheckDots()
   endif

return Self
//------------------------------------------------------------//
METHOD Paint() Class TCyclometric
 local aInfo, aRect

   aInfo    := ::DispBegin()

   if ::lTransparent .or. ::nOpacity < 255
      aRect    := GetClientRect( ::hWnd )
      SetBrushOrgEx( ::hDC, -::nLeft, -::nTop )
      FillRect( ::hDC, aRect, ::oWnd:oBrush:hBrush )
      if ! ::lTransparent
         FillRectEx( ::hDC, aRect, nARGB( ::nOpacity, ::nClrPane ) )
      endif
   else
      ::PaintBack( ::hDC )
   endif

   ::PaintCircle()  //draw the main circle
   ::PaintSmallCircles()  //small circles
   ::PaintNumbers()  //draw the numbers

   if ValType( ::bPainted ) == "B"
      Eval( ::bPainted, ::hDC, ::cPS, Self )
   endif

   ::DispEnd( aInfo )

return nil
//------------------------------------------------------------------------//
METHOD PaintCircle() Class TCyclometric
   local aRect    := GetClientRect( ::hWnd )
   local oPen    := CREATEPEN( PS_SOLID, 2, darkgray )

    ::nTopCir    := ::nHeight / 2
    ::nLeftCir   := ::nWidth  / 2
    ::nMedWidth  := aRect[4]/2
    ::nMedHeight := aRect[3]/2
    ::nMedSide   := min( ::nMedWidth, (::nMedHeight-5) ) - 10

      ellipse( ::hDC, ::nLeftCir - ::nMedSide,;
                      ::nTopCir  - ::nMedSide,;
                      ::nLeftCir + ::nMedSide,;
                      ::nTopCir  + ::nMedSide,oPen )


return 0
//------------------------------------------------------------------------//
METHOD PaintSmallCircles() Class TCyclometric
   local nI
   local  oPen := CREATEPEN( PS_SOLID, 1, CLR_BLUE )
   local  nTotalNumbers := 90


  local  nYOffset := ::oFont:nHeight / 2
  local  nXOffset := ::oFont:nWidth / 2
  local  nDeltaR  := ::oFont:nHeight


  local nAngolo


    ::nRadiusExt := int( ::nMedSide ) * 0.99
    ::nRadiusInt := ::nRadiusExt      * 0.99

     //draw circles
  /*  FOR nI = 1 TO  nTotalNumbers
          nAngolo := 2* PI() / nTotalNumbers * ( nI - 1 )
          nTop  := ::nTopCir  -  ( ::nRadiusInt * Cos( nAngolo  ) )
          nLeft := ::nLeftCir +  ( ::nRadiusInt * Sin( nAngolo  ) )

          Ellipse(::hDC, nLeft - 5, nTop  - 5, nLeft+ 5, nTop  + 5    )

          //positions
          AaDd(::aPosition,{nI,nLeft,nTop} )

       NEXT
     */

    FOR nI = 1 TO  nTotalNumbers
          nAngolo := 2* PI() / nTotalNumbers * ( nI - 1 )
          nTop  := ::nTopCir  -  ( ::nRadiusExt * Cos( nAngolo  ) )
          nLeft := ::nLeftCir +  ( ::nRadiusExt * Sin( nAngolo  ) )

          Ellipse(::hDC, nLeft-2  , nTop-2  , nLeft+2, nTop+2      )

          //positions
          AaDd(::aPosition,{nI,nLeft,nTop} )

       NEXT

 return 0
//------------------------------------------------------------------------//

 METHOD PaintNumbers() Class TCyclometric
   local nI
   local  oPen := CREATEPEN( PS_SOLID, 1, CLR_BLUE )
   local  nTotalNumbers := 90


  local  nYOffset := ::oFont:nHeight / 2
  local  nXOffset := ::oFont:nWidth / 2
  local  nDeltaR  := ::oFont:nHeight

  local nColor
  local nAngolo
  local nMedSidetxt   := min( ::nMedWidth, ::nMedHeight ) -5

    ::nRadiusExt := int( nMedSidetxt ) * 0.98


     //draw numbers
    FOR nI = 1 TO  nTotalNumbers
          nAngolo := 2* PI() / nTotalNumbers * ( nI - 1 )
           nTop  := ::nTopCir  -  ( ::nRadiusExt * Cos( nAngolo  ) )
           nLeft := ::nLeftCir +  ( ::nRadiusExt * Sin( nAngolo  ) )

        ::Say( ntop - nYOffset  , nLeft  , hb_ntoc( nI,0 ),::nColorText , , ::oFont, .t.,.t., TA_CENTER )

       NEXT
 return 0
//------------------------------------------------------------------------//

METHOD Distance_Multiple(num1,num2,num3,num4,num5,nColor)  CLASS  TCyclometric
   local  aNumpos := ::aposition
   local nAt1,nAt2,nAt3,nAt4,nAt5
   local oPen,hOldPen




   local aPoints   := array(5)
   local hBrush1,hOld1
   local nDimPenLine:=1



   nAt1:= AScan( aNumpos, { | a | a[1] = num1 } )
   nAt2:= AScan( aNumpos, { | a | a[1] = num2 } )
   nAt3:= AScan( aNumpos, { | a | a[1] = num3 } )
   nAt4:= AScan( aNumpos, { | a | a[1] = num4 } )
   nAt5:= AScan( aNumpos, { | a | a[1] = num5 } )


     aPoints [5]  := {aNumpos[nAt5][2], aNumpos[nAt5][3]}
     aPoints [4]  := {aNumpos[nAt4][2], aNumpos[nAt4][3]}
     aPoints [3]  := {aNumpos[nAt3][2], aNumpos[nAt3][3]}
     aPoints [2]  := {aNumpos[nAt2][2], aNumpos[nAt2][3]}
     aPoints [1]  := {aNumpos[nAt1][2], aNumpos[nAt1][3]}



     //Intern distance
     ::line( aPoints [1][1],aPoints [1][2],aPoints [2][1],aPoints [2][2], nColor,nDimPenLine)
     ::line( aPoints [2][1],aPoints [2][2],aPoints [3][1],aPoints [3][2], nColor,nDimPenLine)
     ::line( aPoints [3][1],aPoints [3][2],aPoints [4][1],aPoints [4][2], nColor,nDimPenLine)
     ::line( aPoints [4][1],aPoints [4][2],aPoints [5][1],aPoints [5][2], nColor,nDimPenLine)
     ::line( aPoints [5][1],aPoints [5][2],aPoints [1][1],aPoints [1][2], nColor,nDimPenLine)




     //Intern distance

    *   IF ::lShowDistance
         ::Say_distance(num1,num2)
         ::Say_distance(num2,num3)
         ::Say_distance(num3,num4)
         ::Say_distance(num4,num5)
         ::Say_distance(num5,num1)
     *  Endif




     return nil

//----------------------------------------------------------------------------//
     METHOD Line( nTop, nLeft, nBottom, nRight, nColor, nDim ) CLASS  TCyclometric

 *  local hPen := if( oPen = nil, 0, oPen:hPen )

 local  oPen := CreatePen(PS_SOLID, nDim, nColor  )

  *local  oPen := CreatePen(PS_DOT, nDim, nColor  )
 local   hOldPen

   ::GetDC()
   hOldPen := SelectObject( ::hDC, oPen )
   MoveTo( ::hDC, nLeft, nTop )
   LineTo( ::hDC, nRight, nBottom, oPen )
   SelectObject( ::hDC, hOldPen )
   ::ReleaseDC()

   return nil

//------------------------------------------------------------------------------//
    METHOD Say_distance(num1,num2) CLASS  TCyclometric
  local nDistanza:= 0
   local nAt1,nAt2
   local  aNumpos := ::aposition
   local aRect:= {}
   local nYOffset,nXOffset, nY,nX

   //calc the distance
    IF num2>num1
             nDistanza:= num2-num1
          else
             nDistanza:= num1-num2
          Endif
          If nDistanza > 45
            nDistanza:= 90-nDistanza
         Endif

  // Print the distance
       nYOffset = ::oFont:nHeight / 2
       nXOffset = ::oFont:nWidth / 2


   nAt1:= AScan( aNumpos, { | a | a[1] = num1 } )
   nAt2:= AScan( aNumpos, { | a | a[1] = num2 } )



   IF aNumpos[nAt1][3] > aNumpos[nAt2][3]
      nX := aNumpos[nAt2][3] + ( aNumpos[nAt1][3] - aNumpos[nAt2][3] ) /2
   ELSE
      nX := aNumpos[nAt1][3] + ( aNumpos[nAt2][3] - aNumpos[nAt1][3] ) /2
   ENDIF

   IF aNumpos[nAt1][2] > aNumpos[nAt2][2]
      nY := aNumpos[nAt2][2] + ( aNumpos[nAt1][2] - aNumpos[nAt2][2] ) /2
   ELSE
      nY := aNumpos[nAt1][2] + ( aNumpos[nAt2][2] - aNumpos[nAt1][2] ) /2
   ENDIF

   ::Say( nY - nYOffset, nX - 0, LTRIM( STRzero( nDistanza,2 ) ),CLR_BLACK , , ::oFont, .t.,.t., nil )

return Nil

 //------------------------------------------------------------------------//








 
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
Posts: 7104
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Post by Silvio.Falconi »

Antonio,
I tried also with

::bPainted := { |hDC|FillRectEx( ::hDC, aPoints, aGrad) }

or

::bPainted := { |hDC|FloodFill( ::hDC, aPoints [1][1], aPoints [5][1], nil, nColor ) }

or

local hBru := CreateSolidBrush( nColor )
local hOld := SelectObject( ::hDC, hBru )
local hpen:=CreatePen(0,8,nColor)

FillRect( ::hDC, { aPoints [1][1],aPoints [1][2],aPoints [2][1],aPoints [2][2] }, hBru )

SelectObject( ::hDC, hOld )
DeleteObject( hBru )


Not Happen nothing
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
Posts: 7104
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Post by Silvio.Falconi »

Image



when I select another record in the xbrowse , the class doesn't delete the previously drawn lines, how can I fix it?
I would like to fill the polygon space with a gradient color but I can't do that



test.prg

Code: Select all | Expand

#include "fivewin.ch"
#include "constant.ch"

Function Test()

      local oDlg,oFont,oBold
      local oBtnClose,oBtnRoutes
      local oBtnInt,oBtnExt
      local nBottom   := 38
      local nRight    := 118
      local nWidth    := Max( nRight * DLG_CHARPIX_W, 180 )
      local nHeight   := nBottom * DLG_CHARPIX_H
      local cUrl:="http://www.televideo.rai.it/televideo/pub/solotesto.jsp?pagina=786"
      local adata:=TestUrl( cUrl )
      local oBrw
      local oCicloMetric
      local aCicloMetric :=array(11)

      local aColors:= {CLR_BLUE,;
                      CLR_GREEN,;
                      CLR_RED,;
                      CLR_MAGENTA,;
                      CLR_BROWN,;
                      CLR_HGRAY,;
                      CLR_LIGHTGRAY,;
                      CLR_HBLUE,;
                      CLR_HMAGENTA,;
                      METRO_VIOLET ,;
                      METRO_BROWN}

   DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-10
   DEFINE FONT oBold NAME "TAHOMA" SIZE 0,-12  BOLD

   DEFINE DIALOG oDlg SIZE  nWidth, nHeight  ;
   PIXEL TRUEPIXEL  FONT oFont   ;  //
   TiTle "Manage Ciclometric"  ;
   COLOR CLR_BLACK,CLR_WHITE

     oCicloMetric:=TCyclometric():New( 8, 24, oDlg,  400, 400, CLR_HGRAY)
     oCicloMetric:lTransparent:=.t.
     oCicloMetric:nDimPenCircle:= 3
     oCicloMetric:nDimPenLine:=2
     oCicloMetric:lShowNumbers:=.t.
     oCicloMetric:lShowSMallCircles:=.T.
     oCicloMetric:ldrawborder:=.t.

       @ 112,620 XBROWSE oBrw OF oDlg SIZE 300,400 PIXEL NOBORDER;
      COLS 1,2,3,4,5,6;
      HEADERS "Ruota", "E1", "E2", "E3", "E4", "E5" ;
      SIZES  80,30,30,30,30,30  ;
      ARRAY adata ;
      CELL LINES

    WITH OBJECT oBrw
      :nRowHeight    := 36
      :nClrBorder := CLR_GRAY
      :lDrawBorder := .t.
      :nColorBox := CLR_HRED

      :lHeader             := .f.
      :lHscroll            := .f.
      :lvscroll            := .f.
      :l2007               := .F.
      :l2015               := .t.

      :nStretchCol         := STRETCHCOL_WIDEST
      :lAllowRowSizing     := .F.
      :lAllowColSwapping   := .F.
      :lAllowColHiding     := .F.
      :lRecordSelector     := .F.
      :nColDividerStyle    := LINESTYLE_LIGHTGRAY
      :nRowDividerStyle    := LINESTYLE_LIGHTGRAY
      :bClrStd := { || { CLR_BLACK, If( oBrw:KeyNo % 2 == 0, nRgb(173,216,230) , CLR_WHITE ) } }

      :bChange  := { || ( Showform(oBrw:nArrayAt,oCicloMetric,aColors,oBrw,.t.)) }

      :CreateFromCode()
   End

   @ 100,10 BUTTON oBtnClose PROMPT "Close" of oDlg  SIZE 80,22;
          ACTION oDlg:End()

    @ 100,10 BUTTON oBtnRoutes PROMPT "Mostra ruote" of oDlg  SIZE 80,22;
          ACTION Mostra_Form(aCicloMetric,aColors,oBrw)

    @ 100,10 BUTTON oBtnInt PROMPT "Distance Interne" of oDlg  SIZE 80,22;
          ACTION Showform(oBrw:nArrayAt,oCicloMetric,aColors,oBrw,.F.,.T.)

    @ 100,10 BUTTON oBtnExt PROMPT "Distance Esterne" of oDlg  SIZE 80,22;
          ACTION Showform(oBrw:nArrayAt,oCicloMetric,aColors,oBrw,.T.,.F.)


   oDlg:bResized := <||
     local oRect := oDlg:GetCliRect()
        oBtnClose:nLeft    := oRect:nRight - 100
        oBtnClose:nTop     := oRect:nBottom - 45
        oBtnRoutes:nLeft    := oRect:nleft+5
        oBtnRoutes:nTop     := oRect:nBottom - 45
        oBtnInt:nTop     := oRect:nBottom - 45
        oBtnInt:nLeft    := oRect:nleft+125
        oBtnExt:nTop     := oRect:nBottom - 45
        oBtnExt:nLeft    := oRect:nleft+255
    RETURN NIL
    >




  ACTIVATE DIALOG oDlg CENTERED;
    ON INIT (Mostra_Ciclo_Ruote(oBrw,oDlg,aCicloMetric,aColors),;
             Eval(oDlg:bResized))

   RELEASE FONT oFont, oBold
   Return nil
//----------------------------------------------------------------------//

 Function TestUrl( cUrl )
        local cRet:=""
        local cData:=""
        local cFile := "test.txt"
        local cBuff
        local nHndl
        local aShow:={}
        local nI

        IF IsInternet()
               cRet := WebPageContents( cUrl )
               cData := WebPageContents( cUrl )
        if Empty( cRet )
          ? "Invalid URL"
       else
            //per la data estrazione
            cData := subStr( cData, at( "ALMANACCO",  cData )+9 )
            cData := allTrim( subStr( cData, 1, at("BARI",  cData ) -1 ) )

            // per il blocco Bari - Nazionale
            cRet := subStr( cRet, at( "BARI", cRet ) )
            cRet := allTrim( subStr( cRet, 1, at( "Controlla", cRet ) - 1 ) )

            nHndl := fCreate( cFile )
            fWrite( nHndl, cRet )
            fClose( nHndl )
            IF ( nHndl := fOpen( cFile ) ) < 1
                msgStop( "UNABLE TO OPEN: " + cFile  )
            ELSE
                aShow := {}
                WHILE hb_fReadLine( nHndl, @cBuff, chr( 10 ) ) == 0
                    cBuff := allTrim( cBuff )
                    IF ! empty( cBuff )
                        aAdd( aShow, {} )
                        aAdd( aTail( aShow ), subStr( cBuff, 1, 11 ) )
                        FOR nI := 12 TO 28 STEP 4
                            aAdd( aTail( aShow ), subStr( cBuff, nI, 2 ) )
                        NEXT
                    ENDIF
                ENDDO
                * xBrowse( aShow )
                ferase(cfile)
                return aShow
            ENDIF
         endif
      else
         MsgAlert("Controlla la connessione su internet!","EasyLotto")
          endif
          return nil
//----------------------------------------------------------------------//

 Function Showform(nRecord,oCiclo,aColors,oBrw,lShowExternal,lShowInternal)
   local aNumeri:= {}
   local atemp:= {}
   local cText
   local num1,num2,num3,num4,num5
   local aPos
   local cTitle:= oBrw:aArrayData[ nRecord ][1]

   DEFAULT lShowExternal   := .F.
   DEFAULT lShowInternal   := .F.

   nColor:=aColors[ nRecord ]

   AAdd(atemp,oBrw:aArrayData[ nRecord ] )

   cText:=atemp[1][1]  //text
   num1 :=atemp[1][2]
   num2 :=atemp[1][3]
   num3 :=atemp[1][4]
   num4 :=atemp[1][5]
   num5 :=atemp[1][6]

    aNumeri := {num1,num2,num3,num4,num5}

   ASort( aNumeri, nil, nil, { |x,y| x < y } )

   num1 :=aNumeri[1]
   num2 :=aNumeri[2]
   num3 :=aNumeri[3]
   num4 :=aNumeri[4]
   num5 :=aNumeri[5]


   aPos:= oCiclo:CalcPosition()
   oCiclo:cTitle:=cTitle
   oCiclo:lShowInternal_Distance :=lShowInternal
   oCiclo:lShowExternal_Distance :=lShowExternal
   oCiclo:Distance_Multiple(val(num1),val(num2),val(num3),val(num4),val(num5),nColor,aPos)


   Return nil
//-----------------------------------------------------------------------------------------/

 Function Mostra_Ciclo_Ruote(oBrw,oDlg,aCicloMetric,aColors)
     local nRuote:= 11,n
     local xCol
     local xSay
     local nRow,nCol
     local nDia,nHeight,nWidth
     Local aRuote  := {"Bari","Cagliari","Firenze","Genova",;
                       "Milano","Napoli","Palermo","Roma","Torino",;
                        "Venezia","Nazionale"}

     local nColor,atemp:= {}
     local ctext,num1,num2,num3,num4,num5
     local aNumeri:= {}

     nRow:= 0.8
     nCol:= 0.5
     nDia:= 80
     nHeight:= nDia
     nWidth := nDia
     xCol:= 10
     xSay:= 10

    For n:= 1 to 11

        aCicloMetric[n]:= TCyclometric():New( nRow,nCol, oDlg,  nWidth,nHeight, CLR_HGRAY)
        aCicloMetric[n]:lShowNumbers:=.f.
        aCicloMetric[n]:nDimPenCircle:= 0.1
        aCicloMetric[n]:lShowSMallCircles:=.f.
        aCicloMetric[n]:ldrawborder:=.t.
        aCicloMetric[n]:lShowDistance:=.f.
        aCicloMetric[n]:lShowInternal_Distance :=.f.
        aCicloMetric[n]:lShowExternal_Distance :=.T.


        nCol+= xCol +0.5


     * @ nHeight+8,xSay say aRuote[n] size 55,18 PIXEL OF oDlg TRANSPARENT
     * xSay+=  85

   next

     return aCicloMetric


Function Mostra_Form(aCicloMetric,aColors,oBrw)
        local aNum:= {}
        local num1,num2,num3,num4,num5
        local nColor
        local aposNew
        local ctitle

   For n= 1 to len(aCicloMetric)

      aNum:= Give_Numbers(oBrw,n)

      cTitle:= oBrw:aArrayData[ n ][1]

       nColor:=aColors[ n ]
       num1 :=val(aNum[1])
       num2 :=val(aNum[2])
       num3 :=val(aNum[3])
       num4 :=val(aNum[4])
       num5 :=val(aNum[5])

       aPosNew := aCicloMetric[n]:CalcPosition()
       aCicloMetric[n]:ctitle:= ctitle
       aCicloMetric[n]:Distance_Multiple(num1,num2,num3,num4,num5,nColor,aPosNew)

       next

   return nil


   Function Mostra_cerchio(aCicloMetric,aColors,oBrw,n)
        local aNum:= Give_Numbers(oBrw,n)
        local num1,num2,num3,num4,num5
        local nColor
        local aposNew

       nColor:=aColors[ n ]
       num1 :=val(aNum[1])
       num2 :=val(aNum[2])
       num3 :=val(aNum[3])
       num4 :=val(aNum[4])
       num5 :=val(aNum[5])

       aPosNew:=aCicloMetric[n]:CalcPosition()
       aCicloMetric[n]:Distance_Multiple(num1,num2,num3,num4,num5,nColor,aPosNew)

       return nil


Function Give_Numbers(oBrw,nrecord)
   local aNumeri:= {}
   local atemp:= {}
   local cText
   local num1,num2,num3,num4,num5

   AAdd(atemp,oBrw:aArrayData[ nRecord ] )

   cText:=atemp[1][1]  //text
   num1 :=atemp[1][2]
   num2 :=atemp[1][3]
   num3 :=atemp[1][4]
   num4 :=atemp[1][5]
   num5 :=atemp[1][6]

    aNumeri := {num1,num2,num3,num4,num5}

   ASort( aNumeri, nil, nil, { |x,y| x < y } )

   num1 :=aNumeri[1]
   num2 :=aNumeri[2]
   num3 :=aNumeri[3]
   num4 :=aNumeri[4]
   num5 :=aNumeri[5]

   Return aNumeri

//------------------------------------------------------------------//
 


the class

Code: Select all | Expand

 
#include "fivewin.ch"
#include "constant.ch"


#define TA_LEFT              0
#define TA_RIGHT             2
#define TA_CENTER            6


#define PS_SOLID             0
#define PS_DASH              1
#define PS_DOT               2
#define PS_DASHDOT           3
#define PS_DASHDOTDOT        4

#define COLOR_WINDOW         5
#define COLOR_BTNFACE       15


#define TME_LEAVE            2
#define WM_MOUSELEAVE      675
#define NULL_BRUSH      5



Class TCyclometric From Tcontrol
   CLASSDATA lRegistered AS LOGICAL

    DATA oCiclo
    DATA nColorCirc
    DATA nColorText
    DATA oFont

    DATA lDrawBorder   AS LOGIC INIT .F.

    DATA nMedWidth,nMedHeight,nMedSide
    DATA nTopCir, nLeftCir
    DATA nRadiusExt
    DATA nRadiusInt

    DATA aPosition

    DATA lShowSmallCircles
    DATA lShowNumbers

    data lShowInternal_Distance
    data lShowExternal_Distance
    data lShowDistance

    data nDimPenCircle
    data nDimPenLine
    data cTitle
    data   hPen

      METHOD New( nRow, nCol, oWnd,  nWidth, nHeight) CONSTRUCTOR
      METHOD Paint()
      METHOD Display() INLINE ::BeginPaint(), ::Paint(), ::EndPaint(), 0

      METHOD PaintCircle()
      METHOD PaintNumbers()
      METHOD PaintSmallCircles()
      METHOD PaintBorder()
      METHOD Evidence_Number(number)

      METHOD Distance_Multiple(num1,num2,num3,num4,num5,nColor)
      METHOD Distance(num1,num2)
      METHOD Say_distance(num1,num2)

      METHOD Line( nTop, nLeft, nBottom, nRight, nColor, nDim )
      METHOD LineDot( nTop, nLeft, nBottom, nRight, nColor, nDim )
      METHOD REFILL(nTop, nLeft, nBottom, nRight,ncolor)
      METHOD DrawEllipse( hDC, nColor, ntop, nLeft, nWidth, nHeight )

      METHOD Destroy()
      METHOD HandleEvent( nMsg, nWParam, nLParam )
      METHOD CalcPosition()
ENDCLASS
//-----------------------------------------------------------------------//
METHOD New( nRow, nCol, oWnd,  nWidth, nHeight, nColorCirc, oFont, nColorText,;
            lPixel, lDesign,;
                      lShowSMallCircles,;
                      lDrawBorder,;
                      lShowNumbers,;
                      lShowDistance,;
                      lShowInternal_Distance,;
                      lShowExternal_Distance,;
                      nDimPenCircle,;
                      nDimPenLine,;
                      cTitle) Class TCyclometric

   DEFAULT  nRow     := 0, nCol := 0, oWnd := GetWndDefault()
   DEFAULT  lPixel   := .f.
   DEFAULT  nColorCirc   := CLR_HGRAY
   DEFAULT  nColorText   := CLR_BLUE

    DEFAULT nWidth := 50, nHeight := 50,;
            lDesign := .f.             ,;
            lShowSMallCircles := .t.   ,;
            lDrawBorder := .F.         ,;
            lShowNumbers  := .t.       ,;
            lShowDistance := .t.       ,;
            nDimPenCircle := 1         ,;
            nDimPenLine   := 1         ,;
            lShowInternal_Distance :=.F. ,;
            lShowExternal_Distance :=.t.


   ::nTop      = If( lPixel, nRow, nRow * MTR_CHARPIX_H )  //14
   ::nLeft     = If( lPixel, nCol, nCol *  MTR_CHARPIX_W ) //8
   ::nBottom   = ::nTop  + nHeight
   ::nRight    = ::nLeft + nWidth
   ::oWnd      = oWnd
   ::lDrawBorder = lDrawBorder
   ::hPen = CreatePen( PS_SOLID, 1, nRGB( 128, 128, 128 ) )
   ::oCiclo      = self
   ::nId       = ::GetNewId()

   ::nColorCirc   =  nColorCirc
   ::nColorText   = nColorText
   ::nClrPane = nRGB( 220, 223, 228 )

   ::lShowSMallCircles := lShowSMallCircles
   ::lShowNumbers      := lShowNumbers
   ::nDimPenCircle     := nDimPenCircle
   ::nDimPenLine       := nDimPenLine
   ::lShowDistance     := lShowDistance
   ::lShowInternal_Distance := lShowInternal_Distance
   ::lShowExternal_Distance := lShowExternal_Distance





   ::lDrag     = lDesign
   ::lCaptured = .f.
   ::lTransparent =.t.
   ::aPosition := {}
   ::cTitle    := cTitle

    if oFont == nil
      DEFINE FONT ::oFont NAME "TAHOMA" SIZE 0, -10
   else
      ::SetFont( oFont )
   endif

   ::nStyle  = nOr( WS_CHILD, WS_VISIBLE, WS_CLIPCHILDREN, WS_TABSTOP,;
                                 if( lDrawBorder, WS_BORDER, 0 ) )
   ::Register()


     if oWnd:lVisible
      ::Create()
      ::Default()
      ::lVisible = .t.
      oWnd:AddControl( Self )
   else
      oWnd:DefControl( Self )
      ::lVisible  = .F.
   endif



   if lDesign
      ::CheckDots()
   endif

return Self
//------------------------------------------------------------//
METHOD Paint() Class TCyclometric
 local aInfo, aRect
 local  hGrayPen,hOldPen,hWhitePen
 Local hBrush, hOldBrush

   aInfo    := ::DispBegin()

   if ::lTransparent .or. ::nOpacity < 255
      aRect    := GetClientRect( ::hWnd )
      SetBrushOrgEx( ::hDC, -::nLeft, -::nTop )
      FillRect( ::hDC, aRect, ::oWnd:oBrush:hBrush )
      if ! ::lTransparent
         FillRectEx( ::hDC, aRect, nARGB( ::nOpacity, ::nClrPane ) )
      endif
   else
      ::PaintBack( ::hDC )
   endif


   ::PaintCircle()         //draw the main circle
   ::PaintSmallCircles()  //small circles


    IF  ::lShowNumbers
        ::PaintNumbers()       //draw the numbers
    Endif


   //Border
       If ::lDrawBorder
        ::PaintBorder()
      endif


   if ValType( ::bPainted ) == "B"
      Eval( ::bPainted, ::hDC, ::cPS, Self )
   endif

   ::DispEnd( aInfo )

return nil



METHOD PaintBorder() CLASS TCyclometric
    RoundBox( ::hDC, 2, 2, ::nWidth - 2 , ::nHeight - 2, 9, 9  )
  * DrawFocusRect( ::hDC, 3, 3, ::nHeight - 3, ::nWidth - 3 )


  return nil






//------------------------------------------------------------------------//
METHOD PaintCircle() Class TCyclometric
   local aRect    := GetClientRect( ::hWnd )
   local oPen    := CREATEPEN( PS_SOLID, ::nDimPenCircle , ::nColorCirc )

    ::nTopCir    := ::nHeight / 2
    ::nLeftCir   := ::nWidth  / 2
    ::nMedWidth  := aRect[4]/2
    ::nMedHeight := aRect[3]/2
    ::nMedSide   := min( ::nMedWidth, (::nMedHeight-5) ) - 10

      ellipse( ::hDC, ::nLeftCir - ::nMedSide,;
                      ::nTopCir  - ::nMedSide,;
                      ::nLeftCir + ::nMedSide,;
                      ::nTopCir  + ::nMedSide,oPen )


return 0
//------------------------------------------------------------------------//
METHOD PaintSmallCircles() Class TCyclometric
   local nI
   local  oPen := CREATEPEN( PS_SOLID, 2, CLR_BLUE )
   local  nTotalNumbers := 90


  local  nYOffset := ::oFont:nHeight / 2
  local  nXOffset := ::oFont:nWidth / 2
  local  nDeltaR  := ::oFont:nHeight


  local nAngolo


    ::nRadiusExt := int( ::nMedSide ) * 0.99
    ::nRadiusInt := ::nRadiusExt      * 0.99

     //draw circles
  /*  FOR nI = 1 TO  nTotalNumbers
          nAngolo := 2* PI() / nTotalNumbers * ( nI - 1 )
          nTop  := ::nTopCir  -  ( ::nRadiusInt * Cos( nAngolo  ) )
          nLeft := ::nLeftCir +  ( ::nRadiusInt * Sin( nAngolo  ) )
          Ellipse(::hDC, nLeft - 5, nTop  - 5, nLeft+ 5, nTop  + 5    )
          //positions
          AaDd(::aPosition,{nI,nLeft,nTop} )
       NEXT
     */

    FOR nI = 1 TO  nTotalNumbers
          nAngolo := 2* PI() / nTotalNumbers * ( nI - 1 )
          nTop  := ::nTopCir  -  ( ::nRadiusExt * Cos( nAngolo  ) )
          nLeft := ::nLeftCir +  ( ::nRadiusExt * Sin( nAngolo  ) )

       IF  ::lShowSMallCircles
          Ellipse(::hDC, nLeft-2  , nTop-2  , nLeft+2, nTop+2 , oPen)
       ENDIF

          //positions
         *  AaDd(::aPosition,{nI,nTop,nLeft} )
       NEXT

 return 0
//------------------------------------------------------------------------//
 //write the numbers around the circle
 METHOD PaintNumbers() Class TCyclometric
   local nI

   local  nTotalNumbers :=  90


  local  nYOffset := ::oFont:nHeight / 2
  local  nXOffset := ::oFont:nWidth / 2
  local  nDeltaR  := ::oFont:nHeight

  local nColor
  local nAngolo
  local nMedSidetxt   := min( ::nMedWidth, ::nMedHeight ) -5

    ::nRadiusExt := int( nMedSidetxt ) * 0.98

     //draw numbers
    FOR nI = 1 TO  nTotalNumbers
       nAngolo := 2* PI() / nTotalNumbers * ( nI - 1 )

           nTop  := ::nTopCir  -  ( ::nRadiusExt * Cos( nAngolo  ) )
           nLeft := ::nLeftCir +  ( ::nRadiusExt * Sin( nAngolo  ) )

        ::Say( ntop - nYOffset  , nLeft -0  , ( strzero(nI,2) ),::nColorText , , ::oFont, .t.,.t., TA_CENTER )

       NEXT
 return 0
//------------------------------------------------------------------------//
 // to highlight the selected numbers with a blue circle and white text
 METHOD Evidence_Number(number) Class TCyclometric
   local nI
   local  oPen := CREATEPEN( PS_SOLID, 2, CLR_BLUE )
   local  nTotalNumbers := 90


  local  nYOffset := ::oFont:nHeight / 2
  local  nXOffset := ::oFont:nWidth / 2
  local  nDeltaR  := ::oFont:nHeight
  local nAngolo,nMedSidetxt

  local aRect    := GetClientRect( ::hWnd )
    ::nTopCir    := ::nHeight / 2
    ::nLeftCir   := ::nWidth  / 2
    ::nMedWidth  := aRect[4]/2
    ::nMedHeight := aRect[3]/2
    ::nMedSide   := min( ::nMedWidth, (::nMedHeight-5) ) - 10


    nMedSidetxt   := min( ::nMedWidth, ::nMedHeight ) -5

    ::nRadiusExt := int( nMedSidetxt ) * 0.98


    FOR nI = 1 TO  nTotalNumbers
          nAngolo := 2* PI() / nTotalNumbers * ( nI - 1 )
          nTop  := ::nTopCir  -  ( ::nRadiusExt * Cos( nAngolo  ) )
          nLeft := ::nLeftCir +  ( ::nRadiusExt * Sin( nAngolo  ) )

         If nI=number
          *Ellipse(::hDC, nLeft-5  , nTop-5  , nLeft+5, nTop+5 , oPen)
          ::DrawEllipse(nColor,nLeft-5  , nTop-5  , nLeft+8, nTop+8)
         Endif

       NEXT

 return 0

 /*

    local aRect    := GetClientRect( ::hWnd )
  local nI
  local  nYOffset := ::oFont:nHeight / 2
  local  nXOffset := ::oFont:nWidth / 2
  local  nDeltaR  := ::oFont:nHeight
  local  nTotalNumbers :=  90
  local nColor
  local nAngolo
  local nMedSidetxt
    ::nTopCir    := ::nHeight / 2
    ::nLeftCir   := ::nWidth  / 2
    ::nMedWidth  := aRect[4]/2
    ::nMedHeight := aRect[3]/2

   nMedSidetxt   := min( ::nMedWidth, ::nMedHeight ) -5
   ::nRadiusExt := int( nMedSidetxt ) * 0.98

     //draw numbers   evindence

    FOR nI = 1 TO  nTotalNumbers
        nAngolo := 2* PI() / nTotalNumbers * ( nI - 1 )
          nTop  := ::nTopCir  -  ( ::nRadiusExt * Cos( nAngolo  ) )
          nLeft := ::nLeftCir +  ( ::nRadiusExt * Sin( nAngolo  ) )

        If nI=number

        ::DrawEllipse(  nColor,nLeft-5  , nTop-5  , nLeft+5, nTop+5)

         ::Say( ntop - nYOffset  , nLeft -0  , ( strzero(nI,2) ),CLR_YELLOW , , ::oFont, .t.,.t., TA_CENTER )
     endif

  NEXT


  return nil
 */
//---------------------------------------------------------------------//

 METHOD CalcPosition() Class TCyclometric
   local nI
   local  nTotalNumbers := 90
   local nAngolo
   local aRect    := GetClientRect( ::hWnd )

    ::nTopCir    := ::nHeight / 2
    ::nLeftCir   := ::nWidth  / 2
    ::nMedWidth  := aRect[4]/2
    ::nMedHeight := aRect[3]/2
    ::nMedSide   := min( ::nMedWidth, (::nMedHeight-5) ) - 10

    ::nRadiusExt := int( ::nMedSide ) * 0.99
    ::nRadiusInt := ::nRadiusExt      * 0.99

 FOR nI = 1 TO  nTotalNumbers
          nAngolo := 2* PI() / nTotalNumbers * ( nI - 1 )
          nTop  := ::nTopCir  -  ( ::nRadiusExt * Cos( nAngolo  ) )
          nLeft := ::nLeftCir +  ( ::nRadiusExt * Sin( nAngolo  ) )

          //positions
          AaDd(::aPosition,{nI,nTop,nLeft} )

       NEXT

 return ::aPosition
//---------------------------------------------------------------------//
 METHOD Distance(num1,num2)  CLASS  TCyclometric
   local  aNumpos := ::apos
   local nAt1,nAt2
   local oPen,hOldPen
   local aRect:= {}
   local nDistanza,nYOffset,nXOffset, nY,nX

  // xbrowser aNumpos

   nAt1:= AScan( aNumpos, { | a | a[1] = num1 } )
   nAt2:= AScan( aNumpos, { | a | a[1] = num2 } )

   aRect:= {aNumpos[nAt1][2],aNumpos[nAt1][3],aNumpos[nAt2][2],aNumpos[nAt2][3]}

   ::line( aRect[1],aRect[2],aRect[3],aRect[4], CLR_RED)


   // draw the distance number
         IF num2>num1
             nDistanza:= num2-num1
          else
             nDistanza:= num1-num2
          Endif
          If nDistanza > 45
            nDistanza:= 90-nDistanza
         Endif

       nYOffset = ::oFont:nHeight / 2
       nXOffset = ::oFont:nWidth / 2

       nY  := aRect[2]
       nX  := aRect[4]

  ::Say( nY - nYOffset, nX - nXOffset, LTRIM( STRzero( nDistanza,2 ) ), , , ::oFont, .t.,;
            .t., nil )

   return nil

 //--------------------------------------------------------------//
//---------------------------------------------------------------------//
METHOD Distance_Multiple(num1,num2,num3,num4,num5,nColor,aNumpos)  CLASS  TCyclometric
   local nAt1,nAt2,nAt3,nAt4,nAt5,rc
   local oPen,hOldPen

   local nsize1:=1
   local nSize2:=2
   local nClr1:= nColor,nClr2:= CLR_WHITE

   local aPoints   := array(5)
   local hBrush1,hOld1
   local aGrad :=  { { nsize1,  nClr1, nClr2 },;  //for refill
                     { nsize2,  nClr2,nClr1 } }

   local hBru := CreateSolidBrush( nColor )
   local hOld := SelectObject( ::hDC, hBru )
   local  hpen:=CreatePen(0,8,nColor)
   local hBlackBrush, hOldBrush





   nAt1:= AScan( aNumpos, { | a | a[1] = num1 } )
   nAt2:= AScan( aNumpos, { | a | a[1] = num2 } )
   nAt3:= AScan( aNumpos, { | a | a[1] = num3 } )
   nAt4:= AScan( aNumpos, { | a | a[1] = num4 } )
   nAt5:= AScan( aNumpos, { | a | a[1] = num5 } )


     aPoints [5]  := {aNumpos[nAt5][2], aNumpos[nAt5][3]}
     aPoints [4]  := {aNumpos[nAt4][2], aNumpos[nAt4][3]}
     aPoints [3]  := {aNumpos[nAt3][2], aNumpos[nAt3][3]}
     aPoints [2]  := {aNumpos[nAt2][2], aNumpos[nAt2][3]}
     aPoints [1]  := {aNumpos[nAt1][2], aNumpos[nAt1][3]}



   IF ::lShowExternal_Distance
     //External distance
     ::line( aPoints [1][1],aPoints [1][2],aPoints [2][1],aPoints [2][2], nColor,::nDimPenLine)
     ::line( aPoints [2][1],aPoints [2][2],aPoints [3][1],aPoints [3][2], nColor,::nDimPenLine)
     ::line( aPoints [3][1],aPoints [3][2],aPoints [4][1],aPoints [4][2], nColor,::nDimPenLine)
     ::line( aPoints [4][1],aPoints [4][2],aPoints [5][1],aPoints [5][2], nColor,::nDimPenLine)
     ::line( aPoints [5][1],aPoints [5][2],aPoints [1][1],aPoints [1][2], nColor,::nDimPenLine)

      IF ::lShowDistance
         ::Say_distance(num1,num2)
         ::Say_distance(num2,num3)
         ::Say_distance(num3,num4)
         ::Say_distance(num4,num5)
         ::Say_distance(num5,num1)

         //evidence the numers
          ::Evidence_Number(num1)
          ::Evidence_Number(num2)
          ::Evidence_Number(num3)
          ::Evidence_Number(num4)
          ::Evidence_Number(num5)

       Endif
   Endif



   IF ::lShowInternal_Distance
        //Internal distance
     ::LineDot ( aPoints [1][1],aPoints [1][2],aPoints [3][1],aPoints [3][2], nColor,::nDimPenLine)
     ::LineDot ( aPoints [1][1],aPoints [1][2],aPoints [4][1],aPoints [4][2], nColor,::nDimPenLine)
     ::LineDot ( aPoints [2][1],aPoints [2][2],aPoints [4][1],aPoints [4][2], nColor,::nDimPenLine)
     ::LineDot ( aPoints [2][1],aPoints [2][2],aPoints [5][1],aPoints [5][2], nColor,::nDimPenLine)
     IF ::lShowDistance
           ::Say_distance(num1,num3)
           ::Say_distance(num1,num4)
           ::Say_distance(num2,num4)
           ::Say_distance(num2,num5)
        Endif
   Endif


   //Title
    If !Empty(::cTitle )
    ::Say(3 , 50  , ::cTitle,::nColorText , , ::oFont, .t.,.t., TA_CENTER )
 Endif


      //refill  not run
   *   ::GetDC()
 *    rc:={ 0,0,0,0}
 *    FillRect( ::hDC, rc, hBru )
 *    ::ReleaseDC()


    //refill  not run
  *   xbrowser aPoints

  *  ::bPainted := { |hDC|FillRectEx( ::hDC, aPoints, aGrad)  }
    * ::bPainted := { |hDC|FloodFill( ::hDC, aPoints [1][1], aPoints [5][1], nil, nColor )  }


 *  Rectangle( ::hDC, nTop, nLeft, nBottom, nRight, hpen )
  * FillRect( ::hDC, { aPoints [1][1],aPoints [1][2],aPoints [2][1],aPoints [2][2] }, hBru )
  * SelectObject( ::hDC, hOld )
  * DeleteObject( hBru )

  /*GradientFill( ::hDC, INT(aPoints [5][1]),;
                       INT(aPoints [5][2]),;
                       INT(aPoints [1][1]),;
                       INT(aPoints [1][2]), aGrad, .t. )


                       * FillRectEx( ::hDC, aPoints, hbru )

  GradientFill( ::hDC, INT(aPoints [5][1]),;
                       INT(aPoints [5][2]),;
                       INT(aPoints [1][1]),;
                       INT(aPoints [1][2]),;
                  aGrad )
       */


  *     ::Refill( aPoints [1][1],aPoints [1][2],aPoints [4][1],aPoints [4][2],nColor)



    RETURN NIL
//----------------------------------------------------------------------------//

    METHOD Refill(nTop, nLeft, nBottom, nRight,ncolor) CLASS  TCyclometric
    local hPen := CreatePen( 0, 1, ncolor )
     local aGrad :=  { { 5,  nColor, CLR_WHITE },;  //for refill
                       { 20,  CLR_WHITE,CLR_WHITE } }

    local hdc:= ::oWnd:GetDC()

      * FillRect( hdc, { nTop, nLeft, nBottom, nRight }, hPen )

      GradientFill(hdc,  nTop, nLeft, nBottom, nRight ,aGrad)

       DeleteObject( hPen )

           ::oWnd:ReleaseDC()
   return nil
//----------------------------------------------------------------------------//
 METHOD Line( nTop, nLeft, nBottom, nRight, nColor, nDim ) CLASS  TCyclometric
 local  oPen := CreatePen(PS_SOLID, nDim, nColor  )
 local   hOldPen

   ::GetDC()
   hOldPen := SelectObject( ::hDC, oPen )
   MoveTo( ::hDC, nLeft, nTop )
   LineTo( ::hDC, nRight, nBottom, oPen )
   SelectObject( ::hDC, hOldPen )
   ::ReleaseDC()
   return nil
//----------------------------------------------------------------------------//

METHOD LineDot( nTop, nLeft, nBottom, nRight, nColor, nDim ) CLASS  TCyclometric
 local  oPen := CreatePen(PS_DOT, 0.5, nColor  )
 local   hOldPen

   ::GetDC()
   hOldPen := SelectObject( ::hDC, oPen )
   MoveTo( ::hDC, nLeft, nTop )
   LineTo( ::hDC, nRight, nBottom, oPen )
   SelectObject( ::hDC, hOldPen )
   ::ReleaseDC()

   return nil
//------------------------------------------------------------------------------//
METHOD DrawEllipse(nColor, ntop, nLeft, nWidth, nHeight ) CLASS  TCyclometric
  * local hdc:= ::oCiclo:GetDC()
    local hdc:= ::GetDC()
   local hOldBrush := SelectObject( hDC, GetStockObject( NULL_BRUSH ) )
   local hPen := CreatePen( hDC, 1, nColor )

             //    nLeft-2  , nTop-2  , nLeft+2, nTop+2
   Ellipse( hDC,ntop-2,nLeft-2, nWidth+2 , nHeight+2 , hPen )

   SelectObject( hDC, hOldBrush )
   DeleteObject( hPen )
   *::oCiclo:ReleaseDC()
    ::ReleaseDC()
return nil


METHOD Say_distance(num1,num2) CLASS  TCyclometric
    local nDistanza:= 0
   local nAt1,nAt2
   local  aNumpos := ::CalcPosition() // ::aposition
   local aRect:= {}
   local nYOffset,nXOffset, nY,nX

   //calc the distance
    IF num2>num1
             nDistanza:= num2-num1
          else
             nDistanza:= num1-num2
          Endif
          If nDistanza > 45
            nDistanza:= 90-nDistanza
         Endif

  // Print the distance
       nYOffset = ::oFont:nHeight / 2
       nXOffset = ::oFont:nWidth / 2


   nAt1:= AScan( aNumpos, { | a | a[1] = num1 } )
   nAt2:= AScan( aNumpos, { | a | a[1] = num2 } )


   IF aNumpos[nAt1][3] > aNumpos[nAt2][3]
      nX := aNumpos[nAt2][3] + ( aNumpos[nAt1][3] - aNumpos[nAt2][3] ) /2
   ELSE
      nX := aNumpos[nAt1][3] + ( aNumpos[nAt2][3] - aNumpos[nAt1][3] ) /2
   ENDIF

   IF aNumpos[nAt1][2] > aNumpos[nAt2][2]
      nY := aNumpos[nAt2][2] + ( aNumpos[nAt1][2] - aNumpos[nAt2][2] ) /2
   ELSE
      nY := aNumpos[nAt1][2] + ( aNumpos[nAt2][2] - aNumpos[nAt1][2] ) /2
   ENDIF

   ::Say( nY - nYOffset, nX - 0, LTRIM( STRzero( nDistanza,2 ) ),CLR_RED , , ::oFont, .t.,.t., nil )

return Nil

 //------------------------------------------------------------------------//
METHOD Destroy() CLASS  TCyclometric
   if ::hWnd != 0
      ::Super:Destroy()
   endif
return nil

//------------------------------------------------------------------------//
METHOD HandleEvent( nMsg, nWParam, nLParam ) CLASS  TCyclometric

   if nMsg == WM_MOUSELEAVE
      return ::MouseLeave( nHiWord( nLParam ), nLoWord( nLParam ), nWParam )
   endif

return ::Super:HandleEvent( nMsg, nWParam, nLParam )
//------------------------------------------------------------------------//
 
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Marc Venken
Posts: 1481
Joined: Tue Jun 14, 2016 7:51 am
Location: Belgium

Re: cyclometric circle

Post by Marc Venken »

Hello All,

I have to ask :oops:

I have no clue what ever this is doing. Looking at the Wikipedia is giving me no information that I understand about Cyclometric Circle. Can somebody 'try' to explain ? It's just to grap any notice of it )))

I have no mathematic background and this is sure one of the reasons why I went for a desk job in administration :twisted:
Marc Venken
Using: FWH 23.08 with Harbour
User avatar
Silvio.Falconi
Posts: 7104
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Post by Silvio.Falconi »

Marc Venken wrote:Hello All,

I have to ask :oops:

I have no clue what ever this is doing. Looking at the Wikipedia is giving me no information that I understand about Cyclometric Circle. Can somebody 'try' to explain ? It's just to grap any notice of it )))

I have no mathematic background and this is sure one of the reasons why I went for a desk job in administration :twisted:

Small Course
Cyclometry is applied to the extraction of the Italian lotto but can also be extended to other lotteries such as the Spanish or English ones

Cyclometry is based on an abstract concept in which ninety numbers are imagined around a circumference, in progressive order, from the first point, which represents the number 1, continuing clockwise up to 90.

Image

The fundamental notions of cyclometrics, essential to know, are: distance, sum, midpoint and the related specific glossary.
As it is easy to understand, by joining two or more points on the circumference we obtain different geometric figures.

The most used in the cyclometric field are:
THE EQUILATERAL TRIANGLE
THE ISOSCELE TRIANGLE
THE RECTANGLE
THE SYMMETRIC QUADRILATERAL
THE ISOSCELES TRAPEZOID
THE REGULAR PENTAGON
THE DYNAMIC PENTAGON
THE REGULAR HEXAGON

If we join the numbers 90 and 45 on the circumference, we obtain a chord measuring 45 (90-45) which divides the circle into two perfectly equal parts.

Image

This measurement, or rather distance, represents the diameter of the circumference.

Therefore, for the correct calculation of the cyclometric distances, the value 45 assumes particular importance.

From these considerations we can enunciate the following definition:

The cyclometric distance between two numbers is obtained by calculating the arithmetic difference (major minus minor); if the result exceeds "the limit" 45, the latter is subtracted from the fixed 90.

EXAMPLE "A".

Let's consider the numbers 5 - 34 and, in the cyclometric circle, join the two points:

Image

Let's calculate the difference between the largest number (34) and the smallest one (5):

34-5= 29 Cyclometric Distance

The cycling distance between 34 and 5 is equal to 29.


EXAMPLE "B".

Now let's try to find the cyclometric distance between the numbers 25 and 78:

Image

Let's make the difference between 78 (major) and 25 (minor):

78-25= 53 (greater than 45)

We easily notice that the value obtained exceeds 45 therefore, as anticipated, the result is subtracted from the fixed 90:

90-53= 37 Cyclometric Distance

In this case the cyclometric distance between 25 and 78 is equal to 37 (in practice the cyclometric distance corresponds to the shortest distance to travel by counting the numbers on the circumference).



the calculations are used to make a prediction for the numbers that could come out in the next draws for example let's look at the five numbers drawn in the Florence wheel

Image

the numbers are 66,77,4,29,37

I create the shape with the numbers drawn, generally when the geometric shape is similar to a trapezoid the numbers could be sorted more easily

Image

to calculate the numbers that could come out in the next draws, the internal diameter lines are drawn


So , the numbers that could come out in the next draws are the number you see on lines dot (28,33,42,37 on Florence wheel )
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Marc Venken
Posts: 1481
Joined: Tue Jun 14, 2016 7:51 am
Location: Belgium

Re: cyclometric circle

Post by Marc Venken »

Silvio,

Thanks for the information. At least now i get the point of it and see what you mean. But just for the point of argument. If this is working, and this system is mathematic to prove right, there will be a lot of winners with the same
numbers ? Or are you going to put a 'personel touch' and change the number with you personel algoritm. I hope you succeed !!

In Belgium, we have only 45 numbers to draw...
Marc Venken
Using: FWH 23.08 with Harbour
User avatar
Silvio.Falconi
Posts: 7104
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Post by Silvio.Falconi »

Marc Venken wrote:Silvio,

Thanks for the information. At least now i get the point of it and see what you mean. But just for the point of argument. If this is working, and this system is mathematic to prove right, there will be a lot of winners with the same
numbers ? Or are you going to put a 'personel touch' and change the number with you personel algoritm. I hope you succeed !!

In Belgium, we have only 45 numbers to draw...
this is a statistical issue, I also have other procedures that calculate delays, frequencies, forecasts, figures, classes and other procedures.
They can also be adapted to your 45 number system,
Is there a historical archive of extractions in belgium?
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Marc Venken
Posts: 1481
Joined: Tue Jun 14, 2016 7:51 am
Location: Belgium

Re: cyclometric circle

Post by Marc Venken »

Silvio.Falconi wrote:
this is a statistical issue, I also have other procedures that calculate delays, frequencies, forecasts, figures, classes and other procedures.
They can also be adapted to your 45 number system,
Is there a historical archive of extractions in belgium?
Yes, Data for 44 year...

BTW Last weekend there was on the game lotto : euromillions a Belgium winners group : 143 miljoen won, and 1 biljet for 165 person to share. Still a lot of money.
Please keep programming and one day you can be lucky too... (I was not one of those 165 :cry: :cry: )
Marc Venken
Using: FWH 23.08 with Harbour
User avatar
Silvio.Falconi
Posts: 7104
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Post by Silvio.Falconi »

Marc Venken wrote:
Silvio.Falconi wrote:
this is a statistical issue, I also have other procedures that calculate delays, frequencies, forecasts, figures, classes and other procedures.
They can also be adapted to your 45 number system,
Is there a historical archive of extractions in belgium?
Yes, Data for 44 year...

BTW Last weekend there was on the game lotto : euromillions a Belgium winners group : 143 miljoen won, and 1 biljet for 165 person to share. Still a lot of money.
Please keep programming and one day you can be lucky too... (I was not one of those 165 :cry: :cry: )
We're talking about two different things, I'm not dealing with superenalotto (6 numbers + 1 bonus), I'm dealing with the Italian lotto consists of 11 wheels and 5 numbers drawn for each wheel, three times each week. Is not the same thing
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
Post Reply