예제 #1
0
bool matrix_3x3_square_to_quad(const float dx0, const float dy0,
                               const float dx1, const float dy1,
                               const float dx3, const float dy3,
                               const float dx2, const float dy2,
                               math_matrix_3x3 *mat)
{
   float ax  = dx0 - dx1 + dx2 - dx3;
   float ay  = dy0 - dy1 + dy2 - dy3;

   if (float_is_zero(ax) && float_is_zero(ay))
   {
      /* affine case */
      matrix_3x3_inits(mat,
            dx1 - dx0, dy1 - dy0,  0,
            dx2 - dx1, dy2 - dy1,  0,
            dx0,       dy0,        1);
   }
   else
   {
      float a, b, c, d, e, f, g, h;
      float ax1 = dx1 - dx2;
      float ax2 = dx3 - dx2;
      float ay1 = dy1 - dy2;
      float ay2 = dy3 - dy2;

      /* determinants */
      float gtop    =  ax  * ay2 - ax2 * ay;
      float htop    =  ax1 * ay  - ax  * ay1;
      float bottom  =  ax1 * ay2 - ax2 * ay1;

      if (!bottom)
         return false;

      g = gtop / bottom;
      h = htop / bottom;

      a = dx1 - dx0 + g * dx1;
      b = dx3 - dx0 + h * dx3;
      c = dx0;
      d = dy1 - dy0 + g * dy1;
      e = dy3 - dy0 + h * dy3;
      f = dy0;

      matrix_3x3_inits(mat,
            a, d, g,
            b, e, h,
            c, f, 1.f);
   }

   return true;
}
예제 #2
0
bool matrix_3x3_invert(math_matrix_3x3 *mat)
{
   float det = matrix_3x3_determinant(mat);

   if (float_is_zero(det))
      return false;

   matrix_3x3_adjoint(mat);
   matrix_3x3_divide_scalar(mat, det);

   return true;
}
예제 #3
0
node_t* node_optimize2(node_t*n, bool*again)
{
    int t,num;
    switch(node_get_opcode(n)) {
        case opcode_node_block:
            for(t=0;t<n->num_children;t++) {
                if(n->child[t]->type == &node_nop) {
                    node_remove_child(n, t--);
                }
            }
            break;
        case opcode_node_in:
            /* convert 
                    a in [x]
               to
                    a == x
             */
            if(node_is_array(n->child[1]) &&
               n->child[1]->value.a->size == 1) {
                node_t*new_node = node_new(&node_equals, n->parent);
                node_t*constant = node_new_with_args(&node_constant, n->child[1]->value.a->entries[0]);
                node_append_child(new_node, n->child[0]);
                node_append_child(new_node, constant);
                node_destroy_self(n);
                return new_node;
            }
            break;
        case opcode_node_mul:
            /* convert 
                    a * 1.0
               or
                    1.0 * a
               to
                    a
             */
            if(n->child[1]->type == &node_float &&
               float_is_one(n->child[1]->value.f)) {
                node_t*new_node = n->child[0];
                node_destroy(n->child[1]);
                node_destroy_self(n);
                return new_node;
            }
            if(n->child[0]->type == &node_float &&
               float_is_one(n->child[0]->value.f)) {
                node_t*new_node = n->child[1];
                node_destroy(n->child[0]);
                node_destroy_self(n);
                return new_node;
            }
            /* convert 
                    a * 0.0
               or
                    0.0 * a
               to
                    0.0
             */
            if(n->child[0]->type == &node_float &&
               float_is_zero(n->child[0]->value.f)) {
                node_t*new_node = n->child[0];
                node_destroy(n->child[1]);
                node_destroy_self(n);
                return new_node;
            }
            if(n->child[1]->type == &node_float &&
               float_is_zero(n->child[1]->value.f)) {
                node_t*new_node = n->child[1];
                node_destroy(n->child[0]);
                node_destroy_self(n);
                return new_node;
            }
            break;
        case opcode_node_sub:
            /* convert 
                    a - 0.0
               to
                    a
             */
            if(n->child[1]->type == &node_float &&
               float_is_zero(n->child[1]->value.f)) {
                node_t*new_node = n->child[0];
                node_destroy_self(n);
                return new_node;
            }
            break;
        case opcode_node_div:
            /* convert 
                    a / 1.0
               to
                    a
             */
            if(n->child[1]->type == &node_float &&
               float_is_one(n->child[1]->value.f)) {
                node_t*new_node = n->child[0];
                node_destroy_self(n);
                return new_node;
            }
            break;
        case opcode_node_add:
            /* convert 
                    a + 0.0
               to
                    a
             */
            num = 0;
            for(t=0;t<n->num_children;t++) {
                node_set_child(n, num, n->child[t]);
                if(n->child[t]->type != &node_float ||
                   !float_is_zero(n->child[t]->value.f)) {
                    num++;
                }
            }
            if(!num) {
                node_set_child(n, num++, node_new_with_args(&node_float, 0.0));
            }
            n->num_children = num;
            if(num==1) {
                node_t*new_node = n->child[0];
                node_destroy_self(n);
                return new_node;
            }
            break;
        case opcode_node_if:
            /* convert 
                    if 
                        c
                    then
                        a
                    else
                        a
               to
                    a
             */
            if(node_equals_node(n->child[1], n->child[2])) {
                node_t*new_node = n->child[1];
                node_destroy_self(n);
                return new_node;
            }
            break;
        case opcode_node_setlocal:
            /* convert 
                    setlocal i
                        getlocal i
               to
                    nop
             */
            if(n->child[0]->type == &node_getlocal) {
                if(n->child[0]->value.i == n->value.i) {
                    node_t*new_node = node_new(&node_nop, n->parent);
                    node_destroy(n);
                    *again = true;
                    return new_node;
                }
            }
            break;
    }
    for(t=0;t<n->num_children;t++) {
        node_set_child(n, t, node_optimize2(n->child[t], again));
    }
    return n;
}