Harmonic sequence of colors in the RGB

This forum is for eXpress++ general support.
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:

Re: Harmonic sequence of colors in the RGB

#11 Post by Eugene Lutsenko »

In this case, the gradient is not suitable, because I want to display the different values of the variables in the form of their respective colors, such as cartographic database. But in other cases, the gradient can be very useful.

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

Re: Harmonic sequence of colors in the RGB

#12 Post by Eugene Lutsenko »

And I have a question, how to make bright saturated colors by controlling the brightness of rays of RGB. And then I get some greyish

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

Re: Harmonic sequence of colors in the RGB

#13 Post by Eugene Lutsenko »

Well, it worked out! Many thanks to all for your support!
Image

Code: Select all

PROCEDURE AppSys
// Рабочий стол остается окном приложения
RETURN

********************************************************************************
FUNCTION Main()

LOCAL  GetList[0], GetOptions, nColor, oMessageBox, oMenuWords, oDlg, ;
       oMenuBar,oMenu1,oMenu2,oMenu3,oMenu4,oMenu5,oMenu6,oMenu7,;
       oMenu3_3, nKey := 0

DC_IconDefault(1000)


mNGrad = 72

@0,0 DCGROUP oGroup1 CAPTION 'Задайте число градаций:' SIZE 47.0, 3.5
@1,4 DCGET mNGrad PARENT oGroup1 

DCREAD GUI;
      TO lExit ;
      FIT;
      ADDBUTTONS;
      MODAL;
      TITLE "Рисование спектра в системе ЭЙДОС-X++"

********************************************************************
      IF lExit
         ** Button Ok
      ELSE
         QUIT
      ENDIF
********************************************************************

  IF mNGrad > 360

     aMess := {}
     AADD(aMess, 'Задано недопустимое число градаций угла: '+ALLTRIM(STR(mNGrad))+',')
     AADD(aMess, 'Поэтому оно принято максимальным допустимым: = 360.')
     LB_Warning(aMess, 'Система "Эйдос"')

     mNGrad = 360

  ENDIF


DrawSpectr(mNGrad)

RETURN NIL


*******************************************************************************
* 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 := 25
   PRIVATE Y0 := 25                                    // Начало координат по осям 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 / ( 100 )                      // Коэффициент масштабирования по оси 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)

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

   Delta = INT( 360 / mNGrad )

   Column = 0

   FOR n = 359 TO 0 STEP -Delta


       a = 127
       b = 127
       c = 127

       U = 0
       V = 120
       W = 240

       R = INT( a * (1 + COS( ( n + U ) * 3.14159265358979323846 / 180 ) ) )
       G = INT( b * (1 + COS( ( n + V ) * 3.14159265358979323846 / 180 ) ) )
       B = INT( c * (1 + COS( ( n + W ) * 3.14159265358979323846 / 180 ) ) )

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

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

       GraSetColor( oPS, fColor, fColor )

       ++Column
       X1 := X0 + (Column-1) * Kx
       Y1 := Y0
       X2 := X0 +  Column    * Kx
       Y2 := Y0 +       100  * Ky

       GraBox( oPS, { X1, Y1 }, { X2, Y2 }, GRA_FILL) 

   NEXT

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]
Last edited by Eugene Lutsenko on Tue Jun 16, 2015 10:15 pm, edited 1 time in total.

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

Re: Harmonic sequence of colors in the RGB

#14 Post by rdonnay »

Very good work. Congratulations!!
The eXpress train is coming - and it has more cars.

User avatar
Auge_Ohr
Posts: 1428
Joined: Wed Feb 24, 2010 3:44 pm

Re: Harmonic sequence of colors in the RGB

#15 Post by Auge_Ohr »

yes, that is nice :clap:

when compile with /W ( recommend ! ) i got a "Problem" with Memvar Declaration : "b" <-> "B"
Eugene Lutsenko wrote:

Code: Select all

   FOR n = 359 TO 0 STEP -Delta
       a = 127
       b := 127    // -> here "b"
       c = 127
       ...
       R = INT( a * (1 + COS( ( n + U ) * 3.14159265358979323846 / 180 ) ) )
       G = INT( b * (1 + COS( ( n + V ) * 3.14159265358979323846 / 180 ) ) )
       // -> here "B"
       B := INT( c * (1 + COS( ( n + W ) * 3.14159265358979323846 / 180 ) ) )
      
       ...
   NEXT
i also recommend to use ":=" ( not only "=" ) when assign Data to (local) Variable.

when using small "-Delta" Value try :lockPS() / :unlockPS() to speedup GRA* Function.
greetings by OHR
Jimmy

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

Re: Harmonic sequence of colors in the RGB

#16 Post by Eugene Lutsenko »

Thank you! It is strange that it generally worked. After all, "b" and "B" - it's almost the same thing. I have no compiler errors were not. What specifically can be used: :lockPS()/:unlockPS()?

Code: Select all

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

   Delta = INT( 360 / mNGrad )

   Column = 0

   FOR n = 359 TO 0 STEP -Delta


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

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

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

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

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

       GraSetColor( oPS, fColor, fColor )

       ++Column
       X1 := X0 + (Column-1) * Kx
       Y1 := Y0
       X2 := X0 +  Column    * Kx
       Y2 := Y0 +       100  * Ky

       GraBox( oPS, { X1, Y1 }, { X2, Y2 }, GRA_FILL) 

   NEXT
[/size]

User avatar
Auge_Ohr
Posts: 1428
Joined: Wed Feb 24, 2010 3:44 pm

Re: Harmonic sequence of colors in the RGB

#17 Post by Auge_Ohr »

Eugene Lutsenko wrote:Thank you! It is strange that it generally worked. After all, "b" and "B" - it's almost the same thing. I have no compiler errors were not.
did you compile with /w ?

Code: Select all

    COMPILE_FLAGS = /q /w
Eugene Lutsenko wrote:What specifically can be used: :lockPS()/:unlockPS()?
when use a XbpStatic you do not need a "extra" XbpPresspace().

Code: Select all

   oStatic := XbpStatic():new( oDraw,, {10, 10},  aSize )
   oStatic:paint := {|aRect, uNIL, oSelf | CALC(oSelf) }
   oStatic:create()
...

PROCEDURE CALC(oSelf)
LOCAL oPS
...
   oPS := oSelf:lockPS()
   //
   // here GRA*(oPS ... )
   //
   oSelf:unlockPS()

RETURN
Eugene Lutsenko wrote:

Code: Select all

       mV := 120
       mW := 240
compare to 1st Mail Picture you have to change mV <-> mW to get same Color
greetings by OHR
Jimmy

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

Re: Harmonic sequence of colors in the RGB

#18 Post by Eugene Lutsenko »

I compile using bat file:

Code: Select all

CLS
ARC _Aidos.arc
XPP %1
ALINK %1 _Aidos.res /PM:PM
I try this option as you advise:

Code: Select all

CLS
ARC _Aidos.arc
COMPILE_FLAGS = /q /w
XPP %1
ALINK %1 _Aidos.res /PM:PM
It seems to work, too.

And remove excess XbpPresSpace () I do not quickly get out of my overload at work. But in general, it would be interesting.

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

Re: Harmonic sequence of colors in the RGB

#19 Post by Eugene Lutsenko »

Auge_Ohr wrote:as i see you use a FOR / NEXT to paint these Colors ... how long does it take ?

if you just want that shown Colors it does not make Sence to "calculate" Color between
RED/PINK - PINK/BLUE - BLUE/CYAN - CYAN/GREEN - GREEN/YELLOW - YELLOW-RED.

this Sample use GraGradient
HS_RGB_Gradient.JPG
HS_RGB.ZIP
Hi, Jimmy!

A similar function has a GraGradient() that can fill the triangle vertices by color? It is necessary to fill the Delaunay triangulation.

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

Re: Harmonic sequence of colors in the RGB

#20 Post by Eugene Lutsenko »

I figure out how to do it with the help of linear algebra and analytic geometry. If we consider RGB tops the coordinates in space, you can use the equation to calculate the plane coordinates of any point in the triangle. It remains only to display all the points. To do this, use a conformal mapping color space in geometric

Post Reply