FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour cyclometric circle
Posts: 7318
Joined: Thu Oct 18, 2012 07:17 PM
cyclometric circle
Posted: Mon Jul 11, 2022 12:45 PM
I'm trying to create a cycling circle, so i should create one like this



I make a test but I not understood why the number init from a bad point

my test


I need to do this because I could do some statistics in the Italian lotto and calculate the distance between two numbers for example
between 90 and 45 the distance is 45 as you can see in this figure

Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 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
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: cyclometric circle
Posted: Mon Jul 11, 2022 03:09 PM

Dear Silvio,

Please post your code so we can test it

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 7318
Joined: Thu Oct 18, 2012 07:17 PM
Re: cyclometric circle
Posted: Mon Jul 11, 2022 04:00 PM
My test

I made a small class because I need to make until 11 circles ( one for each weel of Lottery)


Code (fw): Select all Collapse
 
#include "FiveWin.ch"
#include "constant.ch"

Function Test()
  local oCicloMetric
  local oDlg,oFont,oBold
  local nBottom   := 33
  local nRight    := 80
  local nWidth    := Max( nRight * DLG_CHARPIX_W, 180 )
  local nHeight   := nBottom * DLG_CHARPIX_H

   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(10,10,450,430, oDlg,410)



   @ 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


//-----------------------------------------------------------//
/*
Copyright (c) 2022 <Falconi Silvio>

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

CLASS TCyclometric FROM TControl

   CLASSDATA lRegistered AS LOGICAL
   DATA nDiametro
   DATA oFont,oBold

   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()
ENDCLASS



METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, nDiametro, lDesign) CLASS  TCyclometric

DEFAULT  nDiametro   := 200             ,;
         nHeight     := 200             ,;
         nLeft       := 10              ,;
         nTop        := 10              ,;
         nWidth      := 200             ,;
         lDesign  := .f.,;
         oWnd        := GetWndDefault()

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

 ::oWnd        := oWnd
 ::lDrag       = lDesign
// ::oBrush := TBrush():New(,GetSysColor(15)-RGB(30,30,30))


 ::nDiametro   =  nDiametro

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

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




   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 onXOffset, nYOffset, nAngolo, nX, nY

   local  nNum
   local  nRaggio := ::nDiametro/2
   local  xCent:=::nLeft+nRaggio
   local  yCent:=6+nRaggio
   local  nTotalNumbers := 90
   ::GetDC()

     //draw the circle
    Ellipse(::hDC,::nLeft,::nTop,::nLeft+::nDiametro,::nTop+ ::nDiametro)


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

       nY := SIN( nAngolo, .T. ) * nRaggio + yCent
       nX := COS( nAngolo, .T. ) * nRaggio + xCent

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

    ::Say( nY - nYOffset, nX - nXOffset, LTRIM( STRzero( nI,2 ) ), , , , .T., .T. )
   NEXT



  ::ReleaseDC()

return nil

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


the numbers must be out of the circle
the number 90 must be as a clock at 12 o'clock, so the number 45 at 18.00
and on circle must be draw a pixel near to number
I think the positions must be save on array because I can calc the distance beetween two numbers
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 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
Posts: 7318
Joined: Thu Oct 18, 2012 07:17 PM
Re: cyclometric circle
Posted: Mon Jul 11, 2022 04:27 PM
I add two methods Say and Line

Code (fw): Select all Collapse
 
#include "FiveWin.ch"
#include "constant.ch"

Function Test()
  local oCicloMetric
  local oDlg,oFont,oBold
  local nBottom   := 33
  local nRight    := 80
  local nWidth    := Max( nRight * DLG_CHARPIX_W, 180 )
  local nHeight   := nBottom * DLG_CHARPIX_H

   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(10,10,450,430, oDlg,410)



   @ 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
//-----------------------------------------------------------//
CLASS TCyclometric FROM TControl

   CLASSDATA lRegistered AS LOGICAL
   DATA nDiametro
   DATA oFont,oBold

   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 )
ENDCLASS



METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, nDiametro, lDesign) CLASS  TCyclometric

DEFAULT  nDiametro   := 200             ,;
         nHeight     := 200             ,;
         nLeft       := 10              ,;
         nTop        := 10              ,;
         nWidth      := 200             ,;
         lDesign  := .f.,;
         oWnd        := GetWndDefault()

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

 ::oWnd        := oWnd
 ::lDrag       = lDesign
// ::oBrush := TBrush():New(,GetSysColor(15)-RGB(30,30,30))


 ::nDiametro   =  nDiametro

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

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




   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 onXOffset, nYOffset, nAngolo, nX, nY

   local  nNum
   local  nRaggio := ::nDiametro/2
   local  xCent   := ::nLeft+nRaggio
   local  yCent   := 5+ nRaggio
   local  nTotalNumbers := 90

   ::GetDC()

     //draw the circle
    Ellipse(::hDC,::nLeft,::nTop,::nLeft+::nDiametro,::nTop+ ::nDiametro)

  *  Moveto(::hDC,xCent,yCent-nRaggio)
   *  Lineto(::hDC,xCent,yCent-nRaggio+nRaggio)

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

          nY:= SIN( nAngolo, .T. ) * nRaggio + yCent
         nX := COS( nAngolo, .T. ) * nRaggio + xCent

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

   *  ::Say( nY - nYOffset, nX - nXOffset, LTRIM( STRzero( nI,2 ) ), , , , .T., .T. )

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


  NEXT



  ::ReleaseDC()

return nil

STAT FUNC Pgreco(); RETURN (3.1415926536)


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

METHOD Line( nTop, nLeft, nBottom, nRight, oPen ) CLASS  TCyclometric

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

   ::GetDC()
   MoveTo( ::hDC, nLeft, nTop )
   LineTo( ::hDC, nRight, nBottom, hPen )
   ::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
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 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
Posts: 7318
Joined: Thu Oct 18, 2012 07:17 PM
Re: cyclometric circle
Posted: Mon Jul 11, 2022 06:53 PM
Antonio,

New release

Code (fw): Select all Collapse
 
 
#include "FiveWin.ch"
#include "constant.ch"

#define COLOR_BTNFACE 15
#define PS_SOLID   0






Function Test()
  local oCicloMetric
  local oDlg,oFont,oBold
  local oBtnPos,oBtnClose
  local nBottom   := 33
  local nRight    := 80
  local nWidth    := Max( nRight * DLG_CHARPIX_W, 180 )
  local nHeight   := nBottom * DLG_CHARPIX_H

   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(10,10,450,430, oDlg,410)




   @ 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 oCicloMetric:Distance(90,45)






     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 ( Eval(oDlg:bResized))

   RELEASE FONT oFont, oBold
   Return nil















//-----------------------------------------------------------//
/*
Copyright (c) 2022 <Falconi Silvio>

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

CLASS TCyclometric FROM TControl

   CLASSDATA lRegistered AS LOGICAL
   DATA nDiametro
   DATA oFont,oBold
   Data apos  AS ARRAY

   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)
ENDCLASS



METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, nDiametro, lDesign) CLASS  TCyclometric

DEFAULT  nDiametro   := 200             ,;
         nHeight     := 200             ,;
         nLeft       := 10              ,;
         nTop        := 10              ,;
         nWidth      := 200             ,;
         lDesign  := .f.,;
         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( "Verdana", 0, -11 )
   ::oBold     = TFont():New( "Verdana", 0, -11, , .t. )

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


   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 onXOffset, nYOffset, nAngolo, nX, nY

   local  nNum
   local  nRaggio := ::nDiametro/2
   local  xCent   := ::nLeft+nRaggio
   local  yCent   := 5+ nRaggio
   local  nTotalNumbers := 90
   local  aTcPen := array(4)


   aTcPen[1] := CREATEPEN( PS_SOLID, 1, nRGB( 128,0,0 ) )

   ::GetDC()

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


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

         nY:=  SIN( nAngolo, .T. ) * nRaggio + yCent
         nX := COS( nAngolo, .T. ) * nRaggio + xCent

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

      aadd( ::apos , {nI,nY,nX} )

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

  NEXT


  ::ReleaseDC()

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

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

 *  local hPen := if( oPen = nil, 0, oPen:hPen )
 local  oPen := CREATEPEN( PS_SOLID, 1, 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

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

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

   ::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-nTemp
         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

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

  Function Positions(oCicloMetric)
     xbrowser oCicloMetric:apos
     return nil


to draw the distance I made

@ 100,10 BUTTON oBtnPos PROMPT "Test position" of oDlg SIZE 80,22 ;
ACTION oCicloMetric:Distance(90,45)







To draw the distance beetween two number I made the METHOD Distance(num1,num2) but noy run ok the line is not good
the number distance is draw good ( 45)

On Paint I add positions of numbers on an array ::aPos

How I can resolve ?
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 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
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: cyclometric circle
Posted: Mon Jul 11, 2022 08:22 PM

Please post your new code :-)

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 1772
Joined: Thu Sep 05, 2019 05:32 AM
Re: cyclometric circle
Posted: Tue Jul 12, 2022 05:07 AM
hi Silvio,

try this

Code (fw): Select all Collapse
  local nWidth    := 800 // Max( nRight * DLG_CHARPIX_W, 180 )
  local nHeight   := 600 //  nBottom * DLG_CHARPIX_H

     oCicloMetric:= TCyclometric():New(20,20,450,450, oDlg,410)


Code (fw): Select all Collapse
METHOD Paint() CLASS  TCyclometric
   local  nRaggio := (::nDiametro/2) +10
   local  xCent   := ::nLeft+nRaggio -15
   local  yCent   := 5+ nRaggio      +5
// add by Jimmy 
   LOCAL step_fi := PI() / 4.5 / 10

   //draw the numbers
   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)
      ::Say(...)
   NEXT
// add by Jimmy
   ::line( ::nTop,::nLeft+(::nDiametro/2),::nTop+ ::nDiametro,::nLeft+(::nDiametro/2), CLR_RED)
greeting,

Jimmy
Posts: 7318
Joined: Thu Oct 18, 2012 07:17 PM
Re: cyclometric circle
Posted: Tue Jul 12, 2022 08:37 AM
Jimmy wrote:hi Silvio,

try this

Code (fw): Select all Collapse
  local nWidth    := 800 // Max( nRight * DLG_CHARPIX_W, 180 )
  local nHeight   := 600 //  nBottom * DLG_CHARPIX_H

     oCicloMetric:= TCyclometric():New(20,20,450,450, oDlg,410)


Code (fw): Select all Collapse
METHOD Paint() CLASS  TCyclometric
   local  nRaggio := (::nDiametro/2) +10
   local  xCent   := ::nLeft+nRaggio -15
   local  yCent   := 5+ nRaggio      +5
// add by Jimmy 
   LOCAL step_fi := PI() / 4.5 / 10

   //draw the numbers
   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)
      ::Say(...)
   NEXT
// add by Jimmy
   ::line( ::nTop,::nLeft+(::nDiametro/2),::nTop+ ::nDiametro,::nLeft+(::nDiametro/2), CLR_RED)



it run ok only the line I must link two numbers

sample 90 and 45 or can be others (generally the 5 numbers of the draw per wheel)

I save the positions when I write the numbers



For a sample the number 1 is on row 10 col 234 I think it are pixel ?


This is the last Source code it seems run ok also the distance method

Code (fw): Select all Collapse
 
#include "FiveWin.ch"
#include "constant.ch"

#define COLOR_BTNFACE 15
#define PS_SOLID   0






Function Test()
  local oCicloMetric
  local oDlg,oFont,oBold
  local oBtnPos,oBtnClose
  local nBottom   := 33
  local nRight    := 80
 * local nWidth    := Max( nRight * DLG_CHARPIX_W, 180 )
 * local nHeight   := nBottom * DLG_CHARPIX_H

  local nWidth    := 800 // Max( nRight * DLG_CHARPIX_W, 180 )
  local nHeight   := 600 //  nBottom * DLG_CHARPIX_H






   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(10,10,430,430, oDlg,410)
      oCicloMetric:= TCyclometric():New(20,20,450,450, oDlg,410)



   @ 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 (oCicloMetric:Distance(11,40),;
           oCicloMetric:Distance(40,45),;
           oCicloMetric:Distance(45,54),;
           oCicloMetric:Distance(54,68),;
           oCicloMetric:Distance(68,11))

     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 ( Eval(oDlg:bResized))

   RELEASE FONT oFont, oBold
   Return nil















//-----------------------------------------------------------//
/*
Copyright (c) 2022 <Falconi Silvio>

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

CLASS TCyclometric FROM TControl

   CLASSDATA lRegistered AS LOGICAL
   DATA nDiametro
   DATA oFont,oBold
   Data apos  AS ARRAY

   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)
ENDCLASS



METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, nDiametro, lDesign) CLASS  TCyclometric

DEFAULT  nDiametro   := 200             ,;
         nHeight     := 200             ,;
         nLeft       := 10              ,;
         nTop        := 10              ,;
         nWidth      := 200             ,;
         lDesign  := .f.,;
         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( "Verdana", 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 ) )


   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) +10
   local  xCent   := ::nLeft+nRaggio -15
   local  yCent   := 5+ nRaggio      +5
   local  aTcPen := array(4)
    local  nTotalNumbers := 90


   LOCAL step_fi := PI() / 4.5 / 10  // add by Jimmy
   ::GetDC()

    aTcPen[1] := CREATEPEN( PS_SOLID, 1, nRGB( 128,0,0 ) )

   ::GetDC()

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


   //draw the numbers
   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)


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

      aadd( ::apos , {nI,nY,nX} )

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

  NEXT
  ::ReleaseDC()

   return nil

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

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

 *  local hPen := if( oPen = nil, 0, oPen:hPen )
 local  oPen := CREATEPEN( PS_SOLID, 1, 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

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

  Function Positions(oCicloMetric)
     xbrowser oCicloMetric:apos
     return nil




on test ( picture) I tried the numbers 11,40,45,54,68




as you can see the points are not on circle but on numbers and it is wrong
also the nDistance is write on bad place the ndistance must be placed on the middle of the line
that is, the geometric figure must be inside the circle
maybe the numbers (01-90) need to be more attached to the circle line
the linked numbers (in my test 11,40,45,54,68) must be highlighted or draw a small circle above

and there is another problem if you put a windows or a dialog over the ciclometric dialog the lines go away
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 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
Posts: 7318
Joined: Thu Oct 18, 2012 07:17 PM
Re: cyclometric circle
Posted: Tue Jul 12, 2022 08:53 AM
I add the small circles near to numbers


but they must be on the line of the circle, how to do?


Code (fw): Select all Collapse
 METHOD Paint() CLASS  TCyclometric
   local nI
   local  nRaggio := (::nDiametro/2) +10
   local  xCent   := ::nLeft+nRaggio -15
   local  yCent   := 5+ nRaggio      +5
   local  aTcPen := array(4)
    local  nTotalNumbers := 90


   LOCAL step_fi := PI() / 4.5 / 10  // add by Jimmy
   ::GetDC()

    aTcPen[1] := CREATEPEN( PS_SOLID, 1, nRGB( 128,0,0 ) )
    aTcPen[2] := CREATEPEN( PS_SOLID, 2, CLR_BLUE )
   ::GetDC()

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


   //draw the numbers
   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)


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

      aadd( ::apos , {nI,nY,nX} )

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




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

  NEXT
  ::ReleaseDC()

   return nil
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 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
Posts: 7318
Joined: Thu Oct 18, 2012 07:17 PM
Re: cyclometric circle
Posted: Tue Jul 12, 2022 09:27 AM
I tried with multiple positions directly but not run ok

ACTION oCicloMetric:Distance_MU(11,40,45,54,68)





Code (fw): Select all Collapse
 METHOD Distance_MU(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

  // 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 } )



   PolyPolygon( ::oWnd:GetDC(),;
                         {   { aNumpos[nAt1][2], aNumpos[nAt1][3] },;
                             { aNumpos[nAt2][2], aNumpos[nAt2][3] },;
                             { aNumpos[nAt3][2], aNumpos[nAt3][3] },;
                             { aNumpos[nAt4][2], aNumpos[nAt4][3] },;
                             { aNumpos[nAt5][2], aNumpos[nAt5][3] };
                             } )
                 ::ReleaseDC()
      return nil



[code]
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 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
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: cyclometric circle
Posted: Tue Jul 12, 2022 10:35 AM

Latest code, full source code, please :-)

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 7318
Joined: Thu Oct 18, 2012 07:17 PM
Re: cyclometric circle
Posted: Tue Jul 12, 2022 01:11 PM
Antonio Linares wrote:Latest code, full source code, please :-)








Is here!!

Code (fw): Select all Collapse
 
#include "FiveWin.ch"
#include "constant.ch"

#define COLOR_BTNFACE 15
#define PS_SOLID   0






Function Test()
  local oCicloMetric
  local oDlg,oFont,oBold
  local oBtnPos,oBtnClose
  local nBottom   := 33
  local nRight    := 80
 * local nWidth    := Max( nRight * DLG_CHARPIX_W, 180 )
 * local nHeight   := nBottom * DLG_CHARPIX_H

  local nWidth    := 800 // Max( nRight * DLG_CHARPIX_W, 180 )
  local nHeight   := 600 //  nBottom * DLG_CHARPIX_H






   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(10,10,430,430, oDlg,410)
      oCicloMetric:= TCyclometric():New(20,20,450,450, oDlg,410)



   @ 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  oCicloMetric:Distance_Multiple(11,40,45,54,68)

 /*  (oCicloMetric:Distance(11,40),;
           oCicloMetric:Distance(40,45),;
           oCicloMetric:Distance(45,54),;
           oCicloMetric:Distance(54,68),;
           oCicloMetric:Distance(68,11)) */

     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 ( Eval(oDlg:bResized))

   RELEASE FONT oFont, oBold
   Return nil















//-----------------------------------------------------------//
/*
Copyright (c) 2022 <Falconi Silvio>

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

CLASS TCyclometric FROM TControl

   CLASSDATA lRegistered AS LOGICAL
   DATA nDiametro
   DATA oFont,oBold
   DATA apos  AS ARRAY

   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)
ENDCLASS



METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, nDiametro, lDesign) CLASS  TCyclometric

DEFAULT  nDiametro   := 200             ,;
         nHeight     := 200             ,;
         nLeft       := 10              ,;
         nTop        := 10              ,;
         nWidth      := 200             ,;
         lDesign  := .f.,;
         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( "Verdana", 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 ) )


   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) +10
   local  xCent   := ::nLeft+nRaggio -15
   local  yCent   := 5+ nRaggio      +5
   local  aTcPen := array(4)
   local  nTotalNumbers := 90
   local step_fi := PI() / 4.5 / 10  // add by Jimmy
   local hDc:=::getDc()


    aTcPen[1] := CREATEPEN( PS_SOLID, 1, nRGB( 128,0,0 ) )
    aTcPen[2] := CREATEPEN( PS_SOLID, 2, CLR_BLUE )

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


   //draw the numbers
   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)


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

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


      aadd( ::apos , {nI,nY,nX} )

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

NEXT


  ::ReleaseDC()

   return nil

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

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

 *  local hPen := if( oPen = nil, 0, oPen:hPen )
 local  oPen := CREATEPEN( PS_SOLID, 1, 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)  CLASS  TCyclometric
   local  aNumpos := ::apos
   local nAt1,nAt2,nAt3,nAt4,nAt5
   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 } )
   nAt3:= AScan( aNumpos, { | a | a[1] = num3 } )
   nAt4:= AScan( aNumpos, { | a | a[1] = num4 } )
   nAt5:= AScan( aNumpos, { | a | a[1] = num5 } )



   PolyPolygon( ::oWnd:GetDC(),;
                         {   { aNumpos[nAt1][2], aNumpos[nAt1][3] },;
                             { aNumpos[nAt2][2], aNumpos[nAt2][3] },;
                             { aNumpos[nAt3][2], aNumpos[nAt3][3] },;
                             { aNumpos[nAt4][2], aNumpos[nAt4][3] },;
                             { aNumpos[nAt5][2], aNumpos[nAt5][3] };
                             } )
                 ::ReleaseDC()
      return nil
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 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
Posts: 7318
Joined: Thu Oct 18, 2012 07:17 PM
Re: cyclometric circle
Posted: Tue Jul 12, 2022 03:15 PM
Last Release ( 12.07.2022 time 17.00)

Code (fw): Select all Collapse
 
#include "FiveWin.ch"
#include "constant.ch"

#define COLOR_BTNFACE 15
#define PS_SOLID   0






Function Test()
  local oCicloMetric
  local oDlg,oFont,oBold
  local oBtnPos,oBtnClose
  local nBottom   := 33
  local nRight    := 80
 * local nWidth    := Max( nRight * DLG_CHARPIX_W, 180 )
 * local nHeight   := nBottom * DLG_CHARPIX_H

  local nWidth    := 800 // Max( nRight * DLG_CHARPIX_W, 180 )
  local nHeight   := 600 //  nBottom * DLG_CHARPIX_H






   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(10,10,430,430, oDlg,410)
      oCicloMetric:= TCyclometric():New(20,20,450,450, oDlg,410)


   @ 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  oCicloMetric:Distance_Multiple(11,40,45,54,68)

 /*  (oCicloMetric:Distance(11,40),;
           oCicloMetric:Distance(40,45),;
           oCicloMetric:Distance(45,54),;
           oCicloMetric:Distance(54,68),;
           oCicloMetric:Distance(68,11)) */

     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 ( Eval(oDlg:bResized))

   RELEASE FONT oFont, oBold
   Return nil















//-----------------------------------------------------------//
/*
Copyright (c) 2022 <Falconi Silvio>

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

CLASS TCyclometric FROM TControl

   CLASSDATA lRegistered AS LOGICAL
   DATA nDiametro
   DATA oFont,oBold
   DATA apos  AS ARRAY

   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)
ENDCLASS



METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, nDiametro, lDesign) CLASS  TCyclometric

DEFAULT  nDiametro   := 200             ,;
         nHeight     := 200             ,;
         nLeft       := 10              ,;
         nTop        := 10              ,;
         nWidth      := 200             ,;
         lDesign  := .f.,;
         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( "Verdana", 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 ) )


   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) +10
   local  xCent   := ::nLeft+nRaggio -15
   local  yCent   := 5+ nRaggio      +5
   local  aTcPen := array(4)
   local  nTotalNumbers := 90
   local step_fi := PI() / 4.5 / 10  // add by Jimmy
   local hDc:=::getDc()


    aTcPen[1] := CREATEPEN( PS_SOLID, 1, nRGB( 128,0,0 ) )
    aTcPen[2] := CREATEPEN( PS_SOLID, 2, CLR_BLUE )

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


   //draw the numbers
   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)


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

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


      aadd( ::apos , {nI,nY - nYOffset,nX - nXOffset} )

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

NEXT


  ::ReleaseDC()

   return nil

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

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

 *  local hPen := if( oPen = nil, 0, oPen:hPen )
 local  oPen := CREATEPEN( PS_SOLID, 1, 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)  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][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]}

       *   PolyPolygon( ::oWnd:GetDC(),aPoints)

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

     ::ReleaseDC()
      return nil



the Polypolygon not run ok I modify it with
Code (fw): Select all Collapse
 ::line( aPoints [1][1],aPoints [1][2],aPoints [2][1],aPoints [2][2], CLR_RED)
     ::line( aPoints [2][1],aPoints [2][2],aPoints [3][1],aPoints [3][2], CLR_RED)
     ::line( aPoints [3][1],aPoints [3][2],aPoints [4][1],aPoints [4][2], CLR_RED)
     ::line( aPoints [4][1],aPoints [4][2],aPoints [5][1],aPoints [5][2], CLR_RED)
     ::line( aPoints [5][1],aPoints [5][2],aPoints [1][1],aPoints [1][2], CLR_RED)


now the geometric shape looks better, but the coordinates are still wrong because they are outside the circle




How I can resolve for the right coordinates ?
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 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
Posts: 375
Joined: Tue Feb 10, 2015 09:48 AM
Re: cyclometric circle
Posted: Tue Jul 12, 2022 03:40 PM
you know when Silvio asks help I cannot resist
Code (fw): Select all Collapse
#include "FiveWin.ch"
#include "constant.ch"

#define COLOR_BTNFACE 15
#define PS_SOLID   0






Function Test()
  local oCicloMetric
  local oDlg,oFont,oBold
  local oBtnPos,oBtnClose
  local nBottom   := 33
  local nRight    := 80
 * local nWidth    := Max( nRight * DLG_CHARPIX_W, 180 )
 * local nHeight   := nBottom * DLG_CHARPIX_H

  local nWidth    := 800 // Max( nRight * DLG_CHARPIX_W, 180 )
  local nHeight   := 600 //  nBottom * DLG_CHARPIX_H






   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(10,10,430,430, oDlg,410)
      oCicloMetric:= TCyclometric():New(20,20,450,450, oDlg,410)


   @ 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  oCicloMetric:Distance_Multiple(11,40,45,54,68)

 /*  (oCicloMetric:Distance(11,40),;
           oCicloMetric:Distance(40,45),;
           oCicloMetric:Distance(45,54),;
           oCicloMetric:Distance(54,68),;
           oCicloMetric:Distance(68,11)) */

     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 ( Eval(oDlg:bResized))

   RELEASE FONT oFont, oBold
   Return nil















//-----------------------------------------------------------//
CLASS TCyclometric FROM TControl

   CLASSDATA lRegistered AS LOGICAL
   DATA nDiametro
   DATA oFont,oBold
   DATA apos  AS ARRAY

   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)
ENDCLASS



METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, nDiametro, lDesign) CLASS  TCyclometric

DEFAULT  nDiametro   := 200             ,;
         nHeight     := 200             ,;
         nLeft       := 10              ,;
         nTop        := 10              ,;
         nWidth      := 200             ,;
         lDesign  := .f.,;
         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( "Verdana", 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 ) )


   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
//--------------------------------------------------------//
#define TA_CENTER         6

 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


    aTcPen[1] := CREATEPEN( PS_SOLID, 1, nRGB( 128,0,0 ) )
    aTcPen[2] := CREATEPEN( PS_SOLID, 2, CLR_BLUE )

     //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(nAngolo) + yCent)
      nX := INT( nRaggio * COS(nAngolo) + xCent)



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


      aadd( ::apos , {nI,nY,nX} )

      nY := INT( (nRaggio+nDeltaR) * SIN(nAngolo) + yCent)
      nX := INT( (nRaggio+nDeltaR) * COS(nAngolo) + xCent)
      //if nI==90
        //Ellipse(hDC, nX,nY ,nX-3,nY+3,aTcPen[2])
        ::Say( nY - nYOffset, nX - 0, hb_ntoc( nI,0 ), , , ::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 ) CLASS  TCyclometric

 *  local hPen := if( oPen = nil, 0, oPen:hPen )
 local  oPen := CREATEPEN( PS_SOLID, 1, 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)  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


there were some math error, other errors because on FiveWin sometime parameter are nCol,nRow other times nRow,nCol :-)
Posts: 7318
Joined: Thu Oct 18, 2012 07:17 PM
Re: cyclometric circle
Posted: Tue Jul 12, 2022 03:46 PM

ok thanks but the numbers are bad
the 90 must be on top

Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 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