Войти
ПрограммированиеФорум2D графика и изометрия

Поворот спрайта

#0
22:23, 15 фев 2009

Вопрос очень лёгки, но мну забыл((
Подскажите формулу, чтоб повернуть спрайт за курсором, зная координаты мышки. Заранее спасибо)

#1
22:37, 15 фев 2009

kremedved

Все крутится вокруг этих вот формул

d = sqrt(x^2 + y^2)
x' = d * sin A
y' = d * cos A

Тебе судя по всему, нужно сделать обратное преобразование... кури функцию arcsin/arccos. И не забудь нормализовать получившийся угол.

Правка:

примерно вот так:

d=sqrt(fx*fx+fy*fy);

float tmp=fy/d;

if (tmp>1.) tmp=1.;
if (tmp<-1.) tmp=-1.;

a=acos(tmp)*57.2957795131;

if (fx/fy<0) a=360.0-a;

Еще правка:

Вышеприведенный код для случая, когда  объект, который нужно повернуть, находится в координатах x=0, y=0. Соответственно нужно корретировать координаты при расчётах, т.е. отнимать от координат мыши координаты объекта. И для скоректированных координат высчитывать угол, на который нужно повернуть объект.

#2
23:16, 15 фев 2009

Спасибо! Буду разбирацццо :)

#3
7:39, 16 фев 2009

oistalker

чегото я не понял.

сам пользуюсь арктангенсом.


#define M_PI        3.14159265358979323846f
#define M_2PI      6.28318530717958647692f
#define M_PI_2      1.57079632679489661923f
#define M_PI_15    4.712388980384689857693f

xlook --координаты курсора относительно спрайта (mouse_x - this.x )
ylook

zna -- полученый угол в радианах.  0 - смотрит ровно вправо.

if (ylook==0) //защита от деления на 0.
{
if (xlook >= 0)
  zna = 0.0f;
else
  zna = M_PI;
}
else if (ylook > 0)
{
  zna = -atan ( xlook / ylook) + M_PI_2;
}
else
{
  zna = -atan ( xlook / ylook) + M_PI_15;
}

#4
16:36, 16 фев 2009

Белеберда какая-то получаеться...

private double RotationAngle = 0f;



Viewport viewport = graphics.GraphicsDevice.Viewport;
            origin.X = player.Width / 2;
            origin.Y = player.Height / 2;
            screenpos.X = viewport.Width / 2;
            screenpos.Y = viewport.Height / 2;





            mx = mouseState.X;
            my = mouseState.Y;

            xlook = mx - graphics.GraphicsDevice.Viewport.X;
            ylook = my - graphics.GraphicsDevice.Viewport.Y;

            if (ylook == 0)
            {
                if (xlook >= 0)
                    RotationAngle = 0.0f;
                else
                    RotationAngle = Math.PI;
            }
            else if (ylook > 0)
            {
                RotationAngle = -Math.Atan(xlook / ylook) + Math.PI / 2;
            }
            else
            {
                RotationAngle = -Math.Atan(xlook / ylook) + Math.PI * 1.5f;
            }





spriteBatch.Draw(player, screenpos, null, Color.White, Convert.ToSingle(RotationAngle),
                origin, 1.0f, SpriteEffects.None, 1f);


Поворачивается вообще рывками и не так как надо... кажется всё сделал правильно... :((((

#5
18:44, 16 фев 2009

Всё оказалось куда проще)))

private Vector2 screenpos;

screenpos = new Vector2(GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2);

mouseState = Mouse.GetState();

            xlook = screenpos.X - mouseState.X;
            ylook = screenpos.Y - mouseState.Y;

            RotationAngle = (float)Math.Atan2(ylook, xlook);


 spriteBatch.Draw(player, screenpos, null, Color.White, RotationAngle,
                origin, 1.0f, SpriteEffects.None, 1f);


Спасибо вам огромное, Megabyte-Ceercop & oistalker

#6
19:19, 16 фев 2009

Megabyte-Ceercop

>сам пользуюсь арктангенсом.

Ну, так тоже можно (даже логичнее), только вот приходится следить за тем в какой четверти находится точка. Для моего же примера еще нужно к результирующему углу прибавить 90 градусов.

#7
19:21, 16 фев 2009

Megabyte-Ceercop

>Поворачивается вообще рывками и не так как надо...

Спрайт наверное представляет собой какой-то физический объект, обладающий массой? Логично будет поворачивать объект в нужную сторону не сразу, а маленькими шажками  от текущего угла к  вычисленному.

#8
21:28, 16 фев 2009

Игра будет с видом сверху, поэтому тут не понадобится физика как такова :)

#9
9:03, 17 фев 2009

>Поворачивается вообще рывками и не так как надо... кажется всё сделал
>правильно... :((((
>-Math.Atan(xlook / ylook) + Math.PI / 2

деление PI на 2 сделал целочисленным. В этом и проблема рывков. 

За Atan2 самому спасибо. Поищу есть ли эта функция в C++  math. : )

#10
17:27, 17 фев 2009

XNA?

#11
12:20, 5 мар 2009

Да чо паритесь то с формулами, вот функция (на Delphi, у мня С++ нету, а скорость нета 64кб\сек :( ) которая определяет угол от x,y и отдаёт угол (думаю перевести с Delphi на С++ не составит огромного труда)

function GetAngleByXY(x,y: Integer): Integer;
var
  ang: Extended;
begin
  ang := 0;
  {x := x2 - x;
  y := y2 - y;}
  ang := RadToDeg(ArcTan2(y,x))+90;

  Result := -round(ang);
end;

#12
17:26, 8 мар 2009

AleD
вы уж простите. но судя по тому что вы C# не отличаете C++, от его наличия толку было бы не много :)

ПрограммированиеФорум2D графика и изометрия

Тема в архиве.