Example #1
0
/////////////////////////////////////////////////////////////////////////////
// Function:	PositionAtom
// Purpose:		Given an atom object, sets the coordinates to be consistent with
//				the given bond length and angle
// Input:       Two atoms, with the first atom is bonded to the new atom and the
//				second atom bonded to the first.
//				The distance in angstroms between the new atom and the first atom
//				The angle in degrees between the new atom, the first atom, and the
//				second atom
// Output:		Writes new coordinates to the atom object
// Requires:
/////////////////////////////////////////////////////////////////////////////
void PositionAtom(MIAtom *atom,
                  const MIAtom *root1,
                  const MIAtom *root2,
                  float length,
                  float angle)
{
    double cosba = cos(DEG2RAD * angle);
    double sinba = sin(DEG2RAD * angle);

    //Calculate the bond vector: the unit vector along the bond from root1 to root2
    double bv[3];
    BondVector(root1, root2, bv);
    NormVect(bv, bv);

    //Construct an orthogonal vector: a unit vector that is orthogonal to the bond vector
    double ov[3];
    ov[0] = -bv[1];
    ov[1] = bv[0];
    ov[2] = 0;
    NormVect(ov, ov);

    //Position the atom along the vector (cosba * bv + sinba * ov)
    atom->setPosition((float)(root1->x() + length * (bv[0] * cosba + ov[0] * sinba)),
                      (float)(root1->y() + length * (bv[1] * cosba + ov[1] * sinba)),
                      (float)(root1->z() + length * (bv[2] * cosba)));     //note that ov[2] = 0
}
Example #2
0
static void Q_refl(STri *t, STri *tnew) {
	DPoint n;
	/* reflect vert 2 in line connecting vert 0 and 1 */
	tnew->p[0] = t->p[0];
	tnew->p[1] = t->p[1];
	DCrossProd(&n.x, &t->p[0].x, &t->p[1].x);
	NormVect(&n.x);	
	ReflVect(&tnew->p[2].x,&t->p[2].x,&n.x);
	ReflVect(&tnew->v.x,&t->v.x,&n.x);
	reg_vert(&tnew->v);
	}
Example #3
0
/////////////////////////////////////////////////////////////////////////////
// Function:    PositionAtom
// Purpose:		Given an atom object, sets the coordinates to be consistent
//			    with the given internal coordinates
// Input:       Three atoms, generally the first atom is bonded to the new atom
//				The distance in angstroms between the new atom and "root1"
//				The angle in degrees between the new atom, root1, and root2
//				The dihedral angle between all four atoms, around the root1-root2 bond
// Output:      Writes new coordinates to the atom object
// Requires:	Note that if root1, root2, and root3 are collinear atoms, the
//				the atom position is underdetermined, because the dihedral angle
//				is meaningless
/////////////////////////////////////////////////////////////////////////////
void PositionAtom(MIAtom *atom,
                  const MIAtom *root1,
                  const MIAtom *root2,
                  const MIAtom *root3,
                  float length,
                  float angle,
                  float torsion)
{

    atom->setPosition(root1->x(), root1->y(), root1->z());                         //Start new atom on top of the previous atom

    double cosba = cos(DEG2RAD * angle);
    double sinba = sin(DEG2RAD * angle);

    double v[3], temp[3];                               //set v to be the unit vector from the
    BondVector(root1, root2, v);                        //attachment pt to a connected atom
    NormVect(v, v);

    atom->translate((float)(v[0] * cosba * length),              //Move to an arbitrary point
                    (float)(v[1] * cosba * length),  //with the correct bond length
                    (float)(v[2] * cosba * length));  //and angle.

    temp[0] = -v[1];
    temp[1] = v[0];
    temp[2] = 0;
    NormVect(temp, temp);

    atom->translate((float)(temp[0] * sinba * length),
                    (float)(temp[1] * sinba * length),
                    0.0f); //Have chosen delta(z)=0

    double chi;
    chi = CalcAtomTorsion(root3, root2, root1, atom);       //Get the current torsion value

    RotateAtom(root2, root1, atom, torsion-(float)chi);
}
Example #4
0
static int MakeHedron(int np, int dp, int nq, int dq, double cp, double cq) {
	STri t0;
	double pang,qang,cosp,cosq,sinp,sinq;

#ifdef DBG
	printf("MakeHedron: p = %d/%d  q = %d/%d  cp = %.4f  cq = %.4f\n",np,dp,nq,dq,cp,cq);
#endif

	nregtris = nfaces = nverts = 0;
	center_verts = state.verts>0?1:0;
	subdiv_sides = state.verts==2?1:0;
	nsides[0] = 4;
	nsides[1] = np;
	nsides[2] = nq;

	/* these are two of the angles of a right spherical triangle */
	pang = PI*(double)dp/(double)np;
	qang = PI*(double)dq/(double)nq;

	/* compute the (sin,cos) of sides of the spherical triangle */
	cosp = cos(pang)/sin(qang);
	cosq = cos(qang)/sin(pang);
	sinp = sqrt(1.0-cosp*cosp);
	sinq = sqrt(1.0-cosq*cosq);

	t0.p[0].x = 0.0;  t0.p[0].y = 0.0;  t0.p[0].z = 1.0;
	t0.p[1].x = sinq; t0.p[1].y = 0.0;  t0.p[1].z = cosq;
	t0.p[2].x = 0.0;  t0.p[2].y = sinp; t0.p[2].z = cosp;

	t0.v.x = cq*sinq; 
	t0.v.y = cp*sinp;
	t0.v.z = 1.0 + cq*(cosq-1.0) + cp*(cosp-1.0);
 	NormVect(&t0.v.x); 

#ifdef DBG
	printf(" pang = %.5f, qang = %.5f \n", RadToDeg(pang), RadToDeg(qang));
	printf(" cpa = %.5f, cqa = %.5f\n", RadToDeg(acos(cosp)),RadToDeg(acos(cosq)));
	printf(" t = (%.4f,%.4f,%.4f) \n",t0.v.x,t0.v.y,t0.v.z);
#endif
	switch(state.axis) {
		case 1:  /* want P aligned with Z -- rotate into pos*/
			RotY(&t0.p[0],-sinq,cosq);									
			RotY(&t0.p[1],-sinq,cosq);									
			RotY(&t0.p[2],-sinq,cosq);									
			RotY(&t0.v,-sinq,cosq);									
			break;
		case 2:  /* Q aligned with Z -- */
			RotX(&t0.p[0],sinp,cosp);									
			RotX(&t0.p[1],sinp,cosp);									
			RotX(&t0.p[2],sinp,cosp);									
			RotX(&t0.v,sinp,cosp);									
			break;
		}

#ifdef DBG
	printf(" p0 = %.4f, %.4f, %.4f \n",t0.p[0].x,t0.p[0].y,t0.p[0].z); 
	printf(" p1 = %.4f, %.4f, %.4f \n",t0.p[1].x,t0.p[1].y,t0.p[1].z); 
	printf(" p2 = %.4f, %.4f, %.4f \n",t0.p[2].x,t0.p[2].y,t0.p[2].z); 
	printf(" v  = %.4f, %.4f, %.4f \n",t0.v.x,t0.v.y,t0.v.z); 
#endif

	memset(axis,0,3*sizeof(AxisList));
	reg_vert(&t0.v);
	level = 0;
	traverse(&t0, -1);

	do_axis[0] = do_axis[1] = do_axis[2] = 1;
	star_axis[0] = star_axis[1] = star_axis[2] = 0;
	if (dp>1) star_axis[1] = 1;	
	if (dq>1) star_axis[2] = 1;	

	if (cp==0||cq==0) do_axis[0] = 0;
	if (cp==0.0 && cq==1.0) do_axis[1] = 0;
	if (cp==1.0 && cq==0.0) do_axis[2] = 0;


#ifdef DBG
	printf(" nsides = %d,%d,%d \n",nsides[0],nsides[1],nsides[2]);
	printf(" do_axis= %d,%d,%d \n",do_axis[0],do_axis[1],do_axis[2]);
	printf(" numaxis = %d,%d,%d \n",axis[0].num,axis[1].num,axis[2].num);
	printf(" nverts = %d \n",nverts);
	printf(" ------------------ MakeHedron done -----------------\n");
#endif
	

	return(1);
	}