I drew attention to the fact that the image of the high-frequency part of the spectrum in the harmonic color does not match the intuitive expectations. Namely - the spectrum is too far away in the purple area:

I tried just did not show extreme color right. It turns out that if you do not use the 360 and 270, it turns out, we are more familiar and understandable:
Code: Select all
******* Гармонические последовательности цветов
Delta = INT( 360 / mNGrad )
Column = 0
FOR n = 359 TO 90 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]
The truth is I do not understand how to display numeric values in this limited the right of the spectrum.
Once I painted in a limited range of the spiral of Archimedes (default settings):
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)
p = 32
mNGrad = 3600 // Число точек
Ax = 1
Ay = 1
Delta = 0.1 // Шаг аргумента
RS = 7 // Радиус цветного кружочка
@0,0 DCGROUP oGroup1 CAPTION 'Задайте параметры:' SIZE 45.0, 6.5
@ 1, 2 DCSAY 'Число точек:' PARENT oGroup1
@ 1, p DCGET mNGrad PARENT oGroup1 PICTURE "#########"
@ 2, 2 DCSAY 'Амплитуда по X:' PARENT oGroup1
@ 2, p DCGET Ax PARENT oGroup1 PICTURE "###.#####"
@ 3, 2 DCSAY 'Амплитуда по Y:' PARENT oGroup1
@ 3, p DCGET Ay PARENT oGroup1 PICTURE "###.#####"
@ 4, 2 DCSAY 'Шаг аргумента:' PARENT oGroup1
@ 4, p DCGET Delta PARENT oGroup1 PICTURE "###.#####"
@ 5, 2 DCSAY 'радиус точки:' PARENT oGroup1
@ 5, p DCGET RS PARENT oGroup1 PICTURE "###.#####"
DCREAD GUI;
TO lExit ;
FIT;
ADDBUTTONS;
MODAL;
TITLE "Спектра в системе ЭЙДОС-X++"
********************************************************************
IF lExit
** Button Ok
ELSE
QUIT
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 := 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 * 90 / 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
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]
Maybe in a couple of thousands of years it will be possible to enjoy all the harmonic colors and do not have to limit the range of 270 degrees?
http://serendip.brynmawr.edu/exchange/node/61