What is "Curl"?
In vector calculus, curl measures the rotation or circulation of a vector field around a point. Imagine placing a pinwheel at a point, if the pinwheel rotates, then the curl is non-zero.
- Think of curl as "how much the field wants to twist around a point"
- In 2D, curl is a scalar:
- Positive = counterclockwise spin
- Negative = clockwise spin
- Zero = no net spin
Curl is a numerical value that describes how a vector field "twists" at a given point.
2D vector field
function vectorField(x, y) {
// return {
// x: -y,
// y: x,
// }
// const angle = Math.atan2(y, x)
// return {
// x: -Math.cos(angle),
// y: -Math.sin(angle),
// }
return {
x: Math.sin(y),
y: Math.cos(x),
}
}
Imagine dropping ping pong balls into this field
Computing Curl
For a 2D vector field, the curl is defined as:
(TODO: I don't know what this formula means or if its right)
∂Q/∂x ≈ (Q(x + h, y) - Q(x - h, y)) / (2 * h)
∂P/∂y ≈ (P(x, y + h) - P(x, y - h)) / (2 * h)
We can estimate the curl at a point by taking the difference between the vector field at a point and the vector field at a nearby point (finite difference method).
function curlAt(x, y, vectorFn, h = 0.001) {
// Q = y-component
const Q_forward = vectorFn(x + h, y).y
const Q_backward = vectorFn(x - h, y).y
const dQdx = (Q_forward - Q_backward) / (2 * h)
// P = x-component
const P_forward = vectorFn(x, y + h).x
const P_backward = vectorFn(x, y - h).x
const dPdy = (P_forward - P_backward) / (2 * h)
return dQdx - dPdy
}
Curl field visualization
TODO: flow particles using curl field instead of vector field Explain how no sources and sinks makes for a better visualization
Further Research
- Implement with Perlin noise fields