Exemplo n.º 1
0
	MTV CirclevsPolygon(Shape* pa, Shape* pb)
	{
		Circle* a = dynamic_cast<Circle*>(pa);
		Polygon* b = dynamic_cast<Polygon*>(pb);

		// Transform circle center to Polygon model space
		Vec2 center = a->center;

		// Find edge with minimum penetration
		float separation = -FLT_MAX;
		unsigned faceNormal = 0;
		for (unsigned i = 0; i < b->getVertsNum(); ++i)
		{
			float s = Dot(b->getAxes(i), center - b->vertices[i]);
			if (s > a->radius) {
				return MTV(false);
			}

			if (s > separation) {
				separation = s;
				faceNormal = i;
			}
		}

		// Grab face's vertices
		Vec2 v1 = b->vertices[faceNormal];
		unsigned i2 = faceNormal + 1 < b->getVertsNum() ? faceNormal + 1 : 0;
		Vec2 v2 = b->vertices[i2];

		// Determine which voronoi region of the edge center of circle lies within
		float dot1 = Dot(center - v1, v2 - v1);
		float dot2 = Dot(center - v2, v1 - v2);
		
		if (dot1 <= 0.0f) {
			if (DistSqr(center, v1) > a->radius * a->radius)
				return MTV(false);
		}
		else if (dot2 <= 0.0f) {
			if (DistSqr(center, v2) > a->radius * a->radius)
				return MTV(false);
		}
		else {
			Vec2 n = b->getAxes(faceNormal);
			if (Dot(center - v1, n) > a->radius)
				return MTV(false);
		}

		return MTV(b->getAxes(faceNormal), a->radius - separation, true);
	}
Exemplo n.º 2
0
 /// \brief
 ///   Returns the distance between this vector and the passed vector
 inline float Dist(const VVertex3f &v2) const
 {
   return hkvMath::sqrt (DistSqr(v2));
 }
Exemplo n.º 3
0
nat32 MeanGridSeg::UpdatePixels(const ds::Array2D<nat32> & oldSeg, ds::Array2D<nat32> & newSeg,
                                const ds::Array<Mean> & mean)
{
 nat32 changes = 0;
 for (nat32 y=0;y<oldSeg.Height();y++)
 {
  for (nat32 x=0;x<oldSeg.Width();x++)
  {
   nat32 cur = oldSeg.Get(x,y);
   nat32 nx = (x!=0)?oldSeg.Get(x-1,y):cur;
   nat32 px = (x+1!=oldSeg.Width())?oldSeg.Get(x+1,y):cur;
   nat32 ny = (y!=0)?oldSeg.Get(x,y-1):cur;
   nat32 py = (y+1!=oldSeg.Height())?oldSeg.Get(x,y+1):cur;
   
   if ((cur!=nx)||(cur!=px)||(cur!=ny)||(cur!=py))
   {
    real32 best = DistSqr(mean[cur],x,y);
    nat32 bestSeg = cur;
    
    if (nx!=cur)
    {
     real32 cost = DistSqr(mean[nx],x,y);
     if (cost<best)
     {
      best = cost;
      bestSeg = nx;
     }
    }
    
    if (px!=cur)
    {
     real32 cost = DistSqr(mean[px],x,y);
     if (cost<best)
     {
      best = cost;
      bestSeg = px;
     }
    }
    
    if (ny!=cur)
    {
     real32 cost = DistSqr(mean[ny],x,y);
     if (cost<best)
     {
      best = cost;
      bestSeg = ny;
     }
    }
    
    if (py!=cur)
    {
     real32 cost = DistSqr(mean[py],x,y);
     if (cost<best)
     {
      best = cost;
      bestSeg = py;
     }
    }
    
    if (bestSeg!=cur) changes += 1;
    newSeg.Get(x,y) = bestSeg;
   }
   else
   {
    newSeg.Get(x,y) = oldSeg.Get(x,y);
   }
  }
 }
 return changes;
}
Exemplo n.º 4
0
	void circletoPolygon(Manifold* m, RigidBody* a, RigidBody* b) {
		Circle* A = reinterpret_cast<Circle *>      (a->shape);
		Polygon* B = reinterpret_cast<Polygon *>(b->shape);

		m->contactCount = 0;

		vec2 center = a->getPosition();
		center = B->m_orientation.transpose() * (center - b->getPosition());

		float separation = -FLT_MAX;
		int faceNormal = 0;
		for (int i = 0; i < B->m_vertexCount; ++i) {
			float s = dot(B->m_normals[i], center - B->m_vertices[i]);

			if (s > A->m_radius)
				return;

			if (s > separation) {
				separation = s;
				faceNormal = i;
			}
		}

		vec2 v1 = B->m_vertices[faceNormal];
		unsigned int i2 = faceNormal + 1 < B->m_vertexCount ? faceNormal + 1 : 0;
		vec2 v2 = B->m_vertices[i2];

		if (separation < EPSILON) {
			m->contactCount = 1;
			m->normal = -(B->m_orientation * B->m_normals[faceNormal]);
			m->contacts[0] = m->normal * A->m_radius + a->getPosition();
			m->penetration = A->m_radius;
			return;
		}

		float dot1 = dot(center - v1, v2 - v1);
		float dot2 = dot(center - v2, v1 - v2);
		m->penetration = A->m_radius - separation;

		if (dot1 <= 0.0f) {
			if (DistSqr(center, v1) > A->m_radius * A->m_radius)
				return;

			m->contactCount = 1;
			vec2 n = v1 - center;
			n = B->m_orientation * n;
			n.normalise();
			m->normal = n;
			v1 = B->m_orientation * v1 + b->getPosition();
			m->contacts[0] = v1;
		}

		else if (dot2 <= 0.0f) {
			if (DistSqr(center, v2) > A->m_radius * A->m_radius)
				return;

			m->contactCount = 1;
			vec2 n = v2 - center;
			v2 = B->m_orientation * v2 + b->getPosition();
			m->contacts[0] = v2;
			n = B->m_orientation * n;
			n.normalise();
			m->normal = n;
		}

		else {
			vec2 n = B->m_normals[faceNormal];
			if (dot(center - v1, n) > A->m_radius)
				return;

			n = B->m_orientation * n;
			m->normal = -n;
			m->contacts[0] = m->normal * A->m_radius + a->getPosition();
			m->contactCount = 1;
		}
	}