Roger Graphics

This forum is for general support of Xbase++
Post Reply
Message
Author
User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Roger Graphics

#1 Post by Eugene Lutsenko »

This topic is in continuation of the theme:
http://bb.donnay-software.com/donnay/vi ... 2&start=30

I'm trying to deal with the extremely interesting graphics programs that gave Roger:

Code: Select all

#pragma library( "dclip1.lib" )
#pragma library( "dclip2.lib" )
#pragma library( "dclipx.lib" )

STATIC snHdll

FUNCTION Main()

LOCAL GetList[0], GetOptions, oSay, hDC1, hDC2, oStatic1, oStatic2, ;
      aPixel

@ 0,0 DCSTATIC TYPE XBPSTATIC_TYPE_BITMAP ;
      CAPTION "colors.jpg" ;
      OBJECT oStatic1 ;
      PREEVAL {|o|o:autoSize := .t.} ;
      EVAL {|o|hDC1 := GetWindowDC(o:getHWnd()), ;
               o:motion := {|a,b,o|ShowColor( hDC1, a, oSay, o )}, ;
               aPixel := Array(o:caption:xSize,o:caption:ySize)}

@ 0,250 DCSTATIC TYPE XBPSTATIC_TYPE_BITMAP;
      CAPTION "colors.jpg" ;
      PREEVAL {|o|o:autoSize := .t.} ;
      OBJECT oStatic2 ;
      EVAL {|o|hDC2 := GetWindowDC(o:getHWnd())}

@ 50,0 DCSAY '' SAYSIZE 350,20 FONT '10.Lucida Console' OBJECT oSay

@ 100,0 DCPUSHBUTTON CAPTION 'Clear Image' SIZE 100,20 ACTION {||ClearImage(hDC2,aPixel)}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'Transfer Image' ;
    SIZE 80,20 ACTION {||TransferImage(hDC1,hDC2,aPixel)}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'Flip Image' ;
    SIZE 80,20 ACTION {||FlipImage(hDC1,hDC2,aPixel)}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'Rotate Image' ;
    SIZE 80,20 ACTION {||RotateImage(hDC1,hDC2,aPixel)}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'Load Array' ;
    SIZE 80,20 ACTION {||LoadArray(hDC1,aPixel)}

DCGETOPTIONS PIXEL

DCREAD GUI FIT TITLE 'Pixel Test' OPTIONS GetOptions ;
   EVAL {||ClearImage(hDC2,aPixel)}

RETURN nil

* ---------

FUNCTION LoadArray( hDC1, aPixel )

LOCAL i, j, oScrn, nXSize := Len(aPixel), nYSize := Len(aPixel[1])

IF !aPixel[1,1] == nil
  DCMSGBOX 'Array is already loaded!'
  RETURN nil
ENDIF

oScrn := DC_WaitOn()

FOR i := 1 TO nXSize
  FOR j := 1 TO nYSize
    aPixel[i,j] := GetPixel(hDC1,i-1,j-1)
  NEXT
NEXT

DC_Impl(oScrn)

RETURN nil

* ---------

FUNCTION ClearImage( hDC2, aPixel )

LOCAL i, j, nXSize := Len(aPixel), nYSize := Len(aPixel[1])
LOCAL nColor := AutomationTranslateColor(GraMakeRGBColor({255,255,255}),.f.)

FOR i := 0 TO nXSize
  FOR j := 0 TO nYSize
    SetPixel(hDC2,i,j,nColor)
  NEXT
NEXT

RETURN nil

* ----------

FUNCTION TransferImage( hDC1, hDC2, aPixel )

LOCAL i, j, nColor, lEmptyArray := aPixel[1,1] == nil, ;
      nXSize := Len(aPixel), nYSize := Len(aPixel[1])

FOR i := 0 TO nXSize-1
  FOR j := 0 TO nYSize-1
    IF lEmptyArray
      SetPixel(hDC2,i,j,GetPixel(hDC1,i,j))
    ELSE
      SetPixel(hDC2,i,j,aPixel[i+1,j+1])
    ENDIF
  NEXT
NEXT

RETURN nil

* ----------

FUNCTION FlipImage( hDC1, hDC2, aPixel )

LOCAL i, j, lEmptyArray := aPixel[1,1] == nil, ;
      nXSize := Len(aPixel), nYSize := Len(aPixel[1])

FOR i := 0 TO nXSize-1
  FOR j := 0 TO nYSize-1
    IF lEmptyArray
      SetPixel(hDC2,j,i,GetPixel(hDC1,j,nXSize-i))
    ELSE
      SetPixel(hDC2,j,i,aPixel[i+1,j+1])
    ENDIF
  NEXT
NEXT

RETURN nil

* ----------

FUNCTION RotateImage( hDC1, hDC2, aPixel )

LOCAL i, j, lEmptyArray := aPixel[1,1] == nil, ;
      nXSize := Len(aPixel), nYSize := Len(aPixel[1])

FOR i := 0 TO nXSize-1
  FOR j := 0 TO nYSize-1
    IF lEmptyArray
      SetPixel(hDC2,i,j,GetPixel(hDC1,j,nXSize-i))
    ELSE
      SetPixel(hDC2,i,j,aPixel[j+1,nXSize-i])
    ENDIF
  NEXT
NEXT

RETURN nil

* ---------

PROC appsys ; RETURN

* ---------

STATIC FUNCTION ShowColor( hDC, aCoords, oSay, oStatic )

LOCAL nColor

aCoords[2] := oStatic:currentSize()[2] - aCoords[2]

nColor := GetPixel(hDC,aCoords[1],aCoords[2])

oSay:setCaption('Color: ' + DC_Array2String(GraGetRGBIntensity(AutomationTranslateColor(nColor,.T.))) + ;
   ' Coords: ' + DC_Array2String(aCoords))

RETURN nil

#command  GDIFUNCTION <Func>([<x,...>]) ;
       => ;
FUNCTION <Func>([<x>]);;
STATIC scHCall := nil ;;
IF scHCall == nil ;;
  IF snHdll == nil ;;
    snHDll := DllLoad('GDI32.DLL') ;;
  ENDIF ;;
  scHCall := DllPrepareCall(snHDll,DLL_STDCALL,<(Func)>) ;;
ENDIF ;;
RETURN DllExecuteCall(scHCall,<x>)

GDIFUNCTION GetPixel( nHDC, x, y)
GDIFUNCTION SetPixel( nHDC, x, y, n )
DLLFUNCTION GetWindowDC( hwnd ) USING STDCALL FROM USER32.DLL
[/size]

I had the opportunity to begin to deal with your interesting programs. I began to modify it to fit your needs. I do not understand everything. Can I ask questions?

The first question is: how to set the size and position of windows to display the original and modified drawings?

I also have the impression that there is any restriction on the dimension of the array, displaying pictures.

How to set the pixel coordinates of the area in the MDM will be determined by the coordinates of the mouse cursor.

How to save created image?

User avatar
rdonnay
Site Admin
Posts: 4728
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: Roger Graphics

#2 Post by rdonnay »

how to set the size and position of windows to display the original and modified drawings?
Are you wanting separate windows for each image? Are you wanting to resize the image to the size of the window?
I also have the impression that there is any restriction on the dimension of the array, displaying pictures.
The size of the array is proportional to the size of the image. X*Y
How to set the pixel coordinates of the area in the MDM will be determined by the coordinates of the mouse cursor.
Are you saying that you want to transfer 1 pixel at a time as the mouse cursor is moved?
How to save created image?
After you answer the above questions, I will modify the program so it also saves the created image.
The eXpress train is coming - and it has more cars.

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Re: Roger Graphics

#3 Post by Eugene Lutsenko »

Hi, Roger!

I would like to use your program for the development of graphics technology: all the necessary operations to modify images.

As for the windows, I put it accurately. I would like to. to both images: the original and transformed, were in the same window. This single window is divided in the middle into two parts: the left side - the original image, and the right - modified. Each image in the center of the field.

I have done to modify the image displayed on the center right of the window (and the height and width). But do not know how to do to the original image is displayed in the center of the left side (and on the height and width).

Of course the mouse should show the coordinates and color of the pixels to the original image. While this is not the case (source program was all right).

While the modified program Roger I's what happened (the source code below). Something happened, and something - no.
http://lc.kubagro.ru/Dima/DC_Graph.rar

PS
Yet for some reason, this topic is not always displayed on the forum, but the link is launched.

Code: Select all

**************************************************************************************************
**************************************************************************************************

#pragma library( "dclip1.lib" )
#pragma library( "dclip2.lib" )
#pragma library( "dclipx.lib" )
#pragma library( "xbtbase1.lib" )
#pragma library( "xbtbase2.lib" )

STATIC snHdll

FUNCTION Main()

LOCAL GetList[0], GetOptions, oSay, hDC1, hDC2, oStatic1, oStatic2, ;
      aPixel

DC_IconDefault(1000)

PUBLIC X_MaxW := 1313, Y_MaxW := 640                // Размер графического окна для изображения в пикселях (чтобы помещалось на ультрабук)

*mNameImage = 'Eng_Upper_A.jpg'
 mNameImage = 'Eng Upper A.bmp'

@ 0,0 DCSTATIC TYPE XBPSTATIC_TYPE_BITMAP SIZE X_MaxW+11, Y_MaxW+20 PIXEL;
      CAPTION mNameImage ;
      OBJECT oStatic1 ;
      PREEVAL {|o|o:autoSize := .t.} ;
      EVAL {|o|hDC1 := GetWindowDC(o:getHWnd()), ;
               o:motion := {|a,b,o|ShowColor( hDC1, a, oSay, o )}, ;
               aPixel := Array(o:caption:xSize,o:caption:ySize)}

@ 0,250 DCSTATIC TYPE XBPSTATIC_TYPE_BITMAP SIZE X_MaxW+11, Y_MaxW+20 PIXEL;
      CAPTION mNameImage ;
      PREEVAL {|o|o:autoSize := .t.} ;
      OBJECT oStatic2 ;
      EVAL {|o|hDC2 := GetWindowDC(o:getHWnd())}

@ Y_MaxW,900 DCSAY 'Координаты курсора мыши: ' SAYSIZE 350,20 FONT '10.Lucida Console' OBJECT oSay       // Позиция для отображения координат пикселя положения курсора мыши

@ Y_MaxW,0 DCPUSHBUTTON CAPTION 'Clear Image' SIZE 100,20 ACTION {||ClearImage(hDC2,aPixel)}             // Позиция для отображения линейки кнопок внизу

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'Transfer Image' ;
    SIZE 80,20 ACTION {||TransferImage(hDC1,hDC2,aPixel)}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'Flip Image' ;
    SIZE 80,20 ACTION {||FlipImage(hDC1,hDC2,aPixel)}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'Rotate Image' ;
    SIZE 80,20 ACTION {||RotateImage(hDC1,hDC2,aPixel)}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'Spectrum Spiral' ;                                     // Моя первая пиксельная функция
    SIZE 100,20 ACTION {||SpectrumSpiral(hDC2,aPixel)}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'Load Array' ;
    SIZE 80,20 ACTION {||LoadArray(hDC1,aPixel)}

DCGETOPTIONS PIXEL

DCREAD GUI FIT TITLE 'Исследование изображений в системе "Эйдос-Х++"' OPTIONS GetOptions ;
   EVAL {||ClearImage(hDC2,aPixel)}

RETURN nil

* ---------

FUNCTION LoadArrayOld( hDC1, aPixel )

LOCAL i, j, oScrn, nXSize := Len(aPixel), nYSize := Len(aPixel[1])

IF !aPixel[1,1] == nil
  DCMSGBOX 'Array is already loaded!'
  RETURN nil
ENDIF

oScrn := DC_WaitOn()

FOR i := 1 TO nXSize
  FOR j := 1 TO nYSize
    aPixel[i,j] := GetPixel(hDC1,i-1,j-1)
  NEXT
NEXT

DC_Impl(oScrn)

RETURN nil

* ---------

FUNCTION LoadArray( hDC1, aPixel )

LOCAL i, j, oScrn, nXSize := Len(aPixel), nYSize := Len(aPixel[1])

   IF !aPixel[1,1] == nil
      DCMSGBOX 'Array is already loaded!'
      RETURN nil
   ENDIF

   oScrn := DC_WaitOn()

   X0R = X_MaxW * 3 / 4             // Для правого изображения
   Y0R = Y_MaxW     / 2 

   FOR i := 1 TO nXSize
       FOR j := 1 TO nYSize
           aPixel[i,j] := GetPixel(hDC1,X0R+i-1-nXSize/2,Y0R+j-1-nYSize/2)
       NEXT
   NEXT

   DC_Impl(oScrn)

RETURN nil

* ---------

FUNCTION ClearImageOld( hDC2, aPixel )

LOCAL i, j, nXSize := Len(aPixel), nYSize := Len(aPixel[1])
LOCAL nColor := AutomationTranslateColor(GraMakeRGBColor({255,255,255}),.f.)

FOR i := 0 TO nXSize
  FOR j := 0 TO nYSize
      SetPixel(hDC2,i,j,nColor)
  NEXT
NEXT

RETURN nil

* ---------

FUNCTION ClearImage( hDC2, aPixel )

LOCAL i, j, nXSize := Len(aPixel), nYSize := Len(aPixel[1])
LOCAL nColor := AutomationTranslateColor(GraMakeRGBColor({255,255,255}),.f.)

   X0R = X_MaxW * 3 / 4             // Для правого изображения
   Y0R = Y_MaxW     / 2 

   FOR i := 0 TO nXSize
       FOR j := 0 TO nYSize
           SetPixel(hDC2, X0R+i-nXSize/2, Y0R+j-nYSize/2, nColor)
       NEXT
   NEXT

RETURN nil

* ---------

FUNCTION SpectrumSpiral( hDC2, aPixel )

LOCAL i, j, nXSize := Len(aPixel), nYSize := Len(aPixel[1])


   *** Расчет позиций центров изображений в стилях "Контур" и "Витраж"

   Dx = 50
   Dy = 30

*  mRadiusMax = MAX(nXSize, nYSize)
 
   mRadiusMax = X_MaxW / 4

   Ax = ( X_MaxW - 2 * Dx ) / ( 2 * mRadiusMax )
   Ay = ( Y_MaxW - 2 * Dy ) / ( 2 * mRadiusMax )

   Dx = ( X_MaxW - 2 * mRadiusMax ) / 2
   Dy = ( Y_MaxW - 2 * mRadiusMax ) / 2

   X0L = X_MaxW / 4                 // Для левого изображения
   Y0L = Y_MaxW / 2

   X0R = X_MaxW * 3 / 4             // Для правого изображения
   Y0R = Y_MaxW     / 2 


   ****** Гармонические последовательности цветов

   Column = 0

   Ax     = 0.05
   Ay     = 0.05

   Kx     = 1
   Ky     = 1

   FOR n = 0 TO 360*50 STEP 0.1

       ma := 127
       mb := 127
       mc := 127

       mU := 0
       mV := 120
       mW := 240

       mColor = n

       R := INT( ma * (1 + COS( ( mColor + mU ) * 3.14159265358979323846 / 180 ) ) )
       G := INT( mb * (1 + COS( ( mColor + mV ) * 3.14159265358979323846 / 180 ) ) )
       B := INT( mc * (1 + COS( ( mColor + mW ) * 3.14159265358979323846 / 180 ) ) )

       fColor := GraMakeRGBColor({ R, G, B })

       ***** Закрасить фон прямоугольника ***************

*      GraSetColor( hDC2, fColor, fColor )

       fColor := AutomationTranslateColor(GraMakeRGBColor({R,G,B}),.f.) 

       Column = Column + 1

       X1 := X0R + Ax * Column * COS((Column-1) * 3.14159265358979323846 / 180 ) * Kx
       Y1 := Y0R + Ay * Column * SIN((Column-1) * 3.14159265358979323846 / 180 ) * Ky

*      GraArc( oPS, { X1, Y1 }, RS, ,,, GRA_OUTLINEFILL )
       
       IF X0R - X_MaxW / 4 <= X1 .AND. X1 <= X0R + X_MaxW / 4
       IF Y0R - Y_MaxW / 2 <= Y1 .AND. Y1 <= Y0R + Y_MaxW / 2
          SetPixel(hDC2, X1, Y1, fColor)
       ENDIF
       ENDIF

   NEXT

*  cFileName = ConvToAnsiCP("Спектр в форме спирали.bmp")
*  DC_Scrn2ImageFile( oStatic, cFileName )

RETURN nil


* ----------

FUNCTION TransferImageOld( hDC1, hDC2, aPixel )

LOCAL i, j, nColor, lEmptyArray := aPixel[1,1] == nil, ;
      nXSize := Len(aPixel), nYSize := Len(aPixel[1])

FOR i := 0 TO nXSize-1
  FOR j := 0 TO nYSize-1
    IF lEmptyArray
      SetPixel(hDC2,i,j,GetPixel(hDC1,i,j))
    ELSE
      SetPixel(hDC2,i,j,aPixel[i+1,j+1])
    ENDIF
  NEXT
NEXT

RETURN nil

* ----------

FUNCTION TransferImage( hDC1, hDC2, aPixel )

LOCAL i, j, nColor, lEmptyArray := aPixel[1,1] == nil, ;
      nXSize := Len(aPixel), nYSize := Len(aPixel[1])

   X0R = X_MaxW * 3 / 4             // Для правого изображения
   Y0R = Y_MaxW     / 2 

FOR i := 0 TO nXSize-1
    FOR j := 0 TO nYSize-1
        IF lEmptyArray
           SetPixel(hDC2,X0R+i-nXSize/2, Y0R+j-nYSize/2, GetPixel(hDC1, X0R+i-nXSize/2, Y0R+j-nYSize/2))
        ELSE
           SetPixel(hDC2, X0R+i-nXSize/2, Y0R+j-nYSize/2, aPixel[i+1,j+1])
        ENDIF
    NEXT
NEXT

RETURN nil

* ----------

FUNCTION FlipImage( hDC1, hDC2, aPixel )

LOCAL i, j, lEmptyArray := aPixel[1,1] == nil, ;
      nXSize := Len(aPixel), nYSize := Len(aPixel[1])

FOR i := 0 TO nXSize-1
  FOR j := 0 TO nYSize-1
    IF lEmptyArray
      SetPixel(hDC2,j,i,GetPixel(hDC1,j,nXSize-i))
    ELSE
      SetPixel(hDC2,j,i,aPixel[i+1,j+1])
    ENDIF
  NEXT
NEXT

RETURN nil

* ----------

FUNCTION RotateImage( hDC1, hDC2, aPixel )

LOCAL i,j, lEmptyArray := aPixel[1,1] == nil

FOR i := 0 TO nXSize-1
  FOR j := 0 TO nYSize-1
    IF lEmptyArray
      SetPixel(hDC2,i,j,GetPixel(hDC1,j,nXSize-i))
    ELSE
      SetPixel(hDC2,i,j,aPixel[j+1,nYSize-i])
    ENDIF
  NEXT
NEXT

RETURN nil

* ---------

PROC appsys ; RETURN

* ---------

STATIC FUNCTION ShowColor( hDC, aCoords, oSay, oStatic )

LOCAL nColor

aCoords[2] := oStatic:currentSize()[2] - aCoords[2]

nColor := GetPixel(hDC,aCoords[1],aCoords[2])

oSay:setCaption('Color: ' + DC_Array2String(GraGetRGBIntensity(AutomationTranslateColor(nColor,.T.))) + ;
   ' Coords: ' + DC_Array2String(aCoords))

RETURN nil

#command  GDIFUNCTION <Func>([<x,...>]) ;
       => ;
FUNCTION <Func>([<x>]);;
STATIC scHCall := nil ;;
IF scHCall == nil ;;
  IF snHdll == nil ;;
    snHDll := DllLoad('GDI32.DLL') ;;
  ENDIF ;;
  scHCall := DllPrepareCall(snHDll,DLL_STDCALL,<(Func)>) ;;
ENDIF ;;
RETURN DllExecuteCall(scHCall,<x>)

GDIFUNCTION GetPixel( nHDC, x, y)
GDIFUNCTION SetPixel( nHDC, x, y, n )
DLLFUNCTION GetWindowDC( hwnd ) USING STDCALL FROM USER32.DLL

*******************************************************************************

*******************************************************************************
* Calculates a RGB color value from RGB color intensities
*******************************************************************************
FUNCTION GraMakeRGBColor( aRGB )

   IF Valtype( aRGB ) <> "A" .OR. ;
      Len( aRGB )     <   3  .OR. ;
      AScan( aRGB, {|n| Valtype(n) <> "N" }, 1, 3 ) > 0
      RETURN NIL
   ENDIF

   aRGB[1] := Max( 0, Min( aRGB[1], 255 ) )
   aRGB[2] := Max( 0, Min( aRGB[2], 255 ) )
   aRGB[3] := Max( 0, Min( aRGB[3], 255 ) )

RETURN (aRGB[1] + (aRGB[2] * 256) + (aRGB[3] * 65536) + 16777216) 


*******************************************************************************
* Check if a numeric value is equivalent to a RGB-color value
*******************************************************************************
FUNCTION GraIsRGBColor( nRGBColor )

   IF Valtype( nRGBColor ) <> "N"
      RETURN .F.
   ENDIF

RETURN ( nRGBColor > GRA_NUMCLR_RESERVED .AND. nRGBColor - 16777216 >= 0  ) 


*******************************************************************************
* Check if a numeric value is equivalent to a RGB-color value
*******************************************************************************
FUNCTION GraGetRGBIntensity( nRGBColor )

   LOCAL aRGB[3]

   IF .NOT. GraIsRGBColor( nRGBColor )
      RETURN NIL
   ENDIF

   aRGB[1] := nRGBColor - 16777216     
   aRGB[3] := Int(aRGB[1] / 65536)

   aRGB[1] -= aRGB[3] * 65536    
   aRGB[2] := Int(aRGB[1] / 256)  

   aRGB[1] -= aRGB[2] * 256 

RETURN aRGB

*******************************************************************************

**********************************************
******** ВИЗУАЛИЗАЦИЯ СПЕКТРА ****************
**********************************************
FUNCTION DrawSpectr(mNGrad)

   PRIVATE nEvent, mp1, mp2, oXbp                      // Переменные анализа событий

   PUBLIC X_MaxW := 1313, Y_MaxW := 640                // Размер графического окна для самого графика в пикселях

   @ 2,1 DCSTATIC TYPE XBPSTATIC_TYPE_RECESSEDBOX SIZE X_MaxW+11, Y_MaxW+20 PIXEL; // Размер окна в пикселях (от Тома)
         OBJECT oStatic;
         EVAL {|| _PresSpaceSpectr(oStatic, mNGrad) }

   DCREAD GUI ;
      TITLE "Рисование спектра в системе ЭЙДОС-X++";   // Надпись на окне графика
      FIT ;
      BUTTONS DCGUI_BUTTON_EXIT

RETURN NIL
*************************************************
STATIC FUNCTION _PresSpaceSpectr( oStatic, mNGrad )

   LOCAL oPS, oDevice

   PUBLIC X_MaxW := 1313, Y_MaxW := 640                // Размер графического окна для самого графика в пикселях

   oPS := XbpPresSpace():new()         // Create a PS
   oDevice := oStatic:winDevice()      // Get the device context
   oPS:create( oDevice )               // Link device context to PS
   oPS:SetViewPort( { 0, 0, X_MaxW, Y_MaxW } )
   oStatic:paint := {|mp1,mp2,obj| mp1 := LC_DrawSpectr( oPS, mNGrad ) }

RETURN NIL

*******************************************************
STATIC FUNCTION LC_DrawSpectr(oPS, mNGrad )

   PRIVATE X0 := 0 + X_MaxW/2
   PRIVATE Y0 := 5 + Y_MaxW/2                          // Начало координат по осям X и Y

   PRIVATE W_Wind := X_MaxW - X0                       // Ширина окна для самого графика
   PRIVATE H_Wind := Y_MaxW - Y0                       // Высота окна для самого графика

   PRIVATE Kx := W_Wind / ( mNGrad )                   // Коэффициент масштабирования по оси X: преобразует аргумент функции в номер пикселя по оси X
   PRIVATE Ky := H_Wind / ( mNGrad )                   // Коэффициент масштабирования по оси Y: преобразует значение функции в номер пикселя по оси Y

   **** Написать заголовок диаграммы

   aFonts := XbpFont():new():list()                    // Все доступные шрифты

   oFont := XbpFont():new():create("14.Arial Bold")
   GraSetFont(oPS , oFont)                             // установить шрифт
   aAttrF := ARRAY( GRA_AS_COUNT ) 
   aAttrF [ GRA_AS_COLOR      ] := GRA_CLR_BLACK 
   aAttrF [ GRA_AS_HORIZALIGN ] := GRA_HALIGN_CENTER   // Выравнивание символов по горизонтали по центру относительно точки начала вывода
   aAttrF [ GRA_AS_VERTALIGN  ] := GRA_VALIGN_HALF     // Выравнивание символов по вертикали по средней линии относительно точки начала вывода
   GraSetAttrString( oPS, aAttrF )                     // Установить символьные атрибуты

   mTitle = 'СПЕКТР ИЗ '+ALLTRIM(STR(mNGrad))+' ЦВЕТОВ В ФОРМЕ СПИРАЛИ АРХИМЕДА'
   aTxtPar = DC_GraQueryTextbox(mTitle, oFont)         // {101,16} Определяет длину и высоту текста в пикселях для некоторых шрифтов
*  MsgBox("Длина текста в пикселях="+ALLTRIM(STR(aTxtPar[1]))+". Высота текста в пикселях="+ALLTRIM(STR(aTxtPar[2])))
   GraStringAt( oPS, { X_MaxW/2, Y_MaxW+aTxtPar[2]+5 }, mTitle)



   ******* Гармонические последовательности цветов

   Column = 0

   FOR n = mNGrad TO mNGrad * 60 / 360 STEP -Delta

       ma := 127
       mb := 127
       mc := 127

       mU := 0
       mV := 120
       mW := 240

       mColor = INT( n / mNGrad * 360 )

       R := INT( ma * (1 + COS( ( mColor + mU ) * 3.14159265358979323846 / 180 ) ) )
       G := INT( mb * (1 + COS( ( mColor + mV ) * 3.14159265358979323846 / 180 ) ) )
       B := INT( mc * (1 + COS( ( mColor + mW ) * 3.14159265358979323846 / 180 ) ) )

       fColor := GraMakeRGBColor({ R, G, B })

       ***** Закрасить фон прямоугольника ***************

       GraSetColor( oPS, fColor, fColor )

       Column = Column + Delta

       X1 := X0 + Ax * Column * COS((Column-1) * 3.14159265358979323846 / 180 ) * Kx
       Y1 := Y0 + Ay * Column * SIN((Column-1) * 3.14159265358979323846 / 180 ) * Ky

       GraArc( oPS, { X1, Y1 }, RS, ,,, GRA_OUTLINEFILL )

   NEXT

   cFileName = ConvToAnsiCP("Спектр в форме спирали.bmp")
   DC_Scrn2ImageFile( oStatic, cFileName )


RETURN NIL

******** Display a warning message
******** Может выдавать сообщения элементами массива и без ctitle:

*message := {}
*AADD(message,'1-е сообщение')
*AADD(message,'2-е сообщение')
*AADD(message,'3-е сообщение')
*LB_Warning( message )

FUNCTION LB_Warning( message, ctitle )

  LOCAL aMsg := {}
  DEFAULT cTitle TO ''
  IF valtype(message) # 'A'
    aadd(aMsg,message)
  ELSE
    aMsg := message
  ENDIF
  IF LEN(ALLTRIM(cTitle)) > 0
     DC_MsgBox( ,,aMsg,cTitle)
  ELSE
     DC_MsgBox( ,,aMsg,'(C) Универсальная когнитивная аналитическая система "Эйдос-Х++"')
  ENDIF

RETURN NIL

*******************************************************
[/size]

Post Reply