Jump to content

  • Log In with Google      Sign In   
  • Create Account

ProvenDantheman

Member Since 27 Jan 2012
Offline Last Active Mar 15 2013 01:12 PM

#5043128 Distance between two entities decide volume of a sound.

Posted by on 14 March 2013 - 01:10 PM

volume = max_volume - sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));




#4906811 Collision Handling Irregular Objects 2d RPG

Posted by on 27 January 2012 - 01:09 PM

Use Separate Axis Theorem
My implementation:

class vert{
public:
float x,y;
~vert();
vert();
vert(float,float);
vert &vert::operator=(vert);
vert normal();
};
vert::~vert(){
}
vert::vert(){
x = y = 0;
}
vert::vert(float initx, float inity){
x = initx;
y = inity;
}
vert  &vert::operator=(vert initp){
x = initp.x;
y = initp.y;
return(*this);
}
vert vert::normal(){
vert norm = *this;
float mag = sqrt((norm.x * norm.x) + (norm.y * norm.y));
norm.x /= mag;
norm.y /= mag;
return(norm);
}
class poly{
vert projection(vert);
public:
int vert_count;
vert * verts;
vert center;
vert mtv;
poly(int,...);
poly();
~poly();
poly &poly::operator = (poly);
void collision(poly*,bool);
bool collided;
float density;
};
poly::poly(int N,...){
density = 1;
verts = new vert[N];
vert_count = N;
va_list list;
va_start(list,N);
for(int i = 0; i < N; i++){
  verts[i] = va_arg(list,vert);
}
va_end(list);
center = vert(0,0);
for(int i = 0; i < N; i++){
  center.x += verts[i].x;
  center.y += verts[i].y;
}
center.x /= N;
center.y /= N;
}
poly::poly(){
vert_count = 0;
density = 1;
}
poly::~poly(){
}
poly &poly::operator=(poly apoly){
if(vert_count > 0){
  delete[]verts;
}
vert_count = apoly.vert_count;
verts = new vert[vert_count];
for(int i = 0; i < vert_count; i++){
  verts[i] = apoly.verts[i];
}
center = apoly.center;
return(*this);
}
vert poly::projection(vert axis){
float min = (axis.x * verts[0].x) + (axis.y * verts[0].y);
float max = min;
for(int i = 0; i < vert_count; i++){
  float pro = (axis.x * verts[i].x) + (axis.y * verts[i].y);
  if(pro < min){
   min = pro;
  }
  if(pro > max){
   max = pro;
  }
}
return(vert(min,max));
}
void poly::collision(poly* tpoly,bool both = false){
vert * edges = new vert[vert_count];
vert * edges2 = new vert[tpoly->vert_count];
collided = true;
for(int i = 0; i < vert_count; i++){
  vert a = verts[i];
  vert b = verts[i+1 == vert_count ? 0 : i+1];
  edges[i] = vert(b.x - a.x, b.y - a.y);
  edges[i] = edges[i].normal();
}
for(int i = 0; i < tpoly->vert_count; i++){
  vert a = tpoly->verts[i];
  vert b = tpoly->verts[i+1 == tpoly->vert_count ? 0 : i+1];
  edges2[i] = vert(b.x - a.x, b.y - a.y);
  edges2[i] = edges2[i].normal();
}
float overlap = 9999;
vert smallest;
for(int i = 0; i < vert_count; i++){
  vert p1 = projection(edges[i]);
  vert p2 = tpoly->projection(edges[i]);
  if(p1.y >= p2.x && p2.y >= p1.x){
   float toverlap;
   if(p1.x <= p2.x){
    toverlap = p1.y - p2.x;
   }
   else{
    toverlap = p2.y - p1.x;
   }
   if(toverlap < overlap){
    overlap = toverlap;
    smallest = edges[i];
   }
  }
  else{
   collided = false;
  }
}
for(int i = 0; i < tpoly->vert_count; i++){
  vert p1 = projection(edges2[i]);
  vert p2 = tpoly->projection(edges2[i]);
  if(p1.y >= p2.x && p2.y >= p1.x){
   float toverlap;
   if(p1.x <= p2.x){
    toverlap = p1.y - p2.x;
   }
   else{
    toverlap = p2.y - p1.x;
   }
   if(toverlap < overlap){
    overlap = toverlap;
    smallest = edges2[i];
   }
  }
  else{
   collided = false;
  }
}
if(collided){
  vert dist = vert(tpoly->center.x - center.x, tpoly->center.y - center.y);
  float check;
  check = dist.x * smallest.x + dist.y * smallest.y;
  if(check < 0){
   smallest.x *= -1;
   smallest.y *= -1;
  }
  if(!both){
   for(int i = 0; i < vert_count; i++){
    verts[i].x -= smallest.x*overlap;
    verts[i].y -= smallest.y*overlap;
   }
   mtv.x = -smallest.x*overlap;
   mtv.y = -smallest.y*overlap;
  }
  else{
   float m1 = density, m2 = tpoly->density;
   float normp = sqrt((density+tpoly->density)*(density+tpoly->density));
   m1 /= normp;
   m2 /= normp;
   for(int i = 0; i < vert_count; i++){
    verts[i].x -= (smallest.x*overlap)*m1;
    verts[i].y -= (smallest.y*overlap)*m1;
   }
   for(int i = 0; i < tpoly->vert_count; i++){
    tpoly->verts[i].x += (smallest.x*overlap)*m2;
    tpoly->verts[i].y += (smallest.y*overlap)*m2;
   }
   mtv.x = -smallest.x*overlap*m1;
   mtv.y = -smallest.y*overlap*m1;
   tpoly->mtv.x = smallest.x*overlap*m2;
   tpoly->mtv.y = smallest.y*overlap*m2;
  }
  center = vert(0,0);
  for(int i = 0; i < vert_count; i++){
   center.x += verts[i].x;
   center.y += verts[i].y;
  }
  center.x /= vert_count;
  center.y /= vert_count;
  tpoly->center = vert(0,0);
  for(int i = 0; i < tpoly->vert_count; i++){
   tpoly->center.x += tpoly->verts[i].x;
   tpoly->center.y += tpoly->verts[i].y;
  }
  tpoly->center.x /= tpoly->vert_count;
  tpoly->center.y /= tpoly->vert_count;
}
delete[]edges;
delete[]edges2;
}



PARTNERS