Конференция "Игры" » Повернуть спрайт вокруг произвольной точки
 
  • DevilDevil © (15.05.07 23:58) [0]
    Часто спрайты вращают вокруг центра. Я вот хочу вращать вокруг произвольной точки. Не получается. Голову сломал себе, не пойму где собака зарыта.

    Вот демо-проект :) 175кб
    http://forum.mirgames.ru/index.php?act=Attach&type=post&id=2823

    Там находится "текстура" 256x256. На ней зелёный квадрат (150x150). В левом верхнем углу красный пиксель. Вокруг него и будем вращать. TRect квадрата в текстуре: Bounds(30, 30, 150, 150). Смещение красной точки в квадрате - (0, 0). При повороте на произвольный угол создаётся ощущение нормальной работы. Однако при поворотах на угол, кратный 90, БАГ смещения на пару пикселей становится виден. Подскажите, где здесь может быть ошибка.

    P.S. для вращения кликните мышкой
    P.P.S. заранее спасибо!
  • antonn © (16.05.07 00:01) [1]
    а на форуме миргеймса типа совесть не дает спросить, чтоб не засмеяли? :)
  • Vga © (16.05.07 07:31) [2]
    Дык он там вроде уже спрашивал на тему :)
  • DevilDevil © (16.05.07 11:46) [3]
    > antonn ©   (16.05.07 00:01) [1]
    > а на форуме миргеймса типа совесть не дает спросить, чтоб
    > не засмеяли? :)


    Всё у меня в порядке с совестью ;)
    Вопрос продублирован, здесь он появился намного позже.

    Ты сам то знаешь, в чём трабла?
  • DevilDevil © (16.05.07 20:14) [4]
    up
  • Vovan #2 (16.05.07 23:23) [5]

     glTranslatef(X, Y, 0);



    Сдвигают на расстояние, а X и Y - координаты мыши.


     SpriteWidth  := (TextureRect.Right-TextureRect.Left);
     SpriteHeight := (TextureRect.Bottom-TextureRect.Top);



    Получишь ширину и высоту минус 1.
  • DevilDevil © (16.05.07 23:54) [6]
    > Сдвигают на расстояние, а X и Y - координаты мыши.

    что ты имел ввиду?

    > Получишь ширину и высоту минус 1.

    Так получается, что его
    TRect

    равен
    Bounds(30, 30, 150, 150)

    . Т.е. ширина/высота равна 150. Как работает Bounds? :
    function Bounds(ALeft, ATop, AWidth, AHeight: Integer): TRect;
    begin
     with Result do
     begin
       Left := ALeft;
       Top := ATop;
       Right := ALeft + AWidth;
       Bottom :=  ATop + AHeight;
     end;
    end;



    Т.е.
    Right - Left

    как раз =
    Width

  • antonn © (17.05.07 00:17) [7]
    потому что пиксел все таки имеет размеры на текстуре.
    canvas.rectangle(10,10,12,12) даст тебе квадрат со стороной 2 пикселя, а не 3 (10,11,12) - аналогично твоей проблеме
  • DevilDevil © (17.05.07 00:28) [8]
    > потому что пиксел все таки имеет размеры на текстуре.
    > canvas.rectangle(10,10,12,12) даст тебе квадрат со стороной
    > 2 пикселя, а не 3 (10,11,12) - аналогично твоей проблеме

    Оно логично, когда создаёшь растр программно, а не в Paint-е :)
    Специально перепроверил, 150!
    Спешиал фо ю отослал по почте размеченную версию "текстуры". По диагонали белая линия, каждый 5й пиксель окрашен в красный. Каждый 20й отмечен чёрным.

    P.S. уж что-что, а пиксели я считать умею :)
  • Vovan #2 (17.05.07 00:57) [9]

    > что ты имел ввиду?



    glTranslatef(X+1, Y+1, 0);

  • antonn © (17.05.07 13:31) [10]

    > DevilDevil ©  

    ты не понял. вот если я сделаю canvas.rectangle(10,10,12,12) ведь должно быть 3 пикселя 10, 11, 12? Но на самом деле их два, у тебя таже "проблема", потому что rect на правую и нижнюю грань делает -1 при рисовании (соответственно нужно тебе ледать где то +1).
  • DevilDevil © (17.05.07 16:57) [11]
    Я гляжу все заумные такие, типа элементарные вещи рассказывают... Вы свои умоизречения в код пробовали всовывать? Давайте сначала попробуем, а потом посоветуем.

    Я не против советов, я за них благодарен. Другое дело, в код взглянуть тоже стоит.

    С Уважением

    P.S. вопрос открыт
  • a22 © (17.05.07 17:28) [12]
    чудес не бывает, вопрос либо в неправильных координатах квада, либо текстурных. по-моему - координаты квада.
    попробуй их руками пересчитать с больше точность, с округлением до целых - и посмотри, будет ли съезжать. если да - увидишь, что с координатами не так
  • Vovan #2 (17.05.07 18:09) [13]
    А чего, +1 на мышь не помогло? У меня вродь пошло.
  • DevilDevil © (17.05.07 18:22) [14]
    > Vovan #2   (17.05.07 18:09) [13]

    Что, прям пиксель в пиксель? неверю! :)
    попробую часа через 4
  • DevilDevil © (18.05.07 00:26) [15]
    хмм... похоже на правду... переспрошу если что....

    Пока парочка вопросов; разве так корректно:
     W := 256; // TextureWidth
     H := 256; // TextureHeight

     // Текстурные координаты
     L  := (TextureRect.Left)    /W;
     R  := (TextureRect.Right)   /W;
     T  := 1-(TextureRect.Top)   /H;
     B  := 1-(TextureRect.Bottom)/H;



    1) текстурные координаты от нуля до единицы. Физически (в данном случае) от нуля до 255. Следовательно логично уменьшать на единицу и
    W

    и
    H

    . Я не прав?

    2) допустим спрайт занимает всю текстуру. Следовательно его
    TRect

    равен
    Bounds(0, 0, 256, 256)

    . Следовательно в данном случае и
    Right

    и
    Bottom

    будут равны 256, хотя физически на текстуре таких пикселей нет. По моему надо уменьшать на единицу и
    Right

    и
    Bottom

    . Как вы считаете?

    3)
    glTranslatef(-TextureOffset.X, -TextureOffset.Y, 0);



    не нужно ли ещё дополнительного смещения на пиксель? если да, то в какую сторону?
  • Vovan #2 (18.05.07 00:44) [16]
    Координата 0 хлопает первый пиксель (нулевой) по левому плечу, а координата 1 хлопает последний по правому. Т.е. она никакой пиксель не нумерует.

    Картинка:
    http://www.imgstore.ru/files/FwiscP0Bwus2J7c6WBUrVuS6CqJv3OlmDlLgqZfV.png
  • DevilDevil © (18.05.07 12:38) [17]
    ерунда какая-то. Сцылко на офф данные!
  • a22 © (18.05.07 15:42) [18]
    координата 0 берет левый (верхний) крайн текселя 0. его центр берет pixel_size/2.. если это не учитывать, тоже съезжать может слегка картинка (от настроек драйвера уже зависит)
  • Cash © (18.05.07 22:52) [19]
    >DevilDevil ©   (15.05.07 23:58):
    хы, прибила меня проблема в 2003-ем далеком году решить такую
    же проблему :)
    Решил в течении 3 часов, 2 из которых вспоминал тригонометрию, а
    оставшийся час прикручивал то что вспомнил к системе координат :)
    Результат был такой:

      TX:=(_TCX*(Cos(DegToRad(Rot))))-(_TCY*(Sin(DegToRad(Rot))));
      TY:=(_TCX*(Sin(DegToRad(Rot))))+(_TCY*(Cos(DegToRad(Rot))));



    _TCX и _TCY - это центр вращения, Rot - это угол поворота в градусах
    (так удобнее вроде как...)

    На панацею не претендует, но юзать можно, отшлефовать (не охота
    показывать просто оптимальный вариант, ну такой вот я жмот ^_^)
    и будет работать даже очень шустро...
 
Конференция "Игры" » Повернуть спрайт вокруг произвольной точки
Есть новые Нет новых   [119258   +42][b:0][p:0.002]