Example #1
0
int main() {
  init();
  // read input
  cin >> n >> m;
  for (int i=0;i<m;i++) {
    for (int j=0;j<3;j++) cin >> e[i][j];
    nextE[e[i][0]].push_back(i);
    nextE[e[i][1]].push_back(i);
    next[e[i][0]].push_back(e[i][1]);
    next[e[i][1]].push_back(e[i][0]);
  }
  // set up linear program
  nA=0;
  for (int i=0;i<n;i++) cycles(i);
  for (int i=0;i<m;i++) {
    A[nA][2*i+1]=1; b[nA]=e[i][2];
    nA++;
    c[2*i]=-1; c[2*i+1]=1;
  }
  // solve
  Simplex s = Simplex(A, b, c, nA, 2*m);
  Fraction f = s.solve();
  f = f.neg();
  for (int i=0;i<m;i++) f = f.add(Fraction(e[i][2]));
  cout << f.str() << endl;
  return 0;
}
Example #2
0
Point OjaData::oja_rank(const Point& x) const
{
	errif(x.dim() != dim(), "OjaData::oja_rank: Illegal dimension on point " << x);

	if (plane)
		return plane->oja_rank(x);

	Point Gr(dim());
	Simplex S;
	double sgn;
	double k = 0;

	for (Index I(dim(), size()); I; I++, k++)
	{
		S.get(*this, I, x);
		sgn = S.sign();
		for (int j = 0; j<dim(); j++)
			Gr[j] += S.row_cof(j + 1) * sgn;
	}

	for (int i = 0; i < dim(); i++)
		Gr[i] /= k;

	return Gr;
}
Example #3
0
  //! Retourne la valeur interpolée d'un point dans le pavage
  float interpolateValue(const Point<N> &Q) {
    bool found = false;
    float value = 0;
    float rapport = 0;
    size_t iSimplex;
    for (iSimplex = 0; iSimplex < multiplex.size(); iSimplex++) {
      if (isInside(Q, multiplex[iSimplex])) {
        found = true;
        break;
      }
    }
    if (!found) {
      cout << "Le point n'est dans aucun simplex" << endl;
      return 0;
    }

    //  le rapport entre le volume du N-simplexe {Q,Fbj} et le volume du
    //  N-simplexe D={Pbj,Fbj}.
    for (int i = 0; i < multiplex[iSimplex].getSize(); i++) {
      Simplex<N> temp;
      temp.pushPoint(Q);
      for (int j = 0; j < multiplex[iSimplex].getSize(); j++) {
        if (i != j)
          temp.pushPoint((multiplex[iSimplex])[j]);
      }
      // temp le simplex {Q,Fbj}
      // <multiplex[iSimplex] le simplex {Pbj,Fbj}
      rapport = temp.calculateVol() / multiplex[iSimplex].calculateVol();
      value += rapport * (multiplex[iSimplex][i]).getValeur();
    }
    return value;
  }
Example #4
0
 //! return true if p is in the simplex s
 static bool isInside(const Point<N> &p, Simplex<N> &s) {
   bool inside = true;
   std::vector<Point<N> > opposed;
   float m1[N][N]; // x par rapport a l'arrete
   float m2[N][N]; // R par rapport a l'arrete
   for (int k = 0; k < s.getSize(); k++) {
     opposed.clear();
     for (int i = 0; i < s.getSize(); i++) {
       if (i != k)
         opposed.push_back(s[i]);
     }
     // creation of matrix N*N
     for (size_t i = 0; i < N; i++) {
       for (size_t j = 0; j < N; j++) {
         m1[i][j] = p[i] - (opposed[j])[i];      // x par rapport a Fbi
         m2[i][j] = (s[k])[i] - (opposed[j])[i]; // R par rapport a Fbi
       }
     }
     if (Simplex<N>::determinant(m1, N) * Simplex<N>::determinant(m2, N) <
         0) { // determinants de signes different
       inside = false;
       break;
     }
   }
   return inside;
 }
void add_simplices(SimplexVector& sv, int d, const PointContainer& points)
{
	PointIndex indices[d+1];
	for (int i = 0; i < d+1; ++i) 
		indices[i] = d - i;

	while(indices[d] < points.size() - d)
	{
		// Add simplex
		Miniball mb(points[indices[0]].dim());
		Simplex s;
		for (int i = 0; i < d+1; ++i)
		{
			s.add(indices[i]);
			mb.check_in(points[indices[i]]);
		}
		mb.build();
		s.set_value(mb.squared_radius());
		sv.push_back(s);

		
		// Advance indices
		for (int i = 0; i < d+1; ++i)
		{
			++indices[i];
			if (indices[i] < points.size() - i)
			{
				for (int j = i-1; j >= 0; --j)
					indices[j] = indices[j+1] + 1;
				break;
			}
		}
	}
}
Example #6
0
void OjaData::get_oja_and_gradient(const Point& x,double& oja
  ,Point& grad) const
{
    errif(x.dim() != dim(),"OjaData::get_oja_and_gradient: point " << x
	  << " has illegal dimension");

 	if(plane)
 	{
 		plane->oja_and_gradient(x,oja,grad);
 		return;
 	}
			
    double sum = 0.0;
    double sgn;
    double k = 1.0 / double(fact(dim()));
    Simplex S;
    Point Gr(dim());
	
    for(Index I(dim(),size()); I; I++)
    {
		S.get(*this,I,x);
		sum += S.size();
		sgn = S.sign();
		for(int j=0; j<dim(); j++)
			Gr[j] +=  S.row_cof(j+1) * sgn * k;
    }
    
    oja = sum;
    grad = Gr;
}
Example #7
0
double Handler::optimise_single(vector<double> &parameters, vector<vector<double> > &results, vector<vector<vector<double> > > &allResults, int& itr){
  double SSE = 99999999999999.9;
  double tempSSE;
  vector<double> tempPar, seedParams;
  Simplex simplex;

  parameters.clear();
  allResults.clear();
  parameters = generate_seed_parameters();
  for(int index = 0;index<20;index++){
    seedParams.clear();
    seedParams = generate_seed_parameters();
    //printcon(seedParams);
    if(this->useMLE == false) tempPar = simplex.neldermead(&Handler::fitEpidemicsMLE, *this,  seedParams, itr);
    else tempPar = simplex.neldermead(&Handler::fitEpidemics, *this,  seedParams, itr);
    // Store the SSE value for this
    tempSSE = fitEpidemics(tempPar);
    if(tempSSE < SSE){
      SSE = tempSSE;
      parameters=tempPar;
    }
    cout << "." << flush;
  }
  results = ode_solve(parameters);
  allResults = ode_solve_separate(parameters);
  //allResults.clear();
  cout << endl;
  return SSE;
}
	void SetToSimplex(Simplex& s){
		data.clear();
		for(unsigned int i = 0; i< s.GetSize(); i++){
			data.push_back(s[i]);
			dataA.push_back(s.atA(i));
			dataB.push_back(s.atB(i));
		}
	}
Example #9
0
 static void PrintSimplex(std::ostream &str, const Simplex &simplex)
 {
     for (typename Simplex::const_iterator i = simplex.begin(); i != simplex.end(); i++)
     {
         str<<(*i)<<" ";
     }
     str<<std::endl;
 }
int main()
{
	Simplex s;
	s.getInput();
	cout << "\n\n";
	s.simplexMethod();
	return 0;
}
Example #11
0
/* Optimisation procedure. Takes a reference to parameters, combined results, component results and number of iterations taken. The function updates these
   arguments with the results of the Nelder-Mead optimisation procedure. */
double Handler::optimiseEpidemics(vector<double> &parameters, vector<vector<double> > &results, vector<vector<vector<double> > > &allResults, int& itr){
  double SSE = 99999999999999999.9;
  double tempSSE;
  vector<double> tempPar, seedParams;
  Simplex simplex;
  int iterations = 10001;

  // If no epidemics have yet been detected, use the mean of the current data as the 
  // current model and return the corresponding SSE.
  if(epidemics.size() == 0){
    //baseModel = base_model(temp_data);
    results = base_model(temp_data);
    SSE = calculate_SSE(results, temp_data);
    parameters.clear();
    allResults.clear();
    allResults.push_back(baseModel);
    return(SSE);
  }
  srand(time(NULL));
  parameters = generate_seed_parameters();

  // If there are epidemics to be fitted, perform X random fits and keep best fitting model
  for(int index=0;index<10;index++){
    // Create random seed parameters
    seedParams.clear();      
    seedParams = generate_seed_parameters();
    
    while(fitEpidemics(seedParams) != fitEpidemics(seedParams)){
      seedParams.clear();            
      seedParams = generate_seed_parameters();
    }
    
    // Get the optimised parameters from nelder mead algorithm
    tempPar = simplex.neldermead(&Handler::fitEpidemics, *this,  seedParams, iterations);
    // Store the SSE value for this
 
    tempSSE = fitEpidemics(tempPar);
    //if(tempSSE == tempSSE) cout << "Temp RSquare: " << (1-tempSSE/(SStot(temp_data,1))) << endl;
 
    // If this SSE value is better than the previous, store it and the corresponding parameters
    if(tempSSE < SSE){
      itr = iterations;
      SSE = tempSSE;
      parameters=tempPar;
    }
    cout << "." << flush;
  }

  // Get the combined values from these parameters, as well as a vector of 
  // each sub-epidemic
  results = ode_solve(parameters);
   
  allResults.clear();
  allResults = ode_solve_separate(parameters);
  cout << endl;
  return(SSE);

}
Example #12
0
int main()
{
	struct user_data::_userdata ud;
	user_data::get_data_from_user(&ud);
	

	Simplex s;
	s.generate_plane(&ud);
	s.run();

	return 0;
}
	/**
	* @param includeMargin Indicate whether algorithm operates on objects with margin
	*/
	template<class T> std::unique_ptr<GJKResult<T>> GJKAlgorithm<T>::processGJK(const CollisionConvexObject3D &convexObject1,
			const CollisionConvexObject3D &convexObject2, bool includeMargin) const
	{
		//get point which belongs to the outline of the shape (Minkowski difference)
		Vector3<T> initialDirection = Vector3<T>(1.0, 0.0, 0.0);
		Point3<T> initialSupportPointA = convexObject1.getSupportPoint(initialDirection.template cast<float>(), includeMargin).template cast<T>();
		Point3<T> initialSupportPointB = convexObject2.getSupportPoint((-initialDirection).template cast<float>(), includeMargin).template cast<T>();
		Point3<T> initialPoint = initialSupportPointA - initialSupportPointB;

		Vector3<T> direction = (-initialPoint).toVector();

		Simplex<T> simplex;
		simplex.addPoint(initialSupportPointA, initialSupportPointB);

		T minimumToleranceMultiplicator = (T)1.0;

		for(unsigned int iterationNumber=0; iterationNumber<maxIteration; ++iterationNumber)
		{
			Point3<T> supportPointA = convexObject1.getSupportPoint(direction.template cast<float>(), includeMargin).template cast<T>();
			Point3<T> supportPointB = convexObject2.getSupportPoint((-direction).template cast<float>(), includeMargin).template cast<T>();
			Point3<T> newPoint = supportPointA - supportPointB;

			const Vector3<T> &vClosestPoint = -direction; //vector from origin to closest point of simplex
			T closestPointSquareDistance = vClosestPoint.dotProduct(vClosestPoint);
			T closestPointDotNewPoint = vClosestPoint.dotProduct(newPoint.toVector());

			//check termination conditions: new point is not more extreme that existing ones OR new point already exist in simplex
			T distanceTolerance = std::max(minimumTerminationTolerance*minimumToleranceMultiplicator, relativeTerminationTolerance*closestPointSquareDistance);
			if((closestPointSquareDistance-closestPointDotNewPoint) <= distanceTolerance || simplex.isPointInSimplex(newPoint))
			{
				if(closestPointDotNewPoint <= 0.0)
				{ //collision detected
					return std::make_unique<GJKResultCollide<T>>(simplex);
				}else
				{
					return std::make_unique<GJKResultNoCollide<T>>(std::sqrt(closestPointSquareDistance), simplex);
				}
			}

			simplex.addPoint(supportPointA, supportPointB);

			direction = (-simplex.getClosestPointToOrigin()).toVector();

			minimumToleranceMultiplicator += percentageIncreaseOfMinimumTolerance;
		}

		#ifdef _DEBUG
			logMaximumIterationReach();
		#endif

		return std::make_unique<GJKResultInvalid<T>>();
	}
D3DXVECTOR3 CollisionSolver::GetConvexHullPenetration(const CollisionMesh& particle, 
                                                      const CollisionMesh& hull, 
                                                      Simplex& simplex)
{
    D3DXVECTOR3 furthestPoint;
    D3DXVECTOR3 penetrationDirection;
    float penetrationDistance = 0.0f;
    bool penetrationFound = false;
    const float minDistance = 0.1f;
    const int maxIterations = 10;
    int iteration = 0;

    while(!penetrationFound && iteration < maxIterations)
    {
        ++iteration;
        const Face& face = simplex.GetClosestFaceToOrigin();
        penetrationDirection = face.normal;
        penetrationDistance = face.distanceToOrigin;
        penetrationFound = penetrationDistance == 0.0f;

        if(!penetrationFound)
        {
            // Check if there are any edge points beyond the closest face
            furthestPoint = GetMinkowskiSumEdgePoint(face.normal, particle, hull);
            const D3DXVECTOR3 faceToPoint = furthestPoint - simplex.GetPoint(face.indices[0]);
            const float distance = fabs(D3DXVec3Dot(&faceToPoint, &face.normal));
            penetrationFound = distance < minDistance;

            if(!penetrationFound)
            {
                // Add the new point and extend the convex hull
                simplex.ExtendFace(furthestPoint);
            }
        }
    }

    if(!penetrationFound)
    {
        // Fallback on the initial closest face
        const Face& face = simplex.GetClosestFaceToOrigin();
        penetrationDirection = face.normal;
        penetrationDistance = face.distanceToOrigin;
    }

    if(particle.RenderSolverDiagnostics())
    {
        UpdateDiagnostics(simplex, furthestPoint);
    }

    return -(penetrationDirection * penetrationDistance);
}
bool CollisionSolver::SolveTetrahedronSimplex(Simplex& simplex, D3DXVECTOR3& direction)
{
    const D3DXVECTOR3& pointA = simplex.GetPoint(3);
    const D3DXVECTOR3& pointB = simplex.GetPoint(0);
    const D3DXVECTOR3& pointC = simplex.GetPoint(1);
    const D3DXVECTOR3& pointD = simplex.GetPoint(2);

    const D3DXVECTOR3 AB = pointB - pointA;
    const D3DXVECTOR3 AC = pointC - pointA;
    const D3DXVECTOR3 AD = pointD - pointA;
    const D3DXVECTOR3 AO = -pointA;

    // Check if within the three surrounding planes
    // The forth plane has been previously tested with the plane simplex
    // All normals will point to the center of the tetrahedron
    D3DXVECTOR3 CBnormal, BDnormal, DCnormal;
    D3DXVec3Cross(&CBnormal, &AC, &AB);
    D3DXVec3Cross(&BDnormal, &AB, &AD);
    D3DXVec3Cross(&DCnormal, &AD, &AC);

    const float CBdistance = D3DXVec3Dot(&CBnormal, &AO);
    const float BDdistance = D3DXVec3Dot(&BDnormal, &AO);
    const float DCdistance = D3DXVec3Dot(&DCnormal, &AO);

    bool originInsideSimplex = true;
    if(CBdistance < 0.0f)
    {
        // Origin is outside of the CB plane
        // D is furthest point, remove it and search towards the origin
        simplex.RemovePoint(pointD);
        direction = -CBnormal;
        originInsideSimplex = false;
    }
    else if(BDdistance < 0.0f)
    {
        // Origin is outside of the BD plane
        // C is furthest point, remove it and search towards the origin
        simplex.RemovePoint(pointC);
        direction = -BDnormal;
        originInsideSimplex = false;
    }
    else if(DCdistance < 0.0f)
    {
        // Origin is outside of the DC plane
        // C is furthest point, remove it and search towards the origin
        simplex.RemovePoint(pointB);
        direction = -DCnormal;
        originInsideSimplex = false;
    }
    return originInsideSimplex;
}
bool CollisionSolver::AreConvexHullsColliding(const CollisionMesh& particle, 
                                              const CollisionMesh& hull, 
                                              Simplex& simplex)
{
    // If two convex hulls have collided, the Minkowski Sum A + (-B) of both 
    // hulls will contain the origin. Reference from 'Proximity Queries and 
    // Penetration Depth Computation on 3D Game Objects' by Gino van den Bergen
    // http://graphics.stanford.edu/courses/cs468-01-fall/Papers/van-den-bergen.pdf

    const std::vector<D3DXVECTOR3>& particleVertices = particle.GetVertices();
    const std::vector<D3DXVECTOR3>& hullVertices = hull.GetVertices();

    // Determine an initial point for the simplex
    const int initialIndex = 0;
    D3DXVECTOR3 direction = particleVertices[initialIndex] - hullVertices[initialIndex];
    D3DXVECTOR3 lastEdgePoint = GetMinkowskiSumEdgePoint(direction, particle, hull);
    simplex.AddPoint(lastEdgePoint);
        
    direction = -direction;
    int iteration = 0;
    bool collisionFound = false;
    bool collisionPossible = true;
    const int maxIterations = 20;

    // Iteratively create a simplex within the Minkowski Sum Hull
    while(iteration < maxIterations && !collisionFound && collisionPossible)
    {
        ++iteration;
        lastEdgePoint = GetMinkowskiSumEdgePoint(direction, particle, hull);
        simplex.AddPoint(lastEdgePoint);

        if(D3DXVec3Dot(&lastEdgePoint, &direction) <= 0)
        {
            // New edge point of simplex is not past the origin.
            collisionPossible = false;
        }
        else if(simplex.IsLine())
        {
            SolveLineSimplex(simplex, direction);
        }
        else if(simplex.IsTriPlane())
        {
            SolvePlaneSimplex(simplex, direction);
        }
        else if(simplex.IsTetrahedron())
        {
            collisionFound = SolveTetrahedronSimplex(simplex, direction);
        }
    }
    return collisionFound;
}
Example #17
0
 //! Initialize the Paving with all points and multiplex
 void init() {
   generate_point();
   Simplex<N> container;
   for (size_t i = 0; i < N + 1; i++) {
     container.pushPoint(multiPoints[i]);
   }
   multiplex.push_back(container);
   for (size_t i = N + 1; i < multiPoints.size(); i++) {
     for (size_t j = 0; j < multiplex.size(); j++) {
       if (isInside(multiPoints[i], multiplex[j])) {
         replaceSimplex(multiPoints[i], multiplex[j]);
         break;
       }
     }
   }
 }
Example #18
0
//////////////////////////////////////////////////////////////////////////////////////////////
////
//// SUPPORT FUNCTION
////
/////////////////////////////////////////////////////////////////////////////////////////////
//
//
Vec3f Support(vector<Vec3f>& A, vector<Vec3f>& B, Vec3f v, Simplex& P){
	Vector3f d(v[0], v[1], v[2]);
	double farthestADir = Vector3f(A[0][0], A[0][1], A[0][2]).dot(d);
	unsigned int farthestAIndex = 0;
	for(unsigned int i = 1; i<A.size(); i++){
		float newDot = Vector3f(A[i][0], A[i][1], A[i][2]).dot(d);
		if(newDot > farthestADir){
			farthestADir = newDot;
			farthestAIndex = i;
		}
	}
	d = -d;
	double farthestBDir = ConvertToEigen3Vector(B[0]).dot(d);
	unsigned int farthestBIndex = 0;
	for(unsigned int i = 1; i<B.size(); i++){
		float newDot = ConvertToEigen3Vector(B[i]).dot(d);
		if(newDot > farthestBDir){
			farthestBDir = newDot;
			farthestBIndex = i;
		}
	}
	float D = (ConvertToEigen3Vector(-A[farthestAIndex])).dot(ConvertToEigen3Vector(B[farthestBIndex]) - ConvertToEigen3Vector(A[farthestAIndex]));
	P.AddAandB(A[farthestAIndex], B[farthestBIndex]);
	return (A[farthestAIndex]-B[farthestBIndex]);
}
Image* GenerateWoodSide(int width, int height){

	// Initialize Variables:
	Image *terrain = new Image(width, height); // Output Map
	double xValue, yValue, turb, distValue, sineValue;
	int value;
	const double PI = 3.141592653589793238463;

	double xyFactor = 2.0;	//Rings
	double turbFactor = 1.0 / 800.0;
	double turbPower = 0.05;
	int octaves = 10;


	// Initialize Simplex Generator:
	srand(time(0) ^ rand()); // Initialize Random Seed
	Simplex generator = Simplex();

	// Loops through all the pixels
	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {

			xValue = (x + width) / ((double)width);
			yValue = (y - height / 2) / ((double)height);
			turb = turbPower*generator.Turbulence(x*turbFactor, y*turbFactor, octaves);
			distValue = (sqrt(xValue * xValue + yValue * yValue) + turb);
			sineValue = 128 * fabs(sin(2 * distValue*PI*xyFactor));


			// Convert the 0.0 to 1.0 noise value to a 0 to 255 RGB value:
			value = int(sineValue);
			if (value > 128)
				value = 128;
			else if (value < 0)
				value = 0;

			// Output heightmap to image:
			(*terrain)[y][x].red = 80 + value;
			(*terrain)[y][x].green = 30 + value;
			(*terrain)[y][x].blue = 30;
		}
	}

	return terrain;
}
void CollisionSolver::SolvePlaneSimplex(Simplex& simplex, D3DXVECTOR3& direction)
{
    const D3DXVECTOR3& pointA = simplex.GetPoint(2);
    const D3DXVECTOR3& pointB = simplex.GetPoint(0);
    const D3DXVECTOR3& pointC = simplex.GetPoint(1);

    const D3DXVECTOR3 AB = pointB - pointA;
    const D3DXVECTOR3 AC = pointC - pointA;
    const D3DXVECTOR3 AO = -pointA;
                
    // Determine which side of the plane the origin is on
    D3DXVECTOR3 planeNormal;
    D3DXVec3Cross(&planeNormal, &AB, &AC);

    // Determine the new search direction towards the origin
    const float distanceToPlane = D3DXVec3Dot(&planeNormal, &AO);
    direction = (distanceToPlane < 0.0f) ? -planeNormal : planeNormal;
}
Example #21
0
double OjaData::oja(const Point& x) const
{
	if (size() == 0) return -1;
    errif(x.dim() != dim(),"OjaData::oja: Illegal dimension on point " << x);
	
    if(plane)
		return plane->oja(x);
	
    double sum = 0.0;
    Simplex S;
	
    for(Index I(dim(),size()); I; I++)
    {
		S.get(*this,I,x);
		sum += S.size();
    }
    
    return sum;
}
void CollisionSolver::SolveParticleHullCollision(CollisionMesh& particle, 
                                                 const CollisionMesh& hull)
{
    // Determine if within a rough radius of the convex hull
    const D3DXVECTOR3 sphereToParticle = particle.GetPosition() - hull.GetPosition();
    const float lengthSqr = D3DXVec3LengthSq(&sphereToParticle);
    const float extendedParticleRadius = particle.GetRadius() * 2.0f;
    const float combinedRadius = hull.GetRadius() + extendedParticleRadius;

    if (lengthSqr < (combinedRadius*combinedRadius))
    {
        Simplex simplex;
        if(AreConvexHullsColliding(particle, hull, simplex))
        {
            simplex.GenerateFaces();
            const D3DXVECTOR3 penetration = GetConvexHullPenetration(particle, hull, simplex);
            particle.ResolveCollision(penetration, hull.GetVelocity(), hull.GetShape());
        }
    }
}
	/**
	 * @param separatingDistance Separating distance of two objects. In case of collision, the distance is zero.
	 */
	template<class T> GJKResultNoCollide<T>::GJKResultNoCollide(T separatingDistance, const Simplex<T> &simplex) :
		GJKResult<T>(),
		separatingDistance(separatingDistance),
		simplex(simplex)
	{
		simplex.computeClosestPoints(closestPointA, closestPointB);

		#ifdef _DEBUG
			const float subtractDistance = closestPointA.vector(closestPointB).squareLength() - separatingDistance*separatingDistance;
			assert((subtractDistance-0.01) <= 0.0 && (subtractDistance+0.01) >= 0.0);
		#endif
	}
		bool	operator()(const Simplex& s1, const Simplex& s2) const
		{
			if (s1.dimension() == s2.dimension())
				return s1.get_value() < s2.get_value();
			else
				return s1.dimension() < s2.dimension();
		}
Example #25
0
Vec3f GJKDistance(vector<Vec3f>&A, vector<Vec3f>&B, Simplex& P){
	P.clearSimplex();
	Vec3f v= Support(A, B, A[0] - B[0],P);
	P.Add(v);
	v = ClosestIn(P);

	float lastDist = FLT_MAX;
	Simplex lastP;
	lastP.SetToSimplex(P);
	Vec3f lastV = v;
	float epsilon = 0.1;

	while(true){
		float dist = v.norm();
		Vec3f w = Support(A, B, -v, P);
		Vector3f vE(v[0], v[1], v[2]);
		Vector3f wE(w[0], w[1], w[2]);
		float f = dist - (dist - w.norm());
		if(f<= tolerance*dist || dist<tolerance){
			return v;
		}if(lastDist-dist<= epsilon*lastDist){
			P.SetToSimplex(lastP);
			return lastV;
		}else{
			lastP.SetToSimplex(P);
			lastV = v;
		}
		if(P.alreadyIn(w))
			return v;
		if(vE.dot(wE) > 0)return v;
		P.Add(w);

		v = ClosestIn(P);
		P.DeleteNonClosestIn();

		if(P.GetSize() > 3) return v; //Should never reach here.
	}
	return v;
}
void CollisionSolver::SolveLineSimplex(const Simplex& simplex, D3DXVECTOR3& direction)
{
    const D3DXVECTOR3& pointA = simplex.GetPoint(1);
    const D3DXVECTOR3& pointB = simplex.GetPoint(0);
    const D3DXVECTOR3 AB = pointB - pointA;
    const D3DXVECTOR3 AO = -pointA;

    // Generate a new direction for the next point 
    // perpendicular to the line using triple product
    D3DXVECTOR3 ABcrossAO;
    D3DXVec3Cross(&ABcrossAO, &AB, &AO);
    D3DXVec3Cross(&direction, &ABcrossAO, &AB);
}
void MainWindow::sort_simplex(Simplex &smplx)
{
    unsigned ar_size = smplx.get_number_of_vertexes();   //sort
    for (unsigned j=0; j<ar_size-1; j++)
        for (unsigned i=0; i<ar_size-1; i++)
            if (func(smplx.get_vertex(i)) > func(smplx.get_vertex(i+1)))
                std::swap(smplx.m_array[i], smplx.m_array[i+1]);
    smplx.set_h(smplx.get_vertex(ar_size-1));   //set h,g,l
    smplx.set_g(smplx.get_vertex(ar_size-2));
    smplx.set_l(smplx.get_vertex(0));
    Point c;     //calculate center of mass
    for (unsigned i=0; i<ar_size-1; i++)
        c += smplx.m_array[i];
//    c = std::accumulate(m_array.begin(), m_array.end() - 1, 0) /(ar_size - 1);
    c /= ar_size-1;
    smplx.set_c(c);

//    std::sort(m_array.begin(), m_array.end(), comparator_by_f);
}
Example #28
0
Point OjaData::gradient(const Point& x) const
{
    errif(x.dim() != dim(),"OjaData::gradient: Illegal dimension on point " << x);

 	if(plane)
 		return plane->gradient(x);

    Point Gr(dim());
    Simplex S;
    double sgn;
    double k = 1.0 / double(fact(dim()));
	
    for(Index I(dim(),size()); I; I++)
    {
		S.get(*this,I,x);
		sgn =  S.sign();
		for(int j=0; j<dim(); j++)
			Gr[j] +=  S.row_cof(j+1) * sgn * k;
    }
    
    
    return Gr;
}
void CollisionSolver::UpdateDiagnostics(const Simplex& simplex, 
                                        const D3DXVECTOR3& furthestPoint)
{
    if(m_engine->diagnostic()->AllowDiagnostics(Diagnostic::COLLISION))
    {
        const float radius = 0.1f;
        const float normalLength = 1.5f;
        D3DXVECTOR3 origin(0.0, 0.0, 0.0);

        m_engine->diagnostic()->UpdateSphere(Diagnostic::COLLISION,
            "OriginPoint", Diagnostic::WHITE, origin, radius);

        m_engine->diagnostic()->UpdateSphere(Diagnostic::COLLISION, 
            "FurthestPoint", Diagnostic::MAGENTA, furthestPoint, radius);

        const auto& borders = simplex.GetBorderEdges();
        for(unsigned int i = 0; i < borders.size(); ++i)
        {
            m_engine->diagnostic()->UpdateLine(Diagnostic::COLLISION,
                "BorderEdge" + StringCast(i), Diagnostic::RED, 
                simplex.GetPoint(borders[i].indices[0]), 
                simplex.GetPoint(borders[i].indices[1]));                    
        }

        const auto& faces = simplex.GetFaces();
        for(unsigned int i = 0; i < faces.size(); ++i)
        {
            if(faces[i].alive)
            {
                std::string id = StringCast(i);
                const Face& face = faces[i];

                const D3DXVECTOR3 center = simplex.GetFaceCenter(i);
                const D3DXVECTOR3& normal = face.normal * normalLength;
                const D3DXVECTOR3& pointA = simplex.GetPoint(face.indices[0]);
                const D3DXVECTOR3& pointB = simplex.GetPoint(face.indices[1]);
                const D3DXVECTOR3& pointC = simplex.GetPoint(face.indices[2]);

                m_engine->diagnostic()->UpdateSphere(Diagnostic::COLLISION, 
                    "sCenter" + id, Diagnostic::BLUE, center, radius);

                m_engine->diagnostic()->UpdateLine(Diagnostic::COLLISION, 
                    "sNormal" + id, Diagnostic::BLUE, center, center + normal);

                m_engine->diagnostic()->UpdateLine(Diagnostic::COLLISION, 
                    "sLine1" + id, Diagnostic::YELLOW, pointA, pointB);

                m_engine->diagnostic()->UpdateLine(Diagnostic::COLLISION, 
                    "sLine2" + id, Diagnostic::YELLOW, pointA, pointC);

                m_engine->diagnostic()->UpdateLine(Diagnostic::COLLISION,
                    "sLine3" + id, Diagnostic::YELLOW, pointC, pointB);
            }
        }
    }
}
Example #30
0
void add_cofaces (const Graph& graph, Simplex& tau, 
		  const Neighbors& neighbors, 
		  Complex& complex, const std::size_t dimension) {
    typedef typename Neighbors::const_iterator Neighbor_iterator;
    complex.insert_open_cell(tau);
    if(tau.dimension() >= dimension) { return; }
    Neighbors lower_neighbors; 
    Neighbors final_neighbors; 
    for(Neighbor_iterator i = neighbors.begin(); i != neighbors.end(); ++i){
      lower_neighbors.clear();
      Simplex sigma( tau);
      sigma.insert( *i);
      get_lower_neighbors(graph, *i, lower_neighbors);
      final_neighbors.clear();
      set_intersection(lower_neighbors.begin(),lower_neighbors.end(),
                       neighbors.begin(),neighbors.end(),
                       back_inserter(final_neighbors));
      add_cofaces(graph, sigma, final_neighbors, complex, dimension); 
    }
}