Yea, I hadn't realized at first that projecting using the Constraint gradient formula was an approximation (we're doing a newton-raphson step)
The main assumption is
C(p+Dp) ~ C(p) + Grad(C(p)).Dp = 0
so
applying
Dp_i = - C(p) Grad_i(C(p))/[Sum_i |Grad_i(C)|^2]
*once* isn't enough to satisfy the constraint (by an epsilon) if the penetration is significant (although in the case of the length constraint it works, it's all linear).
Is that correct?
I worked with the vertex/triangle collision constraint
C = ( q - p1 ) . (( p2-p1)X(p3-p1))
or rather its 2D version
C = (q-p1) . (1z X (p2-p1)) (1z coming out of the page)
I get
grad_q (C) = 1z X (p2-p1) (q moves down in the direction of the normal of p1p2)
grad_p1 (C) = 1z X (q-p2) (p1 moves in the direction of the normal of qp2)
grad_p2 (C) = 1z X (p1-q) (p2 moves in the direction the normal of qp2)
the projections are (unless I made some error... I wish
)
dq = - (q-p1).(1z X p12) (1z X p12)
-------------------------------
|p12|^2 + |qp1|^2 + |qp2|^2
dp2 = - (q-p1).(1z X p12) (1z X (qp1))
-------------------------------
|p12|^2 + |qp1|^2 + |qp2|^2
dp1 = - (q-p1).(1z X p12) (1z X (p2q))
-------------------------------
|p12|^2 + |qp1|^2 + |qp2|^2
if q is close to the segment p1p2, q moves along the normal of p1p2 and p1 & p2 almost move along the normal as well, but a bit towards q (1z x p2q ~ 1z X p1p2 ).
But if q, p1 and p2 form a equilateral triangle with side 1 (admittedly a very extreme case of collision).
each vertex moves toward the center of the triangle, by the same distance (sqrt(3)/6 along the normal)
And projecting repeatedly such a collision constraint doesn't help (I guess you'd have to apply it once, then project the length constraints, project the collision constraint again, etc...).
My point with all this is that it's quite different from what Jakobsen is doing, where he moves the vertices all in the same direction qp (with some weighing based on geometry (ratio p1-p and p2-p):
in the case q and p1p2 all belong to rigid non static bodies, he just says to move them along some point between q and p, but not where that point lies.