//判定线段与空间三角形相交,不包括交于边界和(部分)包含
int seg_triangle_inter2(const Line &l, const Plane &s)
{
    return opposite_side(l.a, l.b, s)
           && opposite_side(s.a, s.b, Plane(l.a, l.b, s.c))
           && opposite_side(s.b, s.c, Plane(l.a, l.b, s.a))
           && opposite_side(s.c, s.a, Plane(l.a, l.b, s.b));
}
Ejemplo n.º 2
0
/*
 * There are two cases of single rotation possible:
 * 1) Right rotation (side = TNODE_LEFT)
 *         [P]             [L]
 *        /  \            /  \
 *      [L]  x1    =>   x2   [P]
 *     /  \                 /  \
 *    x2  x3               x3  x1
 *
 * 2) Left rotation (side = TNODE_RIHGT)
 *      [P]                [R]
 *     /  \               /  \
 *    x1  [R]      =>   [P]   x2
 *       /  \          /  \
 *     x3   x2        x1  x3
 */
static void rotate_single(TtreeNode **target, int side) {
  TtreeNode *n;

  __rotate_single(target, side);
  n = (*target)->sides[opposite_side(side)];

  /*
   * Recalculate balance factors of nodes after rotation.
   * Let X was a root node of rotated subtree and Y was its
   * child. After single rotation Y is new root of subtree and X is its child.
   * Y node may become either balanced or overweighted to the
   * same side it was but 1 level less.
   * X node scales at 1 level down and possibly it has new child, so
   * its balance should be recalculated too. If it still internal node and
   * its new parent was not overwaighted to the opposite to X side,
   * X is overweighted to the opposite to its new parent side, otherwise it's balanced.
   * If X is either half-leaf or leaf, balance racalculation is obvious.
   */
  if (is_internal_node(n)) {
    n->bfc = (n->parent->bfc != side2bfc(side)) ? side2bfc(side) : 0;
  }
  else {
    n->bfc = !!(n->right) - !!(n->left);
  }

  (*target)->bfc += side2bfc(opposite_side(side));
  TTREE_ASSERT((abs(n->bfc < 2) && (abs((*target)->bfc) < 2)));
}
Ejemplo n.º 3
0
/*
 * There are two possible cases of double rotation:
 * 1) Left-right rotation: (side == TNODE_LEFT)
 *      [P]                     [r]
 *     /  \                    /  \
 *   [L]  x1                [L]   [P]
 *  /  \          =>       / \    / \
 * x2  [r]                x2 x4  x3 x1
 *    /  \
 *  x4   x3
 *
 * 2) Right-left rotation: (side == TNODE_RIGHT)
 *      [P]                     [l]
 *     /  \                    /  \
 *    x1  [R]               [P]   [R]
 *       /  \     =>        / \   / \
 *      [l] x2             x1 x3 x4 x2
 *     /  \
 *    x3  x4
 */
static void rotate_double(TtreeNode **target, int side) {
  int opside = opposite_side(side);
  TtreeNode *n = (*target)->sides[side];

  __rotate_single(&n, opside);

  /*
   * Balance recalculation is very similar to recalculation after
   * simple single rotation.
   */
  if (is_internal_node(n->sides[side])) {
    n->sides[side]->bfc = (n->bfc == side2bfc(opside)) ? side2bfc(side) : 0;
  }
  else {
    n->sides[side]->bfc =
    !!(n->sides[side]->right) - !!(n->sides[side]->left);
  }

  TTREE_ASSERT(abs(n->sides[side]->bfc) < 2);
  n = n->parent;
  __rotate_single(target, side);
  if (is_internal_node(n)) {
    n->bfc = ((*target)->bfc == side2bfc(side)) ? side2bfc(opside) : 0;
  }
  else {
    n->bfc = !!(n->right) - !!(n->left);
  }

    /*
     * new root node of subtree is always ideally balanced
     * after double rotation.
     */
  TTREE_ASSERT(abs(n->bfc) < 2);
  (*target)->bfc = 0;
}
Ejemplo n.º 4
0
/*
 * generic single rotation procedrue.
 * side = TNODE_LEFT  - Right rotation
 * side = TNODE_RIGHT - Left rotation.
 * "target" will be set to the new root of rotated subtree.
 */
static void __rotate_single(TtreeNode **target, int side) {
  TtreeNode *p, *s;
  int opside = opposite_side(side);

  p = *target;
  TTREE_ASSERT(p != NULL);
  s = p->sides[side];
  TTREE_ASSERT(s != NULL);
  tnode_set_side(s, tnode_get_side(p));
  p->sides[side] = s->sides[opside];
  s->sides[opside] = p;
  tnode_set_side(p, opside);
  s->parent = p->parent;
  p->parent = s;
  if (p->sides[side]) {
    p->sides[side]->parent = p;
    tnode_set_side(p->sides[side], side);
  }
  if (s->parent) {
    if (s->parent->sides[side] == p) s->parent->sides[side] = s;
    else s->parent->sides[opside] = s;
  }

  *target = s;
}
Ejemplo n.º 5
0
	void report_income(price_t income, std::ostream & os)
	{
		assert(income > 0);
		if (myabs(income - m_last_income) < 0.005)
			return;

#ifndef PROFILING
		//printf("%u %c %.2f\n", m_last_timestamp, opposite_side(m_side), income);
		os << m_last_timestamp << ' ' << char_from_side(opposite_side(m_side))
				<< ' ' << income << '\n';
#endif
		m_last_income = income;
	}
Ejemplo n.º 6
0
//判线段在任意多边形内,顶点按顺时针或逆时针给出,与边界相交返回1
int inside_polygon(point l1,point l2,int n,point* p){
	point t[MAXN],tt;
	int i,j,k=0;
	if (!inside_polygon(l1,n,p)||!inside_polygon(l2,n,p))
		return 0;
	for (i=0;i<n;i++)
		if (opposite_side(l1,l2,p[i],p[(i+1)%n])&&opposite_side(p[i],p[(i+1)%n],l1,l2))
			return 0;
		else if (dot_online_in(l1,p[i],p[(i+1)%n]))
			t[k++]=l1;
		else if (dot_online_in(l2,p[i],p[(i+1)%n]))
			t[k++]=l2;
		else if (dot_online_in(p[i],l1,l2))
			t[k++]=p[i];
	for (i=0;i<k;i++)
		for (j=i+1;j<k;j++){
			tt.x=(t[i].x+t[j].x)/2;
			tt.y=(t[i].y+t[j].y)/2;
			if (!inside_polygon(tt,n,p))
				return 0;			
		}
	return 1;
}
Ejemplo n.º 7
0
	bool not_available(int target_size, std::ostream &os)
	{
		// if enough shares to (buy) sell
		if (m_shares < target_size)
		{
			if (m_last_income > 0)
			{
#ifndef PROFILING
				os << m_last_timestamp << ' ' << char_from_side(opposite_side(
						m_side)) << " NA\n";
#endif
				m_last_income = -1; // not available
			}
			return true;
		}
		return false;
	}
//判定两线段相交,不包括端点和部分重合
bool seg_seg_inter(const Line &u, const Line &v)
{
    return point_on_plane(u.a, Plane(u.b, v.a, v.b))
           && opposite_side(u.a, u.b, v)
           && opposite_side(v.a, v.b, u);
}
Ejemplo n.º 9
0
//判两线段相交,不包括端点和部分重合
int intersect_ex(line u,line v){
	return opposite_side(u.a,u.b,v)&&opposite_side(v.a,v.b,u);
}
Ejemplo n.º 10
0
int intersect_ex(point u1,point u2,point v1,point v2){
	return opposite_side(u1,u2,v1,v2)&&opposite_side(v1,v2,u1,u2);
}
Ejemplo n.º 11
0
static void rebalance(Ttree *ttree, TtreeNode **node, TtreeCursor *cursor) {
  int lh = left_heavy(*node);
  int sum = abs((*node)->bfc + (*node)->sides[opposite_side(lh)]->bfc);

  if (sum >= 2) {
    rotate_single(node, opposite_side(lh));
    goto out;
  }

  rotate_double(node, opposite_side(lh));

  /*
   * T-tree rotation rules difference from AVL rules in only one aspect.
   * After double rotation is done and a leaf became a new root node of
   * subtree and both its left and right childs are half-leafs.
   * If the new root node contains only one item, N - 1 items should
   * be moved into it from one of its childs.
   * (N is a number of items in selected child node).
   */
  if ((tnode_num_keys(*node) == 1) && is_half_leaf((*node)->left) && is_half_leaf((*node)->right)) {
    TtreeNode *n;
    int offs, nkeys;

    /*
     * If right child contains more items than left, they will be moved
     * from the right child. Otherwise from the left one.
     */
    if (tnode_num_keys((*node)->right) >= tnode_num_keys((*node)->left)) {
      /*
       * Right child was selected. So first N - 1 items will be copied
       * and inserted after parent's first item.
       */
      n = (*node)->right;
      nkeys = tnode_num_keys(n);
      (*node)->keys[0] = (*node)->keys[(*node)->min_idx];
      offs = 1;
      (*node)->min_idx = 0;
      (*node)->max_idx = nkeys - 1;
      if (!cursor) {
        goto no_cursor;
      }
      else if (cursor->tnode == n) {
        if (cursor->idx < n->max_idx) {
          cursor->tnode = *node;
          cursor->idx = (*node)->min_idx + (cursor->idx - n->min_idx + 1);
        }
        else {
          cursor->idx = first_tnode_idx(ttree);
        }
      }
    }
    else {
      /*
       * Left child was selected. So its N - 1 items
       * (starting after the min one)
       * will be copied and inserted before parent's single item.
       */
      n = (*node)->left;
      nkeys = tnode_num_keys(n);
      (*node)->keys[ttree->keys_per_tnode - 1] = (*node)->keys[(*node)->min_idx];
      (*node)->min_idx = offs = ttree->keys_per_tnode - nkeys;
      (*node)->max_idx = ttree->keys_per_tnode - 1;
      if (!cursor) {
        goto no_cursor;
      }
      else if (cursor->tnode == n) {
        if (cursor->idx > n->min_idx) {
          cursor->tnode = *node;
          cursor->idx = (*node)->min_idx + (cursor->idx - n->min_idx);
        }
        else {
          cursor->idx = first_tnode_idx(ttree);
        }
      }

      n->max_idx = n->min_idx++;
    }

    no_cursor: memcpy((*node)->keys + offs, n->keys + n->min_idx, sizeof(void *) * (nkeys - 1));
    n->keys[first_tnode_idx(ttree)] = n->keys[n->max_idx];
    n->min_idx = n->max_idx = first_tnode_idx(ttree);
  }

  out: if (ttree->root->parent) {
    ttree->root = *node;
  }
}