/* 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; }
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); }
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; }
/* 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; }
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); } }
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; }