float AtomInfoGetBondLength()

in layer2/AtomInfo.cpp [1373:1757]


float AtomInfoGetBondLength(PyMOLGlobals * G, const AtomInfoType * ai1, const AtomInfoType * ai2)
{
  float result = 1.6F;
  const AtomInfoType *a1, *a2;

  /* very simple for now ... 
     flush this out with pattern-based parameters later on */

  if(ai1->protons > ai2->protons) {
    a1 = ai2;
    a2 = ai1;
  } else {
    a1 = ai1;
    a2 = ai2;
  }
  switch (a1->protons) {


/* hydrogen =========================== */
  case cAN_H:
    switch (a2->protons) {
    case cAN_H:
      result = 0.74F;
      break;
    case cAN_C:
      result = 1.09F;
      break;
    case cAN_N:
      result = 1.01F;
      break;
    case cAN_S:
      result = 1.34F;
      break;
    case cAN_O:
      result = 0.96F;
      break;
    default:
      result = 1.09F;
      break;
    }
    break;

/* carbon =========================== */

  case cAN_C:                  /* carbon */
    switch (a1->geom) {

    case cAtomInfoLinear:      /* linear carbon ============= */
      switch (a2->geom) {
      case cAtomInfoLinear:
        switch (a2->protons) {
        case cAN_C:
          result = 1.20F;
          break;                /* C#^C */
        case cAN_N:
          result = 1.16F;
          break;                /* C#^N */
        default:
          result = 1.20F;
          break;
        }
        break;
      case cAtomInfoPlanar:
        switch (a2->protons) {
        case cAN_I:
          result = 2.14F;
          break;                /* normal single bond lengths */
        case cAN_Cl:
          result = 1.77F;
          break;
        case cAN_Br:
          result = 1.94F;
          break;
        case cAN_F:
          result = 1.35F;
          break;
        case cAN_S:
          result = 1.82F;
          break;
        case cAN_N:
          result = 1.47F;
          break;
        case cAN_O:
          result = 1.43F;
          break;
        case cAN_P:
          result = 1.84F;
          break;
        case cAN_C:
          result = 1.54F;
          break;
        default:
          result = 1.54F;
          break;
        }
        break;
      default:                 /* ?#C-^? */
        switch (a2->protons) {
        case cAN_I:
          result = 2.14F;
          break;                /* normal single bond lengths */
        case cAN_Cl:
          result = 1.77F;
          break;
        case cAN_Br:
          result = 1.94F;
          break;
        case cAN_F:
          result = 1.35F;
          break;
        case cAN_S:
          result = 1.82F;
          break;
        case cAN_N:
          result = 1.47F;
          break;
        case cAN_O:
          result = 1.43F;
          break;
        case cAN_P:
          result = 1.84F;
          break;
        case cAN_C:
          result = 1.54F;
          break;
        default:
          result = 1.54F;
          break;
        }
        break;
      }
      break;

    case cAtomInfoPlanar:      /* planer carbon ============= */
      switch (a2->geom) {
      case cAtomInfoLinear:
        switch (a2->protons) {
        case cAN_I:
          result = 2.14F;
          break;                /* normal single bond lengths */
        case cAN_Cl:
          result = 1.77F;
          break;
        case cAN_Br:
          result = 1.94F;
          break;
        case cAN_F:
          result = 1.35F;
          break;
        case cAN_S:
          result = 1.82F;
          break;
        case cAN_N:
          result = 1.47F;
          break;
        case cAN_O:
          result = 1.43F;
          break;
        case cAN_P:
          result = 1.84F;
          break;
        case cAN_C:
          result = 1.54F;
          break;
        default:
          result = 1.54F;
          break;
        }
        break;
      case cAtomInfoPlanar:
        switch (a2->protons) {
        case cAN_C:
          result = 1.34F;
          break;                /* C=^C or ?=C-^C=? */
        case cAN_O:
          result = 1.20F;
          break;                /* carbonyl */
        case cAN_N:
          result = 1.29F;
          break;                /* C=^N or ?=C-^N=? */
        case cAN_S:
          result = 1.60F;
          break;                /* C=^S or ?=C-^S-?=? */
        default:
          result = 1.34F;
          break;
        }
        break;
      default:                 /* ?#C-^? */
        switch (a2->protons) {
        case cAN_I:
          result = 2.14F;
          break;                /* normal single bond lengths */
        case cAN_Cl:
          result = 1.77F;
          break;
        case cAN_Br:
          result = 1.94F;
          break;
        case cAN_F:
          result = 1.35F;
          break;
        case cAN_S:
          result = 1.71F;
          break;                /* mmod */
        case cAN_N:
          result = 1.47F;
          break;
        case cAN_O:
          result = 1.43F;
          break;
        case cAN_P:
          result = 1.84F;
          break;
        case cAN_C:
          result = 1.54F;
          break;
        default:
          result = 1.54F;
          break;
        }
        break;
      }
      break;

    default:                   /* tetrahedral carbon */
      switch (a2->protons) {
      case cAN_I:
        result = 2.14F;
        break;                  /* normal single bond lengths */
      case cAN_Cl:
        result = 1.77F;
        break;
      case cAN_Br:
        result = 1.94F;
        break;
      case cAN_F:
        result = 1.35F;
        break;
      case cAN_S:
        result = 1.82F;
        break;
      case cAN_N:
        result = 1.47F;
        break;
      case cAN_O:
        result = 1.43F;
        break;
      case cAN_P:
        result = 1.84F;
        break;
      case cAN_C:
        result = 1.54F;
        break;
      default:
        result = 1.54F;
        break;
      }
      break;
    }
    break;


/* nitrogen ========================= */

  case cAN_N:
    if((a1->geom == cAtomInfoPlanar) && (a2->geom == cAtomInfoPlanar))
      switch (a2->protons) {
      case cAN_N:
        result = 1.25F;
        break;
      case cAN_O:
        result = 1.21F;
        break;
      case cAN_S:
        result = 1.53F;
        break;                  /* interpolated */
      default:
        result = 1.25F;
        break;
    } else {
      switch (a2->protons) {
      case cAN_N:
        result = 1.45F;
        break;
      case cAN_O:
        result = 1.40F;
        break;
      case cAN_S:
        result = 1.75F;
        break;                  /* interpolated */
      default:
        result = 1.45F;
        break;
      }
    }
    break;


/* oxygen =========================== */

  case cAN_O:
    if((a1->geom == cAtomInfoPlanar) && (a2->geom == cAtomInfoPlanar))
      switch (a2->protons) {
      case cAN_O:
        result = 1.35F;
        break;                  /* guess */
      case cAN_S:
        result = 1.44F;
        break;                  /* macromodel */
      default:
        result = 1.35F;
        break;
    } else if(a1->geom == cAtomInfoPlanar) {
      switch (a2->protons) {
      case cAN_O:
        result = 1.35F;
        break;                  /* guess */
      case cAN_S:
        result = 1.44F;
        break;                  /* macromodel */
      default:
        result = 1.35F;
        break;
      }
    } else {
      switch (a2->protons) {
      case cAN_O:
        result = 1.40F;
        break;
      case cAN_S:
        result = 1.75F;
        break;                  /* interpolated */
      default:
        result = 1.45F;
        break;
      }
    }
    break;


/* sulfur =========================== */

  case cAN_S:
    switch (a2->protons) {
    case cAN_S:
      result = 2.05F;
      break;                    /* interpolated */
    default:
      result = 1.82F;
      break;
    }
    break;

    /* fall-back to old method */
  default:

    result = 0.0;
    switch (a1->geom) {
    case cAtomInfoLinear:
      result += 1.20F;
      break;
    case cAtomInfoPlanar:
      result += 1.34F;
      break;
    default:
      result += 1.54F;
      break;
    }
    switch (a2->geom) {
    case cAtomInfoLinear:
      result += 1.20F;
      break;
    case cAtomInfoPlanar:
      result += 1.34F;
      break;
    default:
      result += 1.54F;
      break;
    }
    result /= 2.0F;
    break;
  }
  return (result);
}