std::pair< T, T > intersection( const ray<T,2u>& ray, const circle<T>& circle )
    { 
      // check for no intersection
    
      const T a = dot( ray.direction(), ray.direction() );
      const T b = T(2.) * sum( ray.direction() * ( ray.source() - circle.center() ) );
      const T c =   dot( circle.center(), circle.center() ) 
                  + dot( ray.source(), ray.source() ) 
                  - T(2.) * dot( ray.source(), circle.center() )
                  - sqr( circle.radius() );

      return solve_quadratic_equation(a,b,c);
    }
Esempio n. 2
0
//圆与圆切线 a[],b[],存放对应切线的切点
int gettangentcc(circle c1,circle c2,pt *a,pt *b){
    int cnt=0;
    if (c1.r<c2.r){swap(c1,c2);swap(a,b);}
    double d2=length(c1.p-c2.p);
    double rdiff=c1.r-c2.r;
    double rsum=c1.r+c2.r;
    if (dcmp(d2-rdiff)<0) return 0;//内含,无切线

    double base=atan2(c1.p.y-c2.p.y,c1.p.x-c2.p.x);
    if (dcmp(d2)==0&&c1.r==c2.r) return -1;//重合 无数条切线
    if (dcmp(d2-rdiff)==0){//内切,一条切线
        a[cnt]=c1.getpt(base);b[cnt]=c2.getpt(base);cnt++;
        return 1;
    }
    //求外切线
    double ang=acos((c1.r-c2.r)/d2);
    a[cnt]=c1.getpt(base+ang);b[cnt]=c2.getpt(base+ang);cnt++;
    a[cnt]=c1.getpt(base-ang);b[cnt]=c2.getpt(base-ang);cnt++;
    if (dcmp(d2-rsum)==0){//两圆外切,一条内切线
        a[cnt]=c1.getpt(base);b[cnt]=c2.getpt(pi+base);cnt++;
    }
    else if (dcmp(d2-rsum)>0){//两圆相离,两条内切线
        ang=acos((c1.r+c2.r)/d2);
        a[cnt]=c1.getpt(base+ang);b[cnt]=c2.getpt(pi+base+ang);cnt++;
        a[cnt]=c1.getpt(base-ang);b[cnt]=c2.getpt(pi+base-ang);cnt++;
    }
    return cnt;
}
Esempio n. 3
0
//两圆交点
int cinsc(circle c1,circle c2,vector<pt> &sol){
    double d=length(c1.p-c2.p);
    if (dcmp(d)==0){
        if (dcmp(c1.r-c2.r)==0) return -1;//重合
        return 0;//包含
    }
    if (dcmp(c1.r+c2.r-d)<0) return 0;
    if (dcmp(fabs(c1.r-c2.r)-d)>0) return 0;
    double a=atan2(c1.p.y-c2.p.y,c1.p.x-c2.p.x);
    double da=acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));

    pt p1=c1.getpt(a-da),p2=c1.getpt(a+da);
    sol.push_back(p1);
    if (p1==p2) return 1;
    sol.push_back(p2);
    return 2;
}
Esempio n. 4
0
std::tuple<bool, float, int> line::intersect(const circle& circle) const {
    std::tuple<bool, float, int> best = std::make_tuple(false, 0.0f, 0);
    for(int i = 0; i < 8; ++i) {
        auto res = std::tuple_cat(intersect(circle.getLineSegment(i)), std::make_tuple(i));
        if (std::get<0>(best) == false) {
            best = res;
        } else if (std::get<1>(best) > std::get<1>(res)) {
            best = res;
        }
    }
    return best;
}
vector<pair<point, point> > tanCC(const circle &cir1, const circle &cir2) { 
//	`注意: 如果只有三条切线, 即 $s1 = 1, s2 = 1$, 返回的切线可能重复, 切点没有问题`
	vector<pair<point, point> > list;
	if (cir1.contain(cir2) || cir2.contain(cir1)) return list;
	const point &c1 = cir1.o, &c2 = cir2.o;
	double r1 = cir1.r, r2 = cir2.r;
	point p, a1, b1, a2, b2; int s1, s2;
	if (sign(r1 - r2) == 0) {
		p = c2 - c1;
		p = (p * (r1 / p.len())).rot90();
		list.push_back(make_pair(c1 + p, c2 + p));
		list.push_back(make_pair(c1 - p, c2 - p));
	} else {
		p = (c2 * r1 - c1 * r2) / (r1 - r2);
		s1 = cir1.tanCP(p, a1, b1);
		s2 = cir2.tanCP(p, a2, b2);
		if (s1 >= 1 && s2 >= 1) {
			list.push_back(make_pair(a1, a2));
			list.push_back(make_pair(b1, b2));
		}
	} p = (c1 * r2 + c2 * r1) / (r1 + r2);
	s1 = cir1.tanCP(p, a1, b1);
	s2 = cir2.tanCP(p, a2, b2);
	if (s1 >= 1 && s2 >= 1) {
		list.push_back(make_pair(a1, a2));
		list.push_back(make_pair(b1, b2));
	} return list;
}
Esempio n. 6
0
   void draw_indicator(canvas& cnv, circle cp, float val, color c)
   {
      constexpr float w_factor = 0.05; // relative width of the indicator
      constexpr float h_factor = 0.2;  // relative height of the indicator
      using namespace radial_consts;

      auto state = cnv.new_state();
      auto center = cp.center();
      cnv.translate({ center.x, center.y });
      cnv.rotate(offset + (val * range));

      float r = cp.radius * 0.85;
      float ind_w = r * w_factor;
      float ind_h = r * h_factor;
      rect  ind_r = { -ind_w, -ind_h, ind_w, ind_h };
      ind_r = ind_r.move(0, r*0.6);

      draw_indicator(cnv, ind_r, c);
   }
Esempio n. 7
0
/* static */ void compact::rotate_branch(
                iterator it,
                circle c,
                double alpha)
{
    assert(!rna_tree::is_leaf(it));

    for (pre_post_order_iterator ch = pre_post_order_iterator(it, true); id(ch) <= id(it); ++ch)
    {
        if (!ch->inited_points())
            continue;

        double dist = distance(c.centre, ch->at(ch.label_index()).p);
        c.p1 = ch->at(ch.label_index()).p;
        c.p2 = move_point(c.centre, c.p2, dist);

        ch->at(ch.label_index()).p = c.rotate(alpha);
    }
}
Esempio n. 8
0
   void draw_radial_marks(canvas& cnv, circle cp, float size, color c)
   {
      using namespace radial_consts;
      auto state = cnv.new_state();
      auto center = cp.center();
      constexpr auto num_divs = 50;
      float div = range / num_divs;
      auto const& theme = get_theme();

      cnv.translate({ center.x, center.y });
      cnv.stroke_style(theme.ticks_color);
      for (int i = 0; i != num_divs+1; ++i)
      {
         float from = cp.radius;
         if (i % (num_divs / 10))
         {
            // Minor ticks
            from -= size / 4;
            cnv.line_width(theme.minor_ticks_width);
            cnv.stroke_style(c.level(theme.minor_ticks_level));
         }
         else
         {
            // Major ticks
            cnv.line_width(theme.major_ticks_width);
            cnv.stroke_style(c.level(theme.major_ticks_level));
         }

         float angle = offset + (M_PI / 2) + (i * div);
         float sin_ = std::sin(angle);
         float cos_ = std::cos(angle);
         float to = cp.radius - (size / 2);

         cnv.move_to({ from * cos_, from * sin_ });
         cnv.line_to({ to * cos_, to * sin_ });
         cnv.stroke();
      }
   }
Esempio n. 9
0
   void draw_radial_labels(
      canvas& cnv
    , circle cp
    , float size
    , float font_size
    , std::string const labels[]
    , std::size_t num_labels
   )
   {
      if (num_labels < 2)
         return; // Nothing to do

      using namespace radial_consts;
      auto state = cnv.new_state();
      auto center = cp.center();
      float div = range / (num_labels-1);
      auto const& theme = get_theme();

      cnv.translate({ center.x, center.y });
      cnv.text_align(cnv.middle | cnv.center);
      cnv.fill_style(theme.label_font_color);

      cnv.font(
         theme.label_font,
         theme.label_font_size * font_size,
         theme.label_style
      );

      for (int i = 0; i != num_labels; ++i)
      {
         float angle = offset + (M_PI / 2) + (i * div);
         float sin_ = std::sin(angle);
         float cos_ = std::cos(angle);

         cnv.fill_text({ cp.radius * cos_, cp.radius * sin_ }, labels[i].c_str());
      }
   }
Esempio n. 10
0
circle::circle(circle &old)
{
    radius = old.getRadius();
    color = old.getColor();
    circle(radius, color);
}
Esempio n. 11
0
 inline bool operator() (const circle &a, const circle &b)
 {
     return a.highest(curt) < b.highest(curt);
 }
Esempio n. 12
0
double intersect(circle c, point a, point b){
    if ( a == c.o || b == c.o ) {
//        cout << "point same as center" << endl;
        return 0.0;
    }
    if( signum( det(a,b) ) == 0 ) {
//        cout << "area 0" << endl;
        return 0.0;
    }

    a.x -= c.o.x, a.y -= c.o.y;
    b.x -= c.o.x , b.y -= c.o.y;
    c.o = point();
    if (c.contains(b)) swap(a, b);
    if (c.contains(a) && c.contains(b)) {
//        cout << "sec1 ans : " << 0.5 * fabs(det(a, b)) << endl;
        return 0.5 * fabs(det(a, b)); // 1. the area of the triangle
    }
    if (c.contains(a)) {
        point p = intersect_cir_line(c, b, a);
//        cout << "1 pt " << p.x << " " << p.y << endl;
//cout << "sec1 ans : " << 0.5 * ( fabs(det(a, p)) + fabs( c.r*c.r * angle(p, b) ) ) << endl;
        return 0.5 * ( fabs(det(a, p)) + fabs( c.r*c.r * angle(p, b) ) ); // 2. one point inside
    }
    if ( point_to(c.o,a, b) >= c.r - EPS){
//        cout << "section " << 3 << endl;
//cout << "sec3 ans : " << 0.5 * fabs(c.r*c.r * angle(a, b)) << endl;
        return 0.5 * fabs(c.r*c.r * angle(a, b)); // 3. Both outside and line doesnt intersect
    }
    // 4. Both Outside & Line Intersects circle at 2 points
    point p = intersect_cir_line(c, a, b);
    point q = intersect_cir_line(c, b, a);

    point prj = project( point(0,0) , a, b );

    double totSector = fabs( c.r * c.r * angle(a,b) ) / 2;
    double triangle = fabs( det(p,q) ) / 2;
    double smallSector = fabs( c.r * c.r * angle(p,q) ) / 2;

    if( onSegment( prj , a, b ) ) {
    //    cout << "sec4 ans: " << totSector - ( smallSector - triangle ) << endl;
//        cout << "sec4 ans: " << totSector << endl;

        return totSector - ( smallSector - triangle ) ;
    }
//    cout << "2 pts " << " (" << p.x << " " <<p.y << ") (" << q.x << " " << q.y <<")"<< endl;
//    cout << p.x << " " << p.y << " " << q.x << " " << q.y << endl;
//    cout << withA.x << " " << withA.y << " " << withB.x << " " << withB.y << endl;
//    cout << "section " << 4  << endl;
//        cout << "2 pts " << " (" << p.x << " " <<p.y << ") (" << q.x << " " << q.y <<")"<< endl;

//    cout << angle(p,q) << endl;
//    if( p == q ) {
////            cout << "here1" << endl;
//        return 0.5 * fabs(c.r*c.r * angle(a, b));
//    }

//    cout << "here2" << endl;
//    swap(p,q);
//    cout << "2 pts " << " (" << p.x << " " <<p.y << ") (" << q.x << " " << q.y <<")"<< endl;
//    cout << "angles: " << angle( a, p ) << " " << angle(q,b) << endl;
//cout << "sec4 ans : " <<  0.5 * ( fabs(c.r*c.r*angle(a,p)) + fabs( det(p,q) ) + fabs(c.r*c.r*angle(q,b)) ) << endl;

//    return 0.5 * ( fabs(c.r*c.r*angle(a,p)) + fabs( det(p,q) ) + fabs(c.r*c.r*angle(q,b)) ); // seems fine

//    double totSector = fabs( c.r * c.r * angle(a,b) ) / 2;
//    double triangle = fabs( det(p,q) ) / 2;
//    double smallSector = fabs( c.r * c.r * angle(p,q) ) / 2;
////    cout << "sec4 ans: " << totSector - ( smallSector - triangle ) << endl;
//    cout << "sec4 ans: " << totSector << endl;

    return totSector ;

}
Esempio n. 13
0
// Area
template<class T>                inline pure T area(const circle<T>& a) { return M_PI * std::sqr(a.r()); }