-
Не подскажет ли кто алгоритм градиентной линейной заливки, но не горизонтальной или вертикальной, он есть, а с произвольным углом Alfa?
-
школьные знания по геометрии должны пригодиться.
-
Аналогичным образом я мог бы отвечать абсолютно на все вопросы форума.
-
>Аналогичным образом я мог бы отвечать абсолютно на все вопросы форума. Попробуй
homm © прав градиентная заливка по горизонтали или по вертикали по сути есть зависимость цвета от одной координаты. В случае диагонали зависимость будет от двух координат. С Пифагором вместе не служили?
-
>Не подскажет ли кто алгоритм градиентной линейной заливки, но не горизонтальной или вертикальной, он есть, а с произвольным углом Alfa?
А где должен быть чисто первый цвет и чисто второй?
-
Есть алгоритм рисования линии по клеткам(как в школьной тетрадке) реализуй его, а цвет меняй сам что бы плавно изменялся от начала к концу
-
> [5] ha (14.09.07 13:59)
Что-бы потом тот, кто такой код увидит, руки оторвал тому, кто его напишет :)
-
Бабах! %)) procedure Draw_GradientAngle(canvas:Tcanvas; _Rect:Trect; const Color_start,Color_end:Tcolor;angle:double);
const
Pixels = MaxInt div SizeOf(TRGBTriple);
type
PRGBArray = ^TRGBArray;
TRGBArray = array[0..Pixels-1] of TRGBTriple;
var _F_shadow_Bitmap:Tbitmap; x, y: Integer; Row1: PRGBArray;
rc1, rc2, gc1, gc2, bc1, bc2:integer;
long:double;
_r,_b,_g:integer;
begin
_F_shadow_Bitmap:=Tbitmap.Create;
try
_F_shadow_Bitmap.PixelFormat:=pf24bit;
_F_shadow_Bitmap.Width:=_Rect.Right-_Rect.Left;
_F_shadow_Bitmap.Height:=_Rect.Bottom-_Rect.Top;
rc1 := GetRValue(Color_start); gc1 := GetGValue(Color_start); bc1 := GetBValue(Color_start);
rc2 := GetRValue(Color_end); gc2 := GetGValue(Color_end); bc2 := GetBValue(Color_end);
rc2:=rc2-rc1;
gc2:=gc2-gc1;
bc2:=bc2-bc1;
long:= (abs(GetTrace(0,0,(_Rect.Right-_Rect.Left)div 2,(_Rect.Bottom-_Rect.Top) div 2)*sin(angle)))/2;
messagedlg(floattostr(long),mterror,[mbOK],0);
for Y := 0 to _F_shadow_Bitmap.Height - 1 do begin
Row1:= _F_shadow_Bitmap.ScanLine[y];
for x := 0 to _F_shadow_Bitmap.Width -1 do begin
_r:=trunc(rc1+rc2*(((GetTrace(_F_shadow_Bitmap.Width div 2,_F_shadow_Bitmap.Height div 2,x,y)*cos(angle-(Getpos2Angle(_F_shadow_Bitmap.Width div 2,_F_shadow_Bitmap.Height div 2,x,y))))+1)/long));
if _r>255 then _r:=255 else if _r<0 then _r:=0;
_g:=trunc(gc1+gc2*(((GetTrace(_F_shadow_Bitmap.Width div 2,_F_shadow_Bitmap.Height div 2,x,y)*cos(angle-(Getpos2Angle(_F_shadow_Bitmap.Width div 2,_F_shadow_Bitmap.Height div 2,x,y))))+1)/long));
if _g>255 then _g:=255 else if _g<0 then _g:=0;
_b:=trunc(bc1+bc2*(((GetTrace(_F_shadow_Bitmap.Width div 2,_F_shadow_Bitmap.Height div 2,x,y)*cos(angle-(Getpos2Angle(_F_shadow_Bitmap.Width div 2,_F_shadow_Bitmap.Height div 2,x,y))))+1)/long));
if _b>255 then _b:=255 else if _b<0 then _b:=0;
Row1[x].rgbtRed:=_r;
Row1[x].rgbtGreen:=_g;
Row1[x].rgbtBlue:=_b;
end;
end;
canvas.CopyRect(_Rect,_F_shadow_Bitmap.Canvas,_F_shadow_Bitmap.Canvas.ClipRect);
finally
_F_shadow_Bitmap.Free;
end;
end; юзать: Draw_GradientAngle(paintbox1.Canvas,rect(0,0,paintbox1.Width,paintbox1.Height),c lwhite,clblack,-pi/2);
-
ой, я там забыл почистить %)))
-
+ [7]function Getpos2Angle(x1,y1,x2,y2:real):real;
begin
if x1=x2 then begin
if y1>y2 then
result:=pi/2 else result:=3*pi/2;
exit;
end;
result:=ArcTan((y1-Y2)/(X1-x2));
if (X1-x2)<0 then result:=result-pi;
end;
function GetTrace(x1,y1,x2,y2:real):real;
begin
result:=(sqrt(sqr(x1-x2)+sqr(y1-y2)));
end;
-
> antonn ©
ужос какой то
-
> ужос какой то
согласен, но все же лучше, чем размышления, что школьный курс геометрии может пригодиться :)
-
> [11] antonn © (14.09.07 17:33) > согласен, но все же лучше, чем размышления, что школьный > курс геометрии может пригодиться :)
Вот по этому я промолчал, когда увидел твой код :)
-
> [11] antonn © (14.09.07 17:33)
Хрень полную рисует, если честно :(
-
в натуре... ехе не перекомпилил и запостил, щас исправлю:)
-
-
>Jimmy (12.09.07 22:48)
procedure DrawAngleGradient(aCanvas: TCanvas; aRect: TRect; aColor1, aColor2: TColor; aAngle: Integer; aSteps: Integer = 256);
var
i, x1, y1, x2, y2, W, H: Integer;
Angle, Delta, SinA, CosA, TanA, C: Extended;
R, G, B, FromR, ToR, FromG, ToG, FromB, ToB: Byte;
begin
if (aAngle > 0) and (aAngle < 90) then begin
W := aRect.Right - aRect.Left;
H := aRect.Bottom - aRect.Top;
FromR := GetRValue(AColor1);
FromG := GetGValue(AColor1);
FromB := GetBValue(AColor1);
ToR := GetRValue(AColor2);
ToG := GetGValue(AColor2);
ToB := GetBValue(AColor2);
SinA := 0; CosA := 0; Delta := 1;
Angle := (aAngle * PI) / 180;
SinCos(Angle, SinA, CosA);
TanA := SinA / CosA;
C := (W + (H / TanA)) / CosA;
if C < aSteps then
aSteps := Round(C)
else
Delta := C / aSteps;
aCanvas.Pen.Style := psClear;
X1 := 0; Y1 := 0;
for i := 0 to aSteps - 1 do begin
X2 := aRect.Left + Round(Delta * CosA * (i + 1));
Y2 := aRect.Top + Round(X2 * TanA);
R := FromR + MulDiv(i, ToR - FromR, aSteps - 1);
G := FromG + MulDiv(i, ToG - FromG, aSteps - 1);
B := FromB + MulDiv(i, ToB - FromB, aSteps - 1);
aCanvas.Brush.Color := RGB(R, G, B);
aCanvas.Polygon([Point(X1, 0), Point(X2, 0), Point(0, Y2), Point(0, Y1)]);
X1 := X2; Y1 := Y2;
end
end
end;
-
procedure MyGradient(Can:TCanvas; ApplyRect:TRect; ColorFrom, ColorTo: TColor; Angle: Single);
type
ARGBQuad = array[0..0] of TRGBQuad;
var
Bmp: TBitmap;
Line: ^ARGBQuad;
i, j, i2: Integer;
Wi, He: DWORD;
s, c, t, t90, t_t90: Single;
L, R: Single;
dr, dg, db: Single;
Col: TColor;
inv: Boolean;
begin
Wi := ApplyRect.Right - ApplyRect.Left;
He := ApplyRect.Bottom - ApplyRect.Top;
Bmp := TBitmap.Create;
Bmp.HandleType := bmDIB;
Bmp.PixelFormat := pf32bit;
Bmp.Width := Wi;
Bmp.Height := He;
Angle := Angle*pi/180.0;
Angle := Angle - trunc(Angle/(pi*2))*(pi*2);
if Angle < 0 then
Angle := Angle + 2*pi;
inv := true;
if ((Angle > pi) and (Angle < pi*3/2)) or ((Angle > 0) and (Angle < pi/2)) then begin
inv := false;
Angle := pi - Angle;
end;
if (Angle > pi/2) and (Angle < pi) then begin
Col := ColorFrom;
ColorFrom := ColorTo;
ColorTo := Col;
end;
t := Tan(Angle);
t90 := Tan(Angle+pi/2.0);
t_t90 := t - t90;
L := (t*Wi-He);
L := L/(t_t90);
L := sqrt( sqr(L) + sqr(L*t90) );
dr := (TRGBQuad(ColorTo).rgbRed - TRGBQuad(ColorFrom).rgbRed)/L;
dg := (TRGBQuad(ColorTo).rgbGreen - TRGBQuad(ColorFrom).rgbGreen)/L;
db := (TRGBQuad(ColorTo).rgbBlue - TRGBQuad(ColorFrom).rgbBlue)/L;
for i := 0 to He-1 do begin
Line := Bmp.ScanLine[i];
if inv then i2 := i else i2 := He - i;
for j := 0 to Wi-1 do begin
R := (i2 - t90*j)/(t_t90);
R := sqrt( sqr(R-j) + sqr(R*t-i2) );
Line[j].rgbRed := TRGBQuad(ColorFrom).rgbRed + round(r*dr);
Line[j].rgbGreen := TRGBQuad(ColorFrom).rgbGreen + round(r*dg);
Line[j].rgbBlue := TRGBQuad(ColorFrom).rgbBlue + round(r*db);
end;
end;
BitBlt(Can.Handle, ApplyRect.Left, ApplyRect.Top, Wi, He, Bmp.Canvas.Handle, 0, 0, SRCCOPY);
Bmp.Free;
end;
-
Огромное спасибо to Lacmus! А также всем, кто пытается оказать реальную помощь!
-
Красный и синий канал были спутаны местами. procedure MyGradient(Can:TCanvas; ApplyRect:TRect; ColorFrom, ColorTo: TColor; Angle: Single);
type
ARGBQuad = array[0..0] of TRGBQuad;
var
Bmp: TBitmap;
Line: ^ARGBQuad;
i, j, i2: Integer;
Wi, He: DWORD;
s, c, t, t90, t_t90: Single;
L: Single;
dr, dg, db: Single;
r, g, b: byte;
Col: TColor;
inv: Boolean;
begin
Wi := ApplyRect.Right - ApplyRect.Left;
He := ApplyRect.Bottom - ApplyRect.Top;
Bmp := TBitmap.Create;
Bmp.HandleType := bmDIB;
Bmp.PixelFormat := pf32bit;
Bmp.Width := Wi;
Bmp.Height := He;
Angle := Angle*pi/180.0;
Angle := Angle - trunc(Angle/(pi*2))*(pi*2);
if Angle < 0 then
Angle := Angle + 2*pi;
inv := true;
if ((Angle > pi) and (Angle < pi*3/2)) or ((Angle > 0) and (Angle < pi/2)) then begin
inv := false;
Angle := pi - Angle;
end;
if (Angle > pi/2) and (Angle < pi) then begin
Col := ColorFrom;
ColorFrom := ColorTo;
ColorTo := Col;
end;
t := Tan(Angle);
t90 := Tan(Angle+pi/2.0);
t_t90 := t - t90;
L := (t*Wi-He);
L := L/(t_t90);
L := sqrt( sqr(L) + sqr(L*t90) );
ColorFrom := ColorToRGB(ColorFrom);
ColorTo := ColorToRGB(ColorTo);
r := GetRValue(ColorFrom);
g := GetGValue(ColorFrom);
b := GetbValue(ColorFrom);
dr := (GetRValue(ColorTo) - r)/L;
dg := (GetGValue(ColorTo) - g)/L;
db := (GetBValue(ColorTo) - b)/L;
for i := 0 to He-1 do begin
Line := Bmp.ScanLine[i];
if inv then i2 := i else i2 := He - i;
for j := 0 to Wi-1 do begin
L := (i2 - t90*j)/(t_t90);
L := sqrt( sqr(L-j) + sqr(L*t-i2) );
Line[j].rgbRed := r + round(L*dr);
Line[j].rgbGreen := g + round(L*dg);
Line[j].rgbBlue := b + round(L*db);
end;
end;
BitBlt(Can.Handle, ApplyRect.Left, ApplyRect.Top, Wi, He, Bmp.Canvas.Handle, 0, 0, SRCCOPY);
Bmp.Free;
end;
|