Конференция "Игры" » Повернуть спрайт вокруг произвольной точки
 
  • 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 - это угол поворота в градусах
    (так удобнее вроде как...)

    На панацею не претендует, но юзать можно, отшлефовать (не охота
    показывать просто оптимальный вариант, ну такой вот я жмот ^_^)
    и будет работать даже очень шустро...
  • DevilDevil © (19.05.07 00:53) [20]
    > Cash ©   (18.05.07 22:52) [19]

    Формула конечно рульная :)
    Формулой этой ты меня не удивишь.

    Оптимизировать надо от простого к сложному. Сейчас недопонимаю простое ;)

    P.S. и на рисунок тот внимания обращать не стоит. Всё на уровне догадок. Где ссылки на статьи авторитетов?
  • Vovan #2 (19.05.07 01:25) [21]
    Так, два бреда:

    >Cash ©   (18.05.07 22:52) [19]

    Речь о вращении средствами OpenGL, куда ты пиксели пихать будешь?

    > DevilDevil ©   (19.05.07 00:53) [20]

    >P.S. и на рисунок тот внимания обращать не стоит. Всё на уровне догадок. Где ссылки на статьи авторитетов?

    Сам ищи. Тебе указали на ошибку и как её починить. Я проверял, пиксель в пиксель работает. Если у тебя нет - давай скриншот и описание своей конфигурации. До этого ты называл это словом "баг", хотя бага там нет в помине. Сейчас ты пытаешься доказать, что ты прав, а OpenGL не прав.
  • Vovan #2 (19.05.07 01:58) [22]
  • DevilDevil © (19.05.07 10:28) [23]
    > Vovan #2   (19.05.07 01:25) [21]

    Я конечно извиняюсь, но:

    - давайте обижаться не будем!
    - на рисунках ничего относящегося к делу нет
    - не доверяю я твоему рисунку. Ерунда, мне кажется, с левым/правым плечом. А то, что ты проверял... может повезло ;)

    P.S. у кого либо из здесь находящихся есть офф данные по рассматриваемому вопросу?
  • antonn © (19.05.07 14:54) [24]
    горизонтальные пиксели из canvas.rectangle()
    |0|1|2|3|4|



    закрашиваем 1-3 (считай по палкам пиксели, вхождение между двух палок закрашивается, • - курсор на пикселе 1, § вхождение)
    |0|1•|1|0|0|0
    |0|§|§|0|0|0



    при переворачивании текстуры получишь следущее (курсор на пикселе 3)

    |0|1|1|0•|0|0
    |0|§|§|0|0|0



    вот тебе и пустой пиксель.
 
Конференция "Игры" » Повернуть спрайт вокруг произвольной точки
Есть новые Нет новых   [119261   +45][b:0][p:0.002]