コード例 #1
0
std::vector<Pose> cubicSpline_LineSegmentIntersection(const CubicSpline &s, const LineSegment &ls) {
    // unpack the x and y splines
    using namespace alglib;
    real_2d_array tbly, tblx;
    ae_int_t ny, nx;
    alglib::spline1dunpack(s.getSplineX(), nx, tblx);
    alglib::spline1dunpack(s.getSplineY(), ny, tbly);
    // both should have same number of pieces
    assert(nx == ny);
    int n = nx;
    vector<Pose> results;
    for (int i = 0; i < n-1; i++) {
        // confirm that u intervals are same for both x and y splines
        assert(tbly[i][0] == tblx[i][0] && tbly[i][1] == tblx[i][1]);
        double u_low = tbly[i][0], u_high = tbly[i][1];
        double cX[4], cY[4];
        for (int j = 0; j < 4; j++) {
            cX[j] = tblx[i][j+2];
            cY[j] = tbly[i][j+2];
        }
        vector<double> u = cubic_LineSegmentIntersection(cX, cY, u_low, u_high, ls);
        for (int i = 0; i < u.size(); i++) {
            double x = cX[0] + cX[1]*u[i] + cX[2]*u[i]*u[i] + cX[3]*u[i]*u[i]*u[i];
            double y = cY[0] + cY[1]*u[i] + cY[2]*u[i]*u[i] + cY[3]*u[i]*u[i]*u[i];
            results.push_back(Pose(x*fieldXConvert, y*fieldXConvert, 0));
        }
    }
    return results;
}
コード例 #2
0
ファイル: EAM.cpp プロジェクト: hsidky/OpenMD
  CubicSpline* EAM::getPhi(AtomType* atomType1, AtomType* atomType2) {
    EAMAdapter ea1 = EAMAdapter(atomType1);
    EAMAdapter ea2 = EAMAdapter(atomType2);
    CubicSpline* z1 = ea1.getZ();
    CubicSpline* z2 = ea2.getZ();

    // Thise prefactors convert the charge-charge interactions into
    // kcal / mol all were computed assuming distances are measured in
    // angstroms Charge-Charge, assuming charges are measured in
    // electrons.  Matches value in Electrostatics.cpp
    pre11_ = 332.0637778;

    // make the r grid:

    // we need phi out to the largest value we'll encounter in the radial space;

    RealType rmax = 0.0;
    rmax = max(rmax, ea1.getRcut());
    rmax = max(rmax, ea1.getNr() * ea1.getDr());

    rmax = max(rmax, ea2.getRcut());
    rmax = max(rmax, ea2.getNr() * ea2.getDr());

    // use the smallest dr (finest grid) to build our grid:

    RealType dr = min(ea1.getDr(), ea2.getDr());

    int nr = int(rmax/dr + 0.5);

    vector<RealType> rvals;
    for (int i = 0; i < nr; i++) rvals.push_back(RealType(i*dr));

    // construct the pair potential:

    vector<RealType> phivals;
    RealType phi;
    RealType r;
    RealType zi, zj;

    phivals.push_back(0.0);

    for (unsigned int i = 1; i < rvals.size(); i++ ) {
      r = rvals[i];

      // only use z(r) if we're inside this atom's cutoff radius,
      // otherwise, we'll use zero for the charge.  This effectively
      // means that our phi grid goes out beyond the cutoff of the
      // pair potential

      zi = r <= ea1.getRcut() ? z1->getValueAt(r) : 0.0;
      zj = r <= ea2.getRcut() ? z2->getValueAt(r) : 0.0;

      phi = pre11_ * (zi * zj) / r;

      phivals.push_back(phi);
    }
    CubicSpline* cs = new CubicSpline();
    cs->addPoints(rvals, phivals);
    return cs;
  }
コード例 #3
0
ファイル: EAM.cpp プロジェクト: Patrick-Louden/2.2
  void EAM::addExplicitInteraction(AtomType* atype1, AtomType* atype2, 
                                   RealType dr, int nr,
                                   vector<RealType> phiVals) {
    
    // in case these weren't already in the map
    addType(atype1);
    addType(atype2);

    EAMInteractionData mixer;
    CubicSpline* cs = new CubicSpline();
    vector<RealType> rVals;

    for (int i = 0; i < nr; i++) rVals.push_back(i * dr);

    cs->addPoints(rVals, phiVals);
    mixer.phi = cs;
    mixer.rcut = mixer.phi->getLimits().second;
    mixer.explicitlySet = true;

    int eamtid1 = EAMtids[ atype1->getIdent() ];
    int eamtid2 = EAMtids[ atype2->getIdent() ];
    
    MixingMap[eamtid1][eamtid2] = mixer;
    if (eamtid2 != eamtid1) {
      MixingMap[eamtid2][eamtid1] = mixer;
    }    
    return;
  }
コード例 #4
0
// Calculate Paramater B for LoadBasedScreen1
//##ModelId=40A1898A0191
double LoadBasedScreen1::CalculateB( double FractOS )
  {	
	double B = 0;

	const int nRowsB = 7;
	static double BArray [ nRowsB ] [ 2 ] = 
	{
//       Fract       B	
//      Oversize  Oversize
//      in Feed    Factor
        { 0.00  ,  1.60 },
		{ 0.50  ,  1.00 },
		{ 0.80  ,  0.64 },
		{ 0.85  ,  0.56 },
		{ 0.90  ,  0.44 },
		{ 0.95  ,  0.24 },
		{ 1.00  ,  0.00 }, };

  double* p = (pBArray ? pBArray : *BArray);
	Matrix BMatrix( nRowsB, 2, p );
	CubicSpline BSpline;

	BSpline.SetSpline ( BMatrix.column(0), BMatrix.column(1) );

	B = BSpline.CalculateY ( FractOS );
    
//	Vector TempSplineVec( nRows );

//	SPN3( nRows, BMatrix.column(0), BMatrix.column(1), TempSplineVec );

//	B = SPNV3( nRows, BMatrix.column(0), BMatrix.column(1), TempSplineVec, FractOS );

	return B;
  }
コード例 #5
0
ファイル: PiecewiseCubicSpline.cpp プロジェクト: jietan/src
void PiecewiseCubicSpline::calculateSplines()
{
    mSplines.clear();
    int numCtrlPoints = static_cast<int>(mCtrlPoints.size());
    for (int i = 0; i < numCtrlPoints - 1; ++i)
    {
        CubicSpline spline;
        spline.SetControlPoints(mCtrlPoints[i].p, mCtrlPoints[i + 1].p, mCtrlPoints[i].v, mCtrlPoints[i + 1].v);
        mSplines.push_back(spline);
    }
}
コード例 #6
0
ファイル: SC.cpp プロジェクト: TomParsons/OpenMD
  void SC::addExplicitInteraction(AtomType* atype1, AtomType* atype2, 
                                  RealType epsilon, RealType m, RealType n,
                                  RealType alpha) {
    
    // in case these weren't already in the map
    addType(atype1);
    addType(atype2);

    SCInteractionData mixer;

    mixer.epsilon = epsilon;
    mixer.m = m;
    mixer.n = n;
    mixer.alpha = alpha;
    mixer.rCut = 2.0 * mixer.alpha;
    
    RealType dr = mixer.rCut / (np_ - 1);
    vector<RealType> rvals;
    vector<RealType> vvals;
    vector<RealType> phivals;
    
    rvals.push_back(0.0);
    vvals.push_back(0.0);
    phivals.push_back(0.0);
    
    for (int k = 1; k < np_; k++) {
      RealType r = dr * k;
      rvals.push_back(r);
      vvals.push_back( mixer.epsilon * pow(mixer.alpha/r, mixer.n) );
      phivals.push_back( pow(mixer.alpha/r, mixer.m) );
    }
    
    mixer.vCut = mixer.epsilon * pow(mixer.alpha/mixer.rCut, mixer.n);
    
    CubicSpline* V = new CubicSpline();
    V->addPoints(rvals, vvals);
    
    CubicSpline* phi = new CubicSpline();
    phi->addPoints(rvals, phivals);
    
    mixer.V = V;
    mixer.phi = phi;
    
    mixer.explicitlySet = true;

    int sctid1 = SCtids[ atype1->getIdent() ];
    int sctid2 = SCtids[ atype2->getIdent() ];

    MixingMap[sctid1][sctid2] = mixer;
    if (sctid2 != sctid1) {
      MixingMap[sctid2][sctid1] = mixer;
    }    
    return;
  }
コード例 #7
0
// Calculate Paramater C for LoadBasedScreen1
//##ModelId=40A1898A019B
double LoadBasedScreen1::CalculateC( double FractHS )
  {
  double C = 0;

  const int nRowsC = 18;
  static double CArray [ nRowsC ] [ 2 ] = 
    {
//      Fract of    C	
//     Feed < S/2
//                Factor
        { 0.00 ,  0.70 },
        { 0.25 ,  1.00 },
        { 0.30 ,  1.06 },
        { 0.35 ,  1.13 },
        { 0.40 ,  1.21 },
        { 0.45 ,  1.30 },
        { 0.50 ,  1.40 },
        { 0.55 ,  1.52 },
        { 0.60 ,  1.67 },
        { 0.65 ,  1.85 },
        { 0.70 ,  2.05 },
        { 0.75 ,  2.26 },
        { 0.80 ,  2.50 },
        { 0.85 ,  2.75 },
        { 0.90 ,  3.20 },
        { 0.95 ,  4.00 },
        { 0.98 ,  6.00 },
        { 1.00 , 10.00 }, };

  double* p = (pCArray ? pCArray : *CArray);
	Matrix CMatrix( nRowsC, 2, p );
	CubicSpline CSpline;

	CSpline.SetSpline ( CMatrix.column(0), CMatrix.column(1) );

	C = CSpline.CalculateY ( FractHS );
    
//    Vector TempSplineVec( nRows );

//	SPN3( nRows, CMatrix.column(0), CMatrix.column(1), TempSplineVec );

//	C = SPNV3( nRows, CMatrix.column(0), CMatrix.column(1), TempSplineVec, FractHS );

	return C;
  }
コード例 #8
0
ファイル: render.cpp プロジェクト: vgck/opendr2
  //
  // Render a spline curve
  //
  void Spline(CubicSpline &curve, Color c, Bool normals, U32 normalMesh)
  {
    const U32 STEPS = 10;

    if (curve.length < 1e-4F)
    {
      return;
    }

    F32 step = curve.length / F32(STEPS);
    Vector v0 = curve.Step(0.0F);
    Vector v1, tangent;

    for (U32 i = 1; i <= STEPS; i++)
    {
      v1 = curve.Step(F32(i) * step, &tangent);

      // Draw the line
      FatLine(v0, v1, c, 0.15F);

      // Draw normals
      if (normals)
      {
        F32 veloc = tangent.Magnitude();

        Matrix m = Matrix::I;
        m.posit = v1;

        // Normalize
        if (veloc > 1e-4)
        {
          tangent *= 1.0F / veloc;
          m.SetFromFront(tangent);
        }

        Common::Display::Mesh(normalMesh, m, c); // "TerrainMarker"
      }

      // Swap points
      v0 = v1;
    }
  }
コード例 #9
0
	//compute the camera path using the camera keyframes
	void computeCubicSplineCameraPath()
	{
		//Build the cubic splines
		CubicSpline splineEyePosition;
		CubicSpline splineLookAt;
		vector<int> keyIdFrame;
		//Add points CubicSpline
		for (unsigned int fc = 0; fc <= LarmorPhysx::ConfigManager::total_anim_steps; ++fc)
		{
			Camera cam = loadCamera(fc);
			if(cam.keyframe)
			{
				cout << "Add point to camera path: frame: " << fc << endl;
				splineEyePosition.addPoint(cam.eyePosition);
				splineLookAt.addPoint(cam.lookAt);
				keyIdFrame.push_back(fc);
			}
		}
		//compute paths
		splineEyePosition.compute();
		splineLookAt.compute();

		//draw camera path getting the points from the spline objects
		for(int kf = 0; kf < keyIdFrame.size()-1; kf++)
		{
			int fc0 = keyIdFrame.at(kf);
			int fc1 = keyIdFrame.at(kf+1);
			int framesInterval = fc1 - fc0;
			double frameStep = 1.0L / framesInterval;
			double cubicPos = 0.0;

			cout << "interpolation from keyframe: " << fc0 << endl;
			for(int pf = fc0+1; pf < fc1; pf++)
			{
				cout << "interpolation frame: " << pf << endl;
				cubicPos += frameStep;
				LVector3 eyePosition = splineEyePosition.getPoint(kf, cubicPos);
				LVector3 lookAt = splineLookAt.getPoint(kf, cubicPos);

				//Create the Camera object and save
				Camera camera;
				camera.idFrame = pf;
				camera.eyePosition = eyePosition;
				camera.lookAt = lookAt;
				camera.keyframe = false;
				//Save camera
				saveCamera(camera);
			}
			cout << "interpolation to keyframe: " << fc1 << endl;
		}
	}
コード例 #10
0
// Calculate Paramater A for LoadBasedScreen1
//##ModelId=40A1898A017D
double LoadBasedScreen1::CalculateA( double S )
  {
  double A = 0;

  const int nRowsA = 19;
  static double AArray [ nRowsA ] [ 2 ] = 
	{
//          S       A	
//      Screen    Basic
//      Opening Capacity
        { 0    ,   0.0 },
		{ 1    ,   1.1 },
		{ 2    ,   2.0 },
		{ 3    ,   3.0 },
		{ 4    ,   3.9 },
		{ 5    ,   4.8 },
		{ 6.35 ,   5.9 },
		{ 8    ,   7.0 },
		{ 10   ,   8.2 },
		{ 12   ,   9.4 },
		{ 15   ,  10.7 },
		{ 18   ,  12.0 },
		{ 22   ,  13.4 },
		{ 26   ,  14.6 },
		{ 30   ,  15.8 },
		{ 40   ,  18.2 },
		{ 75   ,  25.0 },
		{ 160  ,  41.5 },
		{ 500  , 107.5 }, };
        
  double* p = (pAArray ? pAArray : *AArray);
  Matrix AMatrix( nRowsA, 2, p );
  CubicSpline ASpline;

	ASpline.SetSpline( AMatrix.column(0), AMatrix.column(1) );

	A = ASpline.CalculateY ( S );
	
	return A;
  }
コード例 #11
0
double ParzDens_1::density ( double x )
{
   int i ;
   double sum, diff ;

   if (spline != NULL)
      return spline->evaluate ( x ) ;

   sum = 0.0 ;
   for (i=0 ; i<nd ; i++) {
      diff = x - d[i];
      sum += exp ( -0.5 * diff * diff / var ) ;
      }

   return sum * factor ;
}
コード例 #12
0
int main(){
    Mat img(1000, 800, CV_8UC3);
    img = Scalar::all(0);
    vector<Point> mousev,kalmanv;
    mousev.clear();
    kalmanv.clear(); 
    mousePos.clear(); 
    float startThetaX = 0, endThetaX, startThetaY = 0, endThetaY;
    namedWindow("nimble", 1);
    setMouseCallback("nimble", CallBackFunc, NULL);
    int check = 0;
    int numPoints = 5;
    cout << img.cols << endl;
    while(1)
    {
      imshow("nimble", img);
      if(mousePos.size() > numPoints){
        //cout << "hjere1:" << endl; 
        Pose start(mousePos[0].x , mousePos[0].y , 0);
        Pose end(mousePos[numPoints].x, mousePos[numPoints].y, 0);
        vector<Pose> midpoints;
        for(int i = 1; i <numPoints; i++)
          midpoints.push_back(Pose(mousePos[i].x , mousePos[i].y , 0));
        CubicSpline *p = new CubicSpline(start, end, midpoints);
        //cout << "hjere:" << endl;  
        for(int i = 0; i < 1000 ;i++){
           if((p->x(i/1000.) >= 0) && (p->x(i/1000.) < img.rows) && (p->y(i/1000.) >=0) && (p->y(i/1000.) < img.cols))
              img.at<Vec3b>(Point(p->x(i/1000.), p->y(i/1000.))) = 255;
        }
          mousePos.erase(mousePos.begin(), mousePos.begin() + numPoints );
      }
      waitKey(16);
    //  break;
    }
    return 0;
  }
コード例 #13
0
ファイル: HeightField.cpp プロジェクト: kamalsirsa/vtp
/**
 * Create a set of points on the heightfield for a 2D polyline by draping the point onto
 * the surface.
 *
 * \param line	The 2D line to drape, in Earth coordinates.
 * \param fSpacing	The approximate spacing of the surface tessellation, used to
 *		decide how finely to tessellate the line.
 * \param fOffset	An offset to elevate each point in the resulting geometry,
 *		useful for keeping it visibly above the ground.
 * \param bInterp	True to interpolate between the vertices of the input
 *		line. This is generally desirable when the ground is much more finely
 *		spaced than the input line.
 * \param bCurve	True to interpret the vertices of the input line as
 *		control points of a curve.  The created geometry will consist of
 *		a draped line which passes through the control points.
 * \param bTrue		True to use the true elevation of the terrain, ignoring
 *		whatever scale factor is being used to exaggerate elevation for
 *		display.
 * \param output	Received the points.
 * \return The approximate length of the resulting 3D polyline.
 */
float vtHeightField3d::LineOnSurface(const DLine2 &line, float fSpacing, float fOffset,
	bool bInterp, bool bCurve, bool bTrue, FLine3 &output)
{
	uint i, j;
	FPoint3 v1, v2, v;

	float fTotalLength = 0.0f;
	int iVerts = 0;
	uint points = line.GetSize();
	if (bCurve)
	{
		DPoint2 p2, last(1E9,1E9);
		DPoint3 p3;

		int spline_points = 0;
		CubicSpline spline;
		for (i = 0; i < points; i++)
		{
			p2 = line[i];
			if (i > 1 && p2 == last)
				continue;
			p3.Set(p2.x, p2.y, 0);
			spline.AddPoint(p3);
			spline_points++;
			last = p2;
		}
		spline.Generate();

		// Estimate how many steps to subdivide this line into
		const double dLinearLength = line.Length();
		float fLinearLength, dummy;
		m_LocalCS.VectorEarthToLocal(DPoint2(dLinearLength, 0.0), fLinearLength, dummy);
		double full = (double) (spline_points-1);
		int iSteps = (uint) (fLinearLength / fSpacing);
		if (iSteps < 3)
			iSteps = 3;
		double dStep = full / iSteps;

		FPoint3 last_v;
		for (double f = 0; f <= full; f += dStep)
		{
			spline.Interpolate(f, &p3);

			m_LocalCS.EarthToLocal(p3.x, p3.y, v.x, v.z);
			FindAltitudeAtPoint(v, v.y, bTrue);
			v.y += fOffset;
			output.Append(v);
			iVerts++;

			// keep a running total of approximate ground length
			if (f > 0)
				fTotalLength += (v - last_v).Length();
			last_v = v;
		}
	}
	else
	{
		// not curved: straight line in earth coordinates
		FPoint3 last_v;
		for (i = 0; i < points; i++)
		{
			if (bInterp)
			{
				v1 = v2;
				m_LocalCS.EarthToLocal(line[i].x, line[i].y, v2.x, v2.z);
				if (i == 0)
					continue;

				// estimate how many steps to subdivide this segment into
				FPoint3 diff = v2 - v1;
				float fLen = diff.Length();
				uint iSteps = (uint) (fLen / fSpacing);
				if (iSteps < 1) iSteps = 1;

				for (j = (i == 1 ? 0:1); j <= iSteps; j++)
				{
					// simple linear interpolation of the ground coordinate
					v.Set(v1.x + diff.x / iSteps * j, 0.0f, v1.z + diff.z / iSteps * j);
					FindAltitudeAtPoint(v, v.y, bTrue);
					v.y += fOffset;
					output.Append(v);
					iVerts++;

					// keep a running total of approximate ground length
					if (j > 0)
						fTotalLength += (v - last_v).Length();
					last_v = v;
				}
			}
			else
			{
				m_LocalCS.EarthToLocal(line[i], v.x, v.z);
				FindAltitudeAtPoint(v, v.y, bTrue);
				v.y += fOffset;
				output.Append(v);
			}
		}
	}
	return fTotalLength;
}
コード例 #14
0
ファイル: EAM.cpp プロジェクト: Patrick-Louden/2.2
  void EAM::calcForce(InteractionData &idat) {

    if (!initialized_) initialize();

    if (haveCutoffRadius_) 
      if ( *(idat.rij) > eamRcut_) return;
   

    int eamtid1 = EAMtids[idat.atid1];
    int eamtid2 = EAMtids[idat.atid2];
    
    EAMAtomData &data1 = EAMdata[eamtid1];
    EAMAtomData &data2 = EAMdata[eamtid2];
    
    // get type-specific cutoff radii
    
    RealType rci = data1.rcut;
    RealType rcj = data2.rcut;
    
    RealType rha(0.0), drha(0.0), rhb(0.0), drhb(0.0);
    RealType pha(0.0), dpha(0.0), phb(0.0), dphb(0.0);
    RealType phab(0.0), dvpdr(0.0);
    RealType drhoidr, drhojdr, dudr;
    
    if ( *(idat.rij) < rci) {
      data1.rho->getValueAndDerivativeAt( *(idat.rij), rha, drha);
      CubicSpline* phi = MixingMap[eamtid1][eamtid1].phi;
      phi->getValueAndDerivativeAt( *(idat.rij), pha, dpha);
    }
    
    if ( *(idat.rij) < rcj) {
      data2.rho->getValueAndDerivativeAt( *(idat.rij), rhb, drhb );
      CubicSpline* phi = MixingMap[eamtid2][eamtid2].phi;
      phi->getValueAndDerivativeAt( *(idat.rij), phb, dphb);
    }

    switch(mixMeth_) {
    case eamJohnson:
      
      if ( *(idat.rij) < rci) {
        phab = phab + 0.5 * (rhb / rha) * pha;
        dvpdr = dvpdr + 0.5*((rhb/rha)*dpha + 
                             pha*((drhb/rha) - (rhb*drha/rha/rha)));
      }
      
      
      
      if ( *(idat.rij) < rcj) {
        phab = phab + 0.5 * (rha / rhb) * phb;
        dvpdr = dvpdr + 0.5 * ((rha/rhb)*dphb + 
                               phb*((drha/rhb) - (rha*drhb/rhb/rhb)));
      }
      
      break;
      
    case eamDaw:
      
      if ( *(idat.rij) <  MixingMap[eamtid1][eamtid2].rcut) {
        MixingMap[eamtid1][eamtid2].phi->getValueAndDerivativeAt( *(idat.rij), 
                                                                  phab, dvpdr);
      }
      
      break;
    case eamUnknown:
    default:
      
      sprintf(painCave.errMsg,
              "EAM::calcForce hit a mixing method it doesn't know about!\n"
              );
      painCave.severity = OPENMD_ERROR;
      painCave.isFatal = 1;
      simError();        
      
    }
    
    drhoidr = drha;
    drhojdr = drhb;
    
    dudr = drhojdr* *(idat.dfrho1) + drhoidr* *(idat.dfrho2) + dvpdr; 
    
    *(idat.f1) += *(idat.d) * dudr / *(idat.rij);

        
    if (idat.doParticlePot) {
      // particlePot is the difference between the full potential and
      // the full potential without the presence of a particular
      // particle (atom1).
      //
      // This reduces the density at other particle locations, so we
      // need to recompute the density at atom2 assuming atom1 didn't
      // contribute.  This then requires recomputing the density
      // functional for atom2 as well.
      
      *(idat.particlePot1) += data2.F->getValueAt( *(idat.rho2) - rha ) 
        - *(idat.frho2);
      
      *(idat.particlePot2) += data1.F->getValueAt( *(idat.rho1) - rhb) 
        - *(idat.frho1);
    }
    
    (*(idat.pot))[METALLIC_FAMILY] += phab;
    
    *(idat.vpair) += phab;
  
    return;
    
  }
コード例 #15
0
bool CubicSpline::intersects(const CubicSpline &rt, VectorF ignoreAxis) const
{
#if 1
    vector<VectorF> path1 = getSplinePoints(*this);
    vector<VectorF> path2 = getSplinePoints(rt);
    for(size_t i = 1; i < path1.size(); i++)
    {
        for(size_t j = 1; j < path2.size(); j++)
        {
            if(linesIntersect(path1[i - 1], path1[i], path2[j - 1], path2[j], 0))
                return true;
        }
    }
    return false;
#else
    const int splitCount = 50; // number of line segments to split spline into
    ignoreAxis = normalize(ignoreAxis);

    for(int segmentNumber = 0; segmentNumber < splitCount; segmentNumber++)
    {
        float startT = (float)(segmentNumber) / splitCount;
        float endT = (float)(segmentNumber + 1) / splitCount;
        VectorF startP = rt.evaluate(startT);
        startP -= ignoreAxis * dot(ignoreAxis, startP); // move to plane normal to ignoreAxis
        VectorF endP = rt.evaluate(endT);
        endP -= ignoreAxis * dot(ignoreAxis, endP); // move to plane normal to ignoreAxis
        VectorF delta = endP - startP;

        if(absSquared(delta) < eps * eps) // if delta is too small
        {
            continue;
        }

        // solve dot(evaluate(t), cross(ignoreAxis, delta)) == 0 and it intersects if dot(evaluate(t) - startP, delta) / dot(delta, delta) is in [0, 1] and t is in [0, 1]
        VectorF normal = cross(ignoreAxis, delta);
        float cubic = dot(getCubic(), normal);
        float quadratic = dot(getQuadratic(), normal);
        float linear = dot(getLinear(), normal);
        float constant = dot(getConstant(), normal);
        float intersections[3];
        int intersectionCount = solveCubic(constant, linear, quadratic, cubic, intersections);

        for(int i = 0; i < intersectionCount; i++)
        {
            float t = intersections[i];

            if(t < 0 || t > 1)
            {
                continue;
            }

            float v = dot(evaluate(t) - startP, delta) / dot(delta, delta);

            if(v < 0 || v > 1)
            {
                continue;
            }

            return true;
        }
    }

    return false;
#endif
}
コード例 #16
0
ファイル: SC.cpp プロジェクト: TomParsons/OpenMD
  void SC::addType(AtomType* atomType){

    SuttonChenAdapter sca = SuttonChenAdapter(atomType);
    SCAtomData scAtomData;
    
    scAtomData.c = sca.getC();
    scAtomData.m = sca.getM();
    scAtomData.n = sca.getN();
    scAtomData.alpha = sca.getAlpha();
    scAtomData.epsilon = sca.getEpsilon();
    scAtomData.rCut = 2.0 * scAtomData.alpha;
 
    // add it to the map:
    int atid = atomType->getIdent();
    int sctid = SCtypes.size();

    pair<set<int>::iterator,bool> ret;    
    ret = SCtypes.insert( atid );
    if (ret.second == false) {
      sprintf( painCave.errMsg,
               "SC already had a previous entry with ident %d\n",
               atid );
      painCave.severity = OPENMD_INFO;
      painCave.isFatal = 0;
      simError();         
    }
    
    SCtids[atid] = sctid;
    SCdata[sctid] = scAtomData;
    MixingMap[sctid].resize(nSC_);
    
    // Now, iterate over all known types and add to the mixing map:
    
    std::set<int>::iterator it;
    for( it = SCtypes.begin(); it != SCtypes.end(); ++it) {
      
      int sctid2 = SCtids[ (*it) ];
      AtomType* atype2 = forceField_->getAtomType( (*it) );
      
      SCInteractionData mixer;

      mixer.alpha = getAlpha(atomType, atype2);
      mixer.rCut = 2.0 * mixer.alpha;
      mixer.epsilon = getEpsilon(atomType, atype2);
      mixer.m = getM(atomType, atype2);
      mixer.n = getN(atomType, atype2);

      RealType dr = mixer.rCut / (np_ - 1);
      vector<RealType> rvals;
      vector<RealType> vvals;
      vector<RealType> phivals;
    
      rvals.push_back(0.0);
      vvals.push_back(0.0);
      phivals.push_back(0.0);

      for (int k = 1; k < np_; k++) {
        RealType r = dr * k;
        rvals.push_back(r);
        vvals.push_back( mixer.epsilon * pow(mixer.alpha/r, mixer.n) );
        phivals.push_back( pow(mixer.alpha/r, mixer.m) );
      }

      mixer.vCut = mixer.epsilon * pow(mixer.alpha/mixer.rCut, mixer.n);
    
      CubicSpline* V = new CubicSpline();
      V->addPoints(rvals, vvals);
      
      CubicSpline* phi = new CubicSpline();
      phi->addPoints(rvals, phivals);
      
      mixer.V = V;
      mixer.phi = phi;

      mixer.explicitlySet = false;

      MixingMap[sctid2].resize( nSC_ );
      
      MixingMap[sctid][sctid2] = mixer;
      if (sctid2 != sctid) {
        MixingMap[sctid2][sctid] = mixer;
      }
    }      
    return;
  }
コード例 #17
0
//##ModelId=40A1898902EF
bool LoadBasedScreen1::CalculateModel( PFlowStream1 FeedStream )
  {
  // Local Variables
  int i = 0;
  int j = 0;
  double ScaleFactor = 0.00;
  double Denom = 0.00;

  Vector CombCPPSizing ( nSize );
  CubicSpline FeedSpline;    

  MatrixView FeedSolids      = FeedStream->AccessSolidsMatrix( );

  MatrixView OversizeSolids  = Oversize->AccessSolidsMatrix( );

  MatrixView UndersizeSolids = Undersize->AccessSolidsMatrix( );

  // Ensure correct shape feed matrix

  if( FeedSolids.rowCount() != nSize )
    goto calcFailed;

  if( FeedSolids.columnCount() != nType ) 
    goto calcFailed;

  // Calculate total feed flow rate (solids)

  QF = FeedSolids.sum( );

  // Convert feed matrix into single component size distribution

  for( i = 0; i < nSize; i++ )
    CombRetSizing[ i ] = (FeedSolids.row(i)).sum();

  if (fabs(QF)<1e-8)
    ScaleFactor = 0.00;
  else 
    ScaleFactor = 1/QF;

  // Scale single component distribution to cumulative sizing
  //  scaled to fraction basis: ie. 1 passes top-size

  CombCPPSizing[ nSize - 1 ] = 0;
  for( i = nSize - 2; i >=0; i-- )
    CombCPPSizing[ i ] = CombCPPSizing[i + 1] + ( CombRetSizing[i + 1] * ScaleFactor );

  // Construct cubic spline passing through cumulative curve    

  FeedSpline.SetSpline( Sizes, CombCPPSizing );

  // Use cubic spline to get fraction passing half apperture size

  Feed_HS = FeedSpline.CalculateY( S/2 );

  // Use spline to get fraction passing apperture size    

  U = Feed_US = FeedSpline.CalculateY( S );
  Feed_OS = 1 - Feed_US;

  // Calculate area factors for this screen

  A = CalculateA( S );
  B = CalculateB( Feed_OS );
  C = CalculateC( Feed_HS );
  D = CalculateD( DL );
  E = CalculateE( WS, S );
  H = CalculateH( OT );
  J = CalculateJ( ST, S, OA );
  K = CalculateK( FT );
  L = CalculateL();
  X = CalculateX( CF );

  // Calculate denominator of load equation - ensure not zero

  Denom = A * B * C * D * E * F * H * J * K * L * AF * X;
  if (fabs(Denom)<1e-8)
    Denom = 1e-8;

  // Calculate load

  V = ( 90 * QF * U ) / ( Denom );

  // Calculate efficiency that matches this load

  T = CalculateT( V );

  // Calculate factor G

  G = ( V * T ) / 90;

  // calculate flow to undersize at this efficiency

  QU = QF * U * T;

  // Solve for D50 that matches the undersize flow

  D50 = zbrent( S * 0.1, S * 0.99, TOLERANCE );

  // Calculate splitting of feed water to products

  Undersize->SetLiquidMass( FeedStream->GetLiquidMass() * WR );
  Oversize->SetLiquidMass( FeedStream->GetLiquidMass() * (1-WR) );

  // Calculate splitting of solids components to products 

  for( i=0; i<nType; i++ )
    {
    for( j=0; j<nSize; j++ )
      {
      double feed = FeedSolids[j][i];

      OversizeSolids[j][i] = feed * PartitionCurve[j];
      UndersizeSolids[j][i] = feed * ( 1 - PartitionCurve[j] );
      }
   }

  // Setup model output vector

  ModelOutput[0]  = QF;
  ModelOutput[1]  = Feed_OS;
  ModelOutput[2]  = Feed_US;
  ModelOutput[3]  = Feed_HS;
  ModelOutput[4]  = QU;
  ModelOutput[5]  = QF - QU;
  ModelOutput[6]  = S;
  ModelOutput[7]  = T;
  ModelOutput[8]  = AF;
  ModelOutput[9]  = D50;
  ModelOutput[10] = A;
  ModelOutput[11] = B;
  ModelOutput[12] = C;
  ModelOutput[13] = D;
  ModelOutput[14] = E;
  ModelOutput[15] = F;
  ModelOutput[16] = G;
  ModelOutput[17] = H;
  ModelOutput[18] = J;
  ModelOutput[19] = K;
  ModelOutput[20] = L;
  ModelOutput[21] = X;
  ModelOutput[22] = V;

  // Indicate success
  return true;

  calcFailed:

  // Indicate failure
  return false;
  }