Frumusețea este o putere teribilă.
În acest articol, am în vedere mai multe moduri de a face forma frumoasă. Exemplele discutate aici sunt mai estetice decât valoarea practică, dar cred că pot fi utilizate în proiectarea de ferestre, dragi cititori, programul. Pentru înregistrarea voi discuta mai multe moduri de forme gradient de inundare (un exemplu de astfel de turnare - instalatori, în care utilizatorul admiră o fereastră frumoasă, în timp ce programul face treaba murdara). În diverse Faq am văzut exemple, se toarnă o formă - fie un gradient, și există componente care utilizează un gradient umple de înregistrare (de exemplu, TRxGradientCaption de RxLib), dar articole, sistematizrii informații cu privire la acest subiect nu am văzut. Deci, sper că acest material vă va fi de folos.
Pentru a umple panza (Canvas) forma I folosesc cod, baza pe care l-am luat de la onorabilul FAQ Nomadic'a Ozerovskogo. Codul am convertit un eveniment OnPaint (de exemplu, în Nomadic'a a fost plasat temporizator și FormCreate obrabatyvlis, Timer.OnTimer, FormDestroy). Iată codul:
procedura TForm1.FormPaint (expeditor: TObject);
tip TRGB = înregistrare
b, g, r: octet;
se încheie;
ARGB = array [0..1] din TRGB;
PARGB = ARGB;
var
b: TBitMap;
p: PARGB;
x, y: întreg;
începe
b: = TBitMap.Create;
b.pixelformat: = pf24bit;
b.width: = Clientwidth;
b.height: = clientheight;
pentru y: = 0 la b.height-1 nu
începe
p: = b.scanline [y];
pentru x: = 0 până la b.width-1
începe
// modificăm această parte a codului
p [x] .r: = aleatoriu (256);
p [x] .g: = aleatoriu (256);
p [x] .b: = aleatoriu (256);
se încheie;
se încheie;
canvas.draw (0,0, b);
b.free;
se încheie;
p [x], r: = 255;
p [x] .g: = 255;
p [x] .b: = - 255 * x div b. lățime;
Atunci când se aplică o umplutură orizontală, trebuie luat în considerare faptul că un obiect gol umplut pare instabil și trebuie să fie echilibrat prin plasarea de ceva pe el (figura 3).
Vărsarea verticală nu este mult mai dificilă. Pentru a face acest lucru, trebuie să modificați culorile nu prin x, ci prin y. De exemplu, următorul cod ne va da o umplutură alb-albastră (atât de iubită de instalatori) (Figura 4).
p [x] .r: = 255 * y div b.Înălțime;
p [x] .g: = 255 * y div b.Înălțime;
p [x] b: = 255;
Notă - pentru a obține un gradient albastru-alb, schimba culorile roșu și verde, iar cel albastru rămâne neschimbat. În general, cred că obținerea unei culori corecte este una dintre cele mai delicate întrebări din acest subiect și mă voi întoarce la ea la sfârșitul acestui articol.
Un efect chiar mai frumos poate fi atins prin impunerea unor gradienti unul pe altul. De exemplu, schimbând culoarea roșie de-a lungul verticalei și verticale verticale, obținem următoarea imagine (Figura 5)
p [x] .r: = 255 * y div b.Înălțime;
p [x] .g: = 255 * x div b.Lățime;
p [x] b: = 255;
Gradientul rezultat poate primi o structură granulară schimbând una sau mai multe culori primare aleatoriu. Ce puteți spune despre umplerile din figurile 6 și 7? p [x] .r: = aleatoriu (250);
p [x] .g: = 255;
p [x] .b: = 255 * x div b.Lățime; (Figura 6)
p [x] .r: = aleatoriu (250);
p [x] .g: = 255 * y div b.Înălțime;
p [x] .b: = 255 * x div b.Lățime; (Figura 7)
Pentru a obține o distribuție mai complexă a gradientului în formă, va trebui să utilizați formule mai complexe la atribuirea valorilor de culoare. Luați în considerare primirea umplerii "către centru". Culoarea evident variabilă ar trebui să scadă sau să crească de la marginea până la centrul formei și apoi să se schimbe în ordine inversă. Acest lucru poate fi realizat cu ajutorul unui operator condițional (o metodă mai vizuală) (figura 8).
p [x] r: = 0;
dacă y <= b.Height div 2
apoi p [x] .g: = 255 * y * 2 div b.Înălțime
altfel p [x] .g: = - 255 * y * 2 div b.Height;
dacă abs (y - b.Height div 2)<3 then p[x].g:=255;
p [x] b: = 200;
O modalitate mai complicată este de a crea o funcție care să schimbe culoarea în mod corect. Pentru exemplul următor, avem nevoie de funcția Sgn:
funcția Sgn (i: integer): integer;
începe
dacă i<>0 apoi Sgn: = rotund (i / abs (i))
altfel Sgn: = 1
se încheie;
Funcția de semnare din modulul Math nu funcționează; returnează 0 cu valoarea 0.
Următorul cod dă această opțiune (Figura 9):
p [x] r = 150;
p [x] .g: = Sgn (b.Lățime div 2-x) * (255 * x * 2 div b.Lățime);
p [x] b: = 50;
Figura 9a prezintă rezultatul înlocuirii funcției Sgn, pe care am definit-o cu funcția Semnare din modulul Math. O revenire zero are ca rezultat o bandă în mijlocul formularului.
Combinând metodele de umplere, puteți obține o formă a cărei formă va uimi toată lumea, inclusiv creatorul (fig.10-12).
p [x] r = = 50;
p [x] .g: = sgn (b.Lățime div 2-x) * (255 * x * 2 div b.Lățime);
p [x] .b: = sgn (b.Height div 2-y) * (255 * y * 2 div b.Height);
<Зелёная составляющая изменяется к центру по горизонтали, а синяя по вертикали> (Figura 10)
p [x] .r: = 150 * x div b.Lățime;
p [x] .g: = sgn (b.Lățime div 2-x) * (255 * x * 2 div b.Lățime);
p [x] .b: = 155 * y div b.Înălțime;
(Figura 11)
p [x] .r: = 150 * x div b.Lățime;
p [x] .g: = sgn (b.Lățime div 2-x) * (255 * x * 2 div b.Lățime);
p [x] .b: = 155 + aleator (100);
(Figura 12)
Nu ești intrigat de numărul 255, care este prezent în formule? Evident, reducerea acesteia putem schimba culoarea, cu care, pentru a începe de umplere, dar crește numărul de clienți potențiali la un efect interesant de „jaluzele“ - gradientului duplicarea completați formularul (Figura 13).
p [x] r: = 0;
p [x] .g: = 255 * 4 * y div b.Înălțime;
p [x], b: = 155;
Aici nu am scris 1020 în loc de 255 * 4, așa că am putut vedea unde provin cele patru "valuri" de la umplutura de gradient.
Un alt efect (Figura 14) - undele de gradient trecând fără probleme sunt obținute cu ajutorul următorului cod, mai degrabă ciudat:
p [x] g: = 0;
dacă (x <= b.Width div 4) or ((x <= 3*b.Width div 4) and (x>= b.Lățimea div 2))
apoi p [x] .r: = 255 * x * 4 div b.Lățime
altfel p [x] .r: = - 255 * x * 4 div b.Lățime;
dacă abs (x - b.Lățime div 2)<3 then p[x].r:=0;
dacă (abs (x -b.Lățime div 4)<3) or (abs(x - 3*b.Width div 4)<3) then p[x].r:=255;
p [x] b: = 0;
Cu toate acestea, acest efect va fi obținut la sfârșitul articolului într-un mod diferit, mai simplu.
Așa că ai o formă frumoasă și ai început să-i schimbi dimensiunea. Iar aici vă veți confrunta cu un efect urât - artefactele provenite din turnare sunt imprimate pe formular (fig.15).
Există multe modalități de a corecta această situație. Să folosim cele mai evidente dintre ele:
procedura TForm1.FormResize (expeditor: TObject);
începe
form1.DoubleBuffered: = adevărat;
form1.Repaint;
se încheie;
Acum, când redimensionați formularul, aspectul umplerii nu se schimbă.
Următoarea întrebare care nu poate fi ignorată în acest articol este alegerea culorilor pentru crearea unui gradient. Pentru a-l studia în general, trebuie să aveți o idee despre modelul de culoare RGB. Trecerea de culoare a gradientului este o curbă în acest model, a cărei ecuație trebuie specificată în program. Studiul modelului de culoare și crearea unui gradient de culoare arbitrar nu este o sarcină pentru articol. Aici analizăm modul de obținere a unei tranziții în două culori. Destul de înțelept soluția pentru culorile primare (roșu, albastru, verde) și amestecurile acestora. Deci, RG dă o culoare galbenă, RB - violet, GB - azur. De exemplu, pentru a obține o întindere galben-albastră, trebuie să schimbați B de la 255 la 0, R și G de la 0 la 255 - ca aceasta (Figura 16).
p [x] .g: = 255 * y div b.Înălțime;
p [x] .b: = -255 * y div b.Înălțime;
Pentru a obține o întindere de culoare arbitrară, propun următoarea procedură.
După ce ați determinat vizual vizual valorile culorilor dorite (de exemplu, utilizând fereastra de selectare a culorilor), înlocuiți-le cu locația dorită și determinați direcția umplerii.
Image1.Stretch: = adevărat // undeva, poți la etapa de proiectare.