简单三维几何,判断俩个三角形是否相交

简单三维几何,多贴些三维几何的基本的东西,一些基本函数,和定义,

判断俩个三角形是否相交,如果相交,那么必然有一个三角形的一条边经过另一个三角形的内部、边上或者顶点,

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
const double eps=1e-6;
int dcmp(double x)
{
    return fabs(x)<eps?0:(x>0?1:-1);
}
struct Point3
{
    double x,y,z;
    Point3(double x,double y,double z):x(x),y(y),z(z){}
    Point3() {}
    void in()
    {
        cin>>x>>y>>z;
    }
};
typedef Point3 Vector3;
Vector3 operator +(Vector3 A,Vector3 B)
{
    return Vector3(A.x+B.x,A.y+B.y,A.z+B.z);
}
Vector3 operator -(Vector3 A,Vector3 B)
{
    return Vector3(A.x-B.x,A.y-B.y,A.z-B.z);
}
Vector3 operator * (Vector3 A,double p)
{
    return Vector3(A.x*p,A.y*p,A.z*p);
}
Vector3 operator / (Vector3 A,double p)
{
    return Vector3(A.x/p,A.y/p,A.z/p);
}
bool operator == (Vector3 A,Vector3 B)
{
    return !dcmp(A.x-B.x)&&!dcmp(A.y-B.y)&&!dcmp(A.z-B.z);
}
double Dot(Vector3 A,Vector3 B)
{
    return A.x*B.x+A.y*B.y+A.z*B.z;
}
double Length(Vector3 A)
{
    return sqrt(Dot(A,A));
}
double Angle(Vector3 A,Vector3 B)
{
    return acos(Dot(A,B)/Length(A)/Length(B));
}
double DistanceToPlane(Point3 p,Point3 p0,Vector3 n)
{
    return fabs(Dot(p-p0,n)/Length(n));
}
Point3 GetPlaneProjection(Point3 p,Point3 p0,Vector3 n)
{
    double d=Dot(p-p0,n)/Length(n);
    return p+n*d;
}
Point3 LinePlaneIntersection(Point3 p1,Point3 p2,Point3 p3,Point3 p0,Vector3 n)
{
    Vector3 v=p2-p1;
    double t=(Dot(n,p0-p1)/Dot(n,p2-p1));
    return p1+v*t;
}
Vector3 Cross(Vector3 A,Vector3 B)
{
    return Vector3(A.y*B.z-A.z*B.y,A.z*B.x-A.x*B.z,A.x*B.y-A.y*B.x);
}
double  Area2(Point3 A,Point3 B,Point3 C)
{
    return Length(Cross(B-A,C-A));
}
bool PointInTri(Point3 P,Point3 P0,Point3 P1,Point3 P2)
{
    double area1=Area2(P,P0,P1);
    double area2=Area2(P,P1,P2);
    double area3=Area2(P,P2,P0);
    return dcmp(area1+area2+area3-Area2(P0,P1,P2))==0;
}
bool TriSegIntersection(Point3 P0,Point3 P1,Point3 P2,Point3 A,Point3 B,Point3 &P)
{
    Vector3 n=Cross(P1-P0,P2-P0);
    if(dcmp(Dot(n,B-A)==0)) return false;
    else
    {
        double t=Dot(n,P0-A)/Dot(n,B-A);
        if(dcmp(t)<0||dcmp(t-1)>0) return false;
        P=A+(B-A)*t;
        return PointInTri(P,P0,P1,P2);
    }
}
double DistaceToLine(Point3 P,Point3 A,Point3 B)
{
    Vector3 v1=B-A,v2=P-A;
    return Length(Cross(v1,v2)/Length(v1));
}
double DistaceToSegment(Point3 P,Point3 A,Point3 B)
{
    if(A==B) return Length(P-A);
    Vector3 v1=B-A,v2=P-A,v3=P-B;
    if(dcmp(Dot(v1,v2))<0) return Length(v2);
    else if(dcmp(Dot(v1,v3))>0) return Length(v3);
    else return Length(Cross(v1,v2))/Length(v1);
}
double Volume6(Point3 A,Point3 B,Point3 C,Point3 D)
{
    return Dot(D-A,Cross(B-A,C-A));
}
struct Face
{
    int v[3];
    Vector3 normal(Point3 *P)const
    {
        return Cross(P[v[1]]-P[v[0]],P[v[2]]-P[v[0]]);
    }
    int cansee(Point3 *P,int i) const
    {
        return Dot(P[i]-P[v[0]],normal(P))>0?1:0;
    }
};
vector<Face> CH3D(Point3 *P,int n)
{
    int vis[100][100];
    memset(vis,0,sizeof(vis));
    vector<Face> cur;
    cur.push_back((Face) {{0,1,2}});
    cur.push_back((Face) {{2,1,0}});
    for(int i=3;i<n;i++)
    {
        vector<Face> next;
        for(int j=0;j<cur.size();j++)
        {
            Face &f=cur[j];
            int res=f.cansee(P,i);
            if(!res) next.push_back(f);
            for(int k=0;k<3;k++) vis[f.v[k]][f.v[(k+1)%3]]=res;
        }
        for(int j=0;j<cur.size();j++)
            for(int k=0;k<3;k++)
            {
                int a=cur[j].v[k],b=cur[j].v[(k+1)%3];
                if(vis[a][b]!=vis[b][a]&&vis[a][b])
                next.push_back((Face) {{a,b,i}});
            }
            cur=next;
    }
    return cur;
}
double rand01() {return rand()/(double)RAND_MAX;}
double randeps() {return (rand01()-0.5)*eps;}
Point3 add_noise(Point3 p)
{
    return Point3(p.x+randeps(),p.y+randeps(),p.z+randeps());
}
bool TriTriIntersection(Point3 *T1,Point3 *T2)
{
    Point3 P;
    for(int i=0;i<3;i++)
    {
        if(TriSegIntersection(T1[0],T1[1],T1[2],T2[i],T2[(i+1)%3],P))
            return true;
        if(TriSegIntersection(T2[0],T2[1],T2[2],T1[i],T1[(i+1)%3],P))
            return true;
    }
    return false;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        Point3 T1[3],T2[3];
        for(int i=0;i<3;i++)
            T1[i].in();
        for(int i=0;i<3;i++)
            T2[i].in();
        printf("%d\n",TriTriIntersection(T1,T2)?1:0);
    }
    return 0;
}


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ACM Fighting! 2 1.计算几何 5 1.1 注意 5 1.2几何公式 6 1.3 多边形 8 1.4多边形切割 11 1.5 浮点函数 12 1.6 面积 18 1.7球面 18 1.8三角形 19 1.9三维几何 22 1.10 凸包 30 1.11 网格 32 1.12 圆 33 1.13 矢量运算求几何模板 35 1.14结构体表示几何图形 47 1.15四城部分几何模板 52 1.16 一些代码 54 1.16.1 最小圆覆盖_zju1450 54 1.16.2 直线旋转_两凸包的最短距离(poj3608) 58 1.16.3 扇形的重心 62 1.16.4 根据经度纬度求球面距离 62 1.16.5 多边形的重心 64 1.16.6 存不存在一个平面把两堆点分开(poj3643) 66 1.16.7 pku_3335_判断多边形的核是否存在 67 1.16.8 pku_2600_二分+圆的参数方程 74 1.16.9 pku_1151_矩形相交的面积 76 1.16.10 pku_1118_共线最多的点的个数 78 1.16.11 pku2826_线段围成的区域可储水量 80 1.16.12 Pick公式 84 1.16.13 N点中三个点组成三角形面积最大 86 1.16.14 直线关于圆的反射 89 1.16.15 pku2002_3432_N个点最多组成多少个正方形(hao) 94 1.16.16 pku1981_单位圆覆盖最多点(poj1981)CircleandPoints 97 1.16.17 pku3668_GameofLine_N个点最多确定多少互不平行的直线(poj3668) 99 1.16.18 求凸多边形直径 100 2.组合 102 2.1 组合公式 102 2.2 排列组合生成 102 2.3 生成gray码 104 2.4 置换(polya) 104 2.5 字典序全排列 105 2.6 字典序组合 105 2.7 一些原理及其例子 106 3.数论 108 3.1 阶乘最后非0位 108 3.2 模线性方程组 108 3.3 素数 110 3.4 欧拉函数 114 3.6高精度 116 3.6.1平方根 116 3.6.2 高精度乘幂 117 3.7 高斯消元回代法 122 3.8 数值计算 124 3.8.1 定积分计算 124 3.8.2 多项式求根(牛顿法) 125 3.8.3 周期性方程(追赶法) 127 4.排序 128 4.1快速选择算法 128 4.2归并排序+逆序数的求取 128 5.字符串 130 5.1 KMP应用 130 5.2 后缀数组 131 5.3 中缀表达式转后缀表达式 134 5.4 Firefighters 表达式求值 135 6.博弈 139 6.1 博弈的AB剪枝 139 6.1.1 取石子 139 6.2 博弈 SG函数 局势分割 141 7.数据结构 142 7.1 TRIE 142 7.2 线段树 147 7.3 并查集 151 7.4 树状数组 152 7.5 点树 154 7.6 STL 156 7.7 离散化 157 8.图论 158 8.0 2-SAT 158 8.2 寻找Euler回路 163 8.3 拓扑排序 163 8.4 差分约束系统 164 8.5 笛卡尔树 165 8.6 LCA和RMQ 167 8.7 割和桥 171 8.8 最小生成树(kruskal) 172 8.9 最短路径 173 8.10 最大网络流 175 8.11 最小费用流 180 8.12 最大团问题 182 8.13 二分图匹配 184 8.14 带权的最优二分图匹配 184 9.搜索算法概略 187 9.1 迭代深搜+IDA* 187 9.2 分之界限法(深搜) 189 9.3 A* 8数码问题( pascal ) 192 9.4 优先队列广搜 194 10.应用 197 10.1 Joseph问题 197 10.2 N皇后构造解 197 10.3 布尔母函数 198 10.4 第k元素 199 10.5 幻方构造 199 10.6 模式匹配(kmp) 201 10.7 逆序对数 201 10.8 字符串最小表示 202 10.9 最长公共单调子序列 202 10.10 最长子序列 204 10.11 最大子串匹配 204 10.12 最大子段和 205 10.13 最大子阵和 206 11.其它 207 11.1 大数(只能处理正数) 207 11.2 分数 212 11.3 矩阵 214 11.4 线性方程组 216 11. 5 线性相关 218 11.6 日期 219 11.7 读入 220 11.8 函数 220
### 回答1: Delaunay三角剖分是计算机图形学中常用的方法,它是将点云转化为无重叠的三角形集合的过程。对于三维点云而言,我们可以利用C++语言编写Delaunay三角剖分的源代码。 具体而言,我们需要借助第三方库来完成这个过程。例如,我们可以使用CGAL库中的Delaunay_triangulation_3类来实现三维点云的Delaunay三角剖分。在使用该类之前,我们需要将点云转化为一系列顶点,将顶点作为参数传入Delaunay_triangulation_3类的对象中。 在通过Delaunay_triangulation_3类计算Delaunay三角剖分后,我们可以通过遍历三角形集合,计算每个三角形的顶点坐标和法向量,从而得到三维点云的表面重建结果。 需要注意的是,Delaunay三角剖分的结果可能会产生“拟合问题”,即存在一些三角形的边缘与点云的表面重建结果不完全吻合。为了解决这个问题,我们可以使用一些优化方法,例如对三角形的边缘进行局部调整,以提高重建结果的精度。 总之,通过编写三维点云Delaunay三角剖分的源代码,我们可以将点云转化为一系列无重叠的三角形,从而实现三维模型的重建。 ### 回答2: 三维点云 delaunay 三角剖分是一种将无序的三维点云数据转化为三角形面片的方法,可以在三维建模、地质勘探等领域中应用。其源代码一般采用 C++ 编写,下面简单介绍其实现。 三维点云 delaunay 三角剖分主要分为以下几步: 1. 构建超级三角形。为了保证所有点都在三角剖分内部,需要在点云的边界之外添加一个超级三角形(一般为一个比点云面积大的等边三角形),保证所有点都在其内部。 2. 将点逐一插入。从点云中随机选取一个点开始,将其插入到当前三角剖分中。插入过程中会检查新插入点与其它三角形的关系,同时进行三角形翻转和边的反转等操作以维护 delaunay 三角剖分的特性。 3. 剖分收敛。当所有点都插入完成后,需要对剩余的三角形进行处理,将所有与超级三角形相交三角形删除,以得到最终的三角剖分结果。 其源代码主要包括点的数据结构定义、超级三角形的构建、插入点和剖分收敛等函数的实现。在实现中需要注意,对于边界点或重复点等特殊情况需要进行处理,同时可根据具体应用场景做出一些优化。 ### 回答3: 三维点云的Delaunay三角剖分源代码是一个算法实现,可以将一个三维点云数据集转化为一组无重叠三角形的连接。这个算法通常由C++实现,并且主要包含以下步骤: 首先,需要定义一个三维点云数据结构,用于存储所有的点。然后,通过半边数据结构来表示三角形的连接关系,并创建一个起始三角形,该三角形的外接圆可以囊括所有的点。 接下来,使用一个扫描线算法来生成三角剖分。该算法主要通过在扫描线上移动,并利用拐角点的概念来不断更新Delaunay三角形网格。在每个点上,都会查找在当前点的左侧和右侧的最高顶点,并通过一个旋转操作来更新三角形的连接关系。 通过以上步骤,就可以生成一个Delaunay三角剖分,其中每个三角形都与它的外接圆不包含任何点。这个算法在计算几何和计算机图形学领域十分流行,并且有多种优化和扩展,可以更好地满足具体应用的需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值