图形问题

 

转转:不记得从哪里转载的了,如果博主发现,请私信告知

已知两圆圆心坐标和半径,求相交部分面积


//如果两个圆的圆心距离+小半径,小于 大半径,就说明两个圆内交或包含,那么相交面积就是小圆面积
//如果两个圆的圆心距离>大半径+小半径,说明两者外交或相离,那么相交面积就是0
//前两者都不是说明,两者相交。相交的面积等于,(r1的扇形-三角形)+(r2的扇形-三角形)
//求三角形的一个角,double d=acos( (相邻边1的平方+相邻边2的平方-对边3的平方)/(2*相邻边1*相邻边2) )
//扇形面积:S=PI*r*r*θ/(2*PI)  三角形面积:S=1/2*a*c*sin(B)

看一个点在不在一个扇形内

|D|^2 = (dx^2 + dy^2)
// |D|^2 > r^2. false
// D dot U > |D| cos(theta)
// <=>
// (D dot U)^2 > |D|^2 (cos(theta))^2 if D dot U >= 0 and cos(theta) >= 0
// (D dot U)^2 < |D|^2 (cos(theta))^2 if D dot U <  0 and cos(theta) <  0
// true                               if D dot U >= 0 and cos(theta) <  0
// false                              if D dot U <  0 and cos(theta) >= 0


#ifndef LEETCODE_C_图形问题_H
#define LEETCODE_C_图形问题_H


#include <iostream>
using namespace std;
#include<cmath>
#include<stdio.h>
#define PI 3.141593
struct point//点
{
    double x,y;
};
struct circle//圆
{
    point center;
    double r;
};
float dist(point a,point b)//求圆心距
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

int tuxing_1()
{
    //已知两圆圆心坐标和半径,求相交部分面积:
    //如果两个圆的圆心距离+小半径,小于 大半径,就说明两个圆内交或包含,那么相交面积就是小圆面积
    //如果两个圆的圆心距离>大半径+小半径,说明两者外交或相离,那么相交面积就是0
    //前两者都不是说明,两者相交。相交的面积等于,(r1的扇形-三角形)+(r2的扇形-三角形)
    //求三角形的一个角,double d=acos( (相邻边1的平方+相邻边2的平方-对边3的平方)/(2*相邻边1*相邻边2) )
    //扇形面积:S=PI*r*r*θ/(2*PI)  三角形面积:S=1/2*a*c*sin(B)
    circle a,b;
    while(cin>>a.center.x>>a.center.y>>a.r>>b.center.x>>b.center.y>>b.r)
    {
        if((dist(a.center,b.center)+min(a.r,b.r))<=max(a.r,b.r))//两圆内交或包含
        {
            if(a.r<b.r) printf("%.3lf\n",PI*a.r*a.r);
            else printf("%.3lf\n",PI*b.r*b.r);
        }
        else if(dist(a.center,b.center)>=(a.r+b.r))//两圆外交或相离
            cout<<"0.000"<<endl;
        else
        {
            double length=dist(a.center,b.center);
            double d1=2*acos((a.r*a.r+length*length-b.r*b.r)/(2*a.r*length)); //求两扇形圆心角
            double d2=2*acos((b.r*b.r+length*length-a.r*a.r)/(2*b.r*length));
            double area1=a.r*a.r*d1/2-a.r*a.r*sin(d1)/2;
            //根据圆心角求扇形面积,减去三角形面积,得到相交部分面积
            //扇形面积:S=PI*r*r*θ/(2*PI)  三角形面积:S=1/2*a*c*sin(B)
            double area2=b.r*b.r*d2/2-b.r*b.r*sin(d2)/2;
            double area=area1+area2;
            printf("%.3lf\n",area);
        }
    }
    return 0;
}

// Bit trick 看一个点在不在一个扇形内
bool IsPointInCircularSector3( float cx, float cy, float ux, float uy, float squaredR, float cosTheta, float px, float py)
{
    const float Epsinon=0.00001;
//    assert(cosTheta > -1 && cosTheta < 1);
//    assert(squaredR > 0.0f);
 
    // D = P - C
    float dx = px - cx;
    float dy = py - cy;
 
    // |D|^2 = (dx^2 + dy^2)
    float squaredLength = dx * dx + dy * dy;
 
    // |D|^2 > r^2
    if (squaredLength > squaredR)
        return false;
 
    // D dot U
    float DdotU = dx * ux + dy * uy;
 
    // D dot U > |D| cos(theta)
    // <=>
    // (D dot U)^2 > |D|^2 (cos(theta))^2 if D dot U >= 0 and cos(theta) >= 0
    // (D dot U)^2 < |D|^2 (cos(theta))^2 if D dot U <  0 and cos(theta) <  0
    // true                               if D dot U >= 0 and cos(theta) <  0
    // false                              if D dot U <  0 and cos(theta) >= 0
    const unsigned cSignMask = 0x80000000;
    union {
        float f;
        unsigned u;
    }a, b, lhs, rhs;
    a.f = DdotU;
    b.f = cosTheta;
    unsigned asign = a.u & cSignMask;
    unsigned bsign = b.u & cSignMask;
    if (asign == bsign) {
        lhs.f = DdotU * DdotU;
        rhs.f = squaredLength * cosTheta * cosTheta;
        lhs.u |= asign;
        rhs.u |= asign;
        return (lhs.f - rhs.f) > Epsinon;
    }
    else
        return asign == 0;
}


#endif //LEETCODE_C_图形问题_H

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值