1. C++ / Говнокод #9420

    +997

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    void TexQ::Move()
    {
    	mx = quad.v[0].x;
    	my = quad.v[0].y;
    	if(hge->Input_GetKeyState(HGEK_RBUTTON) || hge->Input_KeyDown(HGEK_LBUTTON))
    	{
    		hge->Input_GetMousePos(&nx, &ny);
    		move = true;
    		sx = GetPositionX();
    		sy = GetPositionY();
    		subx = nx - sx;
    		suby = ny - sy;
    
    		if ( abs(subx) > abs(suby) ) 
    		{
    			iter = abs(subx);
    			ms = subx;
    			subx = (subx < 0) ? -1.0f : 1.0f;
    			suby = (suby < 0 ) ? suby/abs(ms) : abs(suby/ms);
    		}
    		else 
    		{
    			iter = abs(suby);
    			ms = suby;
    			suby = (suby < 0) ? -1.0f : 1.0f;
    			subx = (subx < 0 ) ? subx/abs(ms) : abs(subx/ms);
    		}
    	}
    
    	if (move) 
    	{	
    		if (iter >= shift)
    		{
    			iter-=shift;
    			this->SetPosition(
    				GetPositionX() + subx * shift, 
    				GetPositionY() + suby * shift);
    		}
    		else
    		{
    			this->SetPosition(nx , ny);
    			move = false;
    		}
    
    	}
    
    }

    Хреновый из меня математик. Этот метод втыкается в функцию фрейминга. И текстура едет по прямой туда, куда мышью тыкнешь.
    Позже узнал, как можно тригонометрией в 5 строк написать такую же )

    Запостил: idec, 14 Февраля 2012

    Комментарии (26) RSS

    • Сдаётся, тут заноза не только в математике...
      Ответить
    • Тригонометрию? Это задача уровня GUI, как я понял. Для решения такой задачи не надо в принципе приплетать ни тригонометрию, ни плавающие операции вообще. За использование тригонометрии, плавающего деления или плавающих типов в решении подобной задачи - сразу бить по рукам.

      Насколько я понял, задача состала в том, чтобы сдивнуть текстуру в направлении мыши на расстояние 'shift'. То что вы сделали - шаг в правильном направлении, но очень криво реализованный.

      Говнокодом тут попахивает из-за того, что не видно не одного объявления переменной. У вас что, все эти переменные являются членами класса что-ли?
      Ответить
      • dx = nx - sx;
        dy = ny - sy;
        adx = abs(dx);
        ady = abs(dy);
        
        if (adx >= ady)
          if (adx <= shift) {
            sx = nx;
            sy = ny;
          }
          else {
            sx += shift * ((dx > 0) - (dx < 0)); // оформить как 'signum(dx)'
            sy += dy * shift / adx;
          }
        else
          if (ady <= shift) {
            sx = nx;
            sy = ny;
          }
          else {
            sy += shift * ((dy > 0) - (dy < 0)); // оформить как 'signum(dy)'
            sx += dx * shift / ady;
          }
        
        // sx, sy - новая позиция текстуры
        Ответить
        • А вот вычислять скорость в каждый тик движения это как то попахивает.
          Ответить
          • Нет, не попахивает.

            Во-первых, тут нет никакого вычисления скорости (в явном виде). Вся идея тут заключается именно в том, чтобы избежать выделения "скорости", как отдельной сущности. В выражении вида 'dy * shift / adx' первым выполняется именно умножение, что избегает явного вычисления скорости и позволяет нам решить задачу не притягивая сюда за уши плавающие вычисления.

            Во-вторых, кто вам сказал, что скорость постоянна? А именно, кто сказал, что значение 'shift' не меняется от тика к тику? Даже если оно и не меняется в данной конкретной задаче , все равно в ситцуации, когда нет ущерба эффективности, более общее решение всегда неизмеримо лучше более частного. (Как я уже говорил выше, вычислительной код должен быть отделен от GUI-шного и ничего не должен знать о GUI-специфичной конкретике).

            Даже если скорость постоянна, попытки вычислить ее заранее в виде явной сущности будет ярко выраженной тупейшей говнооптимизацией.
            Ответить
            • Обновилась скорость - пересчитали, и все ок.
              Вы не гейм разработчик:-)
              Ответить
              • Нет, не гейм :) Мое программировнаие проходит в области вычислительной геометрии. Отсюда и ноги растут...
                Ответить
      • А если учесть, что код симметричен относительно 'x' и 'y', то вместо повторения одного и того же в этажерке if-ов можно просто сделать

        dx = nx - sx;
        dy = ny - sy;
        adx = abs(dx);
        ady = abs(dy);
        
        flip_xy = adx < ady;
        if (flip_xy) {
          swap(sx, sy);
          swap(nx, ny);
          swap(dx, dy);
          swap(adx, ady);
        }
        
        if (adx <= shift) {
          sx = nx;
          sy = ny;
        }
        else {
          sx += shift * ((dx > 0) - (dx < 0)); // оформить как 'signum(dx)'
          sy += dy * shift / adx;
        }
        
        if (flip_xy)
          swap(sx, sy);
        
        // sx, sy - новая позиция текстуры


        Разумеется, во избежание говногокдовости надо бы отделить GUI-шные вызовы от чистой математики, т.е. вынести вычисления новых координат в отдельную функцию.
        Ответить
    • Никакая это ни задача уровня ГУИ ) Текстуру надо перемещать не за мышью а в место, куда тыкнул мышью причем по прямой и с равной скоростью. Тут действует принцип пропорций в моем коде. Сперва высчитывается как будет меняться Х и У : минусоваться или плюсоваться каждая. затем определяется разность величин Х1 - Х0 и У1 - У0. наибольшая разность будет "ведущей" и итерироваться она будет заданным целым числом shift (фактически это скорость перемещения) а другая величина будет изменяться по пропорции. суть вычисления "ведущей" величины и есть идея равной скорости. т.е за кадр будет текстура перемещаться на shift точек.
      Ответить
      • Сколько умных слов описывающие связку из условия и двух строк с элементарнейшими вычислениями.
        И не знаю как у вас а у нас для этого либы есть...
        Ответить
      • Нет (с)

        Задача, решаемая вы кординатах пространства отображения (например, в координатах курсора мыши, как у вас) - это всегда задача уровня GUI.
        Ответить
        • На движке HGE вы не найдете движения по прямой от точки к точке. Там много чего нет.
          Ответить
    • http://hge-blog.ru/262_primer-dvizhenie-k-kursoru
      вот решение с тригонометрией
      оно намного короче моего говна, от чего я и начал этот пост )
      Ответить
      • Охуеть, сначала делаем атан, потом син и кос.
        У автора жопа вместо головы.
        Ответить
        • И там и там закомментил )
          Ответить
          • Да потому что такой пиздец что я не выдержал это ж блять надо формулу пифагора как не знать, чтобы так через жопу нормализовать вектор, это же шестой блять класс.
            Ответить
            • пифагор ваще лошара
              Ответить
            • может мне поможешь решить задачу:
              есть текстура, ее координаты и положение определяются 4мя парами координат (углы четырехугольника)
              0 ------------- 1
              |(пробелы)|
              3 ------------- 2
              Допустим я тыкаю мышью в произвольное место в экране и текстура смотрит в эту точку. ее лицо - это сторона 1-2.
              PS. По сути Гуя поддерживает поворот, но не текстур а спрайтов и тем более на определенное количество радиан, которое тоже надо считать ( решение на том же сайте). в данном случае мне спрайт не нужен.
              Ответить
    • Я ужинал совсем без аппетита. Мать что-то ворчала, опять гремя в тазике тарелками. Мухи уныло кружили вокруг лампочки. Через два окна - летней кухни и дома был виден краешек работающего телевизора, освещающего комнату нереальным мерцающим голубоватым светом.
      Ответить

    Добавить комментарий