![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
поворот спрайта (програмно) [Delphi, Windows]
TButton © (2005-10-25 02:30:00)не совсем уверен, что знаю как реализовать сабж
для реализации не исползуется ни DX, ни OGL
просто софтварно
моё предположение
нужно вычислять полярные координаты кадого поворачиваемого пиксела
относительно точки поворота,
изменять угол на угол поворота
и выводить пиксель
но, боюсь появления гапов
(дырок в которую не попал ни один пиксель)
есть другие варианты (алгоритмы)?
OSokin (2005-11-01 18:33:00) [1]procedure DrawRotated(DC: HDC; Bitmap: HBitmap; X, Y: Integer; Angle: Real);
var
TempDC: HDC;
BmpSize: SIZE;
t: Real;
Points: Array[0..2] of TPoint;
Xc, Yc: integer;
begin
TempDC := CreateCompatibleDC(DC);
SelectObject(TempDC, Bitmap);
GetBitmapDimensionEx(Bitmap, BmpSize);
Xc := X + (BmpSize.cX div 2); //I'a`o~i^a"e`i` o"a*i'o`?
Yc := Y + (BmpSize.cY div 2);
t := Angle * 0.0174533;
Points[0].X := Round((X - Xc) * cos(t) - (Y - Yc) * sin(t) + Xc);
Points[0].Y := Round((Y - Yc) * cos(t) + (X - Xc) * sin(t) + Yc);
Points[1].X := Round((X + BmpSize.cX - Xc) * cos(t) - (Y - Yc) * sin(t) + Xc);
Points[1].Y := Round((Y - Yc) * cos(t) + (X + BmpSize.cX - Xc) * sin(t) + Yc);
Points[2].X := Round((X - Xc) * cos(t) - (Y + BmpSize.cY - Yc) * sin(t) + Xc);
Points[2].Y := Round((Y + BmpSize.cY - Yc) * cos(t) + (X - Xc) * sin(t) + Yc);
PlgBlt(DC, Points, TempDC, 0, 0, BmpSize.cX, BmpSize.cY, 0, 0, 0);
DeleteDC(TempDC);
end;
Antonn (2005-10-30 06:05:00) [2]или вот, "очеловеченая" процедурка из модуля(пост [1])
_SourceBitmap - поворачиываемый спрайт
_DestBitmap - битмап вывода
_x,_y - координаты левого верхнего угла выводимого спрайта на _DestBitmap
centerX,centerY - точка поворота(можно и не только относительно центра) _SourceBitmap
transparentColor - "прозрачный цвет"
_angle - угол поворота в радианах
procedureCopyRotateTransparentBitmap(_SourceBitmap,_DestBitmap: TBitmap; _x,_y,centerX,centerY:integer; transparentColor:Tcolor; _angle: Double);
constPixels = MaxInt divSizeOf(TRGBTriple);
typePRGBArray = ^TRGBArray;
TRGBArray = array[0..Pixels-1] ofTRGBTriple;
varcosRadians,sinRadians : Double;
x,y,x_cor,y_cor,x_corS,y_corS,inXOut,inXPr,inXRotated,inYOut,inYPr,inYRotated: Integer;
RowOut, RowIn: PRGBArray;
rc1, bc1, gc1:byte;
begin
if(_x)> _DestBitmap.Width-1 thenexit; if(_x+_DestBitmap.Width)< 0 thenexit; //проверки на "вхождение" хоть части вращаемого битмапа в выводимый
if(_y)> _DestBitmap.Height-1 thenexit; if(_y+_DestBitmap.Height)< 0 thenexit;
_SourceBitmap.PixelFormat:=pf24bit; //убрать, если изначально этот формат
_DestBitmap.PixelFormat:=pf24bit; //убрать, если изначально этот формат
sinRadians:=Sin(_angle);
cosRadians:=Cos(_angle);
if_x < 0 thenx_corS:=abs(_x) elsex_corS:=0; //находим TRect исходного битмапа, который будет выводится,
if_y < 0 theny_corS:=abs(_y) elsey_corS:=0; //на тот случай, если выводим вращающийся битмап скраю на выводимый
if(_x+_SourceBitmap.Width)> _DestBitmap.Width thenx_cor:=_x+_SourceBitmap.Width-_DestBitmap.Width elsex_cor:=0;
if(_y+_SourceBitmap.Height)> _DestBitmap.Height theny_cor:=_y+_SourceBitmap.Height-_DestBitmap.Height elsey_cor:=0;
rc1:=GetRValue(transparentColor); //цвет прозрачности, не копируется
gc1:=GetGValue(transparentColor);
bc1:=GetBValue(transparentColor);
forx:=_SourceBitmap.Height-1-y_cor downtoy_corS do begin
RowIn:=_SourceBitmap.Scanline[x+_y];
inXPr:=2*(x-centerY)+1;
fory:=_SourceBitmap.Width-1-x_cor downtox_corS do begin
inYPr:=2*(y-centerX)+1;
inYRotated:=Round(inYPr*CosRadians-inXPr*sinRadians);
inXRotated:=Round(inYPr*sinRadians+inXPr*cosRadians);
inYOut:=(inYRotated-1) div2 + centerX;
inXOut:=(inXRotated-1) div2 + centerY;
if(inYOut >=0) and(inYOut <=_SourceBitmap.Width-1) and(inXOut >=0) and(inXOut <=_SourceBitmap.Height-1) then begin
RowOut:=_SourceBitmap.Scanline[inXOut];
if not((RowOut[inYOut].rgbtRed=rc1) and(RowOut[inYOut].rgbtGreen=gc1) and(RowOut[inYOut].rgbtBlue=bc1)) then
RowIn[y+_x] := RowOut[inYOut];
end;
end;
end;
end;
Fenik (2005-10-30 00:38:00) [3]> TButton ©
посмотри это
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1129046372&n=9&from=29
TButton (2005-10-29 01:10:00) [4]
> Ну теперь разобрался, что прямое вообще не нужно?
да =) ещё раз спасибо =)
> http://www.delphimaster.ru/articles/pixels/index.html
собсна с этого я и начинал =)
MBo (2005-10-28 08:28:00) [5]>я понял твой пост, как
необходимость дополнять прямое мапирование обратным =)
Ну теперь разобрался, что прямое вообще не нужно?
Пример, правда, усложненный, есть в статье:
http://www.delphimaster.ru/articles/pixels/index.html
TButton (2005-10-28 08:17:00) [6]
> на произведение матриц афинного преобразования -переноса,
> поворота, и обратного переноса
я технарь, с высшей математикой - напряг
но в общих чертах понял =)
просто у нас ещё раньше возникло непонимание
я понял твой пост, как
необходимость дополнять прямое мапирование обратным =)
MBo (2005-10-28 06:55:00) [7]>TButton © (28.10.05 04:56) [13]
Еще раз повторю - обратное маппирование эффективнее, бесплатно избавляет от дырок.
А для прямого, если все же очень хочется -
XNew = XCenter + (XOld-XCenter)*Cos(fi) +(YOld-YCenter)*Sin(fi)
YNew=YCenter - (XOld-XCenter)*Sin(fi) + (YOld-YCenter)*Cos(fi)
Это фактически умножение исходного вектора (в однородных координатах)
(XOld, YOld, 1) на произведение матриц афинного преобразования -переноса, поворота, и обратного переноса
TButton (2005-10-28 04:56:00) [8]2 MBo
нифига не выйдет
для вычисления XNew мне понадобится YNew
и наоборот...
TButton (2005-10-28 04:39:00) [9]
> извращенцы блин. гуглить софтверную отрисовку (растеризацию)
> затекстуреных треугольников или rotozoom
> ускорение по сравнению с предложенными вариантами на порядок
3Д отсутствует напрочь
физически отсутствует
двиган ориентирован на чисто софтверный просчёт
и пиксельную графику
Zer0 (2005-10-28 02:38:00) [10]извращенцы блин. гуглить софтверную отрисовку (растеризацию) затекстуреных треугольников или rotozoom
ускорение по сравнению с предложенными вариантами на порядок
TButton (2005-10-26 14:52:00) [11]
> Из этих же формул можно выразить.
и действительно...
что-то я протупил с утра по-раньше
MBo (2005-10-26 07:33:00) [12]>а прямое без полярных как выглядит?
Из этих же формул можно выразить.
Будет почти тот же вид, только знаки слагаемых с синусами поменяются.
TButton (2005-10-26 00:53:00) [13]2 MBo
хм... я уже полярными замутил
починил я таки глюк с повышением частоты дискретизации
теперь каждый пиксель отрисовывается 4 раза
гапов нет, но потеря в скорости чувствуется
просто у меня модуль для работы с направлениями и расстояниями без дела валялся =)
> XOld = XCenter + (XNew-XCenter)*Cos(fi) - (YNew-YCenter)*Sin(fi)
> YNew=YCenter + (XNew-XCenter)*Sin(fi) + (YNew-YCenter)*Cos(fi)
а прямое без полярных как выглядит?
или достаточно ограничиться этим, обозначив зону поиска как окружность с радиусом равным половине диагонали спрайта?
MBo (2005-10-25 14:31:00) [14]Во второй строчке слева - YOld
MBo (2005-10-25 14:27:00) [15]>минус один - гапы...
Для избавления от них - делай обратное маппирование - т.е. для каждой точке новой картинки находи соотв. точку исходной.
Полярные координаты - не нужны, лишняя работа.
XOld = XCenter + (XNew-XCenter)*Cos(fi) - (YNew-YCenter)*Sin(fi)
YNew=YCenter + (XNew-XCenter)*Sin(fi) + (YNew-YCenter)*Cos(fi)
TButton (2005-10-25 13:24:00) [16]
> сам мучался, вот глянь то, что получилось:
я из тех, кто
> идут лесом:)
код поворота вообще никак не откоментирован
все в перемешку
в принципе
у меня всё работает
минус один - гапы...
попробовал увеличить дискретизацию вдвое
пока не помогло
гапы сменились глюками =)
JUS (2005-10-25 06:50:00) [17]А я вот панель сегодня до утра аж рисовал в Corel'е часов пять. Всё придумывал как что разместить, кое как закончил. Нарисовал красиво, аж неверится самому что это я сам нарисовал, самому нравится.
это я веткой ошибся, сорри!
JUS (2005-10-25 06:35:00) [18]Круто
JUS (2005-10-25 06:32:00) [19]Ща заценю.
А я вот панель сегодня до утра аж рисовал в Corel'е часов пять. Всё придумывал как что разместить, кое как закончил. Нарисовал красиво, аж неверится самому что это я сам нарисовал, самому нравится.
Antonn (2005-10-25 06:20:00) [20]сам мучался, вот глянь то, что получилось:
http://kladovka.net.ru/index.cgi?pid=list&rid=252