Logo Search packages:      
Sourcecode: pymol version File versions  Download package

Shaker.c

/* 
A* -------------------------------------------------------------------
B* This file contains source code for the PyMOL computer program
C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific. 
D* -------------------------------------------------------------------
E* It is unlawful to modify or remove this copyright notice.
F* -------------------------------------------------------------------
G* Please see the accompanying LICENSE file for further information. 
H* -------------------------------------------------------------------
I* Additional authors of this source file include:
-* 
-* 
-*
Z* -------------------------------------------------------------------
*/

#include"os_predef.h"
#include"os_std.h"
#include"os_gl.h"
#include"Base.h"
#include"OOMac.h"
#include"CGO.h"

#include"Map.h"

#include"Shaker.h"

CShaker *ShakerNew(PyMOLGlobals *G)
{
  OOAlloc(G,CShaker);
  I->G=G;
  I->DistCon = VLAlloc(ShakerDistCon,1000);
  I->PyraCon = VLAlloc(ShakerPyraCon,1000);
  I->PlanCon = VLAlloc(ShakerPlanCon,1000);
  I->TorsCon = VLAlloc(ShakerTorsCon,1000);
  I->LineCon = VLAlloc(ShakerLineCon,100);
  I->NDistCon = 0;
  I->NPyraCon = 0;
  I->NPlanCon = 0;
  I->NLineCon = 0;
  I->NTorsCon = 0;
  return(I);
}

void ShakerReset(CShaker *I)
{
  I->NDistCon = 0;
  I->NPyraCon = 0;
  I->NPlanCon = 0;
  I->NLineCon = 0;
  I->NTorsCon = 0;
}

#if 0
/* this code moved into Sculpt.c */

float ShakerDoDist(float target,float *v0,float *v1,float *d0to1,float *d1to0,float wt)
{
  float d[3],push[3];
  float len,dev,dev_2,sc,result;

  subtract3f(v0,v1,d);
  len = (float)length3f(d);
  dev = target-len;
  if((result=fabs(dev))>R_SMALL8) {
    dev_2 = wt*dev*0.5F;
    if(len>R_SMALL8) { /* nonoverlapping */
      sc = dev_2/len;
      scale3f(d,sc,push);
      add3f(push,d0to1,d0to1);
      subtract3f(d1to0,push,d1to0);
    } else { /* overlapping, so just push in a random direction */
      float rd[3];
      get_random3f(rd);
      d0to1[0]-=rd[0]*dev_2;
      d1to0[0]+=rd[0]*dev_2;
      d0to1[1]-=rd[1]*dev_2;
      d1to0[1]+=rd[1]*dev_2;
      d0to1[2]-=rd[2]*dev_2;
      d1to0[2]+=rd[2]*dev_2;
    }
  } else
    result = 0.0;
  return result;
}

float ShakerDoDistLimit(float target,float *v0,float *v1,float *d0to1,float *d1to0,float wt)
{
  float d[3],push[3];
  float len,dev,dev_2,sc;

  if(wt==0.0F) return 0.0F;
  subtract3f(v0,v1,d);
  len = (float)length3f(d);
  dev = target-len;
  if(dev<0.0F) { /* assuming len is non-zero since it is above target */
    dev_2 = wt*dev*0.5F;
    sc = dev_2/len;
    scale3f(d,sc,push);
    add3f(push,d0to1,d0to1);
    subtract3f(d1to0,push,d1to0);
    return -dev;
  } else
    return 0.0F;
}

#endif

void ShakerAddDistCon(CShaker *I,int atom0,int atom1,float target,int type,float wt)
{
  ShakerDistCon *sdc;

  VLACheck(I->DistCon,ShakerDistCon,I->NDistCon);
  sdc = I->DistCon+I->NDistCon;
  sdc->at0=atom0;
  sdc->at1=atom1;
  sdc->targ = target;
  sdc->type = type;
  sdc->weight = wt;
  I->NDistCon++;
}

float ShakerGetPyra(float *v0,float *v1,float *v2,float *v3)
{
  float d0[3],cp[3],d2[3],d3[3];
  subtract3f(v2,v1,d2);
  /*  normalize3f(d2);*/
  subtract3f(v3,v1,d3);
  /* normalize3f(d3);*/
  cross_product3f(d2,d3,cp);
  normalize3f(cp);
  subtract3f(v1,v0,d0);
  return(dot_product3f(d0,cp));
}


float ShakerDoPyra(float target,float *v0,float *v1,float *v2,float *v3,
                   float *p0,float *p1,float *p2,float *p3,float wt)
{
  float d0[3],cp[3],d2[3],d3[3],push[3];
  float cur,dev,sc,result;
  subtract3f(v2,v1,d2);
  /*  normalize3f(d2);*/
  subtract3f(v3,v1,d3);
  /*  normalize3f(d3);*/
  cross_product3f(d2,d3,cp); 
  subtract3f(v1,v0,d0);
  normalize3f(cp); /* this is our axis */
  cur = dot_product3f(d0,cp);

  dev = cur-target;
  if((result = (float)fabs(dev))>R_SMALL8) {
    sc = wt*dev;
    scale3f(cp,sc,push);
    add3f(push,p0,p0);
    scale3f(push,1.0F*0.333333F,push);
    subtract3f(p1,push,p1);
    subtract3f(p2,push,p2);
    subtract3f(p3,push,p3);
  } else
    dev = 0.0;
  return result;

}


float ShakerDoLine(float *v0,float *v1,float *v2,
                   float *p0,float *p1,float *p2,float wt)
{
  /* v0-v1-v2 */

  float d0[3],d1[3],cp[3],d2[3],d3[3],d4[3],push[3];
  float dev,sc,lcp,result;

  subtract3f(v2,v1,d2);
  subtract3f(v0,v1,d1);
  normalize3f(d2);
  normalize23f(d1,d0);

  cross_product3f(d2,d0,cp); 
  lcp = (float)length3f(cp);
  if(lcp>R_SMALL4) {
    lcp = 1.0F/lcp;
    scale3f(cp,lcp,cp); /* axis 0 */

    subtract3f(v2,v0,d3);
    normalize3f(d3);  /* axis 1 */
    
    cross_product3f(cp,d3,d4); 
    normalize3f(d4); /* displacement direction */

    dev = dot_product3f(d1,d4); /* current deviation */

    if((result = (float)fabs(dev))>R_SMALL8) {
      sc = wt*dev;
      scale3f(d4,sc,push);
      add3f(push,p1,p1);
      scale3f(push,0.5F,push);
      subtract3f(p0,push,p0);
      subtract3f(p2,push,p2);
    } else {
      result = 0.0;
    }
  } else
    result = 0.0;
  return result;

}



float ShakerDoPlan(float *v0,float *v1,float *v2,float *v3,
                   float *p0,float *p1,float *p2,float *p3,
                   float target, int fixed, float wt)
{

  float result;

#if 0
  float vc[3],d0[3],d1[3],d2[3],cp[3];
  float push[3];
  float cur,dev,sc;

  average3f(v0,v3,vc);

  subtract3f(v1,vc,d1);
  normalize3f(d1);

  subtract3f(v2,vc,d2);
  normalize3f(d2);

  cross_product3f(d1,d2,cp); 
  normalize3f(cp); /* this is our axis */

  subtract3f(v0,vc,d0);
  cur = dot_product3f(d0,cp);

  dev = (float)fabs(cur);
  if((result = (float)fabs(dev))>R_SMALL8) {

    sc = -wt*dev*0.5F;

    subtract3f(v0,v3,d0);
    normalize3f(d0);
    scale3f(d0,sc,push);
    add3f(push,p0,p0); 
    subtract3f(p3,push,p3);

    sc = -2.0F*sc ;

    subtract3f(v0,v2,d0);
    normalize3f(d0);
    scale3f(d0,sc,push);
    add3f(push,p0,p0); 
    subtract3f(p2,push,p2);

    subtract3f(v1,v3,d0);
    normalize3f(d0);
    scale3f(d0,sc,push);
    add3f(push,p1,p1); 
    subtract3f(p3,push,p3);
  } else

#else
    
    float d01[3],d12[3],d23[3],d03[3],cp0[3],cp1[3],dp,sc,dev,d0[3],push[3];
  double s01,s12,s23,s03;
    
    subtract3f(v0,v1,d01);
    subtract3f(v1,v2,d12);
    subtract3f(v2,v3,d23);
    subtract3f(v0,v3,d03);    

    s03 = lengthsq3f(d03);
    s01 = lengthsq3f(d01);
    s12 = lengthsq3f(d12);
    s23 = lengthsq3f(d23);
    
    if( (s03<s01) || (s03<s12) || (s03<s23))
      return 0.0F;

    cross_product3f(d01,d12,cp0);
    cross_product3f(d12,d23,cp1);
    
    normalize3f(cp0);
    normalize3f(cp1);

    dp = dot_product3f(cp0,cp1);
    
    result = (dev = 1.0F - (float)fabs(dp));
    
    if(dev>R_SMALL4) {

      /*
        add3f(cp0,cp1,d0);
        normalize3f(d0);
        
        cross_product3f(cp0,d12,pos);
        dp2 = dot_product3f(cp1,pos);
      */
      
      if(fixed && (dp*target<0.0F)) {
        if(dp<0.0F) {
          sc = -wt*dev*0.5F;
        } else {
          sc = wt*dev*0.5F;
        }
      } else if(dp>0) {
        sc = -wt*dev*0.5F;
      } else {
        sc = wt*dev*0.5F;
      }
      
      if(fixed) {
        sc *= 8;
      } else {
        sc *= 0.2F;
      }

      /* pair-wise nudges */

      subtract3f(v0,v3,d0);
      normalize3f(d0);
      scale3f(d0,sc,push);
      add3f(push,p0,p0); 
      subtract3f(p3,push,p3);

      subtract3f(v1,v2,d0);
      normalize3f(d0);
      scale3f(d0,sc,push);
      add3f(push,p1,p1); 
      subtract3f(p2,push,p2);

      sc = -sc;
      subtract3f(v0,v2,d0);
      normalize3f(d0);
      scale3f(d0,sc,push);
      add3f(push,p0,p0); 
      subtract3f(p2,push,p2);

      subtract3f(v1,v3,d0);
      normalize3f(d0);
      scale3f(d0,sc,push);
      add3f(push,p1,p1); 
      subtract3f(p3,push,p3);

    } else
#endif    
      result = 0.0;
  return result;

}

void ShakerAddPyraCon(CShaker *I,int atom0,int atom1,int atom2,int atom3,float target)
{
  ShakerPyraCon *spc;
  
  VLACheck(I->PyraCon,ShakerPyraCon,I->NPyraCon);
  spc = I->PyraCon+I->NPyraCon;
  spc->at0=atom0;
  spc->at1=atom1;
  spc->at2=atom2;
  spc->at3=atom3;
  spc->targ = target;
  I->NPyraCon++;

}


void ShakerAddTorsCon(CShaker *I,int atom0,int atom1,int atom2,int atom3,int type)
{
  ShakerTorsCon *stc;
  
  VLACheck(I->TorsCon,ShakerTorsCon,I->NTorsCon);
  stc = I->TorsCon+I->NTorsCon;
  stc->at0=atom0;
  stc->at1=atom1;
  stc->at2=atom2;
  stc->at3=atom3;
  stc->type = type;
  I->NTorsCon++;

}

void ShakerAddPlanCon(CShaker *I,int atom0,int atom1,int atom2,int atom3,float target, int fixed)
{
  ShakerPlanCon *spc;
  
  VLACheck(I->PlanCon,ShakerPlanCon,I->NPlanCon);
  spc = I->PlanCon+I->NPlanCon;
  spc->at0=atom0;
  spc->at1=atom1;
  spc->at2=atom2;
  spc->at3=atom3;
  spc->fixed=fixed;
  spc->target=target;
  I->NPlanCon++;
}

void ShakerAddLineCon(CShaker *I,int atom0,int atom1,int atom2)
{
  ShakerLineCon *slc;
  
  VLACheck(I->LineCon,ShakerLineCon,I->NLineCon);
  slc = I->LineCon+I->NLineCon;
  slc->at0=atom0;
  slc->at1=atom1;
  slc->at2=atom2;
  I->NLineCon++;
}

void ShakerFree(CShaker *I)
{
  VLAFreeP(I->PlanCon);
  VLAFreeP(I->PyraCon);
  VLAFreeP(I->DistCon);
  VLAFreeP(I->LineCon);
  VLAFreeP(I->TorsCon);
  OOFreeP(I);
}






Generated by  Doxygen 1.6.0   Back to index