예제 #1
0
void
pl_collcontext_insert_object(pl_collisioncontext_t *ctxt, pl_recgrid_t *grid, pl_object_t *obj)
{
  int octant = getoctant(&grid->centre, obj);
  if (grid->children[octant] && fits(grid->children[octant], obj)){
    pl_collcontext_insert_object(ctxt, grid->children[octant], obj);
  } else {
    obj_array_push(&grid->objs, obj);
  }

  if (grid->objs.length > THRESHOLD) {
    split(ctxt, grid);
  }
}
예제 #2
0
void
plInsertObject(PLcollisioncontext *ctxt, PLrecgrid *grid, PLobject *obj)
{
  int octant = getoctant(&grid->centre, obj);
  if (grid->children[octant] && fits(grid->children[octant], obj)){
    plInsertObject(ctxt, grid->children[octant], obj);
  } else {
    obj_array_push(&grid->objs, obj);
  }

  if (grid->objs.length > THRESHOLD) {
    split(ctxt, grid);
  }
}
예제 #3
0
static void
split(pl_collisioncontext_t *ctxt, pl_recgrid_t *grid)
{
  if (grid->children[0] == NULL) {
    for (int i = 0 ; i < 8 ; i++) {
      grid->children[i] = pl_new_recgrid(ctxt, grid->size/2.0);
      grid->children[i]->centre = grid->centre;
    }
    lwc_translate3f(&grid->children[0]->centre,
                      grid->size/4.0,  grid->size/4.0,  grid->size/4.0);
    lwc_translate3f(&grid->children[1]->centre,
                      grid->size/4.0,  grid->size/4.0, -grid->size/4.0);
    lwc_translate3f(&grid->children[2]->centre,
                      grid->size/4.0, -grid->size/4.0,  grid->size/4.0);
    lwc_translate3f(&grid->children[3]->centre,
                      grid->size/4.0, -grid->size/4.0, -grid->size/4.0);
    lwc_translate3f(&grid->children[4]->centre,
                     -grid->size/4.0,  grid->size/4.0,  grid->size/4.0);
    lwc_translate3f(&grid->children[5]->centre,
                     -grid->size/4.0,  grid->size/4.0, -grid->size/4.0);
    lwc_translate3f(&grid->children[6]->centre,
                     -grid->size/4.0, -grid->size/4.0,  grid->size/4.0);
    lwc_translate3f(&grid->children[7]->centre,
                     -grid->size/4.0, -grid->size/4.0, -grid->size/4.0);
  }

  for (int i = 0 ; i < grid->objs.length ; i++) {
    pl_object_t *obj = grid->objs.elems[i];
    int octant = getoctant(&grid->centre, obj);
    if (fits(grid->children[octant], obj)) {
      pl_collcontext_insert_object(ctxt, grid->children[octant], obj);
      obj_array_remove(&grid->objs, i);
      i --;
    }
  }
}
예제 #4
0
static void
split(PLcollisioncontext *ctxt, PLrecgrid *grid)
{
  if (grid->children[0] == NULL) {
    for (int i = 0 ; i < 8 ; i++) {
      grid->children[i] = plNewRecgrid(ctxt, grid->size/2.0);
      grid->children[i]->centre = grid->centre;
    }
    ooLwcTranslate3f(&grid->children[0]->centre,
                      grid->size/4.0,  grid->size/4.0,  grid->size/4.0);
    ooLwcTranslate3f(&grid->children[1]->centre,
                      grid->size/4.0,  grid->size/4.0, -grid->size/4.0);
    ooLwcTranslate3f(&grid->children[2]->centre,
                      grid->size/4.0, -grid->size/4.0,  grid->size/4.0);
    ooLwcTranslate3f(&grid->children[3]->centre,
                      grid->size/4.0, -grid->size/4.0, -grid->size/4.0);
    ooLwcTranslate3f(&grid->children[4]->centre,
                     -grid->size/4.0,  grid->size/4.0,  grid->size/4.0);
    ooLwcTranslate3f(&grid->children[5]->centre,
                     -grid->size/4.0,  grid->size/4.0, -grid->size/4.0);
    ooLwcTranslate3f(&grid->children[6]->centre,
                     -grid->size/4.0, -grid->size/4.0,  grid->size/4.0);
    ooLwcTranslate3f(&grid->children[7]->centre,
                     -grid->size/4.0, -grid->size/4.0, -grid->size/4.0);
  }

  for (int i = 0 ; i < grid->objs.length ; i++) {
    PLobject *obj = grid->objs.elems[i];
    int octant = getoctant(&grid->centre, obj);
    if (fits(grid->children[octant], obj)) {
      plInsertObject(ctxt, grid->children[octant], obj);
      obj_array_remove(&grid->objs, i);
      i --;
    }
  }
}
예제 #5
0
파일: lbresen.c 프로젝트: Johnson13/xLearn
/* ================================================= */
void lconiclist(ellipse *ell, int32_t rs, int32_t cs, int32_t xs, int32_t ys, int32_t xe, int32_t ye,
           int32_t A, int32_t B, int32_t C, int32_t D, int32_t E, int32_t F, int32_t xoffset, int32_t yoffset)
/* ================================================= */
{
  int32_t octant; 
  int32_t dxS, dyS, dxD, dyD;
  int32_t d,u,v;
  int32_t k1sign, k1, Bsign, k2, k3;
  int32_t gxe, gye, gx, gy;
  int32_t octantcount;
  int32_t x, y;
  int32_t tmp, tmpdk;

  A *= 4;
  B *= 4;
  C *= 4;
  D *= 4;
  E *= 4;
  F *= 4;

  if (DEBUG) fprintf(stderr,"lconic -- %d %d %d %d %d %d\n", xs, ys, xe, ye, xoffset, yoffset);
  if (DEBUG) fprintf(stderr,"lconic -- %d %d %d %d %d %d\n", A,B,C,D,E,F);

  /* Translate start point to origin... */
  /*
  F = A*xs*xs + B*xs*ys + C*ys*ys + D*xs + E*ys + F;
  D = D + 2 * A * xs + B * ys;
  E = E + B * xs + 2 * C * ys;
  */

  /* Work out starting octant */
  octant = getoctant(D,E);
  
  dxS = SIDEx[octant]; 
  dyS = SIDEy[octant]; 
  dxD = DIAGx[octant];
  dyD = DIAGy[octant];

  switch (octant) {
  case 1:
    d = A + B/2 + C/4 + D + E/2 + F;
    u = A + B/2 + D;
    v = u + E;
    break;
  case 2:
    d = A/4 + B/2 + C + D/2 + E + F;
    u = B/2 + C + E;
    v = u + D;
    break;
  case 3:
    d = A/4 - B/2 + C - D/2 + E + F;
    u = -B/2 + C + E;
    v = u - D;
    break;
  case 4:
    d = A - B/2 + C/4 - D + E/2 + F;
    u = A - B/2 - D;
    v = u + E;
    break;
  case 5:
    d = A + B/2 + C/4 - D - E/2 + F;
    u = A + B/2 - D;
    v = u - E;
    break;
  case 6:
    d = A/4 + B/2 + C - D/2 - E + F;
    u = B/2 + C - E;
    v = u - D;
    break;
  case 7:
    d = A/4 - B/2 + C + D/2 - E + F;
    u =  -B/2 + C - E;
    v = u + D;
    break;
  case 8:
    d = A - B/2 + C/4 + D - E/2 + F;
    u = A - B/2 + D;
    v = u - E;
    break;
  default:
    fprintf(stderr,"FUNNY OCTANT\n");
    abort();
  }
  
  k1sign = dyS*dyD;
  k1 = 2 * (A + k1sign * (C - A));
  Bsign = dxD*dyD;
  k2 = k1 + Bsign * B;
  k3 = 2 * (A + C + Bsign * B);

  /* Work out gradient at endpoint */
  gxe = xe - xs;
  gye = ye - ys;
  gx = 2*A*gxe +   B*gye + D;
  gy =   B*gxe + 2*C*gye + E;
  
  octantcount = getoctant(gx,gy) - octant;
  if (octantcount < 0)
    octantcount = octantcount + 8;
  else if (octantcount==0)
    if((xs>xe && dxD>0) || (ys>ye && dyD>0) ||
       (xs<xe && dxD<0) || (ys<ye && dyD<0))
      octantcount +=8;

  if (DEBUG)
    fprintf(stderr,"octantcount = %d\n", octantcount);
  
  x = xs;
  y = ys;
  
  while (octantcount > 0) {
    if (DEBUG)
      fprintf(stderr,"-- %d -------------------------\n", octant); 
    
    if (mcodd(octant)) {
      while (2*v <= k2) {
        /* Plot this point */
        plotlist(ell, rs, cs, x+xoffset, y+yoffset);
        
        /* Are we inside or outside? */
        if (DEBUG) fprintf(stderr,"x = %3d y = %3d d = %4d\n", x,y,d);
        if (d < 0) {                    /* Inside */
          x = x + dxS;
          y = y + dyS;
          u = u + k1;
          v = v + k2;
          d = d + u;
        }
        else {                          /* outside */
          x = x + dxD;
          y = y + dyD;
          u = u + k2;
          v = v + k3;
          d = d + v;
        }
      }
    
      d = d - u + v/2 - k2/2 + 3*k3/8; 
      /* error (^) in Foley and van Dam p 959, "2nd ed, revised 5th printing" */
      u = -u + v - k2/2 + k3/2;
      v = v - k2 + k3/2;
      k1 = k1 - 2*k2 + k3;
      k2 = k3 - k2;
      tmp = dxS; dxS = -dyS; dyS = tmp;
    }
    else {                              /* Octant is even */
      while (2*u < k2) {
        /* Plot this point */
        plotlist(ell, rs, cs, x+xoffset, y+yoffset);
        if (DEBUG) fprintf(stderr,"x = %3d y = %3d d = %4d\n", x,y,d);
        
        /* Are we inside or outside? */
        if (d > 0) {                    /* Outside */
          x = x + dxS;
          y = y + dyS;
          u = u + k1;
          v = v + k2;
          d = d + u;
        }
        else {                          /* Inside */
          x = x + dxD;
          y = y + dyD;
          u = u + k2;
          v = v + k3;
          d = d + v;
        }
      }
      tmpdk = k1 - k2;
      d = d + u - v + tmpdk;
      v = 2*u - v + tmpdk;
      u = u + tmpdk;
      k3 = k3 + 4*tmpdk;
      k2 = k1 + tmpdk;
      
      tmp = dxD; dxD = -dyD; dyD = tmp;
    }
    
    octant = (octant&7)+1;
    octantcount--;
  }

  /* Draw final octant until we reach the endpoint */
  if (DEBUG)
    fprintf(stderr,"-- %d (final) -----------------\n", octant); 
    
  if (mcodd(octant)) {
    while (2*v <= k2) {
      /* Plot this point */
      plotlist(ell, rs, cs, x+xoffset, y+yoffset);

      if (x == xe && y == ye)
        break;
      if (DEBUG) fprintf(stderr,"x = %3d y = %3d d = %4d\n", x,y,d);
      
      /* Are we inside or outside? */
      if (d < 0) {                      /* Inside */
        x = x + dxS;
        y = y + dyS;
        u = u + k1;
        v = v + k2;
        d = d + u;
      }
      else {                            /* outside */
        x = x + dxD;
        y = y + dyD;
        u = u + k2;
        v = v + k3;
        d = d + v;
      }
    }
  }
  else {                                /* Octant is even */
    while ((2*u < k2)) {
      /* Plot this point */
      plotlist(ell, rs, cs, x+xoffset, y+yoffset);

      if (x == xe && y == ye)
        break;
      if (DEBUG) fprintf(stderr,"x = %3d y = %3d d = %4d\n", x,y,d);
      
      /* Are we inside or outside? */
      if (d > 0) {                      /* Outside */
        x = x + dxS;
        y = y + dyS;
        u = u + k1;
        v = v + k2;
        d = d + u;
      }
      else {                            /* Inside */
        x = x + dxD;
        y = y + dyD;
        u = u + k2;
        v = v + k3;
        d = d + v;
      }
    }
  }
} /* lconiclist() */