Exemplo n.º 1
0
/* Compute the intersection of two edges. The result is provided as a
 * coordinate pair of 128-bit integers.
 *
 * Returns %CAIRO_BO_STATUS_INTERSECTION if there is an intersection
 * that is within both edges, %CAIRO_BO_STATUS_NO_INTERSECTION if the
 * intersection of the lines defined by the edges occurs outside of
 * one or both edges, and %CAIRO_BO_STATUS_PARALLEL if the two edges
 * are exactly parallel.
 *
 * Note that when determining if a candidate intersection is "inside"
 * an edge, we consider both the infinitesimal shortening and the
 * infinitesimal tilt rules described by John Hobby. Specifically, if
 * the intersection is exactly the same as an edge point, it is
 * effectively outside (no intersection is returned). Also, if the
 * intersection point has the same
 */
static cairo_bool_t
_cairo_bo_edge_intersect (cairo_bo_edge_t	*a,
			  cairo_bo_edge_t	*b,
			  cairo_bo_point32_t	*intersection)
{
    cairo_bo_intersect_point_t quorem;

    if (! intersect_lines (a, b, &quorem))
	return FALSE;

    if (! _cairo_bo_edge_contains_intersect_point (a, &quorem))
	return FALSE;

    if (! _cairo_bo_edge_contains_intersect_point (b, &quorem))
	return FALSE;

    /* Now that we've correctly compared the intersection point and
     * determined that it lies within the edge, then we know that we
     * no longer need any more bits of storage for the intersection
     * than we do for our edge coordinates. We also no longer need the
     * remainder from the division. */
    intersection->x = quorem.x.ordinate;
    intersection->y = quorem.y.ordinate;

    return TRUE;
}
Exemplo n.º 2
0
  void quadstretch(float x,float y,float l,float t,
		   float w,float h,float *qx,float *qy,float *ret){
    
    /*
      --x & y are the original point
      -- l & t are left and top of original rect
      -- w & h are width and height of original rect
      --qx and qy are arrays of 4 points describing the new quad.
      
      --1. strip it down to floats between 0 and 1
      --   so we know where it is, relative to the boundaries.
    */
    
    float xF = (x-l)/float(w);
    float yF = (y-t)/float(h);
    // 2. generate "vertical"
    float interpTop[2];
    interpolatePoints(qx[0],qy[0],qx[1],qy[1],xF,interpTop);
    
    float interpBottom[2];
    interpolatePoints(qx[3],qy[3],qx[2],qy[2],xF,interpBottom);
    //3. generate "horizontal"
    float interpLeft[2];
    interpolatePoints(qx[0],qy[0],qx[3],qy[3],yF,interpLeft);
    
    float interpRight[2];
    interpolatePoints(qx[1],qy[1],qx[2],qy[2],yF,interpRight);
    
    intersect_lines(interpTop   [0],   interpTop[1],
		    interpBottom[0],interpBottom[1],
		    interpLeft  [0],  interpLeft[1],
		    interpRight [0], interpRight[1],ret);
  }
Exemplo n.º 3
0
int check_intersection(double *int_x, double *int_y,
                       double beam_x, double beam_y, double
                       dbeam_x, double dbeam_y,
                       double x1, double y1, double x2, double y2)
{

    if (beam_x < x1 || beam_x > x2 || beam_y < y1 || beam_y > y2)
        return FALSE; /* beam origin not in objext x1y1-x2y2 */
    if ((dbeam_y < 0.0 &&
            intersect_lines(int_x, int_y, x1, y1, x2-x1, 0.0,
                            beam_x, beam_y, dbeam_x, dbeam_y, 0)) ||
            (dbeam_x < 0.0 &&
             intersect_lines(int_x, int_y, x1, y1, 0.0, y2-y1,
                             beam_x, beam_y, dbeam_x, dbeam_y, 1)) ||
            (dbeam_y > 0.0 &&
             intersect_lines(int_x, int_y, x1, y2, x2-x1, 0.0,
                             beam_x, beam_y, dbeam_x, dbeam_y, 0)) ||
            (dbeam_x > 0.0 &&
             intersect_lines(int_x, int_y, x2, y1, 0.0, y2-y1,
                             beam_x, beam_y, dbeam_x, dbeam_y, 1))) {
        return TRUE;
    }
    return FALSE;
}
Exemplo n.º 4
0
/* Compute the intersection of two edges. The result is provided as a
 * coordinate pair of 128-bit integers.
 *
 * Returns %CAIRO_BO_STATUS_INTERSECTION if there is an intersection
 * that is within both edges, %CAIRO_BO_STATUS_NO_INTERSECTION if the
 * intersection of the lines defined by the edges occurs outside of
 * one or both edges, and %CAIRO_BO_STATUS_PARALLEL if the two edges
 * are exactly parallel.
 *
 * Note that when determining if a candidate intersection is "inside"
 * an edge, we consider both the infinitesimal shortening and the
 * infinitesimal tilt rules described by John Hobby. Specifically, if
 * the intersection is exactly the same as an edge point, it is
 * effectively outside (no intersection is returned). Also, if the
 * intersection point has the same
 */
static cairo_bool_t
_cairo_bo_edge_intersect (cairo_bo_edge_t	*a,
			  cairo_bo_edge_t	*b,
			  cairo_bo_intersect_point_t *intersection)
{
    if (! intersect_lines (a, b, intersection))
	return FALSE;

    if (! _cairo_bo_edge_contains_intersect_point (a, intersection))
	return FALSE;

    if (! _cairo_bo_edge_contains_intersect_point (b, intersection))
	return FALSE;

    return TRUE;
}
Exemplo n.º 5
0
static void bloat_quad(const SkPoint qpts[3], const SkMatrix* toDevice,
                       const SkMatrix* toSrc, BezierVertex verts[kQuadNumVertices]) {
    SkASSERT(!toDevice == !toSrc);
    // original quad is specified by tri a,b,c
    SkPoint a = qpts[0];
    SkPoint b = qpts[1];
    SkPoint c = qpts[2];

    if (toDevice) {
        toDevice->mapPoints(&a, 1);
        toDevice->mapPoints(&b, 1);
        toDevice->mapPoints(&c, 1);
    }
    // make a new poly where we replace a and c by a 1-pixel wide edges orthog
    // to edges ab and bc:
    //
    //   before       |        after
    //                |              b0
    //         b      |
    //                |
    //                |     a0            c0
    // a         c    |        a1       c1
    //
    // edges a0->b0 and b0->c0 are parallel to original edges a->b and b->c,
    // respectively.
    BezierVertex& a0 = verts[0];
    BezierVertex& a1 = verts[1];
    BezierVertex& b0 = verts[2];
    BezierVertex& c0 = verts[3];
    BezierVertex& c1 = verts[4];

    SkVector ab = b;
    ab -= a;
    SkVector ac = c;
    ac -= a;
    SkVector cb = b;
    cb -= c;

    // We should have already handled degenerates
    SkASSERT(ab.length() > 0 && cb.length() > 0);

    ab.normalize();
    SkVector abN;
    abN.setOrthog(ab, SkVector::kLeft_Side);
    if (abN.dot(ac) > 0) {
        abN.negate();
    }

    cb.normalize();
    SkVector cbN;
    cbN.setOrthog(cb, SkVector::kLeft_Side);
    if (cbN.dot(ac) < 0) {
        cbN.negate();
    }

    a0.fPos = a;
    a0.fPos += abN;
    a1.fPos = a;
    a1.fPos -= abN;

    c0.fPos = c;
    c0.fPos += cbN;
    c1.fPos = c;
    c1.fPos -= cbN;

    intersect_lines(a0.fPos, abN, c0.fPos, cbN, &b0.fPos);

    if (toSrc) {
        toSrc->mapPointsWithStride(&verts[0].fPos, sizeof(BezierVertex), kQuadNumVertices);
    }
}
Exemplo n.º 6
0
int check_obstacle(struct _object *objs_l, int n_obj_l,
                   double *int_x, double *int_y,
                   double beam_x, double beam_y,
                   double dbeam_x, double dbeam_y,
                   double x1, double y1, double x2, double y2,
                   double offset)
{
    int intersect = 0, i;
    double dist, min_dist=0.0;
    double closest_int_x=0.0, closest_int_y=0.0;
    double a, b, c, lambda, h1, h2, discr, diameter;
    double x1_minus_offset = x1 - offset, y1_minus_offset = y1 - offset,
           x2_plus_offset = x2 + offset, y2_plus_offset = y2 + offset;
    double temp1, temp2;

    for (i = 0; i < n_obj_l; i++) {
        if (objs_l[i].type == O_RECTANGLE && objs_l[i].status == 0 &&
                /* rectangle */
                ((objs_l[i].x1 >= x1_minus_offset && objs_l[i].x1 <= x2_plus_offset &&
                  objs_l[i].y1 >= y1_minus_offset && objs_l[i].y1 <= y2_plus_offset) ||
                 (objs_l[i].x2 >= x1_minus_offset && objs_l[i].x2 <= x2_plus_offset &&
                  objs_l[i].y1 >= y1_minus_offset && objs_l[i].y1 <= y2_plus_offset) ||
                 (objs_l[i].x1 >= x1_minus_offset && objs_l[i].x1 <= x2_plus_offset &&
                  objs_l[i].y2 >= y1_minus_offset && objs_l[i].y2 <= y2_plus_offset) ||
                 (objs_l[i].x2 >= x1_minus_offset && objs_l[i].x2 <= x2_plus_offset &&
                  objs_l[i].y2 >= y1_minus_offset && objs_l[i].y2 <= y2_plus_offset))) {
            if (dbeam_y > 0.0 &&
                    intersect_lines(int_x, int_y, objs_l[i].x1-offset,
                                    objs_l[i].y1-offset,
                                    objs_l[i].x2-objs_l[i].x1+(2.0*offset), 0.0,
                                    beam_x, beam_y, dbeam_x, dbeam_y, 0) &&
                    *int_x >= objs_l[i].x1-offset && *int_x <= objs_l[i].x2+offset) {
                temp1 = beam_x - *int_x;
                temp2 = beam_y - *int_y;
                dist = (temp1 * temp1) + (temp2 * temp2);
                if (intersect == FALSE || dist < min_dist) {
                    min_dist = dist;
                    intersect = TRUE;
                    closest_int_x = *int_x;
                    closest_int_y = *int_y;
                }
            } else if (dbeam_y < 0.0 &&
                       intersect_lines(int_x, int_y, objs_l[i].x1-offset,
                                       objs_l[i].y2+offset,
                                       objs_l[i].x2-objs_l[i].x1+(2.0*offset), 0.0,
                                       beam_x, beam_y, dbeam_x, dbeam_y, 0)
                       && *int_x >= objs_l[i].x1-offset
                       && *int_x <= objs_l[i].x2+offset) {
                temp1 = beam_x - *int_x;
                temp2 = beam_y - *int_y;
                dist = (temp1 * temp1) + (temp2 * temp2);
                if (intersect == FALSE || dist < min_dist) {
                    min_dist = dist;
                    intersect = TRUE;
                    closest_int_x = *int_x;
                    closest_int_y = *int_y;
                }
            }
            if (dbeam_x > 0.0 &&
                    intersect_lines(int_x, int_y, objs_l[i].x1-offset,
                                    objs_l[i].y1-offset,
                                    0.0, objs_l[i].y2-objs_l[i].y1+(2.0*offset),
                                    beam_x, beam_y, dbeam_x, dbeam_y, 1) &&
                    *int_y >= objs_l[i].y1-offset && *int_y <=
                    objs_l[i].y2+offset) {
                temp1 = beam_x - *int_x;
                temp2 = beam_y - *int_y;
                dist = (temp1 * temp1) + (temp2 * temp2);
                if (intersect == FALSE || dist < min_dist) {
                    min_dist = dist;
                    intersect = TRUE;
                    closest_int_x = *int_x;
                    closest_int_y = *int_y;
                }
            } else if (dbeam_x < 0.0 &&
                       intersect_lines(int_x, int_y, objs_l[i].x2+offset,
                                       objs_l[i].y1-offset,
                                       0.0, objs_l[i].y2-objs_l[i].y1+(2.0*offset),
                                       beam_x, beam_y, dbeam_x, dbeam_y, 1)
                       && *int_y >= objs_l[i].y1-offset
                       && *int_y <= objs_l[i].y2+offset) {
                temp1 = beam_x - *int_x;
                temp2 = beam_y - *int_y;
                dist = (temp1 * temp1) + (temp2 * temp2);
                if (intersect == FALSE || dist < min_dist) {
                    min_dist = dist;
                    intersect = TRUE;
                    closest_int_x = *int_x;
                    closest_int_y = *int_y;
                }
            }
        }

        diameter = objs_l[i].diameter + offset;
        if (objs_l[i].type == O_ROUND && objs_l[i].status == 0 && /* rectangle */
                objs_l[i].x1 >= x1-diameter && objs_l[i].x1 <= x2+diameter &&
                objs_l[i].y1 >= y1-diameter && objs_l[i].y1 <= y2+diameter) {
            /* intersection circle with line */
            a = (dbeam_x * dbeam_x) + (dbeam_y * dbeam_y);
            b = (beam_x*dbeam_x) + (beam_y*dbeam_y)
                - (dbeam_x*objs_l[i].x1) - (dbeam_y*objs_l[i].y1);
            h1 = beam_x - objs_l[i].x1;
            h2 = beam_y - objs_l[i].y1;
            c = (h1 * h1) + (h2 * h2) - (diameter * diameter);
            if (a != 0.0) {
                discr = ((b*b) / (a*a)) - (c/a);
                if (discr > 0.0) {
                    discr = sqrt(discr);
                    h1 = 0.0 - (b / a);
                    lambda = h1 - discr;
                    if (lambda < 0.0 && h1 + discr >= 0.0) {
                        lambda = 0.0;
                        fprintf(stderr,
                                "\nWarning: object %f %f in obst #%d?",beam_x, beam_y,i);
                    }
                    if (lambda >= 0.0) {
                        h1 = lambda * dbeam_x;
                        h2 = lambda * dbeam_y;
                        *int_x = beam_x + h1;
                        *int_y = beam_y + h2;
                        dist = (h1 * h1) + (h2 * h2);
                        if (intersect == FALSE || dist < min_dist) {
                            min_dist = dist;
                            intersect = TRUE;
                            closest_int_x = *int_x;
                            closest_int_y = *int_y;
                        }
                    }
                }
            }
        }
    }
    if (intersect) {
        *int_x = closest_int_x;
        *int_y = closest_int_y;
    }
    return intersect;
}