Итак, вот код моего 2D точечного класса для поворота:
float nx = (x * cos(angle)) - (y * sin(angle));
float ny = (y * cos(angle)) + (x * sin(angle));
x = nx;
y = ny;
x и y — локальные переменные в классе точек.
А вот код для вращения моего спрайтового класса:
//Make clip
SDL_Rect clip;
clip.w = width;
clip.h = height;
clip.x = (width * _frameX) + (sep * (_frameX) + osX);
clip.y = (height * _frameY) + (sep * (_frameY) + osY);
//Make a rotated image
col bgColor = image->format->colorkey;
//Surfaces
img *toEdit = newImage(clip.w, clip.h);
img *toDraw = 0;
//Copy the source into the workspace
drawRect(0, 0, toEdit->w, toEdit->h, toEdit, bgColor);
drawImage(0, 0, image, toEdit, &clip);
//Edit the image
toDraw = SPG_Transform(toEdit, bgColor, angle, xScale, yScale, SPG_NONE);
SDL_SetColorKey(toDraw, SDL_SRCCOLORKEY, bgColor);
//Find new origin and offset by pivot
2DVec *pivot = new xyVec(pvX, pvY);
pivot->rotate(angle);
//Draw and remove the finished image
drawImage(_x - pivot->x - (toDraw->w / 2), _y - pivot->y - (toDraw->h / 2), toDraw, _destination);
//Delete stuff
deleteImage(toEdit);
delete pivot;
deleteImage(toDraw);
Код использует центр спрайта в качестве источника. Это прекрасно работает, если я оставляю точку поворота в точке (0,0), но если я переместлю ее куда-нибудь еще, например, на плечо персонажа, он начнет заставлять спрайта танцевать вокруг, вращаясь как спирограф, вместо того, чтобы ось оставалась на плечо персонажа.
Функция поворота изображения из SPriG, библиотеки для рисования примитивов и преобразованных изображений в SDL. Поскольку ось исходит от центра изображения, я считаю, что новый размер обрезанной поверхности, создаваемой вращением, не должен иметь значения.
[РЕДАКТИРОВАТЬ] Я немного испортил код. Замедляя его, я обнаружил, что по какой-то причине вектор вращается в 60 раз быстрее, чем изображение, хотя я ничего не умножаю на 60. Итак, я попытался просто разделить входные данные на 60, только сейчас это выходя все рывками и не вращаясь ни к чему между кратными 60.Код вращения вектора, который я нашел на этом самом сайте, и люди неоднократно подтверждали, что он работает, так почему он вращается с шагом 60?
Я давно не касался источника SPriG, но могу дать вам некоторую информацию.
Если у SPriG есть проблемы с вращением не по центру, вам, вероятно, будет проще и быстрее перейти на SDL_gpu (и я предлагаю SDL 2.0). Таким образом, вы получаете похожий API, но производительность намного лучше (он использует видеокарту).
Я могу догадаться, что вектор не вращать в 60 раз быстрее, чем изображение, а точнее как в 57 раз быстрее! Это потому, что вы вращаете вектор с помощью sin () и cos (), которые принимают значения в радианах. Изображение поворачивается на угол в градусах. Коэффициент преобразования радиан в градусы составляет 180 / пи, что составляет около 57. SPriG может использовать градусы или радианы, но по умолчанию использует градусы. Используйте SPG_EnableRadians (1) для переключения этого поведения. Кроме того, вы можете придерживаться меры степени в переменной угла, умножая аргумент на sin () и cos () на pi / 180.