Ejemplo n.º 1
0
			void compute(const Vector3<T>& v1, const Vector3<T>& v2, const Vector3<T>& v3) noexcept
			{
				// https://github.com/ands/trianglepacker/blob/master/trianglepacker.h at 185 line
				Vector3<T> tv[3];
				tv[0] = v2 - v1;
				tv[1] = v3 - v2;
				tv[2] = v1 - v3;

				T len2[3];
				len2[0] = length2(tv[0]);
				len2[1] = length2(tv[1]);
				len2[2] = length2(tv[2]);

				std::uint8_t maxi; T maxl = len2[0]; maxi = 0;
				if (len2[1] > maxl) { maxl = len2[1]; maxi = 1; }
				if (len2[2] > maxl) { maxl = len2[2]; maxi = 2; }
				std::uint8_t nexti = (maxi + 1) % 3;

				auto ww = std::sqrt(maxl);
				auto xx = -dot(tv[maxi], tv[nexti]) / ww;
				auto hh = length((tv[maxi] + tv[nexti]) - normalize(tv[maxi]) * (ww - xx));

				this->w = std::ceil(ww);
				this->h = std::ceil(hh);
			}
 bool FloatRect::intersects(const Sphere &sphere){
     float radius2 = sphere.r * sphere.r;
     return length2(sphere.x - this->x, sphere.y - this->y) < radius2 ||
             length2(sphere.x - (this->x + this->w), sphere.y - this->y) < radius2 ||
             length2(sphere.x - this->x, sphere.y - (this->y + this->h)) < radius2 ||
             length2(sphere.x - (this->x + this->w), sphere.y - (this->y + this->h)) < radius2;
 }
Ejemplo n.º 3
0
void draw_sec(CHpoints *p) {
  dpoint c;
  CHpoints *p1,*p2,*p3;
  double radius;
  
  if ((length2(before(p)->node,p->node) > 
       length2(p->node,next(p)->node)) &&
      (length2(before(p)->node,p->node) > 
       length2(before(p)->node,next(p)->node)))
    p2=next(p);  /* the angle at next(p) is the biggest */
  else if ((length2(p->node,next(p)->node) > 
	    length2(before(p)->node,next(p)->node)) &&
	   (length2(p->node,next(p)->node) > 
	    length2(p->node,before(p)->node)))
    p2=before(p); /* the angle at before(p) is the biggest */
  else
    p2=p; /* the angle at p is the biggest */
  p1=before(p2);
  p3=next(p2);

  if (angle(p1,p2,p3)<0) {
    c.x=(midpoint(p1->node,p3->node)).x;      /* center is midpoint of */
    c.y=(midpoint(p1->node,p3->node)).y;      /* p1 and p3             */
    radius=sqrt((double)length2(p1->node,p3->node))/2.00;    
  }
  else {
    c=centre(p1->node,p2->node,p3->node);
    radius=sqrt((double)radius2(p->node,c));
  }
  printf("The center is (%d,%d)\n",(int)c.x,(int)c.y);
  printf("The radius is %9.2f\n",radius);
}	
Ejemplo n.º 4
0
void longer(line *p_line1, line *p_line2,
		line **pp_line)
{
	if(length2(p_line1) >= length2(p_line2))
	{
		*pp_line = p_line1;
	}
	else
	{
		*pp_line = p_line2;
	}

}
Ejemplo n.º 5
0
bool MotionManager::isShakingImpl( float minShakeDeltaThreshold )
{
    const vec3& accel = getAcceleration();
	std::unique_lock<std::mutex> lock( sMutex ); // lock after we get the acceleration so there is no deadlock
    bool isShaking = false;
    if( mPrevAcceleration != vec3( 0 ) ) {
        mShakeDelta = length2(accel - mPrevAcceleration);
        if( length2(accel - mPrevAcceleration) > (minShakeDeltaThreshold * minShakeDeltaThreshold) )
            isShaking = true;
    }
    mPrevAcceleration = accel;
    return isShaking;
}
Ejemplo n.º 6
0
vfloat sin2vec(const vec& r1, const vec& r2) { 
  // sinus of angle between vectors
  pvecerror("vfloat sin2vec(const vec& r1, const vec& r2)");
  vfloat lr1 = length2(r1);  
  vfloat lr2 = length2(r2);
  if (lr1 == 0 || lr2 == 0) {vecerror=1; return 0;}
  vfloat sn = length(r1||r2); 
  sn = sn * sn;
  sn = sqrt(sn / (lr1 * lr2));
  //mcout<<"r1="<<r1<<"r2="<<r2<<"sin="<<sn<<'\n';
  return sn;
  //return sin(ang2vec(r1,r2));
}
Ejemplo n.º 7
0
static void handleCollisionHuge(Particle *p)
{
	Vec3 phuge;
	Vec3 dv, dr, dx1, dx2, d;
	Vec3 comv, comv1; /* Center Of Mass velocity */
	Vec3 dv1, dv2; /* Change of velocity after collision */
	float dvt1; 
	/* Difference of velocity in the direction of the tangent */
	float dt;
	float drsq, dvsq, dvdr, mindist;

	/* First, backtrack the movements of the particle to the moment they
	 * were just touching */
	sub(&p->pos, &huge.pos, &dr);
	sub(&p->vel, &huge.vel, &dv);

	drsq = length2(&dr);
	dvsq = length2(&dv); /* Square of the velocity difference */
	dvdr = dot(&dv, &dr);
	mindist = config.radius + config.radiusHuge;

	dt = (dvdr + sqrt(dvdr*dvdr + dvsq*(mindist * mindist - drsq))) / dvsq;
	if (fabs(dt) > 2 * config.timeStep)
		return;

	scale(&p->vel, -dt, &dx1);
	scale(&huge.vel, -dt, &dx2);

	add(&p->pos, &dx1, &p->pos);
	add(&huge.pos, &dx2, &huge.pos);

	normalize(&dr, &d);
	scale(&huge.vel, config.massHuge, &phuge);
	add(&p->vel, &phuge, &comv);
	scale(&comv, 1.0/(1 + config.massHuge), &comv);
	sub(&p->vel, &comv, &comv1);
	dvt1 = dot(&comv1, &d);
	scale(&d, -2*dvt1, &dv1);
	scale(&d,  2*dvt1/config.massHuge, &dv2);

	scale(&dv1, dt, &dx1);
	scale(&dv2, dt, &dx2);

	add(&p->pos, &dx1, &p->pos);
	add(&p->vel, &dv1, &p->vel);

	add(&huge.pos, &dx2, &huge.pos);
	add(&huge.vel, &dv2, &huge.vel);

	return;
}
Ejemplo n.º 8
0
/* Calculate Pearson correlation coefficient */
double pearson_correlation_coefficient(double* vectX, double* vectY, size_t dim)
{
	double sumXX = length2(vectX, dim);
	double sumYY = length2(vectY, dim);

	double sumX = sum(vectX, dim);
	double sumY = sum(vectY, dim);

	double N = (double) dim;

	double d = (dot_product(vectX, vectY, dim) - (sumX * sumY) / N);
	double f = sqrt((sumXX - sumX * sumX / N) * (sumYY - sumY * sumY / N));

	return d / f;
}
Ejemplo n.º 9
0
static void kineticHelper(Particle *p, void *data)
{
	assert(isSaneVector(p->vel));

	double *twiceK = (double*) data;
	*twiceK += p->m * length2(p->vel);
}
Ejemplo n.º 10
0
// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CAiwImagePrintIf::ConstructL()
    {
    
    TFileName file( KResource );
    file = PathInfo::RomRootPath();
    TBuf<KResource> length2(KResourceFile);    
    file.SetLength(KDriver + length2.Length());
    file.Replace(KDriver, length2.Length(), KResourceFile);
    
    BaflUtils::NearestLanguageFile( iEikEnv.FsSession(), file );
    iResourceOffset = iEikEnv.AddResourceFileL( file );
    iDRM = DRMCommon::NewL();
    User::LeaveIfError( iDRM->Connect() );
    iNumberOfUnSuppFiles = 0;
    
    
    TFileName printNameFile( KResource ); 
    printNameFile = PathInfo::PhoneMemoryRootPath(); 
    TBuf<KResource> length3(KParamFile);
    printNameFile.SetLength(KDriver + length3.Length());
    printNameFile.Replace(KDriver, length3.Length(), KParamFile); 
    
    iPrintFileName = HBufC::NewL(printNameFile.Length() );
    iPrintFileName->Des().Copy(printNameFile);
    
    TFileName unSuppFile( KResource ); 
    unSuppFile = PathInfo::PhoneMemoryRootPath(); 
    TBuf<KResource> lengthUn(KUnSuppFile);
    unSuppFile.SetLength(KDriver + lengthUn.Length());
    unSuppFile.Replace(KDriver, lengthUn.Length(), KUnSuppFile);
    
    iUnsuppFileName = HBufC::NewL(unSuppFile.Length() );
    iUnsuppFileName->Des().Copy(unSuppFile);
    
    }
Ejemplo n.º 11
0
/* p is the particle we're checking, ps is the first particle in the box */
static Particle *collideWith(const Particle *p, Particle *ps)
{
	Particle *other = ps;
	Vec3 diff;
	const float r = config.radius;
	
	if (ps == NULL)
		return NULL;

	do
	{
		if (p == other)
		{
			other = other->next;
			continue;
		}

		sub(&p->pos, &other->pos, &diff);
		if (length2(&diff) < 4*r*r)
			return other;

		other = other->next;
	} while (other != ps);

	return NULL;
}
Ejemplo n.º 12
0
VEC2	*normalized2(VEC2 *vec)
{
	float	length;

	length = length2(vec);
	vec->x /= length;
	vec->y /= length;
	return (vec);
}
Ejemplo n.º 13
0
	Vec3& normalize()
	{
		T nor2 = length2();
		if (nor2 > 0) {
			T invNor = 1 / sqrt(nor2);
			x *= invNor, y *= invNor, z *= invNor;
		}
		return *this;
	}
Ejemplo n.º 14
0
// **** vector ****
vfloat cos2vec(const vec& r1, const vec& r2) { 
  // cosinus of angle between vectors
  // If one of vectors has zero length, it returns 2.
  pvecerror("vfloat cos2vec(const vec& r1, const vec& r2)");
  vfloat lr1 = length2(r1);  
  vfloat lr2 = length2(r2);
  //mcout<<"cos2vec:\n";
  //Iprintn(mcout, lr1);
  //Iprintn(mcout, lr2);
  if (lr1 == 0 || lr2 == 0) {vecerror = 1; return 0;}
  vfloat cs = r1 * r2;
  int sign = 1; 
  if (cs < 0) sign = -1;
  cs = cs * cs;
  cs = sign * sqrt(cs / (lr1 * lr2));
  //mcout<<"r1="<<r1<<"r2="<<r2<<"cos="<<cs<<'\n';
  return cs;
  //return r1*r2/(lr1*lr2);
}
Ejemplo n.º 15
0
static inline void quaternionTFToMsg(const geometry_msgs::Quaternion& bt, geometry_msgs::Quaternion& msg)  {
	if (fabs(length2(bt) - 1 ) > QUATERNION_TOLERANCE)  {
		nh.loginfo("TF to MSG: Quaternion Not Properly Normalized");
		geometry_msgs::Quaternion bt_temp = bt; 
		bt_temp = normalize(bt_temp);
		msg.x = bt_temp.x; msg.y = bt_temp.y; msg.z = bt_temp.z;  msg.w = bt_temp.w;
	} else {
		msg.x = bt.x; msg.y = bt.y; msg.z = bt.z;  msg.w = bt.w;
	}
};
Ejemplo n.º 16
0
void TestCppTools::Quantity_test()
{
    Length length1(1.);
    Length length2(length1 * 5);
    Length length3;
    length3 = length2;
    //qDebug() << length1 << length2;

    QCOMPARE(sizeof(Length), sizeof(double));
}
Ejemplo n.º 17
0
		inline constexpr Vector3<T> normalize(const Vector3<T>& v) noexcept
		{
			T magSq = length2(v);
			if (magSq > 0.0f)
			{
				T invSqrt = 1.0f / std::sqrt(magSq);
				return v * invSqrt;
			}

			return v;
		}
Ejemplo n.º 18
0
void OBB::computeAxes(void)
{
  axis[0] = corner[1] - corner[0];
  axis[1] = corner[3] - corner[0];

  // Make the length of each axis 1/edge length so we know any
  // dot product must be less than 1 to fall within the edge.
  for (int a = 0; a < 2; ++a) {
    axis[a] /= length2(axis[a]);
		origin[a] = dot(corner[0],axis[a]);
  }
}
Ejemplo n.º 19
0
glm::mat4 alignZAxisWithTarget( vec3 targetDir, vec3 upDir )
{
    // Ensure that the target direction is non-zero.
    if( length2( targetDir ) == 0 )
		targetDir = vec3( 0, 0, 1 );

    // Ensure that the up direction is non-zero.
    if( length2( upDir ) == 0 )
		upDir = vec3( 0, 1, 0 );

    // Check for degeneracies.  If the upDir and targetDir are parallel 
    // or opposite, then compute a new, arbitrary up direction that is
    // not parallel or opposite to the targetDir.
    if( length2( cross( upDir, targetDir ) ) == 0 ) {
		upDir = cross( targetDir, vec3( 1, 0, 0 ) );
	if( length2( upDir ) == 0 )
	    upDir = cross( targetDir, vec3( 0, 0, 1 ) );
    }

    // Compute the x-, y-, and z-axis vectors of the new coordinate system.
	vec3 targetPerpDir = cross( upDir, targetDir );
	vec3 targetUpDir = cross( targetDir, targetPerpDir );

    // Rotate the x-axis into targetPerpDir (row 0),
    // rotate the y-axis into targetUpDir   (row 1),
    // rotate the z-axis into targetDir     (row 2).
    vec3 row[3];
    row[0] = normalize( targetPerpDir );
	row[1] = normalize( targetUpDir );
	row[2] = normalize( targetDir );

    const float v[16] = {	row[0].x,  row[0].y,  row[0].z,  0,
							row[1].x,  row[1].y,  row[1].z,  0,
							row[2].x,  row[2].y,  row[2].z,  0,
					        0,         0,         0,		 1 };
	
    
    return glm::make_mat4( v );
}
Ejemplo n.º 20
0
ItemPtr getClosestItem(Ray ray) {
	ItemPtr closestItem = NULL;
	real distance2 = 1e300;
	for(int i=0;i<itemNumber;i++) {
		Vector intersection = getIntersectPoint(&items[i], ray);
		real cur2 = length2(intersection);
		if(cur2 != 0 && cur2 < distance2) {
			distance2 = cur2;
			closestItem = &items[i];
		}
	}
	return closestItem;
}
Ejemplo n.º 21
0
Vector getNormal(ItemPtr item, Ray ray, Vector point) {
	switch(item->type) {
	case SPHERE:
	case LIGHT:
		if(length2(ray.from-item->center)<item->radius * item->radius) {
			//inside!
			return fast_normalize(item->center-point);
		}
		return fast_normalize(point-item->center);
	case CHECKER:
		return item->normal;
	default:
		return ZERO;
	}
}
Ejemplo n.º 22
0
void TestStyles::testCopyParagraphStyle()
{
    QTextLength length1(QTextLength::FixedLength, 10.0);
    QTextLength length2(QTextLength::FixedLength, 20.0);
    QTextLength length3(QTextLength::FixedLength, 30.0);

    KoParagraphStyle style1;
    KoParagraphStyle style2;
    style2.setParentStyle(&style1);

    style1.setLeftMargin(length1);
    style1.setRightMargin(length3);
    style2.setRightMargin(length2);

    KoParagraphStyle newStyle;
    newStyle.copyProperties(&style2);
    QCOMPARE(newStyle.leftMargin(), 10.0);
    QCOMPARE(newStyle.rightMargin(), 20.0);
}
Ejemplo n.º 23
0
static void Fstack(Particle *p1, Particle *p2, int monomerDistance)
{
	assert(isBase(p1->type) && isBase(p2->type));

	if (!interactions.enableStack)
		return;

	Vec3 r = nearestImageVector(p1->pos, p2->pos);
	double rSq = length2(r);
	if (rSq > truncationLenSq)
		return;

	double rEqSq = neighbourStackDistance2(p1->type, p2->type,
						monomerDistance);
	double FperDist = calcFLJperDistance(STACK_COUPLING, rEqSq, rSq);
	Vec3 F = scale(r, FperDist);
	debugVectorSanity(F, "Fstack");
	p1->F = add(p1->F, F);
	p2->F = sub(p2->F, F);
}
Ejemplo n.º 24
0
static void Fexclusion(Particle *p1, Particle *p2)
{
	if (!interactions.enableExclusion)
		return;

	if (!feelExclusion(p1, p2))
		return;

	double cutOffSq = getExclusionCutOff2(p1->type, p2->type);
	Vec3 r = nearestImageVector(p1->pos, p2->pos);
	double rSq = length2(r);
	if (rSq > cutOffSq)
		return;

	double FperDist = calcFLJperDistance(EXCLUSION_COUPLING, cutOffSq, rSq);
	Vec3 F = scale(r, FperDist);
	debugVectorSanity(F, "Fexclusion");
	p1->F = add(p1->F, F);
	p2->F = sub(p2->F, F);
}
Ejemplo n.º 25
0
Vector getIntersectPointSphere(ItemPtr item, Ray ray) {
	Vector centerRay = item->center - ray.from;
	real dotValue = dot(ray.ray, centerRay);
	if(dotValue<0) {
		//behind
		return ZERO;
	}
	//http://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection
	real discriminant = dotValue*dotValue - length2(centerRay) + item->radius*item->radius;
	if(discriminant<0) {
		//does not intersect
		return ZERO;
	}
	discriminant=sqrt(discriminant);

	real close = dotValue - discriminant;
	real further = dotValue + discriminant;

	return ray.ray * (close > 0 ? close : further);
}
Ejemplo n.º 26
0
	virtual float3 sample_direct(UniformRandomGenerator & gen, const float3 & P, float3 & Wi, float & pdf) const override final
	{
		if (dot(quad->normal, P - quad->base) <= 0.0f)
			return float3(0, 0, 0);

		float2 xi = { gen.random_float(), gen.random_float() };
		const float3 q = quad->base + xi.x*quad->edge0 + xi.y*quad->edge1;
		float3 pt = q - P;

		float rSq = length2(pt);
		const float distance = std::sqrt(rSq);
		pt /= distance;

		const float cosTheta = -dot(quad->normal, pt);

		Wi = pt;
		pdf = rSq / (cosTheta * quad->area);

		return intensity * (1.f / (distance)); // linear

	}
Ejemplo n.º 27
0
static Particle *collides(const Particle *p)
{
	Particle *other;
	Box *b;
	int ix, iy, iz;
	int nx, ny, nz;

#ifdef BROWNIAN
	const float d = config.radius + config.radiusHuge;
	Vec3 dhuge;
	sub(&p->pos, &huge.pos, &dhuge);
	if (length2(&dhuge) < d*d)
		return &huge;
#endif

	nx = p->pos.x / config.boxSize;
	ny = p->pos.y / config.boxSize;
	nz = p->pos.z / config.boxSize;

	b = boxFromIndex(nx, ny, nz);
	other = collideWith(p, b->p);
	if (other != NULL)
		return other;

	for (ix = -1; ix <= 1; ix++)
	for (iy = -1; iy <= 1; iy++)
	for (iz = -1; iz <= 1; iz++)
	{
		if (ix == 0 && iy == 0 && iz == 0)
			continue;

		b = boxFromIndex(nx+ix, ny+iy, nz+iz);
		other = collideWith(p, b->p);
		if (other != NULL)
			return other;
	}

	return NULL;
}
Ejemplo n.º 28
0
void TestStyles::testApplyParagraphStyleWithParent()
{
    KoParagraphStyle style1;
    style1.setStyleId(1002);
    KoParagraphStyle style2;
    style2.setStyleId(1003);
    KoParagraphStyle style3;
    style3.setStyleId(1004);

    style3.setParentStyle(&style2);
    style2.setParentStyle(&style1);

    style1.setAlignment(Qt::AlignRight);
    QCOMPARE(style1.alignment(), Qt::AlignRight);
    QCOMPARE(style2.alignment(), Qt::AlignRight);
    QCOMPARE(style3.alignment(), Qt::AlignRight);

    style2.setAlignment(Qt::AlignCenter);
    QCOMPARE(style1.alignment(), Qt::AlignRight);
    QCOMPARE(style2.alignment(), Qt::AlignCenter);
    QCOMPARE(style3.alignment(), Qt::AlignCenter);

    style3.setAlignment(Qt::AlignLeft | Qt::AlignAbsolute);
    QCOMPARE(style1.alignment(), Qt::AlignRight);
    QCOMPARE(style2.alignment(), Qt::AlignCenter);
    QCOMPARE(style3.alignment(), Qt::AlignLeft | Qt::AlignAbsolute);

    style3.setLineSpacing(23.45);
    style3.setLineHeightPercent(150);
    style3.setLineHeightAbsolute(8.0);
    QCOMPARE(style3.lineHeightPercent(), 0.0);
    QCOMPARE(style3.lineHeightAbsolute(), 8.0);
    QCOMPARE(style3.lineSpacing(), 23.45);
    QVERIFY(!style3.hasNormalLineHeight());

    style3.setNormalLineHeight();
    QCOMPARE(style3.lineHeightPercent(), 0.0);
    QCOMPARE(style3.lineHeightAbsolute(), 0.0);
    QCOMPARE(style3.lineSpacing(), 0.0);
    QVERIFY(style3.hasNormalLineHeight());

    style3.setLineHeightPercent(150);
    style3.setLineSpacing(56.78);
    QCOMPARE(style3.lineHeightPercent(), 150.0);
    QCOMPARE(style3.lineHeightAbsolute(), 0.0);
    QCOMPARE(style3.lineSpacing(), 56.78);
    QVERIFY(!style3.hasNormalLineHeight());

    QTextLength length0(QTextLength::FixedLength, 0.0);
    QTextLength length1(QTextLength::FixedLength, 10.0);
    QTextLength length2(QTextLength::FixedLength, 20.0);

    style1.setLeftMargin(length1);
    QCOMPARE(style1.leftMargin(), 10.0);
    QCOMPARE(style2.leftMargin(), 10.0);
    QCOMPARE(style3.leftMargin(), 10.0);
    style2.setRightMargin(length2);
    QCOMPARE(style1.rightMargin(), 0.0);
    QCOMPARE(style2.rightMargin(), 20.0);
    QCOMPARE(style3.rightMargin(), 20.0);

    // now actually apply it.
    QTextBlockFormat rawFormat;
    style1.applyStyle(rawFormat);
    KoParagraphStyle format(rawFormat, rawFormat.toCharFormat());
    QCOMPARE(rawFormat.properties().count(), 4);
    QCOMPARE(format.alignment(), Qt::AlignRight);
    QCOMPARE(rawFormat.property(KoParagraphStyle::StyleId).toInt(), 1002);
    //since we have not specified any NextStyle it should be the same as the current style
    QCOMPARE(rawFormat.property(KoParagraphStyle::StyleId).toInt(), rawFormat.property(KoParagraphStyle::NextStyle).toInt());
    QCOMPARE(format.leftMargin(), 10.0);
    QCOMPARE(format.rightMargin(), 0.0);

    style2.applyStyle(rawFormat);
    KoParagraphStyle format2(rawFormat, rawFormat.toCharFormat());
    QCOMPARE(rawFormat.properties().count(), 5);
    QCOMPARE(format2.alignment(), Qt::AlignCenter);
    QCOMPARE(rawFormat.property(KoParagraphStyle::StyleId).toInt(), 1003);
    //since we have not specified any NextStyle it should be the same as the current style
    QCOMPARE(rawFormat.property(KoParagraphStyle::StyleId).toInt(), rawFormat.property(KoParagraphStyle::NextStyle).toInt());
    QCOMPARE(format2.leftMargin(), 10.0);
    QCOMPARE(format2.rightMargin(), 20.0);

    style3.applyStyle(rawFormat);
    KoParagraphStyle format3(rawFormat, rawFormat.toCharFormat());
    QCOMPARE(rawFormat.properties().count(), 9);
    QCOMPARE(rawFormat.property(KoParagraphStyle::LineSpacing).toReal(), 56.78);
    QCOMPARE(format3.alignment(), Qt::AlignLeft | Qt::AlignAbsolute);
    QCOMPARE(rawFormat.property(KoParagraphStyle::StyleId).toInt(), 1004);
    //since we have not specified any NextStyle it should be the same as the current style
    QCOMPARE(rawFormat.property(KoParagraphStyle::StyleId).toInt(), rawFormat.property(KoParagraphStyle::NextStyle).toInt());
    QCOMPARE(format3.leftMargin(), 10.0);
    QCOMPARE(format3.rightMargin(), 20.0);
}
Ejemplo n.º 29
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);
}
Ejemplo n.º 30
0
 inline float length(const vec2& v) {
     return sqrtf(length2(v));
 }