The Minimum Drawing Library (MDL) includes a sophisticated "Water Ripple" effect that simulates the realistic appearance of ripples on a water surface. This document explains how this complex visual effect works, its implementation details, and how you can use it in your LiveCode applications.
The water ripple effect creates the illusion of waves spreading across an image, similar to what happens when you drop a stone into a pond. It uses displacement mapping and alpha blending to distort the original image, creating a convincing water distortion that reveals a new image underneath.
This effect is part of the enhanced alpha channel effects in MDL version 0.93, which adds support for transparency and sophisticated image transitions.
The water ripple effect is based on principles from physics and optics:
The mathematical model for a radial water ripple can be expressed as:
Where:
r
is the distance from the centert
is timeA
is amplitudek
is the wave number (related to wavelength)ω
is the angular frequencyα
is the damping factorThe water ripple effect is implemented in the veWaterRipple
function. Here's a simplified overview of how it works:
on veWaterRipple pImageName, pEffect, pSpeed
local tNewBuffer, tOldBuffer, tWidth, tHeight, tWait
local tSteps, tTempBuffer, tCenterX, tCenterY, tMaxRadius
local tT
put gMdBuffer into tNewBuffer
put (the imageData of image pImageName) into tOldBuffer
put MdGetBufferWidth() into tWidth
put MdGetBufferHeight() into tHeight
put getVeWait(pSpeed) into tWait
put 20 into tSteps
put tWidth div 2 into tCenterX
put tHeight div 2 into tCenterY
put sqrt(tWidth^2 + tHeight^2) / 2 into tMaxRadius
The heart of the ripple effect is the pixel displacement logic:
-- Calculate ripple effect strength (0-1)
local tRippleStrength
put 1 - abs(tDist - tRippleRadius) / tRippleWidth into tRippleStrength
-- Apply sinusoidal distortion based on distance
local tAngle, tDisplacement
put (tDist / 5) * 360 + (tStep * 18) into tAngle
put tRippleStrength * 8 * sin(tAngle) into tDisplacement
-- Calculate direction vector
local tDx, tDy
if tDist > 0 then
put (tX - tCenterX) / tDist into tDx
put (tY - tCenterY) / tDist into tDy
else
put 0 into tDx
put 0 into tDy
end if
-- Calculate source pixel with displacement
local tSrcX, tSrcY
put tX + tDx * tDisplacement into tSrcX
put tY + tDy * tDisplacement into tSrcY
Note: This code shows how pixels are displaced based on a sine wave function. The displacement is strongest at the ripple's edge and follows a circular pattern outward from the center point.
To understand the ripple effect, it's helpful to visualize how pixels are displaced:
What makes the water ripple effect particularly sophisticated is its integration with the alpha channel for transparency effects:
-- Calculate refractive alpha effect
local tRefractiveAlpha
put tSrcAlpha * (0.7 + 0.3 * tRippleStrength) into tRefractiveAlpha
-- Blend with new image alpha based on progress
local tResultAlpha
put tRefractiveAlpha * (1 - tMixRatio) + tNewAlpha * tMixRatio into tResultAlpha
put numToByte(round(tResultAlpha)) into byte tDestIdx of tTempBuffer
This code creates a refractive effect by modulating the alpha (transparency) based on the ripple strength. This simulates how light intensity varies as it passes through rippling water.
To use the water ripple effect in your LiveCode application:
-- Create an image object
create image "myImage"
set the rect of image "myImage" to 0,0,400,300
-- Initialize the drawing buffer
MdMakeBuffer "myImage"
-- Draw your initial content
MdEraseScreen
MdSetPenColor "255,255,0,0" -- Red
MdDrawRect "50,50,350,250", true
MdPushBuffer -- Save this state
-- Create new content
MdEraseScreen
MdSetPenColor "255,0,0,255" -- Blue
MdDrawRect "100,100,300,200", true
-- Apply the water ripple effect when updating
MdUpdate "myImage", "waterRipple", "normal"
Parameter | Description | Options |
---|---|---|
pImageName | Name of the image object to update | Any valid image name |
pEffect | The visual effect to apply | "waterRipple" |
pSpeed | The speed of the transition | "slow", "normal", "fast", or empty for default |
The water ripple effect is computationally intensive because:
The water ripple effect demonstrates several advanced concepts:
The effect uses vector calculations to determine the direction and magnitude of pixel displacement:
(tX - tCenterX) / tDist
tDx * tDisplacement
sqrt((tX - tCenterX)^2 + (tY - tCenterY)^2)
The sine function models the oscillatory nature of water waves:
tRippleStrength * 8
tStep * 18
tDist / 5
Alpha blending creates the transparent water effect:
tSrcAlpha * (0.7 + 0.3 * tRippleStrength)
tResultAlpha * (1 - tMixRatio) + tNewAlpha * tMixRatio
The water ripple effect in MDL showcases how mathematical principles from physics and computer graphics can create realistic visual effects. By understanding the underlying calculations and buffer manipulations, you can not only use this effect effectively but also potentially customize it or create similar advanced effects of your own.
This effect builds upon the basic principles seen in simpler effects like wipe or fade, but adds sophisticated pixel displacement, wave simulation, and transparency handling to create a visually striking transition that mimics natural water behavior.