Page 1 of 4

cyclometric circle

PostPosted: Mon Jul 11, 2022 12:45 pm
by Silvio.Falconi
I'm trying to create a cycling circle, so i should create one like this

Image

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

my test
Image

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

Image

Re: cyclometric circle

PostPosted: Mon Jul 11, 2022 3:09 pm
by Antonio Linares
Dear Silvio,

Please post your code so we can test it

Re: cyclometric circle

PostPosted: Mon Jul 11, 2022 4:00 pm
by Silvio.Falconi
My test

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


Code: Select all  Expand view

#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

Re: cyclometric circle

PostPosted: Mon Jul 11, 2022 4:27 pm
by Silvio.Falconi
I add two methods Say and Line

Code: Select all  Expand view

#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



 

Re: cyclometric circle

PostPosted: Mon Jul 11, 2022 6:53 pm
by Silvio.Falconi
Antonio,

New release

Code: Select all  Expand view

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



Image



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 ?

Re: cyclometric circle

PostPosted: Mon Jul 11, 2022 8:22 pm
by Antonio Linares
Please post your new code :-)

Re: cyclometric circle

PostPosted: Tue Jul 12, 2022 5:07 am
by Jimmy
hi Silvio,

try this

Code: Select all  Expand view
 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: Select all  Expand view
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)
 

Re: cyclometric circle

PostPosted: Tue Jul 12, 2022 8:37 am
by Silvio.Falconi
Jimmy wrote:hi Silvio,

try this

Code: Select all  Expand view
 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: Select all  Expand view
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

Image

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: Select all  Expand view

#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


Image

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

Re: cyclometric circle

PostPosted: Tue Jul 12, 2022 8:53 am
by Silvio.Falconi
I add the small circles near to numbers

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


Code: Select all  Expand view
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

Re: cyclometric circle

PostPosted: Tue Jul 12, 2022 9:27 am
by Silvio.Falconi
I tried with multiple positions directly but not run ok

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

Image



Code: Select all  Expand view
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]

Re: cyclometric circle

PostPosted: Tue Jul 12, 2022 10:35 am
by Antonio Linares
Latest code, full source code, please :-)

Re: cyclometric circle

PostPosted: Tue Jul 12, 2022 1:11 pm
by Silvio.Falconi
Antonio Linares wrote:Latest code, full source code, please :-)



Image




Is here!!

Code: Select all  Expand view

#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






 

Re: cyclometric circle

PostPosted: Tue Jul 12, 2022 3:15 pm
by Silvio.Falconi
Last Release ( 12.07.2022 time 17.00)

Code: Select all  Expand view

#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: Select all  Expand view
::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

Image


How I can resolve for the right coordinates ?

Re: cyclometric circle

PostPosted: Tue Jul 12, 2022 3:40 pm
by AntoninoP
you know when Silvio asks help I cannot resist
Code: Select all  Expand view

#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 :roll:

Re: cyclometric circle

PostPosted: Tue Jul 12, 2022 3:46 pm
by Silvio.Falconi
ok thanks but the numbers are bad
the 90 must be on top