Эффект пульсации воды Pygame

я погуглил для него, но нет готовых скриптов-в отличие от того же эффекта на Flash. Я проверил алгоритм на Эффект Воды Объясняется, а также проверили реализацию Перлин Шума, что обеспечивает хорошее моделирование конца волн на плоской поверхности. Я ищу ту же реализацию, найденную на нескольких флеш-эффектах, основанных на действиях наведения/наведения мыши. Это нацеливание интерактивной библиотеки этажа, и я бы наслаждайтесь отходом от Flash в этом вопросе, особенно чтобы избежать такой простой обратной инженерии кода - и да, я знаю, что он может просто использовать готовый flash-код, но я бы использовал это только в крайнем случае.

кто-нибудь видел подходящую реализацию этого эффекта для Pygame (используя OpenGL или нет)?

EDIT: может ли кто-нибудь обеспечить подходящую реализацию этого эффекта с помощью OpenCV/OpenGL и Pygame?

в виновником здесь является интерфейс (код) для передачи списка значений, которые будут отправлены от внешнего интерпретатора (трекер - не TUIO, хотя) через Python. Я пробовал несколько дней подряд, но Pygame не может генерировать ничего так быстро, как чистый код C/C++ (как используется для шейдеров в OpenGL), и мои знания C/C++ равны нулю. Поэтому цель, по крайней мере, поступающей из Python-кода.

хороший пример, отличный от эффекта вспышки, но это все еще хорошо, это вода Моделирование с помощью Java-апплета.

(bounty показывает, что ответы не имеют достаточной детализации, так как это было ближе всего к "OP неспособен создать код, который он хочет, поскольку ему не хватает фундаментальных навыков, и этот ответ, вероятно, будет полезен нескольким людям").

2 ответов


после выполнения домашнего задания (a.к. a. исследование) и пытается напрямую преобразовать ссылку на Java-код, размещенную на вопрос, в Python и имеющую очень, очень печальный опыт, пытаясь обновить Python/Numpy огромный массив цветов пикселей на основе их позиций для ряби эффекта пульсации (извините, мой первый язык не английский), таким образом, анализируя несколько (x,y) позиций для каждого прохода вычислений эффекта и блитируя это на отображаемую поверхность на экране (surfarray следует), я пришел к выводу - это подтверждается другими комментаторами - что Pygame просто не быть достаточно мощным, чтобы фактически пересечь весь массив пикселей и применить результаты вычислений на каждый пиксель на экране с минимальной скоростью 24 fps (для менее чем среднего опыта).

Цитируя самого разработчика за Последний Свет Productions и бывшего Проект Geometrian Иэн Молоток:

PyGame не так хорош для нажатия пикселей. Ничего нет, кроме GPU.

поиск тогда оказался поиском Alkahest - что-то, что никогда не окажется по-настоящему найдено - и основано на той же идее ряби изображений, но на этот раз с помощью прозрачности посмотреть через несколько слоев поверхностей Pygame, я опубликовал вопрос Pygame круговой обрезки / маски on Гамедев. The выбрали ответ фактически подтверждает тот факт, что я уже боялся, что Pygame никогда не будет мачо достаточно для работы.

через день я вернулся к своим предыдущим идеям по развитию и наткнулся на форумах Ogre3D и посомтрите там. Оказывается, (1) Ogre3D и образцы являются открытым исходным кодом и (2) одним из примеров является трехмерная модель воды, которая взаимодействует с движущимся объектом, точно то же самое, что я пытался достичь в 2-D, но в гораздо большем профессионально.

поскольку мои знания в C / C++ равны нулю, я решил спросить о как настроить демо Ogre3D воды для проблеска того, где начать искать, и один из ответов указал мне на программное обеспечение от Touchscape, где предоставляется SDK (см. ответ).

довольно много форумах Ogre3D и посомтрите там завернула. Эффект пульсации воды, OpenGL (который он может дополнительно использовать в зависимости от оборудования), игровой движок и обертки на Python через Питона-Людоеда - Итак, мой ответ на мой собственный вопрос,

может ли кто-нибудь обеспечить подходящую реализацию этого эффекта с помощью OpenCV/OpenGL и Pygame?

в основном

да. Проверьте демонстрацию воды Ogre3D, предоставленную с SDK - и подключите его к Python через Питона-Людоеда.


следующее использование numpy может помочь вам начать работу. Это должно быть достаточно быстро, как это, хотя вы могли бы получить гораздо быстрее даже в python (посмотрите здесь, чтобы увидеть, какhttp://www.scipy.org/PerformancePython).

кстати есть несколько недостатков в этом методе описано :

  1. вы не можете контролировать скорость ряби - для этого вам придется изменить уравнения, используемые в функции пульсации (если вы выясните, как это относится к волновое уравнение http://en.wikipedia.org/wiki/Wave_equation тогда вы закончили)
  2. "глубина" "бассейна" фиксирована (и, вероятно, слишком мелкая). Я добавил параметр глубины, чтобы увеличить эффект
  3. статья читает целочисленные смещения пикселей - вы получите гораздо лучший результат с интерполированными значениями (я думаю, вы можете сделать это с opengl, но мои знания в этой области равны нулю)

код:

import numpy

def ripple(w1, w2, damp, n = 1):
    for _ in xrange(n):
        w2 *= -2
        w2[1:-1,1:-1] += w1[0:-2, 1: -1]
        w2[1:-1,1:-1] += w1[2:  , 1: -1]
        w2[1:-1,1:-1] += w1[1:-1, 0: -2]
        w2[1:-1,1:-1] += w1[1:-1, 2:   ]
        w2 *= .5 * (1. - 1./damp)
        w1, w2 = w2, w1

def refract(x, y, w, rindex, depth = 10):
    sx = x[0,1] - x[0,0]
    sy = y[1,0] - y[0,0]

    dw_dx = (w[2: ,1:-1] - w[:-2,1:-1]) / sx * .5
    dw_dy = (w[1:-1,2: ] - w[1:-1,:-2]) / sy * .5

    xang = numpy.arctan(dw_dx)
    xrefract = numpy.arcsin(sin(xang) / rindex)
    dx = numpy.tan(xrefract) * dw_dx * depth

    yang = numpy.arctan(dw_dy)
    yrefract = numpy.arcsin(sin(yang) / rindex)
    dy = numpy.tan(yrefract) * dw_dy * depth

    dx *= numpy.sign(dw_dx)
    dy *= numpy.sign(dw_dy)

    xmin = x[0,0]
    xmax = x[0,-1]
    x[1:-1,1:-1] += dx
    x[:,:] = numpy.where(x < xmin, xmin, x)
    x[:,:] = numpy.where(x > xmax, xmax, x)

    ymin = y[0,0]
    ymax = y[-1,0]
    y[1:-1,1:-1] += dy
    y[:,:] = numpy.where(y < ymin, ymin, y)
    y[:,:] = numpy.where(y > ymax, ymax, y)

x и y должны быть сетки от numpy.вызов meshgrid: вот пример использования:

    x,y = meshgrid(x,y)
    w = 10 * exp(- (x*x + y*y))
    w1 = w.copy()
    x1,y1 = meshgrid(r_[0:len(x):1.0], r_[0:len(y):1.0])
    ripple(w, w1, 16) # w1 will be modified
    refract(x1, y1, w1, rindex=2, depth=10) # x1 and y1 will be modified
    numpy.around(x1, out=x1) # but you will get better results with interpolate
    numpy.around(y1, out=y1) #