C++ (Qt)QImage * mImage; // картынкаQPointF mPos; // координаты угла с которого началосьqreal mCurTime; // текущее время qreal mSpeed; // скорость (пикселей/сек)QPointF mWaveDir; // направление волна qreal mDistortAmount; // множитель искажений // установка параметров волныvoid Wave::Setup( bool left, bool top, qreal angle ) // угол альфа в радианах от 0 до PI / 2{ mPos.setX(left ? 0.0 : mImage->width); mPos.setY(top ? 0.0, mImage->height()); if (left) angle = top ? (-angle) : angle; else angle = PI * (top ? 1.0 : 0.5); mDir = QPointF(cos(angle), sin(angle));} void Wave::CalcPixelDistort( int & x, int & y ){ QPointF vec = QPoint(x, y) - mPos; // текущее направление float theX = vec * mDir; // длина проекции на направление волны theX -= mCurTime * mSpeed; // получили то "x" от которого брать n(x) qreal height = CalcHeight(theX); // высота волны n(x) // имитируем refraction qreal heigh2 = CalcHeight(theX + 1); qreal shift = (height2 - height) * mDistortAmount; x += int(mDir.x() * shift); y += int(mDir.y() * shift); x = qMin(x, mImage->width() - 1); y = qMin(y, mImage->height() - 1); x = qMax(x, 0); y = qMax(y, 0);}
C++ (Qt)qreal CalcHeight( float x ){ x /= mBandWidth * 0.5; // mBandWidth = ширина розовой области в пикселях if (fabs(x) > 1) return 0.0f; static qreal theK = ln(0.01); return (exp(x * x * theK) - 0.01) / 0.99; }