//=======================================================================
//function : HasIntersection3
//purpose  : Auxilare for HasIntersection()
//           find intersection point between triangle (P1,P2,P3)
//           and segment [PC,P]
//=======================================================================
static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint,
                             const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3)
{
  //cout<<"HasIntersection3"<<endl;
  //cout<<"  PC("<<PC.X()<<","<<PC.Y()<<","<<PC.Z()<<")"<<endl;
  //cout<<"  P("<<P.X()<<","<<P.Y()<<","<<P.Z()<<")"<<endl;
  //cout<<"  P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
  //cout<<"  P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl;
  //cout<<"  P3("<<P3.X()<<","<<P3.Y()<<","<<P3.Z()<<")"<<endl;
  gp_Vec VP1(P1,P2);
  gp_Vec VP2(P1,P3);
  IntAna_Quadric IAQ(gp_Pln(P1,VP1.Crossed(VP2)));
  IntAna_IntConicQuad IAICQ(gp_Lin(PC,gp_Dir(gp_Vec(PC,P))),IAQ);
  if(IAICQ.IsDone()) {
    if( IAICQ.IsInQuadric() )
      return false;
    if( IAICQ.NbPoints() == 1 ) {
      gp_Pnt PIn = IAICQ.Point(1);
      double preci = 1.e-6;
      // check if this point is internal for segment [PC,P]
      bool IsExternal =
        ( (PC.X()-PIn.X())*(P.X()-PIn.X()) > preci ) ||
        ( (PC.Y()-PIn.Y())*(P.Y()-PIn.Y()) > preci ) ||
        ( (PC.Z()-PIn.Z())*(P.Z()-PIn.Z()) > preci );
      if(IsExternal) {
        return false;
      }
      // check if this point is internal for triangle (P1,P2,P3)
      gp_Vec V1(PIn,P1);
      gp_Vec V2(PIn,P2);
      gp_Vec V3(PIn,P3);
      if( V1.Magnitude()<preci || V2.Magnitude()<preci ||
          V3.Magnitude()<preci ) {
        Pint = PIn;
        return true;
      }
      gp_Vec VC1 = V1.Crossed(V2);
      gp_Vec VC2 = V2.Crossed(V3);
      gp_Vec VC3 = V3.Crossed(V1);
      if(VC1.Magnitude()<preci) {
        if(VC2.IsOpposite(VC3,preci)) {
          return false;
        }
      }
      else if(VC2.Magnitude()<preci) {
        if(VC1.IsOpposite(VC3,preci)) {
          return false;
        }
      }
      else if(VC3.Magnitude()<preci) {
        if(VC1.IsOpposite(VC2,preci)) {
          return false;
        }
      }
      else {
        if( VC1.IsOpposite(VC2,preci) || VC1.IsOpposite(VC3,preci) ||
            VC2.IsOpposite(VC3,preci) ) {
          return false;
        }
      }
      Pint = PIn;
      return true;
    }
  }

  return false;
}
Exemple #2
0
/*
 *      ResidueMutate
 *
 *	Author:	Christian Schafmeister (1991)
 *
 *      Mutate the RESIDUE (rOld) into the RESIDUE (rNew).
 *      Do this by superimposing the coordinates from rOld onto
 *      rNew, breaking all the bonds from rOld to other residues,
 *      and rejoining them to identically named atoms in rNew,
 *      then building the coordinates for the rest of the atoms in rNew.
 *      The new RESIDUE rNew should not be bonded to anything else, it
 *      should also have EXTERNAL coordinates defined, but no INTERNALS.
 *
 */
void
ResidueMutate( RESIDUE rNew, RESIDUE rOld )
{
LOOP            lAtoms, lSpan;
ATOM            aNew, aNeighbor, aOld, aAtom, aSpan, aTemp;
STRING          sTemp, sSpan;
int             i, iDum;
FLAGS		fBondFlags;

    MESSAGE(( "Mutating: %s to: %s\n", sContainerName( rOld ),
                sContainerName(rNew) ));

                /* Build internal coordinates for the new RESIDUE */

    lAtoms = lLoop( (OBJEKT)rNew, ATOMS );
    BuildInternalsUsingFlags( &lAtoms, 
			ATOMPOSITIONKNOWN, 
			0,
			0, 
			ATOMPOSITIONKNOWN,
			&iDum, &iDum, &iDum );

                /* Define the coordinates, and the flags */
                /* if there are bonds out of the old RESIDUE, break them */
                /* and rejoin them to identically named atoms in the new */
                /* RESIDUE */

    lAtoms = lLoop( (OBJEKT)rOld, ATOMS );
    FOREACH( aOld, ATOM, lAtoms ) {
        MESSAGE(( "Searching for atom in new residue with name: %s\n",
                        sContainerName(aOld) ));
        aNew = (ATOM)cContainerFindName( (CONTAINER)rNew, ATOMid,
                                             sContainerName(aOld) );
                                             
                /* If there is a cooresponding ATOM with the same name */
                /* then define its flags and coordinates */
                
        if ( aNew != NULL ) {
            MESSAGE(( "--- Found one\n" ));
            AtomSetPosition( aNew, vAtomPosition(aOld) );
            AtomDefineFlags( aNew, fAtomFlags(aOld) );
        } else {
            MESSAGE(( "--- No atom found\n" ));
        }

                /* Search for bonds out of the old RESIDUE */
        
        for ( i=0; i<iAtomCoordination(aOld); i++ ) {
            aNeighbor = aAtomBondedNeighbor( aOld, i );
	    MESSAGE(( "--- Looking at neighbor: %s\n",
			sContainerFullDescriptor( (CONTAINER)aNeighbor, sTemp ) ));
            if ( rOld != (RESIDUE)cContainerWithin(aNeighbor) ) {
                fBondFlags = fAtomBondFlags( aOld, i );
                AtomRemoveBond( aOld, aNeighbor );
                MESSAGE(( "Removing a bond to: %s\n",
                        sContainerFullDescriptor( (CONTAINER)aNeighbor, sTemp ) ));
                if ( aNew != NULL ) {
                    MESSAGE(( "--- And rejoining it to: %s\n",
                                sContainerFullDescriptor( (CONTAINER)aNew, sTemp ) ));
                    AtomBondToFlags( aNew, aNeighbor, fBondFlags );
                } else {
                    MESSAGE(( "--- Not rejoining it to anything.\n" ));
        VP1(( "There is no atom in residue: %s with the name: %s.\n" ));
        VP1(( "--- No bond could be made to the missing atom.\n" ));
                }
            }
        }
    }