Dragging Cards

Deutsche Version hier

For the Lebenswege project, we wanted to simulate a collection of small cards on a table that could be moved with a mouse or a finger. The idea itself is not particularly unusual and has surely been implemented many times before. Still, it raises a question: how should we model the movement of a card that can be touched at different points and pulled in different directions? In our implementation, the cards are not grabbed directly; the user merely brushes over them. But that only amounts to scaling the force vector, while the underlying question remains the same.

The rough intuition is that a card grabbed at its center should simply translate in any direction without rotating. If it is grabbed at a corner and the finger moves in a circle around the card’s center, on the other hand, its movement should look more like a rotation.

To translate these assumptions into vectors, it is useful to place the origin at the center of the card. Let cc be the contact point in this coordinate system and uu the applied force vector. We only want rotation when cc and uu are not parallel: movement toward or away from the center should not cause any rotation. Otherwise, the amount of rotation should increase with the length of cc, the distance between the contact point and the center, and with the component of the force perpendicular to it.

These dependencies are captured by the cross product

c×u:=cxuycyux,c\times u:=c_xu_y-c_yu_x,

which describes the signed area of the parallelogram spanned by the two vectors and is very easy to compute. In many applications, including this one, the parallelogram itself never appears directly; its area simply has exactly the dependence on vector lengths and angle that we need.

If a touch at a corner followed by movement around the center should produce exactly a rotation of the card around its center, we still need a suitable normalization. Up to the signs of its components, a corner corresponds to c=(w/2,h/2)c=(w/2,\,h/2), and its squared distance from the center is c2=(w2+h2)/4\lVert c\rVert^2=(w^2+h^2)/4. The same is true for all four corners. The square is useful here because it keeps the system dimensionless: only the size of cc and uu relative to the dimensions of the card matters, not their absolute lengths.

This gives us the following formula for the rotation:

ω=c×u(w2+h2)/4.\omega=\frac{c\times u}{(w^2+h^2)/4}.

The rest of the card’s movement follows automatically from the requirement that the contact point itself must always move along uu.

Grab the card at any point.

For most applications, the story could end here. The heuristic is simple, efficient to compute, and feels good. Out of curiosity, however, we can ask how the movement might be derived from physical principles and how good our approximation actually is.

Two models of least resistance

When we force the card to move, it follows the path of least resistance. In other words, the individual points on the card want to travel as little as possible, subject to the condition that cc still follows the direction of uu.

What exactly this means depends on the physical model. For a heavy card with little friction, inertia dominates, so we minimize kinetic energy, which grows quadratically with velocity. This is less like a lightweight card on a table and more like a heavy steel plate on well-mounted wheels.

For a lightweight card on a table, dry friction dominates and grows only linearly with velocity.

Both models can be described at once. Let SS be the area occupied by the card, and let J(x,y)=(y,x)J(x,y)=(-y,x) denote a rotation through 9090^\circ. Every infinitesimal movement compatible with the movement of the finger has the form

vω(x)=u+ωJ(xc),v_\omega(x)=u+\omega J(x-c),

where ω\omega denotes the rotation angle and J(xc)J(x-c) the rotation around cc. At x=cx=c, this gives vω(c)=uv_\omega(c)=u: the held point follows the finger independently of the angular velocity ω\omega. The two optimization problems can therefore be written as the minimization of the following integral, where p=1p=1 represents friction and p=2p=2 the kinetic model:

Ep(ω)=xSvω(x)p,p{1,2}E_p(\omega)=\int_{x\in S} \lVert v_\omega(x)\rVert^p, \qquad p\in\{1,2\}

In the kinetic case, p=2p=2, the integrand can be expanded:

u+ωJ(xc)2=u2+2ωuJ(xc)+ω2xc2\left\lVert u+\omega J(x-c)\right\rVert^2 =\lVert u\rVert^2 +2\omega\,u\cdot J(x-c) +\omega^2\lVert x-c\rVert^2

The integrals of these three terms all have closed-form expressions. The problem therefore reduces to minimizing a quadratic polynomial in ω\omega, whose minimum also has a closed form. For a rectangle of width ww and height hh, the result is

ω2=c×u(w2+h2)/12+c2.\omega_2 =\frac{c\times u}{(w^2+h^2)/12+\lVert c\rVert^2}.

In the friction model, where p=1p=1, there is no closed-form expression for the minimum; it can only be approximated numerically.

In the following demo, the contact point cc can be moved across the card, while the arrow tip controls the movement uu. The plots show the two integrals for different values of ω\omega. The black outlined point marks the computed minimum, and the green circle shows the value of our simple approximation.

card
L1
ω0
L2
ω0

The next demo lets us try out how these different values of ω\omega affect the actual movement. All three cards share the same fixed contact point. Drag it to compare the movement profiles produced by the three models.

L1
L2
approximation

Drag the black point. It marks the same fixed contact point on all three cards.

Interestingly, the approximation feels farther from the friction model than the kinetic model does, even though the kinetic model describes very different physics. In particular, near the center, the kinetic model responds more strongly to sideways movement than our approximation. As the distance grows, the additional term c2\lVert c\rVert^2 increasingly dampens this rotation. Similar behavior can also be observed in the friction model.

Because the kinetic model gives us a neat closed-form expression that is almost as efficient to compute as our original approximation, it may be the most practical choice.

As a final question, do the two models also satisfy our original intuition for a card held at a corner? If the finger moves tangentially around the center, uu is perpendicular to cc. For the corresponding angle ωr\omega_r of a rotation around the center, we have u=ωrJcu=\omega_rJc, which is exactly the angle produced by our approximation.

For the kinetic model, the angle can also be calculated directly. With c2=(w2+h2)/4\lVert c\rVert^2=(w^2+h^2)/4, we get

ω2=ωr(w2+h2)/4(w2+h2)/12+(w2+h2)/4=34ωr.\omega_2 =\frac{\omega_r(w^2+h^2)/4} {(w^2+h^2)/12+(w^2+h^2)/4} =\frac34\omega_r.

For the aspect ratio of our card, the friction model numerically gives approximately ω10.72ωr\omega_1\approx0.72\omega_r. Both optimization models therefore rotate the card slightly less than would be required for a pure rotation around the center. This means that the finger must trace a larger circle to complete one full rotation of the card, while the center itself also describes a small circle. This is easy to reproduce with a sheet of paper on a table: it is impossible to rotate the sheet around its center with just one finger unless you press down firmly and twist your finger along with it—but then the interaction is no longer a simple directional impulse.