cyclometric circle

Re: cyclometric circle

Postby Silvio.Falconi » Sat Jul 30, 2022 9:00 am

Strange where i compile and running not make me error, do i thinked It Is on fwh
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: 7069
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Postby Silvio.Falconi » Sun Jul 31, 2022 9:19 pm

Antonio,
Making this .. run bad


Image

Code: Select all  Expand view  RUN

 // refill area of Polygon
     hBrush1 := CreateSolidBrush( nColor )
     hOld1:= SelectObject( hBrush1 )
     aRect:= { aPoints [1][1], aPoints [2][1], aPoints [3][1], aPoints [4][1]  }
     FillRect( ::hDC, aRect, hBrush1 )
     SelectObject( hOld1 )
     DeleteObject( hBrush1 )




I tried also with

FillRect( ::hDC, aRect, hBrush1 )
or
FloodFill( ::hDC, aPoints [1][1]+nRaggio , aPoints [5][1]+nRaggio , nil, nColor )
or
SetPixel( ::hDC,aPoints [1][1],aPoints [2][1], nColor )
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: 7069
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Postby Jimmy » Mon Aug 01, 2022 5:47 am

hi Silvio,
Silvio.Falconi wrote:Now How I can to refill the area with transparent color ?

have not work with it yet

i "think" you need Polygon API Function
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-polygon

The Polygon function draws a polygon consisting of two or more vertices connected by straight lines.
The polygon is outlined by using the current pen and filled by using the current brush and polygon fill mode.


PolyPolygon
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-polypolygon

The PolyPolygon function draws a series of closed polygons. Each polygon is outlined by using the current pen and filled by using the current brush and polygon fill mode. The polygons drawn by this function can overlap.


---

perhaps you need a "Region" Function

CreatePolygonRgn function
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createpolygonrgn

CreatePolyPolygonRgn function
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createpolypolygonrgn
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1732
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: cyclometric circle

Postby Silvio.Falconi » Wed Aug 03, 2022 8:43 pm

For now I have to give up the refill of the area, I have created 10 circles to display all the shapes of the 10 lottery reels

Image

I saw that it can not do them automatically I do not understand why

if I associate a button with the function Mostra_Form(aCicloSmall,aColors,oBrw) then it create the form but then there is the erro U see on snapshot

In the class I'm going to memorize the graph points where the numbers are positioned, that is the positions where to draw the shapes

when I call the Distance_multiple () method it needs the positions of the circle

I did not understand why it does not find them

this does not happen in the large circle even if it does not initially create the shape of the first record "Bari"

if after I scroll through the browse, the procedure shows the corresponding form


in the test I go to create adata by uploading data from an Italian site of Italian state television

test.prg


Code: Select all  Expand view  RUN
#include "fivewin.ch"
#include "constant.ch"
#include "colors.ch"   //fwcolors

// test for  TCyclometric class for Italian Lottery

Function Test()
  local oCicloMetric
  local aCicloSmall:=array(11)
  local oDlg,oFont,oBold
  local oBtnPos,oBtnClose
  local nBottom   := 43
  local nRight    := 120
  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 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"


     @ 200,500 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


 //------------------------------------------------------------------------//
    //Big Circle
   oCicloMetric:= TCyclometric():New(90,15,510,510, oDlg,380)
   oCicloMetric:lShowNumbers:=.t.
   oCicloMetric:nDimPenCircle:= 3
   oCicloMetric:nDimPenLine:= 3



   @ 100,10 BUTTON oBtnClose PROMPT "Close" of oDlg  SIZE 80,22 ACTION oDlg:End()
   @ 100,10 BUTTON oBtnPos PROMPT "Test position" of oDlg  SIZE 80,22 ;
    ACTION Mostra_Form(aCicloSmall,aColors,oBrw)







     oDlg:bResized := <||
     local oRect := oDlg:GetCliRect()
        oBtnClose:nLeft    := oRect:nRight - 100
        oBtnClose:nTop     := oRect:nBottom - 45
        oBtnPos:nLeft      := oRect:nLeft +10
        oBtnPos:nTop       := oRect:nBottom - 45

                 RETURN NIL
                       >



   ACTIVATE DIALOG oDlg CENTERED ;
   ON INIT (oBrw:setfocus(),;
             Showform(oBrw:nArrayAt,oCicloMetric,aColors,oBrw),;
   aCicloSmall:=Mostra_Ciclo_Ruote(oBrw,oDlg,aCicloSmall,aColors) ,;
                        Eval(oDlg:bResized))

   RELEASE FONT oFont, oBold
   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:apos)

   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 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:= 5
     nCol:= 10
     nDia:= 80
     nHeight:= nDia+20
     nWidth := nDia+nCol
     xCol:= 50
     xSay:= 50

   For n= 1 to 10
        aCicloMetric[n]:= TCyclometric():New(nRow,nCol,nWidth,nHeight, oDlg,nDia)
        aCicloMetric[n]:lShowNumbers:=.f.
        aCicloMetric[n]:nDimPenCircle:= 0.2
        aCicloMetric[n]:lShowSMallCircles:=.f.
        aCicloMetric[n]:lShowDistance:=.f.

        nCol+= xCol -10
        nWidth := nDia+nCol

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

   next

     return aCicloMetric




Function Mostra_Form(aCicloMetric,aColors,oBrw)
   local n
   local aPosNew

   For n= 1 to len(aCicloMetric)

      aNum:= Give_Numbers(oBrw,n)

       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]:apos

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

    next
   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 TCyclometric class ( New Release)
Code: Select all  Expand view  RUN
#include "fivewin.ch"


// TCyclometric class for Italian Lottery


#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 nDiametro
   DATA oFont,oBold
   DATA aPos  AS ARRAY
   DATA lShowNumbers AS LOGICAL init .T.
   DATA lShowSmallCircles AS LOGICAL init .T.
   DATA lShowDistance AS LOGICAL init .T.
   DATA nDimPenCircle,nDimPenLine

   METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, nDiametro) CONSTRUCTOR
   METHOD Init( hDlg )
   METHOD End() INLINE if( ::hWnd == 0, ::Destroy(), Super:End() )
   METHOD Destroy()
   METHOD Display()
   METHOD Paint()
   METHOD Line( nTop, nLeft, nBottom, nRight, oPen )
   METHOD Say( nRow, nCol, cText, nClrFore, nClrBack, oFont, lPixel,lTransparent, nAlign )
   METHOD Distance(num1,num2)
   METHOD Distance_Multiple(num1,num2,num3,num4,num5)
   METHOD Say_distance(num1,num2)
ENDCLASS

METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, nDiametro,;
   lDesign,lShowNumbers,nDimPenCircle,nDimPenLine,lShowSMallCircles,lShowDistance  ) CLASS  TCyclometric

DEFAULT  nDiametro     := 200             ,;
         nHeight       := 200             ,;
         nLeft         := 10              ,;
         nTop          := 10              ,;
         nWidth        := 200             ,;
         lDesign       := .f.             ,;
         lShowNumbers   := .t.             ,;
         lShowDistance  := .t.             ,;
         lShowSMallCircles := .t.             ,;
         nDimPenCircle := 1               ,;
         nDimPenLine   := 1               ,;
         oWnd          := GetWndDefault()

 ::nId         := ::GetNewId()
 ::nTop        := nTop
 ::nLeft       := nLeft
 ::nBottom     := nTop + nHeight - 1
 ::nRight      := nLeft + nWidth - 1

 ::oWnd        := oWnd
 ::lDrag       := lDesign
 ::oBrush      := TBrush():New(,GetSysColor(COLOR_BTNFACE) )
 ::apos        := {}

 ::nDiametro   =  nDiametro

 ::oFont     = TFont():New( "Tahoma", 0, -10 )
 ::oBold     = TFont():New( "Verdana", 0, -10, , .t. )

 ::nStyle   := nOr( WS_CHILD, WS_VISIBLE, WS_TABSTOP, WS_CLIPSIBLINGS )
 ::Register( nOr( CS_VREDRAW, CS_HREDRAW ) )

 ::lShowNumbers  := lShowNumbers
 ::nDimPenCircle := nDimPenCircle
 ::nDimPenLine   := nDimPenLine
 ::lShowSMallCircles := lShowSMallCircles
 ::lShowDistance  := lShowDistance


   if ! Empty( oWnd:hWnd )
       ::Create()
       ::Default()
       ::lVisible = .t.
      oWnd:AddControl( Self )
   else
      oWnd:DefControl( Self )
      ::lVisible = .f.
   endif

   if lDesign
      ::CheckDots()
   endif
   Return self

//--------------------------------------------------------------------------------------------------------//
METHOD Init( hDlg ) CLASS  TCyclometric

   Super:Init( hDlg )

   return nil
//--------------------------------------------------------------------------------------------------------//
METHOD Destroy() CLASS  TCyclometric
   if ::hWnd != 0
      ::Super:Destroy()
   endif
return nil
//--------------------------------------------------------//
METHOD Display() CLASS  TCyclometric
   ::BeginPaint()
   ::Paint()
   ::EndPaint()
return 0
//--------------------------------------------------------//
METHOD Paint() CLASS  TCyclometric
   local nI
   local  nRaggio := (::nDiametro/2)
   local  xCent   := ::nLeft+nRaggio
   local  yCent   := ::nTop+nRaggio
   local  aTcPen := array(4)
   local  nTotalNumbers := 90
   local step_fi := PI() / 4.5 / 10  // add by Jimmy
   local hDc:=::getDc(), nDeltaR
   local nRaggioSay,nY2,nX2


    aTcPen[1] := CREATEPEN( PS_SOLID, ::nDimPenCircle, darkgray )
    aTcPen[2] := CREATEPEN( PS_SOLID, ::nDimPenLine, darkred )



     //draw the circle
    Ellipse(hDC,::nLeft,::nTop,::nLeft+::nDiametro,::nTop+ ::nDiametro,aTcPen[1])


   //draw the numbers
   nYOffset = ::oFont:nHeight / 2
   nXOffset = ::oFont:nWidth / 2
   nDeltaR := ::oFont:nHeight


   FOR nI = 1 TO nTotalNumbers
      nAngolo := 2* Pgreco() / nTotalNumbers * ( nI - 1 )
      nY := INT( nRaggio * SIN(( ni-22.5) * step_fi ) + yCent)
      nX := INT( nRaggio * COS(( ni-22.5) * step_fi ) + xCent)

    If ::lShowSMallCircles
      // small  circles
      Ellipse(hDC, nX,nY ,nX-3,nY+3,aTcPen[2])
   Endif


     // Save the positions of numbers
      aadd( ::apos , {nI,nY,nX} )



      If ::lShowNumbers
         nRaggioSay := (::nDiametro/2) + 10
         nY2 := INT( nRaggioSay * SIN(( ni-22.5) * step_fi ) + yCent)
         nX2 := INT( nRaggioSay * COS(( ni-22.5) * step_fi ) + xCent)
        ::Say( nY2 - nYOffset, nX2 - 0, hb_ntoc( nI,0 ),CLR_RED , , ::oFont, .t.,.t., TA_CENTER )
      Endif

    //Say( nRow, nCol, cText, nClrFore, nClrBack, oFont, lPixel, lTransparent, nAlign )
NEXT




  ::ReleaseDC()

   return nil
//--------------------------------------------------------------//
STAT FUNC Pgreco(); RETURN (3.1415926536)
//--------------------------------------------------------------//

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   hOldPen
 ::GetDC()
   hOldPen := SelectObject( ::hDC, oPen )
   MoveTo( ::hDC, nLeft, nTop )
   LineTo( ::hDC, nRight, nBottom, oPen )
   SelectObject( ::hDC, hOldPen )
   ::ReleaseDC()

return nil
//--------------------------------------------------------------//
METHOD Say( nRow, nCol, cText, nClrFore, nClrBack, oFont, lPixel,;
            lTransparent, nAlign ) CLASS  TCyclometric

   DEFAULT nClrFore := ::nClrText,;
           nClrBack := ::nClrPane,;
           oFont    := ::oFont,;
           lPixel   := .f.,;
           lTransparent := .f.

   if ValType( nClrFore ) == "C"      //  xBase Color string
      nClrBack = nClrFore
      nClrFore = nGetForeRGB( nClrFore )
      nClrBack = nGetBackRGB( nClrBack )
   endif

   ::GetDC()

   DEFAULT nAlign := GetTextAlign( ::hDC )

   WSay( ::hWnd, ::hDC, nRow, nCol, cValToChar( cText ), nClrFore, nClrBack,;
         If( oFont != nil, oFont:hFont, 0 ), lPixel, lTransparent, nAlign )

   ::ReleaseDC()

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

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)  CLASS  TCyclometric
   local  aNumpos := ::apos
   local nAt1,nAt2,nAt3,nAt4,nAt5
   local oPen,hOldPen
   local aRect:= {}
   local nDistanza,nYOffset,nXOffset, nY,nX
   local  nRaggio := (::nDiametro/2)
   local  xCent   := ::nLeft+nRaggio
   local  yCent   := ::nTop+nRaggio
   local aPoints   := array(5)
   local hBrush1,hOld1

   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]}


     ::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)
       Endif



     ::ReleaseDC()
     return nil


 //by Antonino
/* METHOD Distance_Multiple(num1,num2,num3,num4,num5)  CLASS  TCyclometric
   local  aNumpos := ::apos
   local nAt1,nAt2,nAt3,nAt4,nAt5
   local oPen,hOldPen
   local aRect:= {}
   local nDistanza,nYOffset,nXOffset, nY,nX

   local aPoints   := array(5)

  // xbrowser aNumpos
   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][3], aNumpos[nAt5][2]}
     aPoints [4]  := {aNumpos[nAt4][3], aNumpos[nAt4][2]}
     aPoints [3]  := {aNumpos[nAt3][3], aNumpos[nAt3][2]}
     aPoints [2]  := {aNumpos[nAt2][3], aNumpos[nAt2][2]}
     aPoints [1]  := {aNumpos[nAt1][3], aNumpos[nAt1][2]}

       PolyPolygon( ::GetDC(),aPoints)
     ::ReleaseDC()
      return nil
   */


//-----------------------------------------------------------------------//
 METHOD Say_distance(num1,num2) CLASS  TCyclometric
  local nDistanza:= 0
   local nAt1,nAt2
   local  aNumpos := ::apos
   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: 7069
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Postby Silvio.Falconi » Fri Dec 02, 2022 11:12 am

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 view  RUN
#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: 7069
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Postby Silvio.Falconi » Fri Dec 02, 2022 11:37 am

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


Image


Code: Select all  Expand view  RUN
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: 7069
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Postby Silvio.Falconi » Fri Dec 02, 2022 12:10 pm

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 view  RUN
#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: 7069
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Postby Silvio.Falconi » Fri Dec 02, 2022 1:11 pm

* 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 view  RUN
#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: 7069
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Postby Silvio.Falconi » Fri Dec 02, 2022 1:31 pm

] corrected the position line

Problem to refill with agradient With FillRectEx( ::hDC, aPoints, aGrad)

Image

new code


Code: Select all  Expand view  RUN
#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   ;  //
      TiTle "Manage Ciclometric"

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


       @ 200,500 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: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,nTop,nLeft} )
       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 nsize1:=1
   local nSize2:=2
   local nClr1:= nColor,nClr2:= CLR_WHITE


   local aPoints   := array(5)
   local hBrush1,hOld1
   local nDimPenLine:=1
   local aGrad :=   { CLR_BLACK,;
           {{ nsize1, nClr1,nClr2 },{nsize1, nClr2,nClr1}, .t. } }


   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

    //refill
    * xbrowser aPoints
    FillRectEx( ::hDC, aPoints, aGrad)


     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: 7069
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Postby Silvio.Falconi » Sat Dec 03, 2022 3:59 pm

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: 7069
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Postby Silvio.Falconi » Tue Dec 06, 2022 10:27 am

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 view  RUN

#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 view  RUN

#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
Silvio.Falconi
 
Posts: 7069
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Postby Marc Venken » Tue Dec 06, 2022 11:23 am

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.04 with Harbour
User avatar
Marc Venken
 
Posts: 1439
Joined: Tue Jun 14, 2016 7:51 am
Location: Belgium

Re: cyclometric circle

Postby Silvio.Falconi » Tue Dec 06, 2022 12:39 pm

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
Silvio.Falconi
 
Posts: 7069
Joined: Thu Oct 18, 2012 7:17 pm

Re: cyclometric circle

Postby Marc Venken » Tue Dec 06, 2022 2:41 pm

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.04 with Harbour
User avatar
Marc Venken
 
Posts: 1439
Joined: Tue Jun 14, 2016 7:51 am
Location: Belgium

Re: cyclometric circle

Postby Silvio.Falconi » Wed Dec 07, 2022 8:36 am

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
Silvio.Falconi
 
Posts: 7069
Joined: Thu Oct 18, 2012 7:17 pm

PreviousNext

Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 50 guests