几何代码总结

//二维几何


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#include<bitset>
#include<string>
#include<queue>
#include<deque>
#include<ctype.h>
#include<vector>
#include<set>
#include<map>
#include<list>
#include<stack>
#include<functional>
#include<algorithm>

using namespace std;

#define N 100010

const double eps=1e-12;
const double pi=acos(-1.0);
int dcmp(double x){
    if(x>-eps&&x<eps) return 0;
    if(x>eps) return 1;
    return -1;
}
struct Point{
    double x,y;
    int id;
    Point(double a=0,double b=0):x(a),y(b){}
};
struct circle{
    double x,y,r;
    Point make_Point(double a){
        return Point(x+cos(a)*r,y+sin(a)*r);
    }
};
typedef Point Vector;
int operator<(Point a,Point b){
    return dcmp(a.x-b.x)<0||(dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)<0);
}
Point operator-(Point a,Point b){ return Point(a.x-b.x,a.y-b.y); }
Point operator+(Point a,Point b){ return Point(a.x+b.x,a.y+b.y); }
double operator*(Vector a,Vector b){ return a.x*b.x+a.y*b.y; }
int operator==(Point a,Point b){ return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0; }
double Len(Vector a){  return sqrt(a.x*a.x+a.y*a.y); }
Vector operator/(Vector u,double k){
    if(dcmp(u.x)) u.x/=k;
    if(dcmp(u.y)) u.y/=k;
    return u;
}
Vector Rotate(Vector a,double rad){ //向量逆时针旋转rad弧度
    return Vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));
}
double cross(Point a,Point b){ //叉积
    return a.x*b.y-a.y*b.x;
}
double angle(Vector a,Vector b){ //两个向量的夹角
    return acos((a*b)/(Len(a)*Len(b)));
}
int online(Point a,Point b,Point c){ //判断点c是否在线段ab上
    return  (a==c)||(b==c)||(cross(a-c,b-c)==0&&((a-c)*(b-c)<0));
}

int segmentIntersection(Point a1,Point a2,Point b1,Point b2) //判断线段a1a2和b1b2相交(不包含端点)
{
    double c1=cross((a2-a1),(b1-a1)),c2=cross((a2-a1),(b2-a1));
    double c3=cross((b2-b1),(a1-b1)),c4=cross((b2-b1),(a2-b1));
    return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;
}

int Polygon_contains(Point point,Point *points,int n) {  //判断一个点在多边形内
    int i, j, status=0;
    for (i=0,j=n-1;i<n;j=i++){
        if(online(points[i],points[j],point)) return 0;
        if((((points[i].y<=point.y)&&(point.y<points[j].y))
        ||((points[j].y<=point.y)&&(point.y<points[i].y)))
        &&(point.x <(points[j].x - points[i].x)*(point.y - points[i].y)
        /(points[j].y - points[i].y) + points[i].x))
            status = !status;
    }
    return status;
}

Point P[N];
bool cmp(Point a,Point b){   //极坐标排序
    if(cross(a-P[0],b-P[0])==0)
        return dcmp(Len(a-P[0])-Len(b-P[0]))<=0;
    else
        return cross(a-P[0],b-P[0])>0;
}
void Graham(int n,vector<Point> &sta){  //求解二维凸包
    for(int i=1;i<n;i++){
        if(dcmp(P[i].y-P[0].y)<0||(P[i].y==P[0].y&&P[i].x<P[0].x))
            swap(P[i],P[0]);
    }
    sort(P+1,P+n,cmp);
    sta.push_back(P[0]);
    sta.push_back(P[1]);
    for(int i=2;i<n;i++){
        while(sta.size()>1&&dcmp(cross(sta[sta.size()-1]-sta[sta.size()-2],P[i]-sta[sta.size()-1]))<=0)
            sta.pop_back();
        sta.push_back(P[i]);
    }
}

int getTangents(Point p,circle cc,Vector *t){ //求一个点p到圆cc的切线向量
    Vector u=Point(cc.x,cc.y)-p;
    double dist=Len(u);
    if(dcmp(dist-cc.r)<0) return 0;
    else if(dcmp(dist-cc.r)==0){
        t[0]=Rotate(u,pi/2);
        return 1;
    }else {
        double ang=asin(cc.r/dist);
        t[0]=Rotate(u,-ang);
        t[1]=Rotate(u,+ang);
        return 2;
    }
}
void meet(Point p,circle cc,Point *t){ //求一个点p到圆cc的切点
    double dis,l;
    Vector u=Point(cc.x,cc.y)-p;
    getTangents(p,cc,t);l=Len(t[0]);
    dis=sqrt(Len(u)*Len(u)-cc.r*cc.r);
    t[0].x=t[0].x*dis/l;t[0].y=t[0].y*dis/l;
    t[1].x=t[1].x*dis/l;t[1].y=t[1].y*dis/l;
    t[0]=t[0]+p;
    t[1]=t[1]+p;
}

double SrcAB(Point a,Point b,circle cc){ //求a点到b点在的圆上的圆弧长度
    double ang1,ang2;
    Vector v1,v2;
    v1=a-Point(cc.x,cc.y);
    v2=b-Point(cc.x,cc.y);
    ang1=atan2(v1.y,v1.x);
    ang2=atan2(v2.y,v2.x);
    if(ang2<ang1) ang2+=2*pi;
    return cc.r*(ang2-ang1);
}

int getgqx(circle A,circle B,Point* sa,Point* sb) //求圆A和B的公切线
{
    int cnt=0;
    Point *a=sa,*b=sb;
    if(A.r<B.r){ swap(A,B);swap(a,b);}
    double d2=(A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.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.y-A.y,B.x-A.x);
    if(dcmp(d2)==0&&dcmp(A.r-B.r)==0) return -1; //无限多条切线
    if(dcmp(d2-rdiff*rdiff)==0)
    {
        a[cnt]=A.make_Point(base);b[cnt]=B.make_Point(base);cnt++;
        return 1;
    }
    //有外共切线
    double ang=acos((A.r-B.r)/sqrt(d2));
    a[cnt]=A.make_Point(base+ang);b[cnt]=B.make_Point(base+ang);cnt++;
    a[cnt]=A.make_Point(base-ang);b[cnt]=B.make_Point(base-ang);cnt++;
    if(dcmp(d2-rsum*rsum)==0)//一条内共切线
    {
        a[cnt]=A.make_Point(base);b[cnt]=B.make_Point(pi+base);cnt++;
    }
    else if(dcmp(d2-rsum*rsum)>0)
    {
        double ang=acos((A.r+B.r)/sqrt(d2));
        a[cnt]=A.make_Point(base+ang);b[cnt]=B.make_Point(pi+base+ang);cnt++;
        a[cnt]=A.make_Point(base-ang);b[cnt]=B.make_Point(pi+base-ang);cnt++;
    }
    return cnt;
}
//点到直线的距离
double disptoline(Point p,Point l1,Point l2){
    return fabs(cross((p-l2),(l1-l2)))/Len(l1-l2);
}
//判直线和圆相交
int intersect_line_circle(Point c,double r,Point l1,Point l2){
    return disptoline(c,l1,l2)<r;
}
Point intersection(Point u1,Point u2,Point v1,Point v2){
    Point ret=u1;
    double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
    /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
    ret.x+=(u2.x-u1.x)*t;
    ret.y+=(u2.y-u1.y)*t;
    return ret;
}
//直线和圆的交点
void intersection_line_circle(Point c,double r,Point l1,Point l2,Point& p1,Point& p2){
    Point p=c;
    double t;
    p.x+=l1.y-l2.y;
    p.y+=l2.x-l1.x;
    p=intersection(p,c,l1,l2);
    t=sqrt(r*r-Len(p-c)*Len(p-c))/Len(l1-l2);
    p1.x=p.x+(l2.x-l1.x)*t;
    p1.y=p.y+(l2.y-l1.y)*t;
    p2.x=p.x-(l2.x-l1.x)*t;
    p2.y=p.y-(l2.y-l1.y)*t;
}

已知三点(不共线)求外接圆圆心代码:

Point getCircleDot(Point a,Point b,Point c){
	double T1=b.x*b.x+b.y*b.y-a.x*a.x-a.y*a.y;
	double T2=c.x*c.x+c.y*c.y-a.x*a.x-a.y*a.y;
	double y,x=(T1*(c.y-a.y)-T2*(b.y-a.y))/(2*cross((b-a),(c-a)));
	if(dcmp(a.y-b.y))
		 y=(T1+2*x*(a.x-b.x))/(2*(b.y-a.y));
	else 
		 y=(T2+2*x*(a.x-c.x))/(2*(c.y-a.y));
	return Point(x,y);
}


/*==================================================*/   
//| 求最小覆盖圆  
//| CALL: 最小圆 = minC(Point *p,int n);   
//代码摘自:http://blog.csdn.net/he11oworld/article/details/6167262
/*==================================================*/    

#include<math.h>
#include<string.h>
#include<stdio.h>

struct Point{double x,y;};   
struct Circle{Point c;double r;};   
double dist(Point a,Point b){ 
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));   
}   
Circle calc(Point p1,Point p2,Point p3){   
    Circle temp;   
	double a,b,c,d,e,f;   
    a=p2.x-p1.x;   
	b=p2.y-p1.y;   
    c=(p2.x*p2.x+p2.y*p2.y-p1.x*p1.x-p1.y*p1.y)/2;   
    d=p3.x-p1.x;   
	e=p3.y-p1.y;   
    f=(p3.x*p3.x+p3.y*p3.y-p1.x*p1.x-p1.y*p1.y)/2;   
    temp.c.y=(c*d-f*a)/(b*d-e*a);   
    temp.c.x=(c*e-f*b)/(a*e-b*d);   
	return temp;   
}   
Circle minC(Point *p,int n){   
    Circle O;   
    int i,j,k;   
	O.c=p[0];O.r=0;
    for(i=1;i<n;i++){  
		if(dist(O.c,p[i])<=O.r+1e-6)continue;   
        O.c=p[i];O.r=0;   
        for(j=0;j<i;j++){   
            if(dist(O.c,p[j])<=O.r+1e-6)continue;   
            O.c.x=(p[i].x+p[j].x)/2;O.c.y=(p[i].y+p[j].y)/2;O.r=dist(O.c,p[j]);   
            for(k=0;k<j;k++){  
                if(dist(O.c,p[k])<=O.r+1e-6)continue;   
                O=calc(p[i],p[j],p[k]);   
                O.r=dist(O.c,p[k]);   
            }   
        }   
    }   
    return O;   
}  



三维几何:

const double eps=1e-10;
const double pi=acos(-1.0);

struct Point{
    double x,y,z;
    Point(double a=0,double b=0,double c=0):
    x(a),y(b),z(c){}
    static Point read(){
        double rx,ry,rz;
        scanf("%lf%lf%lf",&rx,&ry,&rz);
        return Point(rx,ry,rz);
    }
};

typedef Point Vector;

int dcmp(double a){
    if(fabs(a)<eps) return 0;
    return a<0?-1:1;
}
Point operator+(Point a,Point b){ return Point(a.x+b.x,a.y+b.y,a.z+b.z); }
Point operator-(Point a,Point b){ return Point(a.x-b.x,a.y-b.y,a.z-b.z); }
double operator*(Vector a,Vector b){ return a.x*b.x+a.y*b.y+a.z*b.z; }
double Len(Vector a){ return sqrt(a.x*a.x+a.y*a.y+a.z*a.z); }

Vector cross(Vector a,Vector b){ //叉积
    return Vector(a.y*b.z-b.y*a.z,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x);
}
Vector normalvector(Vector a,Vector b){ //平面的法向量
    return cross(a,b);
}
double linetoline(Point a1,Point a2,Point b1,Point b2){ //直线a1a2和直线b1b1之间的距离

    return fabs((a1-b1)*cross(a1-a2,b1-b2))/Len(cross(a1-a2,b1-b2));
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 中位数几何是指通过对一组数据进行排序,找出其中间的数值。在几何学中,中位数是指通过一条线将一个平面图形分成两个面积相等的部分的线段。下面是一个用Python计算中位数几何的例子: ```python import math # 计算一个列表的中位数 def median(lst): n = len(lst) s = sorted(lst) if n % 2 == 0: return (s[n//2-1] + s[n//2]) / 2 else: return s[n//2] # 计算两点之间的距离 def dist(p1, p2): return math.sqrt((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2) # 计算多边形的中位线 def median_line(poly): n = len(poly) med_point = poly[n//2] if n % 2 == 0: med_point = [(poly[n//2-1][0]+poly[n//2][0])/2, (poly[n//2-1][1]+poly[n//2][1])/2] distances = [dist(p, med_point) for p in poly] min_dist_idx = distances.index(min(distances)) if min_dist_idx == 0: return [poly[min_dist_idx], poly[-1]] else: return [poly[min_dist_idx], poly[min_dist_idx-1]] # 测试 points = [(0,0), (1,1), (2,0), (1,-1)] print("Points:", points) print("Median point:", median(points)) print("Median line:", median_line(points)) ``` 输出: ``` Points: [(0, 0), (1, 1), (2, 0), (1, -1)] Median point: (1, 0.0) Median line: [(1, 1), (1, -1)] ``` 上面的代码分别实现了计算列表中的中位数,计算两点之间的距离以及计算多边形的中位线。可以通过调用这些函数来计算任意多边形的中位线。 ### 回答2: 中位数是一种统计中常见的中心位置测量指标,表示数据集的中间值。在几何学中,我们也可以使用Python来计算中位数。 首先,我们需要将数据集的几何特征表示为一个列表或数组。假设我们的数据集是一组点的坐标值。我们可以使用Python中的numpy库来处理这些计算。 接下来,我们可以使用numpy库中的函数来计算点的几何中位数。例如,我们可以使用numpy.median()函数来计算数据集的中位数。这个函数将返回一个点,表示数据集的几何中位数。 另一种方法是计算点的中心位置。我们可以计算数据集中所有点的坐标的平均值,作为数据集的中位数。我们可以使用numpy.mean()函数计算点的平均值。 最后,我们可以使用Python的可视化库(如matplotlib)来绘制数据集和中位数点的图形。通过绘制这个图形,我们可以更直观地理解数据集的中位数位置。 总结起来,通过使用Python和一些相关的库和函数,我们可以计算几何数据集的中位数,并展示出来,从而更好地理解数据集的中间值。 ### 回答3: 中位数是一组数据中的一个中间值,即将数据按照升序或降序排列后,处于中间位置的数据。如果数据的个数为奇数,那么中位数就是排序后中间位置的数据,如果数据的个数为偶数,那么中位数就是排序后中间两个数据的平均值。 在Python中,我们可以通过一些库函数来计算中位数。常用的库函数包括numpy和statistics。 使用numpy库可以通过numpy.median()函数来计算中位数。该函数接受一个数组作为参数,返回该数组的中位数。示例代码如下: ```python import numpy as np data = np.array([1, 2, 3, 4, 5]) median = np.median(data) print("中位数为:", median) ``` 使用statistics库可以通过statistics.median()函数来计算中位数。该函数接受一个列表作为参数,返回该列表的中位数。示例代码如下: ```python import statistics data = [1, 2, 3, 4, 5] median = statistics.median(data) print("中位数为:", median) ``` 除了使用库函数,我们也可以自己编写函数来计算中位数。首先,需要对数据进行排序,然后根据数据的个数确定中位数的位置,最后返回对应位置的数据或数据的平均值。 以上是关于中位数在Python中的应用和计算方法的简要说明。希望对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值