• 三维计算几何复习


    三维计算几何

     声明:

    由于本人较弱,并不能保证以下内容的100%正确

    欢迎大佬来挑错

    基本定义

     1 struct Point3{
     2     double x,y,z;
     3     Point3(){
     4         x=y=z=0.0;
     5     }
     6     Point3(double xx,double yy,double zz){
     7         x=xx;y=yy;z=zz;
     8     }
     9 };
    10 typedef Point3 Vec3;
    11 
    12 Vec3 operator + (Vec3 v1,Vec3 v2){
    13     return Vec3(v1.x+v2.x,v1.y+v2.y,v1.z+v2.z);
    14 }
    15 Vec3 operator - (Point3 p1,Point3 p2){
    16     return Vec3(p1.x-p2.x,p1.y-p2.y,p1.z-p2.z);
    17 }
    18 Vec3 operator * (Vec3 v,double p){
    19     return Vec3(v.x*p,v.y*p,v.z*p);
    20 }
    21 Vec3 operator / (Vec3 v,double p){
    22     return Vec3(v.x/p,v.y/p,v.z/p);
    23 }

    半平面的表示

    Dot(n,p-p0)=0
    Ax+By+Cz+D>=0

     

    三维点积

    1 double Dt(Vec3 v1,Vec3 v2){
    2     return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z;
    3 }
    4 double Getlen(Vec3 v){
    5     return sqrt(Dt(v,v));
    6 }
    7 double Getang(Vec3 v1,Vec3 v2){
    8     return Dt(v1,v2)/Getlen(v1)/Getlen(v2);
    9 }

    应用:求夹角

    求到平面的距离

    求点在平面内的投影

    1 double DistanceToPlane(Point3 p,Point3 p0,Vec3 n){
    2     return Myabs(Dt(p-p0,n)/Getlen(n));
    3 }
    4 Point3 GetPlaneProjection(Point3 p,Point3 p0,Vec3 n){
    5     return p-n*Dt(p-p0,n)/Getlen(n);
    6 }

    直线和平面的交点

    注意判断分母为0

    Point3 LinePlaneIntersection(Point3 p1,Point3 p2,Point3 p0,Vec3 n){
        Vec3 v=p2-p1;
        double t=Dt(n,p0-p1)/Dt(n,p2-p1);
        return p1+v*t;
    }

    三维叉积

    1 Vec3 Crs(Vec3 v1,Vec3 v2){
    2     return Vec3(v1.y*v2.z-v2.y*v1.z,v1.z*v2.x-v2.z*v1.x,v1.x*v2.y-v2.x*v1.y);
    3 }
    4 double GetS2(Point3 A,Point3 B,Point3 C){
    5     return Getlen(Crs(B-A,C-A));
    6 }

    过不共线三点的平面的法向量

    Crs(p2-p0,p1-p0)

    三角形的有向面积????

    求出叉积后取长度

    判断点是否在三角形内

    1 bool PointInTri(Poitn3 P,Point3 P0,Point3 P1,Point3 P2){
    2     double S1=GetS2(P,P0,P1);
    3     double S2=GetS2(P,P1,P2);
    4     double S3=GetS2(P,P2,P0);
    5     return dcmp(S1+S2+S2-GetS2(P0,P1,P2))==0;
    6 }

    判断线段与三角形相交

     

    1 bool TriSegIntersection(Point3 P0,Point3 P1,Point3 P2,Point3 A,Point3 B){
    2     Vec3 n=Crs(P1-P0,P2-P0);
    3     if(dcmp(Dt(n,B-A))==0)return 0;
    4     double t=Dt(n,P0-A)/Dt(n,B-A);
    5     if(dcmp(t)<0||dcmp(t-1)>0)return 0;
    6     Point3 P=A+(B-A)*t;
    7     return PointInTri(P,P0,P1,P2);
    8 }

    点到直线线段的距离

     1 double DistanceToLine(Point3 P,Point3 A,Point3 B){
     2     Vec3 v1=B-A,v2=P-A;
     3     return Getlen(Crs(v1,v2))/Getlen(v1);
     4 }
     5 
     6 double DistanceToSegment(Point3 P,Point3 A,Point3 B){
     7     //(A!=B)
     8     Vec3 v1=B-A,v2=P-A,v3=P-B;
     9     if(dcmp(Dt(v1,v2))<0)return Getlen(v2);
    10     else if(dcmp(Dt(v1,v3))>0)return Getlen(v3);
    11     else return DistanceToLine(P,A,B);
    12 }

    四面体的体积

    四面体的带符号体积

    1 double Volume6(Point3 A,Point3 B,Point3 C,Point3 D){
    2     return Dt(D-A,Crs(B-A,C-A));
    3 }

    计算有向面积时注意多边形的储存顺序

    三维凸包

    (我的模板是假的,注意四点共面的情况)

    暴力法 O(n4)

    枚举每三个点组成的有向三角形

    判断是否所有点都在同侧

    从而判断是否是凸包的一个面

    判断在三角形的哪一侧需要一次叉积和一次点积(也可以理解为一次混合积)

  • 相关阅读:
    ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal使用及原理解析
    Spring Cloud入门教程
    极简策略模式
    MySQL热点行更新
    OpenResty安装、启动脚本及Lua脚本调试
    Spring Cloud Netflix超时时间设置
    SpringCloudCommons模块
    [转]Spring Boot @EnableConfigurationProperties @ConfigurationProperties注解配置原理源码分析
    SpringCloudContext模块
    [转]Spring源码解析之@Configuration
  • 原文地址:https://www.cnblogs.com/zzyer/p/8953867.html
Copyright © 2020-2023  润新知