Exemplo n.º 1
0
bool Getccinte(Circle c1,Circle c2,Point &a,Point &b)
{
    double d = Length(c1.c-c2.c);
    if(dcmp(d)==0||dcmp(c1.r+c2.r-d)<0||dcmp(fabs(c1.r-c2.r)-d)>0)
        return 0;
    double ang = Angle(c2.c-c1.c);
    double da = acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));
    a = c1.point(ang-da),b = c1.point(ang+da);
    return 1;
}
Exemplo n.º 2
0
// 两圆切线,-1无穷
// a[i]和b[i]分别是第i条切线在圆A和圆B上的切点
int getTangents(Circle& A,Circle& B,Point* a,Point* b) {
	int cnt=0;
	if (A.r<B.r) {swap(A,B);swap(a,b);}
	int d2=(A.c.x-B.c.x)*(A.c.x-B.c.x)+(A.c.y-B.c.y)*(A.c.y-B.c.y);
	int rdiff=A.r-B.r;
	int rsum=A.r+B.r;
	if (d2<rdiff*rdiff) return 0;
	double base=atan2(B.c.y-A.c.y,B.c.x-A.c.x);
	if (d2==0 && A.r==B.r) return -1;
	if (d2==rdiff*rdiff) {
		a[cnt]=A.point(base);b[cnt]=B.point(base);cnt++;
		return 1;
	}
	// 外切
	double ang=acos((A.r-B.r)/sqrt(d2));
	a[cnt]=A.point(ang+base);b[cnt]=B.point(ang+base);cnt++;
	a[cnt]=A.point(base-ang);b[cnt]=B.point(base-ang);cnt++;
	if (d2==rsum*rsum) {
		a[cnt]=A.point(base);b[cnt]=B.point(acos(-1)+base+ang);cnt++;
	}
	else if (d2>rsum*rsum) {
		double ang=acos((A.r+B.r)/sqrt(d2));
		a[cnt]=A.point(base+ang);b[cnt]=B.point(pi+base+ang);cnt++;
		a[cnt]=A.point(base-ang);b[cnt]=B.point(pi+base-ang);cnt++;
	}
	return cnt;
}
Exemplo n.º 3
0
	/* a[i] 和 b[i] 分别是第i条切线在O1和O2上的切点 */
	int getTangents (Circle o1, Circle o2, Point* a, Point* b) {
		int cnt = 0;
		if (o1.r < o2.r) { swap(o1, o2); swap(a, b); }
		double d2 = getLength(o1.o - o2.o); d2 = d2 * d2;
		double rdif = o1.r - o2.r, rsum = o1.r + o2.r;
		if (d2 < rdif * rdif) return 0;
		if (dcmp(d2) == 0 && dcmp(o1.r - o2.r) == 0) return -1;

		double base = getAngle(o2.o - o1.o);
		if (dcmp(d2 - rdif * rdif) == 0) {
			a[cnt] = o1.point(base); b[cnt] = o2.point(base); cnt++;
			return cnt;
		}

		double ang = acos( (o1.r - o2.r) / sqrt(d2) );
		a[cnt] = o1.point(base+ang); b[cnt] = o2.point(base+ang); cnt++;
		a[cnt] = o1.point(base-ang); b[cnt] = o2.point(base-ang); cnt++;

		if (dcmp(d2 - rsum * rsum) == 0) {
			a[cnt] = o1.point(base); b[cnt] = o2.point(base); cnt++;
		} else if (d2 > rsum * rsum) {
			double ang = acos( (o1.r + o2.r) / sqrt(d2) );
			a[cnt] = o1.point(base+ang); b[cnt] = o2.point(base+ang); cnt++;
			a[cnt] = o1.point(base-ang); b[cnt] = o2.point(base-ang); cnt++;
		}
		return cnt;
	}
Exemplo n.º 4
0
// 两圆相交
int getCircleCircleIntersection(Circle& C1, Circle& C2, vector<Point>& sol) {
  double d = Length(C1.c - C2.c);
  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 = angle(C2.c - C1.c);
  double da = acos((C1.r*C1.r + d*d - C2.r*C2.r) / (2*C1.r*d));
  Point p1 = C1.point(a-da), p2 = C1.point(a+da);

  sol.push_back(p1);
  if(p1 == p2) return 1;
  sol.push_back(p2);
  return 2;
}
Exemplo n.º 5
0
	/* 圆和圆的交点 */
	int getCircleCircleIntersection (Circle o1, Circle o2, vector<Point>& sol) {
		double d = getLength(o1.o - o2.o);

		if (dcmp(d) == 0) {
			if (dcmp(o1.r - o2.r) == 0) return -1;
			return 0;
		}

		if (dcmp(o1.r + o2.r - d) < 0) return 0;
		if (dcmp(fabs(o1.r-o2.r) - d) > 0) return 0;

		double a = getAngle(o2.o - o1.o);
		double da = acos((o1.r*o1.r + d*d - o2.r*o2.r) / (2*o1.r*d));

		Point p1 = o1.point(a-da), p2 = o1.point(a+da);

		sol.push_back(p1);
		if (p1 == p2) return 1;
		sol.push_back(p2);
		return 2;
	}
//返回切线的条数,-1表示无穷条切线
//a[i]和b[i]分别是第i条切线在圆A和圆B上的切点。内切,外切时,这两个点相同
int getTangents(Circle A, Circle B, Point* a, Point* b){
	int cnt = 0;
	if(A.r < B.r){
		swap(A, B);
		swap(a, b);
	}
	double d2 = (A.c.x-B.c.x)*(A.c.x-B.c.x) + (A.c.y-B.c.y)*(A.c.y-B.c.y);
	double rdiff = A.r - B.r;
	double rsum = A.r + B.r;
	if(dcmp(d2 - rdiff*rdiff) < 0) // 内含
		return 0;
	double base = atan2(B.c.y-A.c.y, B.c.x-A.c.x);
	if(dcmp(d2)==0 && dcmp(A.r-B.r)==0)// 无限多条切线
		return -1;
	if(dcmp(d2-rdiff*rdiff) == 0){// 内切,一条切线
		a[cnt] = A.point(base);
		b[cnt] = B.point(base);
		cnt++;
		return 1;
	}
	double ang = acos((A.r-B.r)/sqrt(d2));// 两条外公切线
	a[cnt] = A.point(base + ang);
	b[cnt] = B.point(base + ang);
	cnt++;
	a[cnt] = A.point(base - ang);
	b[cnt] = B.point(base - ang);
	cnt++;
	if(dcmp(d2-rsum*rsum) == 0){
		a[cnt] = A.point(base);
		b[cnt] = B.point(PI + base);
		cnt++;
	}
	else if(dcmp(d2 - rsum*rsum) > 0){ // 两条内公切线
		double ang = acos((A.r+B.r) / sqrt(d2));
		a[cnt] = A.point(base+ang);
		b[cnt] = B.point(PI+base+ang);
		cnt++;
		a[cnt] = A.point(base-ang);
		b[cnt] = B.point(PI+base-ang);
		cnt++;
	}
	return cnt;
}