Exemplo n.º 1
0
bool controls_contained_by_ends(const Cubic& c) {
    _Vector startTan = c[1] - c[0];
    if (startTan.x == 0 && startTan.y == 0) {
        startTan = c[2] - c[0];
    }
    _Vector endTan = c[2] - c[3];
    if (endTan.x == 0 && endTan.y == 0) {
        endTan = c[1] - c[3];
    }
    if (startTan.dot(endTan) >= 0) {
        return false;
    }
    _Line startEdge = {c[0], c[0]};
    startEdge[1].x -= startTan.y;
    startEdge[1].y += startTan.x;
    _Line endEdge = {c[3], c[3]};
    endEdge[1].x -= endTan.y;
    endEdge[1].y += endTan.x;
    double leftStart1 = is_left(startEdge, c[1]);
    if (leftStart1 * is_left(startEdge, c[2]) < 0) {
        return false;
    }
    double leftEnd1 = is_left(endEdge, c[1]);
    if (leftEnd1 * is_left(endEdge, c[2]) < 0) {
        return false;
    }
    return leftStart1 * leftEnd1 >= 0;
}
Exemplo n.º 2
0
//returns i < j
bool angle_compare(Point2D  pole, Point2D  i, Point2D  j)
{
    if(pole == i)
        return 1;
    if(pole == j)
        return 0;
    if(is_left(pole, i , j) == 0)
        {
            if( (i.y > pole.y && j.y > pole.y) || (i.y < pole.y && j.y < pole.y) )
            {
                return (get_length(i, pole) < get_length(j, pole));
            }
            else if(i.y == pole.y && j.y == pole.y)
            {
                if( (i.x > pole.x && j.x > pole.x) || (i.x < pole.x && j.x < pole.y) )
                    return (get_length(i, pole) < get_length(j, pole));
                else
                    return (i.x < j.x);
            }
            else
            {
                return (i.y > j.y);
            }
        }
        else
        {
            if(is_left(pole, i, j) > 0)
            {
                if(i.y >= pole.y)
                    return 1;
                else
                {
                    if(j.y < pole.y)
                        return 1;
                    else
                        return 0;
                }
            }
            else
            {
                if(i.y < pole.y)
                    return 0;
                else
                {
                    if(j.y >= pole.y)
                        return 0;
                    else
                        return 1;
                }
            }
        }
}
Exemplo n.º 3
0
void delete_node(RB_tree *tree, short int key){
    RB_node *node = get_node(tree, key);
    if(node != tree->nil){
        RB_node *y, *x;
        if(node->left == tree->nil || node->right == tree->nil){
            y = node;
        }else{
            y = get_successor(node, tree->nil);
        }
        if(y->left != tree->nil){
            x = y->left;
        }else{
            x = y->right;
        }

        x->parent = y->parent;

        if(y->parent == tree->nil){
            tree->root = x;
        }else if(is_left(y)){
            y->parent->left = x;
        }else{
            y->parent->right = x;
        }
        if(y != node){
            node->key = y->key;
        }

        if(y->color == BLACK){
            RB_delete_fixup(tree, x);
        }

        free(y);
    }
}
Exemplo n.º 4
0
    static inline return_type starts_from_middle(side_info const& sides,
                coordinate_type const& dx1, coordinate_type const& dy1,
                S1 const& s1, S2 const& s2,
                char which,
                int how_a, int how_b)
    {
        // Calculate ARROW of b segment w.r.t. s1
        coordinate_type dpx = get<1, 0>(s2) - get<0, 0>(s1);
        coordinate_type dpy = get<1, 1>(s2) - get<0, 1>(s1);

        int dir = is_left(dx1, dy1, dpx, dpy) ? 1 : -1;

        // From other perspective, then reverse
        bool const is_a = which == 'A';
        if (is_a)
        {
            dir = -dir;
        }

        return return_type(sides, 's',
            how_a,
            how_b,
            is_a ? dir : -dir,
            ! is_a ? dir : -dir);
    }
Exemplo n.º 5
0
/*** ConvexHull::find_positive
 * May return any number n where the segment n -> n + 1 (possibly looped around) in the hull such
 * that the point is on the wrong side to be within the hull.  Returns -1 if it is within the hull.*/
int
ConvexHull::find_left(Point p) {
    int l = boundary.size(); //Who knows if C++ is smart enough to optimize this?
    for(int i = 0; i < l; i++) {
        if(is_left(p, i)) return i;
    }
    return -1;
}
Exemplo n.º 6
0
//deleting not sorted useless points
std::vector<Point2D> delete_chain(std::vector<Point2D> points, Point2Df pole)
{

    //find most right and most left;
    int left = 0;
    int right = 0;
    double enext;
    points.push_back(points[0]);
    double eprev = is_left((Point2Df)points[0],(Point2Df) points[1], pole);

    for(int i = 1; i < points.size() - 1; i++)
    {
        enext = is_left((Point2Df)points[i], (Point2Df)points[i + 1], pole);
        if ((eprev <= 0.0) && (enext > 0.0))
        {
            if (is_left(pole, (Point2Df)points[i], (Point2Df)points[right]) >= 0.0)
                right = i;
        }
        else if ((eprev > 0) && (enext <= 0))
        {
            if (is_left(pole, (Point2Df)points[i], (Point2Df)points[left]) <= 0.0)
                left = i;
        }
        eprev = enext;
        if(i == points.size() - 1)
            break;
    }
    points.pop_back();
    //angle_compare_180
    std::vector<Point2D> sset;


    if (right < left)
    {
        sset.assign(points.begin() + right, points.begin() + left + 1);
        return sset;
    }
    else
    {
        points.erase(points.begin() + left + 1, points.begin() + right);
        return points;

    }

}
static void pointFinder(const Quadratic& q1, const Quadratic& q2) {
    for (int index = 0; index < 3; ++index) {
        double t = nearestT(q1, q2[index]);
        _Point onQuad;
        xy_at_t(q1, t, onQuad.x, onQuad.y);
        SkDebugf("%s t=%1.9g (%1.9g,%1.9g) dist=%1.9g\n", __FUNCTION__, t, onQuad.x, onQuad.y,
                onQuad.distance(q2[index]));
        double left[3];
        left[0] = is_left((const _Line&) q1[0], q2[index]);
        left[1] = is_left((const _Line&) q1[1], q2[index]);
        _Line diag = {q1[0], q1[2]};
        left[2] = is_left(diag, q2[index]);
        SkDebugf("%s left=(%d, %d, %d) inHull=%s\n", __FUNCTION__, floatSign(left[0]),
                floatSign(left[1]), floatSign(left[2]),
                point_in_hull(q1, q2[index]) ? "true" : "false");
    }
    SkDebugf("\n");
}
Exemplo n.º 8
0
int in_polygon(std::vector<Point2D> polygon, Point2Df p)
{
    for(int i = 0; i < polygon.size() - 1; i++)
    {
        if(is_left( (Point2Df) polygon[i],(Point2Df) polygon[i + 1], p) < 0.0)
            return 0;
    }
    return 1;
}
Exemplo n.º 9
0
void RB_delete_fixup(RB_tree *tree, RB_node *node){
    RB_node *sibl;
    while(node != tree->root && node->color == BLACK){
        if(is_left(node)){
            sibl = node->parent->right;
            if(sibl->color == RED){//1st CASE
                sibl->color = BLACK;
                sibl->parent->color = RED;
                rotate_left(tree, node->parent);
                sibl = node->parent->right;
            }
            if(sibl->left->color == BLACK && sibl->right->color == BLACK){
                //2nd CASE
                sibl->color = RED;
                node = node->parent;
            }else{
                if(sibl->right->color == BLACK){//3th CASE --> 4th
                    sibl->left->color = BLACK;
                    sibl->color = RED;
                    rotate_right(tree, sibl);
                    sibl = node->parent->right;
                }
                sibl->color = node->parent->color;//4th CASE
                node->parent->color = BLACK;
                sibl->right->color = BLACK;
                rotate_left(tree, node->parent);
                node = tree->root;
            }
        }else{
            sibl = node->parent->left;
            if(sibl->color == RED){//1st CASE
                sibl->color = BLACK;
                sibl->parent->color = RED;
                rotate_right(tree, node->parent);
                sibl = node->parent->left;
            }
            if(sibl->left->color == BLACK && sibl->right->color == BLACK){//2nd CASE
                sibl->color = RED;
                node = node->parent;
            }else{
                if(sibl->left->color == BLACK){//3th CASE --> 4th
                    sibl->right->color = BLACK;
                    sibl->color = RED;
                    rotate_left(tree, sibl);
                    sibl = node->parent->left;
                }
                sibl->color = node->parent->color;//4th CASE
                node->parent->color = BLACK;
                sibl->left->color = BLACK;
                rotate_right(tree, node->parent);
                node = tree->root;
            }
        }
    }
    node->color = BLACK;
}
Exemplo n.º 10
0
std::vector<Point2D> graham_scan(std::vector<Point2D> points, Point2D pole)
{
    std::vector<Point2D> st;

    points.push_back(pole);
    if(is_line(points))
    {
        st.push_back(points[points.size() - 1]);
        st.push_back(points[points.size() - 2]);
        return st;
    }
    points.pop_back();


    st.push_back(points[points.size() - 1]);
    st.push_back(pole);

    for(int i = 0; i < points.size(); i++)
    {
        long long int left = is_left(st[st.size() - 2], st[st.size() - 1], points[i] );
        if( left > 0)
        {
            if(!(points[i] == st[0]) && !(points[i] == st[1]))
            st.push_back(points[i]);
        }
        else
        {
            st.pop_back();
            i--;
        }
    }
    //test of 3 last points on one line
    if(is_left(st[st.size() - 2], st[st.size() - 1], points[points.size() - 1]) == 0)
    {
        st.pop_back();
    }



    return st;

}
Exemplo n.º 11
0
    static inline return_type b_ends_at_middle(side_info const& sides,
                coordinate_type const& dx, coordinate_type const& dy,
                S1 const& s1, S2 const& s2)
    {
        coordinate_type dpx = get<1, 0>(s1) - get<0, 0>(s2);
        coordinate_type dpy = get<1, 1>(s1) - get<0, 1>(s2);

        return is_left(dx, dy, dpx, dpy)
            ? return_type(sides, 'm', 0, 1, 1, 1)
            : return_type(sides, 'm', 0, 1, -1, -1);
    }
Exemplo n.º 12
0
int scan(FILE *target)
{
  hash_t *var_map = malloc(sizeof(hash_t));
  hash_init(var_map, 1024);

  write_header(target);

  int ret = 0;

  while(next() == true){

    if(is_alpha() == false){

      printf("An instruction can only start with a function call or assignment\n");
      return 1;
    }

    char *current_token = get_token();

    char *temp;
    strcpy(temp, current_token);

    if(next() == false){

      printf("Incomplete instruction\n");
      return 1;

    }

    if(is_left()){

      ret = parse_call(target, temp, var_map);  /* It is a call */

    } else if(is_assignment()){

      ret = parse_assignment(target, temp, var_map);  /* It is an assignment */

    } else {
      printf("Not a valid instruction\n");
      return 1;
    }

    if(ret == 1 ){
      printf("Syntax error\n");
      return 1;
    }

  }

  write_end(target);
  free(var_map);
  return ret;

}
Exemplo n.º 13
0
    static inline return_type angle(side_info const& sides,
                coordinate_type const& dx1, coordinate_type const& dy1,
                S1 const& s1, S2 const& s2,
                char how, int how_a, int how_b)
    {
        coordinate_type dpx = get<I, 0>(s2) - get<0, 0>(s1);
        coordinate_type dpy = get<I, 1>(s2) - get<0, 1>(s1);

        return is_left(dx1, dy1, dpx, dpy)
            ? return_type(sides, how, how_a, how_b, 1, 1)
            : return_type(sides, how, how_a, how_b, -1, -1);
    }
Exemplo n.º 14
0
void SimplePolylineConvex::push_point(PointD const& p)
{
    if (vertices_.size() < 2
            || is_left(*(vertices_.end() - 2), *(vertices_.end() - 1), p))
        vertices_.push_back(p);
    else {
        // the middle point (the last one currently in vertices_) is not convex
        // remove it and check again the last three points
        vertices_.pop_back();
        push_point(p);
    }
}
Exemplo n.º 15
0
    // To be harmonized
    static inline return_type a_ends_at_middle(side_info const& sides,
                coordinate_type const& dx, coordinate_type const& dy,
                S1 const& s1, S2 const& s2)
    {
        coordinate_type dpx = get<1, 0>(s2) - get<0, 0>(s1);
        coordinate_type dpy = get<1, 1>(s2) - get<0, 1>(s1);

        // Ending at the middle, one ARRIVES, the other one is NEUTRAL
        // (because it both "arrives"  and "departs"  there
        return is_left(dx, dy, dpx, dpy)
            ? return_type(sides, 'm', 1, 0, 1, 1)
            : return_type(sides, 'm', 1, 0, -1, -1);
    }
Exemplo n.º 16
0
bool is_line(std::vector<Point2D> points)
{
    if(points.size() < 3)
    {
        //printf("2 points");
        return true;
    }

    for(int i = 0; i < points.size() - 2; i++)
    {
        if(is_left(points[i], points[i + 1], points[i + 2]) != 0)
            return false;
    }

    return true;
}
Exemplo n.º 17
0
//takes sorted points
std::vector<Point2D> graham_scan(std::vector<Point2D> points)
{
    std::vector<Point2D> st;
    if(is_line(points))
    {
        st.push_back(points[0]);
        st.push_back(points[points.size() - 1]);
        return st;
    }
    Point2D rightest = points[0];
    int rightest_pos = 0;
    for(int i = 0; i < points.size(); i++)
    {
        if(points[i].x > rightest.x || (points[i].x == rightest.x && points[i].y < rightest.y))
        {
            rightest = points[i];
            rightest_pos = i;
        }
    }

    int cur = 1;
    st.push_back(points[get_index(rightest_pos  - 1, points.size())]);
    st.push_back(points[rightest_pos]);
    while(!(st[1] == st[st.size() - 1]  &&   st.size() > 2))
    {
        long long int left = is_left(st[st.size() - 2], st[st.size() - 1], points[get_index(cur + rightest_pos, points.size())]);
        if( left > 0)
        {
            st.push_back(points[get_index(cur + rightest_pos, points.size())]);
            cur++;
        }
        else
        {
            st.pop_back();
            //cur--;
        }
    }

    st.erase(st.begin());
    st.pop_back();
    return st;


}
Exemplo n.º 18
0
void rotate_right(RB_tree *tree, RB_node *node){
    RB_node *temp = node->left;
    if(node->left != tree->nil){
        node->left = temp->right;
        temp->right = node;
        node->left->parent = node;

        if(node->parent == tree->nil){
            tree->root = temp;
        }else{
            if(is_left(node)){
                node->parent->left = temp;
            }else{
                node->parent->right = temp;
            }
        }
        temp->parent = node->parent;
        node->parent = temp;
    }
}
Exemplo n.º 19
0
void RB_insert_fixup(RB_tree *tree, RB_node *node){
    node->color = RED;
    RB_node *last;
    while(node != tree->root && node->parent->color == RED){
        if(is_left(node->parent)){
            last = node->parent->parent->right;
            if(last->color == RED){//1st CASE
                node->parent->color = BLACK;
                last->color = BLACK;
                node->parent->parent->color = RED;
                node = node->parent->parent;
            }else{
                if(node == node->parent->right){//2nd CASE --> 3rd
                    node = node->parent;
                    rotate_left(tree, node);
                }
                node->parent->color = BLACK;//3rd CASE
                node->parent->parent->color = RED;
                rotate_right(tree, node->parent->parent);
            }
        }else{
            last = node->parent->parent->left;
            if(last->color == RED){//1st CASE
                node->parent->color = BLACK;
                last->color = BLACK;
                node->parent->parent->color = RED;
                node = node->parent->parent;
            }else{
                if(node == node->parent->left){//2nd CASE --> 3rd
                    node = node->parent;
                    rotate_right(tree, node);
                }
                node->parent->color = BLACK;//3rd CASE
                node->parent->parent->color = RED;
                rotate_left(tree, node->parent->parent);
            }
        }
    }
}
Exemplo n.º 20
0
// Partition the given triangles into two groups: those (mostly) left of
// and mostly right of the given split plane, based on a triangle's
// bound for the given split axis. Sets the parameters num_triangles_left
// and num_triangles_right when done.
static void
partition_on_split_value(int *num_triangles_left, int *num_triangles_right,
    triangle *first_triangle, int num_triangles,
    int split_axis, float split_value)
{
    triangle    *l, *r, t;
    triangle    *last_triangle;

    last_triangle = first_triangle + num_triangles - 1;

    l = first_triangle;
    r = last_triangle;

    while (l < r)
    {
        // Increase "l" to first triangle that needs to be on the *right* (yes, right)
        while (l <= last_triangle && is_left(l, split_axis, split_value))
            l++;

        // Decrease "r" to first triangle that needs to be on the *left*
        while (r >= first_triangle && !is_left(r, split_axis, split_value))
            r--;

        if (l < r)
        {
            // Swap triangles to put them in the correct lists
            t = *l;
            *l = *r;
            *r = t;

            // Update pointers as we have now processed 2 triangles
            l++;
            r--;
        }
    }

    // When we get here, l >= r

    if (l > last_triangle)
    {
        // All triangles on the left of the split plane
        *num_triangles_left = num_triangles;
        *num_triangles_right = 0;
    }
    else if (r < first_triangle)
    {
        // All triangles on the right
        *num_triangles_left = 0;
        *num_triangles_right = num_triangles;
    }
    else
    {
        // Triangles on both sides of the split plane
        *num_triangles_left = l - first_triangle;
        *num_triangles_right = num_triangles - *num_triangles_left;

        if (l == r)
        {
            // The triangle pointed to by both l and r hasn't been processed yet
            if (is_left(l, split_value, split_axis))
            {
                // Correct the triangle count in this case, as we included
                // the triangle on the right initially, while it is actually
                // on the left of the split plane
               // *num_triangles_left++;
               // *num_triangles_right--;
            }

        }
    }
}
Exemplo n.º 21
0
/**
 * A.M. Andrew's monotone chain 2D convex hull algorithm
 *
 * \param  points  An array of 2D points presorted by increasing x and y-coords.
 * \param  n  The number of points in points.
 * \param  r_points  An array of the convex hull vertex indices (max is n).
 * \returns the number of points in r_points.
 */
int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points[])
{
	/* the output array r_points[] will be used as the stack */
	int bot = 0;
	int top = -1;  /* indices for bottom and top of the stack */
	int i;  /* array scan index */
	int minmin, minmax;
	int maxmin, maxmax;
	float xmax;

	/* Get the indices of points with min x-coord and min|max y-coord */
	float xmin = points[0][0];
	for (i = 1; i < n; i++) {
		if (points[i][0] != xmin) {
			break;
		}
	}

	minmin = 0;
	minmax = i - 1;
	if (minmax == n - 1) {  /* degenerate case: all x-coords == xmin */
		r_points[++top] = minmin;
		if (points[minmax][1] != points[minmin][1])  /* a nontrivial segment */
			r_points[++top] = minmax;
		r_points[++top] = minmin;  /* add polygon endpoint */
		return top + 1;
	}

	/* Get the indices of points with max x-coord and min|max y-coord */

	maxmax = n - 1;
	xmax = points[n - 1][0];
	for (i = n - 2; i >= 0; i--) {
		if (points[i][0] != xmax) {
			break;
		}
	}
	maxmin = i + 1;

	/* Compute the lower hull on the stack r_points */
	r_points[++top] = minmin;  /* push minmin point onto stack */
	i = minmax;
	while (++i <= maxmin) {
		/* the lower line joins points[minmin] with points[maxmin] */
		if (is_left(points[minmin], points[maxmin], points[i]) >= 0 && i < maxmin) {
			continue;  /* ignore points[i] above or on the lower line */
		}

		while (top > 0) {  /* there are at least 2 points on the stack */
			/* test if points[i] is left of the line at the stack top */
			if (is_left(points[r_points[top - 1]], points[r_points[top]], points[i]) > 0.0f) {
				break;  /* points[i] is a new hull vertex */
			}
			else {
				top--;  /* pop top point off stack */
			}
		}

		r_points[++top] = i;  /* push points[i] onto stack */
	}

	/* Next, compute the upper hull on the stack r_points above the bottom hull */
	if (maxmax != maxmin) {  /* if distinct xmax points */
		r_points[++top] = maxmax;  /* push maxmax point onto stack */
	}

	bot = top;  /* the bottom point of the upper hull stack */
	i = maxmin;
	while (--i >= minmax) {
		/* the upper line joins points[maxmax] with points[minmax] */
		if (is_left(points[maxmax], points[minmax], points[i]) >= 0 && i > minmax) {
			continue;  /* ignore points[i] below or on the upper line */
		}

		while (top > bot) {  /* at least 2 points on the upper stack */
			/* test if points[i] is left of the line at the stack top */
			if (is_left(points[r_points[top - 1]], points[r_points[top]], points[i]) > 0.0f) {
				break;  /* points[i] is a new hull vertex */
			}
			else {
				top--;  /* pop top point off stack */
			}
		}

		if (points[i][0] == points[r_points[0]][0] && points[i][1] == points[r_points[0]][1]) {
			return top + 1;  /* special case (mgomes) */
		}

		r_points[++top] = i;  /* push points[i] onto stack */
	}

	if (minmax != minmin) {
		r_points[++top] = minmin;  /* push joining endpoint onto stack */
	}

	return top + 1;
}
Exemplo n.º 22
0
//merging of 2 convex hulls
std::vector<Point2D> merge(std::vector<Point2D> set1, std::vector<Point2D> set2)
{

    Point2Df p;
    std::vector<Point2D> sum;
    int is_line1 = is_line(set1);
    int is_line2 = is_line(set2);

    if(!is_line1)
    {
        for(int i = 0; i < set1.size() - 2; i++)
        {
            if(is_left(set1[i], set1[i + 1], set1[i + 2]) != 0)
            {
                p = centroid(set1[i], set1[i + 1], set1[i + 2]);
                break;
            }
        }
    }
    else if(!is_line2)
    {
        for(int i = 0; i < set2.size() - 2; i++)
        {
            if(is_left(set2[i], set2[i + 1], set2[i + 2]) != 0)
            {
                p = centroid(set2[i], set2[i + 1], set2[i + 2]);
                break;
            }
        }
    }

    if(!is_line1 && !is_line2)// 2 polygons
    {
        if(in_polygon(set2, p) != 0)
        {
            sum = merge_polygons(set1, set2, p);
            return graham_scan(sum);

        }
        else
        {
            std::vector<Point2D> clean_set2;

            clean_set2 = delete_chain(set2, p);
            sum = merge_polygons(set1, clean_set2, p);

            return graham_scan(sum);
        }
    }
    else if (!is_line1 && is_line2)//polygon with centroid p and line
    {

        std::vector<Point2D> clean_set2;
       /*
        clean_set2 = delete_chain(set2, p);
        sum = merge_polygons(set1, clean_set2, p);
        */


        if(angle_compare(p, (Point2Df)set2[0], (Point2Df)set2[set2.size() - 1]))
        {
            clean_set2.push_back(set2[0]);
            clean_set2.push_back(set2[set2.size() - 1]);
        }
        else
        {
            clean_set2.push_back(set2[set2.size() - 1]);
            clean_set2.push_back(set2[0]);
        }

        sum = merge_polygons(set1, clean_set2, p);

        return graham_scan(sum);
    }
    else if(is_line1 && !is_line2)
    {
        std::vector<Point2D> clean_set1;
    /*
        clean_set1 = delete_chain(set1, p);
        sum = merge_polygons(clean_set1, set2, p);
    */
        if(angle_compare(p, (Point2Df)set1[0], (Point2Df)set1[set1.size() - 1]))
        {
            clean_set1.push_back(set1[0]);
            clean_set1.push_back(set1[set1.size() - 1]);
        }
        else
        {
            clean_set1.push_back(set1[set1.size() - 1]);
            clean_set1.push_back(set1[0]);
        }

        sum = merge_polygons(clean_set1, set2, p);
        return graham_scan(sum);

    }
    else // if(is_line1 && is_line2)
    {
        std::vector<Point2D> clean_set1;
        clean_set1.push_back(set1[0]);
        clean_set1.push_back(set1[set1.size() - 1]);
        clean_set1.push_back(set2[0]);
        clean_set1.push_back(set2[set2.size() - 1]);
        return get_hull(clean_set1);
    }
}