static void cylinder_intersect(cylinder * cyl, ray * ry) { vector rc, n, D, O; flt t, s, tin, tout, ln, d; rc.x = ry->o.x - cyl->ctr.x; rc.y = ry->o.y - cyl->ctr.y; rc.z = ry->o.z - cyl->ctr.z; VCross(&ry->d, &cyl->axis, &n); VDOT(ln, n, n); ln=sqrt(ln); /* finish length calculation */ if (ln == 0.0) { /* ray is parallel to the cylinder.. */ VDOT(d, rc, cyl->axis); D.x = rc.x - d * cyl->axis.x; D.y = rc.y - d * cyl->axis.y; D.z = rc.z - d * cyl->axis.z; VDOT(d, D, D); d = sqrt(d); tin = -FHUGE; tout = FHUGE; /* if (d <= cyl->rad) then ray is inside cylinder.. else outside */ } VNorm(&n); VDOT(d, rc, n); d = fabs(d); if (d <= cyl->rad) { /* ray intersects cylinder.. */ VCross(&rc, &cyl->axis, &O); VDOT(t, O, n); t = - t / ln; VCross(&n, &cyl->axis, &O); VNorm(&O); VDOT(s, ry->d, O); s = fabs(sqrt(cyl->rad*cyl->rad - d*d) / s); tin = t - s; add_intersection(tin, (object *) cyl, ry); tout = t + s; add_intersection(tout, (object *) cyl, ry); } }
static void plane_intersect(plane * pln, ray * ry) { flt t,td; t=-(pln->d + VDot(&pln->norm, &ry->o)); td=VDot(&pln->norm, &ry->d); if (td != 0.0) { t /= td; if (t > 0.0) add_intersection(t,(object *) pln, ry); } }
static void sphere_intersect(sphere * spr, ray * ry) { flt b, disc, t1, t2, temp; vector V; VSUB(spr->ctr, ry->o, V); VDOT(b, V, ry->d); VDOT(temp, V, V); disc=b*b + spr->rad*spr->rad - temp; if (disc<=0.0) return; disc=sqrt(disc); t2=b+disc; if (t2 <= SPEPSILON) return; add_intersection(t2, (object *) spr, ry); t1=b-disc; if (t1 > SPEPSILON) add_intersection(t1, (object *) spr, ry); }
static int intersect_line_segment(TTF_Segment *segment, TTF_Scan_Line *scanline) { if (!segment || !scanline) { return 0; } float y = scanline->y; float x0 = segment->x[0], x1 = segment->x[1]; float y0 = segment->y[0], y1 = segment->y[1]; if ((fabsf(y - y0) + fabsf(y - y1) - fabsf(y1 - y0)) != 0) { /* The scan-line at y is not within the y-bounds of the line segment. */ return 0; } if (y0 == y1) { /* Intersecting with horizontal line (degenerate case). */ if (y == y0) { /* There are two intersections, x0 and x1. */ add_intersection(scanline, x0); add_intersection(scanline, x1); return 2; } else { /* No intersections. */ return 0; } } /* Calculate x-intersection of scan-line and line segment. */ float x = ((x0*y1 - x1*y0) + y*(x1 - x0)) / (y1 - y0); if ((fabsf(x - x0) + fabsf(x - x1) - fabsf(x1 - x0)) != 0) { /* The x-intersection is not within the x-bounds of the line segment. */ return 0; } add_intersection(scanline, x); return 1; }
typename enable_if<is_concept_combinable<is_interval_map, is_interval_set, Type, KeySetT>, void>::type add_intersection(Type& section, const Type& object, const KeySetT& key_set) { typedef typename KeySetT::const_iterator const_iterator; if(icl::is_empty(key_set)) return; const_iterator common_lwb, common_upb; if(!Set::common_range(common_lwb, common_upb, key_set, object)) return; const_iterator it_ = common_lwb; while(it_ != common_upb) add_intersection(section, object, *it_++); }
/* Returns the intersection points between the particle trajectory * and the domain boundaries * intersections are placed in increasing x position */ std::vector<bpoint> boundaries_intersections(Line line) { std::vector<bg::model::segment<bpoint> > segments = get_geometry_segments(); //std::vector<bg::model::segment<bpoint> > segments = get_geometry_segments(); //Compute intersections with all segments of detector boundary std::vector<bpoint> intersections; for (unsigned i = 0; i < segments.size(); i++) { add_intersection(line, segments[i], intersections); } Utils::sort_points_by_coord(&intersections); intersections = Utils::unique_bpoints(intersections); //unique(intersections.begin(), intersections.end()); //intersections.erase(unique(intersections.begin(), intersections.end()), // intersections.end()); //intersections.shrink_to_fit(); return intersections; }
static void ring_intersect(ring * rng, ray * ry) { flt d; flt t,td; vector hit, pnt; d = -VDot(&(rng->ctr), &(rng->norm)); t=-(d+VDot(&(rng->norm), &(ry->o))); td=VDot(&(rng->norm),&(ry->d)); if (td != 0.0) { t= t / td; if (t>=0.0) { hit=Raypnt(ry, t); VSUB(hit, rng->ctr, pnt); VDOT(td, pnt, pnt); td=sqrt(td); if ((td > rng->inrad) && (td < rng->outrad)) add_intersection(t,(object *) rng, ry); } } }
typename enable_if < mpl::and_< mpl::not_<is_total<Type> > , is_concept_compatible<is_interval_map, Type, MapT> > , void >::type add_intersection(Type& section, const Type& object, const MapT& operand) { typedef typename Type::segment_type segment_type; typedef typename Type::interval_type interval_type; typedef typename MapT::const_iterator const_iterator; if(operand.empty()) return; const_iterator common_lwb, common_upb; if(!Set::common_range(common_lwb, common_upb, operand, object)) return; const_iterator it_ = common_lwb; while(it_ != common_upb) add_intersection(section, object, *it_++); }
static void tri_intersect(tri * trn, ray * ry) { vector tvec, pvec, qvec; flt det, inv_det, t, u, v; /* begin calculating determinant - also used to calculate U parameter */ CROSS(pvec, ry->d, trn->edge2); /* if determinant is near zero, ray lies in plane of triangle */ det = DOT(trn->edge1, pvec); if (det > -EPSILON && det < EPSILON) return; inv_det = 1.0 / det; /* calculate distance from vert0 to ray origin */ SUB(tvec, ry->o, trn->v0); /* calculate U parameter and test bounds */ u = DOT(tvec, pvec) * inv_det; if (u < 0.0 || u > 1.0) return; /* prepare to test V parameter */ CROSS(qvec, tvec, trn->edge1); /* calculate V parameter and test bounds */ v = DOT(ry->d, qvec) * inv_det; if (v < 0.0 || u + v > 1.0) return; /* calculate t, ray intersects triangle */ t = DOT(trn->edge2, qvec) * inv_det; add_intersection(t,(object *) trn, ry); }
int main() { std::scanf("%d", &n); rotate_sin = sinl(233.3); rotate_cos = cosl(233.3); for(int i = 0; i != n; ++i) { for(int j = 0; j != 3; ++j) { std::scanf("%Lf %Lf", &pt[i][j].x, &pt[i][j].y); pt[i][j] = rotate(pt[i][j]); coordinate[tot++] = pt[i][j].y; } for(int j = 0; j != i; ++j) { add_intersection(i, 0, 1, j, 0, 1); add_intersection(i, 0, 1, j, 0, 2); add_intersection(i, 0, 1, j, 1, 2); add_intersection(i, 0, 2, j, 0, 1); add_intersection(i, 0, 2, j, 0, 2); add_intersection(i, 0, 2, j, 1, 2); add_intersection(i, 1, 2, j, 0, 1); add_intersection(i, 1, 2, j, 0, 2); add_intersection(i, 1, 2, j, 1, 2); } } std::sort(coordinate, coordinate + tot); tot = std::unique(coordinate, coordinate + tot, cmp) - coordinate; long double area = 0.0, prev_len = 0.0; for(int i = 0; i != tot; ++i, num = 0) { long double y = coordinate[i]; for(int j = 0; j != n; ++j) { if(add_horizontal(y, j, 0, 1)) continue; if(add_horizontal(y, j, 0, 2)) continue; if(add_horizontal(y, j, 1, 2)) continue; long double d1 = get_intersection(y, pt[j][0], pt[j][1]); long double d2 = get_intersection(y, pt[j][0], pt[j][2]); long double d3 = get_intersection(y, pt[j][1], pt[j][2]); add_segment(d2, d3); add_segment(d1, d3); add_segment(d1, d2); } std::sort(data, data + num); int cnt = 0; long double prev = 0.0, len = 0.0; for(int j = 0; j != num; ++j) { if(!cnt) prev = data[j].x; cnt += data[j].cnt; if(!cnt) len += data[j].x - prev; } if(i) area += (len + prev_len) * (y - coordinate[i - 1]) * (long double)0.5; prev_len = len; } std::printf("%.2Lf\n", area); return 0; }
static int intersect_curve_segment(TTF_Segment *segment, TTF_Scan_Line *scanline) { if (!segment || !scanline) { return 0; } float t; float y = scanline->y; float y0 = segment->y[0], y1 = segment->y[1], y2 = segment->y[2]; float x0 = segment->x[0], x1 = segment->x[1], x2 = segment->x[2]; float a = y0 - 2*y1 + y2; float b = 2*y1 - 2*y0; float c = y0 - y; /* Handle degenerate cases first. */ if (a == 0) { /* Curve is a straight line. */ if (b == 0) { /* Curve is a horizontal line. */ if (c == 0) { /* There are two intersections, x0 and x2. */ add_intersection(scanline, x0); add_intersection(scanline, x2); return 2; } else { /* No intersections. */ return 0; } } else { t = -c / b; if (IN(t, 0.0, 1.0)) { /* One intersection. */ add_intersection(scanline, quad_bezier(t, x0, x1, x2)); return 1; } else { /* No intersections. */ return 0; } } } /* Test discriminant for number of roots. */ float D = b*b - 4*a*c; if (D < 0) { /* No roots. */ return 0; } else if (D == 0) { /* One distinct root. */ t = -b / (2*a); if (IN(t, 0.0, 1.0)) { /* One intersection. */ add_intersection(scanline, quad_bezier(t, x0, x1, x2)); return 1; } else { /* No intersections. */ return 0; } } else { /* Two distinct roots. */ int num_intersections = 0; t = (-b + sqrt(D)) / (2*a); if (IN(t, 0.0, 1.0)) { /* Intersection point is within curve endpoints. */ add_intersection(scanline, quad_bezier(t, x0, x1, x2)); num_intersections++; } t = (-b - sqrt(D)) / (2*a); if (IN(t, 0.0, 1.0)) { /* Intersection point is within curve endpoints. */ add_intersection(scanline, quad_bezier(t, x0, x1, x2)); num_intersections++; } return num_intersections; } }