Esempio n. 1
0
// compute the bounding box of the transform of a rectangle
void
transformRegionFromRoD(const RectD &srcRect,
                       const Matrix3x3 &transform,
                       RectD &dstRect)
{
    /// now transform the 4 corners of the source clip to the output image
    Point3D p[4];

    p[0] = matApply( transform, Point3D(srcRect.x1, srcRect.y1, 1) );
    p[1] = matApply( transform, Point3D(srcRect.x1, srcRect.y2, 1) );
    p[2] = matApply( transform, Point3D(srcRect.x2, srcRect.y2, 1) );
    p[3] = matApply( transform, Point3D(srcRect.x2, srcRect.y1, 1) );


    transformRegionFromPoints(p, dstRect);
}
Esempio n. 2
0
/* Derivative of the dihedral potential. This shit gets quite involved.
 *
 * We want to compute
 *   Fi = -grad_ri V(r1, r2, r3, r4)
 * Fi the force on the i'th particle and rj the position of the j'th 
 * particle.
 * 
 * We can rather easily write V as a function of
 *   A = r12 x r23  =  (r2 - r1) x (r3 - r2)
 * and
 *   B = r23 x r34  =  (r3 - r2) x (r4 - r3)
 *
 * Indeed, we have:
 *   V = DIHEDRAL_COUPLING * (1 - cos(phi - phi0))
 * where
 *   phi = acos(A dot B / |A| * |B|)
 *
 * We can then write Fi as:
 *   Fi = -grad_ri Vi(A(r1, r2, r3), B(r2, r3, r4))
 * and use the appropriate chain rule:
 *   Fi = - [J_ri(A)]^t * (grad_A V)
 *        - [J_ri(B)]^t * (grad_B V)
 * where [J_ri(X)]^t is the transpose of the Jacobian matrix of the vector 
 * function X with regards to ri.
 *
 * After some calculus and algebra, we get
 *   grad_A V = DIHEDRAL_COUPLING
 *                * [ sin(phi0)/sin(phi) * (A dot B)/(|A|^2 |B|^2)
 *                                  - cos(phi0) / (|A||B|) ]
 *                * [B - A (A dot B) / (|B||A|)]
 * and due to the symmetry in V of A and B, grad_B V is exactly the same, 
 * but with A and B interchanged.
 *   grad_B V = DIHEDRAL_COUPLING
 *                * [ sin(phi0)/sin(phi) * (A dot B)/(|A|^2 |B|^2)
 *                                  - cos(phi0) / (|A||B|) ]
 *                * [A - B (A dot B) / (|B||A|)]
 *
 *
 * NOTE: when debugging the dihedral force for energy conservation, you 
 * also need to enable angle and bond interactions (which should be 
 * debugged first), otherwise you get a badly conditioned problem and you 
 * will experience blow up.
 */
static void Fdihedral(Particle *p1, Particle *p2, Particle *p3, Particle *p4,
							DihedralCache phi0)
{
	if (!interactions.enableDihedral)
		return;

	Vec3 r12 = nearestImageVector(p1->pos, p2->pos);
	Vec3 r23 = nearestImageVector(p2->pos, p3->pos);
	Vec3 r34 = nearestImageVector(p3->pos, p4->pos);

	double sinPhi, cosPhi; //TODO find better algorithm to only compute sinPhi
	sinCosDihedral(r12, r23, r34, &sinPhi, &cosPhi);
	if (UNLIKELY(fabs(sinPhi) < 1e-5)) //TODO just check for ==0? -> saves an fabs!
		return; /* (Unstable) equilibrium. */

	double sinPhi0 = phi0.sinDihedral;
	double cosPhi0 = phi0.cosDihedral;

	Vec3 A = cross(r12, r23);
	Vec3 B = cross(r23, r34);

	double lAl2 = length2(A);
	double lBl2 = length2(B);
	double lAl2lBl2 = lAl2 * lBl2;
	double lAllBl = sqrt(lAl2lBl2);
	double AdB = dot(A, B);
	double negGradPrefactor = DIHEDRAL_COUPLING * (cosPhi0 / lAllBl
					- sinPhi0/sinPhi * AdB/lAl2lBl2);
	/* -grad_A(V) */
	Vec3 negGrad_AV = scale(
			sub(B, scale(A, AdB/lAl2)),
			negGradPrefactor);
	/* -grad_B(V) */
	Vec3 negGrad_BV = scale(
			sub(A, scale(B, AdB/lBl2)),
			negGradPrefactor);

	/* F1 */
	Mat3 J_r1A = crossProdTransposedJacobian(r12, r23, 1); /* [J_r1(A)]^t */
	/* [J_r1(B)]^t = 0*/
	Vec3 F1 = matApply(J_r1A, negGrad_AV);

	/* F2 */
	Mat3 J_r2A = crossProdTransposedJacobian(r12, r23, 2); /* [J_r2(A)]^t */
	Mat3 J_r2B = crossProdTransposedJacobian(r23, r34, 1); /* [J_r2(B)]^t */
	Vec3 F2 = add(matApply(J_r2A, negGrad_AV), matApply(J_r2B, negGrad_BV));

	/* F4 (not F3 because that has two non-zero jacobi matrices, 
	 * whereas F4 has only one non-zero jacobi matrix, so it's 
	 * faster to compute)*/
	/* [J_r4(A)]^t = 0*/
	Mat3 J_r4B = crossProdTransposedJacobian(r23, r34, 3); /* [J_r4(B)]^t */
	Vec3 F4 = matApply(J_r4B, negGrad_BV);

	/* -F3 */
	Vec3 negF3 = add(add(F1, F2), F4);

	p1->F = add(p1->F, F1);
	p2->F = add(p2->F, F2);
	p3->F = sub(p3->F, negF3);
	p4->F = add(p4->F, F4);
}