gpt4 book ai didi

math - 锥盒碰撞

转载 作者:行者123 更新时间:2023-12-04 09:45:25 26 4
gpt4 key购买 nike

我正在寻找在一个圆锥体(底部是圆的。所以它基本上是一个球体的一部分)和一个盒子之间实现碰撞检测。我不太在意它是 AABB 还是 OBB,因为转换应该足够简单。我找到的每个解决方案都使用三角形锥体,但我的锥体更像是一个具有角度和距离的“弧”。

是否有一个简单的解决方案来进行这种碰撞检测?还是进行多种类型的测试? IE。比如在一个球体上获取交点,r 是我的圆锥距离,然后测试它们是否在一个角度内相交或其他什么?

最佳答案

无论如何,我很好奇并计划以 GLSL 数学风格做这件事所需的东西。所以这里有不同的方法。让我们考虑一下圆锥的定义:
cone

  • 创建一组基本几何图元

  • 您需要支持点、线、三角形、凸三角网格、球面(圆锥)。
  • 在点和三角形、网格、圆锥之间实现内部测试

  • 对于 triangle任何边和点之间的交叉结果 - 边原点应该指向三角形的同一侧(如正常)。如果不是点在外面。
    对于 convex mesh对于所有面,点面原点和面法线指向之间的点积应 <= 0。
    对于 cone该点应在球体半径内,锥轴与点锥原点之间的角度应<= ang。再次点积可用于此。
  • 实现基本原语之间的最近线

  • 这就像在形成一条线的每个图元上找到最近的点。它类似于垂直距离。 point-point这很容易,因为它们是最近的线路。 point-line可以使用将点投影到线上(点积)来完成。但是,您需要限制结果,使其位于行内,而不是外推。 point-triangle可以作为所有圆周线与点组合的最小值以及到表面的垂直距离(与三角形法线的点积)获得。
    所有其他原语组合都可以从这些基本组合构建。
  • 网格和圆锥之间的最近线

  • 只需在圆锥球体中心和网格之间使用最近的线。如果线位于圆锥内,则将其缩短球体半径 R。这将考虑所有帽相互作用。
    然后在锥体表面上测试线,沿其圆周取样,从锥体球心开始,到最外圈(锥体和盖子之间的边缘)结束。如果您需要更好的精度,您也可以测试三角形。
  • 网格和圆锥的交点

  • 这很容易,只需计算网格和圆锥之间的最近留置权。然后测试它在网格侧的点是否在圆锥内。
    检查
        `bool intersect(convex_mesh m0,spherical_sector s0);`
    在下面的代码中实现。
    这里是小的 C++/OpenGL 示例(使用 GLSL 风格的数学) :
    //---------------------------------------------------------------------------
    //--- GL geometry -----------------------------------------------------------
    //---------------------------------------------------------------------------
    #ifndef _gl_geometry_h
    #define _gl_geometry_h
    //---------------------------------------------------------------------------
    const float deg=M_PI/180.0;
    const float rad=180.0/M_PI;
    float divide(float a,float b){ if (fabs(b)<1e-10) return 0.0; else return a/b; }
    double divide(double a,double b){ if (fabs(b)<1e-10) return 0.0; else return a/b; }
    #include "GLSL_math.h"
    #include "List.h"
    //---------------------------------------------------------------------------
    class point
    {
    public:
    // cfg
    vec3 p0;

    point() {}
    point(point& a) { *this=a; }
    ~point() {}
    point* operator = (const point *a) { *this=*a; return this; }
    //point* operator = (const point &a) { ...copy... return this; }

    point(vec3 _p0)
    {
    p0=_p0;
    compute();
    }
    void compute(){};
    void draw()
    {
    glBegin(GL_POINTS);
    glVertex3fv(p0.dat);
    glEnd();
    }
    };
    //---------------------------------------------------------------------------
    class axis
    {
    public:
    // cfg
    vec3 p0,dp;

    axis() {}
    axis(axis& a) { *this=a; }
    ~axis() {}
    axis* operator = (const axis *a) { *this=*a; return this; }
    //axis* operator = (const axis &a) { ...copy... return this; }

    axis(vec3 _p0,vec3 _dp)
    {
    p0=_p0;
    dp=_dp;
    compute();
    }
    void compute()
    {
    dp=normalize(dp);
    }
    void draw()
    {
    vec3 p; p=p0+100.0*dp;
    glBegin(GL_LINES);
    glVertex3fv(p0.dat);
    glVertex3fv(p .dat);
    glEnd();
    }
    };
    //---------------------------------------------------------------------------
    class line
    {
    public:
    // cfg
    vec3 p0,p1;
    // computed
    float l;
    vec3 dp;

    line() {}
    line(line& a) { *this=a; }
    ~line() {}
    line* operator = (const line *a) { *this=*a; return this; }
    //line* operator = (const line &a) { ...copy... return this; }

    line(vec3 _p0,vec3 _p1)
    {
    p0=_p0;
    p1=_p1;
    compute();
    }
    void swap()
    {
    vec3 p=p0; p0=p1; p1=p;
    }
    void compute()
    {
    dp=p1-p0;
    l=length(dp);
    }
    void draw()
    {
    glBegin(GL_LINES);
    glVertex3fv(p0.dat);
    glVertex3fv(p1.dat);
    glEnd();
    }
    };
    //---------------------------------------------------------------------------
    class triangle
    {
    public:
    // cfg
    vec3 p0,p1,p2;
    // computed
    vec3 n;

    triangle() {}
    triangle(triangle& a) { *this=a; }
    ~triangle() {}
    triangle* operator = (const triangle *a) { *this=*a; return this; }
    //triangle* operator = (const triangle &a) { ...copy... return this; }

    triangle(vec3 _p0,vec3 _p1,vec3 _p2)
    {
    p0=_p0;
    p1=_p1;
    p2=_p2;
    compute();
    }
    void swap()
    {
    vec3 p=p1; p1=p2; p2=p;
    n=-n;
    }
    void compute()
    {
    n=normalize(cross(p1-p0,p2-p1));
    }
    void draw()
    {
    glBegin(GL_TRIANGLES);
    glNormal3fv(n.dat);
    glVertex3fv(p0.dat);
    glVertex3fv(p1.dat);
    glVertex3fv(p2.dat);
    glEnd();
    }
    };
    //---------------------------------------------------------------------------
    class convex_mesh
    {
    public:
    // cfg
    List<triangle> tri;
    // computed
    vec3 p0; // center

    convex_mesh() { tri.num=0; }
    convex_mesh(convex_mesh& a) { *this=a; }
    ~convex_mesh() {}
    convex_mesh* operator = (const convex_mesh *a) { *this=*a; return this; }
    //convex_mesh* operator = (const convex_mesh &a) { ...copy... return this; }

    void init_box(vec3 _p0,vec3 _u,vec3 _v,vec3 _w) // center, half sizes
    {
    const vec3 p[8]=
    {
    _p0-_u+_v-_w,
    _p0+_u+_v-_w,
    _p0+_u-_v-_w,
    _p0-_u-_v-_w,
    _p0-_u-_v+_w,
    _p0+_u-_v+_w,
    _p0+_u+_v+_w,
    _p0-_u+_v+_w,
    };
    const int ix[36]=
    {
    0,1,2,0,2,3,
    4,5,6,4,6,7,
    3,2,5,3,5,4,
    2,1,6,2,6,5,
    1,0,7,1,7,6,
    0,3,4,0,4,7,
    };
    tri.num=0;
    for (int i=0;i<36;i+=3) tri.add(triangle(p[ix[i+0]],p[ix[i+1]],p[ix[i+2]]));
    compute();
    }
    void compute()
    {
    int i,n;
    p0=vec3(0.0,0.0,0.0);
    if (!tri.num) return;
    for (i=0,n=0;i<tri.num;i++,n+=3)
    {
    p0+=tri.dat[i].p0;
    p0+=tri.dat[i].p1;
    p0+=tri.dat[i].p2;
    } p0/=float(n);
    for (i=0;i<tri.num;i++)
    if (dot(tri.dat[i].p0-p0,tri.dat[i].n)<0.0)
    tri.dat[i].swap();
    }
    void draw()
    {
    int i;
    glBegin(GL_TRIANGLES);
    for (i=0;i<tri.num;i++) tri.dat[i].draw();
    glEnd();
    }
    };
    //---------------------------------------------------------------------------
    class spherical_sector
    {
    public:
    // cfg
    vec3 p0,p1;
    float ang;
    // computed
    vec3 dp;
    float r,R;

    spherical_sector() {}
    spherical_sector(spherical_sector& a) { *this=a; }
    ~spherical_sector() {}
    spherical_sector* operator = (const spherical_sector *a) { *this=*a; return this; }
    //spherical_sector* operator = (const spherical_sector &a) { ...copy... return this; }

    spherical_sector(vec3 _p0,vec3 _p1,float _ang)
    {
    p0=_p0;
    p1=_p1;
    ang=_ang;
    compute();
    }
    void compute()
    {
    dp=p1-p0;
    R=length(dp);
    r=R*tan(ang);
    }
    void draw()
    {
    const int N=32;
    const int M=16;
    vec3 pnt[M][N]; // points
    vec3 n0[N]; // normals for cine
    vec3 n1[M][N]; // normals for cap
    int i,j;
    float a,b,da,db,ca,sa,cb,sb;
    vec3 q,u,v,w;
    // basis vectors
    w=normalize(dp); u=vec3(1.0,0.0,0.0);
    if (fabs(dot(u,w))>0.75) u=vec3(0.0,1.0,0.0);
    v=cross(u,w);
    u=cross(v,w);
    u=normalize(u);
    v=normalize(v);
    // compute tables
    da=2.0*M_PI/float(N-1);
    db=ang/float(M-1);
    for (a=0.0,i=0;i<N;i++,a+=da)
    {
    ca=cos(a);
    sa=sin(a);
    n0[i]=u*ca+v*sa;
    for (b=0.0,j=0;j<M;j++,b+=db)
    {
    cb=cos(b);
    sb=sin(b);
    q=vec3(ca*sb,sa*sb,cb);
    pnt[j][i]=p0+((q.x*u+q.y*v+q.z*w)*R);
    n1[j][i]=normalize(pnt[j][i]);
    }
    }
    // render
    glBegin(GL_TRIANGLES);
    for (i=1,j=M-1;i<N;i++)
    {
    glNormal3fv(n0[i].dat); // p0 should have average 0.5*(n0[i]+n0[i-1]) as nomal
    glVertex3fv(p0.dat);
    glVertex3fv(pnt[j][i+0].dat);
    glNormal3fv(n0[i-1].dat);
    glVertex3fv(pnt[j][i-1].dat);
    glNormal3fv( n1[0][0].dat);
    glVertex3fv(pnt[0][0].dat);
    glNormal3fv( n1[1][i-1].dat);
    glVertex3fv(pnt[1][i-1].dat);
    glNormal3fv( n1[1][i+0].dat);
    glVertex3fv(pnt[1][i+0].dat);
    }
    glEnd();
    glBegin(GL_QUADS);
    for (i=0;i<N;i++)
    for (j=2;j<M;j++)
    {
    glNormal3fv( n1[j-1][i+0].dat);
    glVertex3fv(pnt[j-1][i+0].dat);
    glNormal3fv( n1[j-1][i-1].dat);
    glVertex3fv(pnt[j-1][i-1].dat);
    glNormal3fv( n1[j+0][i-1].dat);
    glVertex3fv(pnt[j+0][i-1].dat);
    glNormal3fv( n1[j+0][i+0].dat);
    glVertex3fv(pnt[j+0][i+0].dat);
    }
    glEnd();
    }
    };
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    bool inside(point p0,triangle t0);
    bool inside(point p0,convex_mesh m0);
    bool inside(point p0,spherical_sector s0);
    //---------------------------------------------------------------------------
    line closest(point p0,axis a0);
    line closest(point p0,line l0);
    line closest(point p0,triangle t0);
    line closest(point p0,convex_mesh m0);
    //---------------------------------------------------------------------------
    line closest(axis a0,point p0);
    line closest(axis a0,axis a1);
    line closest(axis a0,line l1);
    line closest(axis a0,triangle t0);
    line closest(axis a0,convex_mesh m0);
    //---------------------------------------------------------------------------
    line closest(line l0,point p0);
    line closest(line l0,axis a0);
    line closest(line l0,line l1);
    line closest(line l0,triangle t0);
    line closest(line l0,convex_mesh m0);
    //---------------------------------------------------------------------------
    line closest(triangle t0,point p0);
    line closest(triangle t0,axis a0);
    line closest(triangle t0,line l0);
    line closest(triangle t0,triangle t1);
    line closest(triangle t0,convex_mesh m0);
    //---------------------------------------------------------------------------
    line closest(convex_mesh m0,point p0);
    line closest(convex_mesh m0,axis a0);
    line closest(convex_mesh m0,line l0);
    line closest(convex_mesh m0,triangle t0);
    line closest(convex_mesh m0,spherical_sector s0);
    //---------------------------------------------------------------------------
    bool intersect(convex_mesh m0,spherical_sector s0);
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    bool inside(point p0,triangle t0)
    {
    if (fabs(dot(p0.p0-t0.p0,t0.n))>1e-6) return false;
    float d0,d1,d2;
    d0=dot(t0.n,cross(p0.p0-t0.p0,t0.p1-t0.p0));
    d1=dot(t0.n,cross(p0.p0-t0.p1,t0.p2-t0.p1));
    d2=dot(t0.n,cross(p0.p0-t0.p2,t0.p0-t0.p2));
    if (d0*d1<-1e-6) return false;
    if (d0*d2<-1e-6) return false;
    if (d1*d2<-1e-6) return false;
    return true;
    }
    bool inside(point p0,convex_mesh m0)
    {
    for (int i=0;i<m0.tri.num;i++)
    if (dot(p0.p0-m0.tri.dat[i].p0,m0.tri.dat[i].n)>0.0)
    return false;
    return true;
    }
    bool inside(point p0,spherical_sector s0)
    {
    float t,l;
    vec3 u;
    u=p0.p0-s0.p0;
    l=length(u);
    if (l>s0.R) return false;
    t=divide(dot(u,s0.dp),(l*s0.R));
    if (t<cos(s0.ang)) return false;
    return true;
    }
    //---------------------------------------------------------------------------
    line closest(point p0,axis a0){ return line(p0.p0,a0.p0+(a0.dp*dot(p0.p0-a0.p0,a0.dp))); }
    line closest(point p0,line l0)
    {
    float t=dot(p0.p0-l0.p0,l0.dp);
    if (t<0.0) t=0.0;
    if (t>1.0) t=1.0;
    return line(p0.p0,l0.p0+(l0.dp*t));
    }
    line closest(point p0,triangle t0)
    {
    float t;
    point p;
    line cl,ll;
    cl.l=1e300;
    t=dot(p0.p0-t0.p0,t0.n); p=p0.p0-t*t0.n; if ((fabs(t)>1e-6)&&(inside(p,t0))){ ll=line(p0.p0,p.p0); if (cl.l>ll.l) cl=ll; }
    ll=closest(p0,line(t0.p0,t0.p1)); if (cl.l>ll.l) cl=ll;
    ll=closest(p0,line(t0.p1,t0.p2)); if (cl.l>ll.l) cl=ll;
    ll=closest(p0,line(t0.p2,t0.p0)); if (cl.l>ll.l) cl=ll;
    return cl;
    }
    line closest(point p0,convex_mesh m0)
    {
    int i;
    line cl,ll;
    cl=line(vec3(0.0,0.0,0.0),vec3(0.0,0.0,0.0)); cl.l=1e300;
    for (i=0;i<m0.tri.num;i++)
    {
    ll=closest(p0,m0.tri.dat[i]);
    if (cl.l>ll.l) cl=ll;
    }
    return cl;
    }
    //---------------------------------------------------------------------------
    line closest(axis a0,point p0){ line cl; cl=closest(p0,a0); cl.swap(); return cl; }
    line closest(axis a0,axis a1)
    {
    vec3 u=a0.dp;
    vec3 v=a1.dp;
    vec3 w=a0.p0-a1.p0;
    float a=dot(u,u); // always >= 0
    float b=dot(u,v);
    float c=dot(v,v); // always >= 0
    float d=dot(u,w);
    float e=dot(v,w);
    float D=a*c-b*b; // always >= 0
    float t0,t1;
    // compute the line parameters of the two closest points
    if (D<1e-6) // the lines are almost parallel
    {
    t0=0.0;
    t1=(b>c ? d/b : e/c); // use the largest denominator
    }
    else{
    t0=(b*e-c*d)/D;
    t1=(a*e-b*d)/D;
    }
    return line(a0.p0+(a0.dp*t0),a1.p0+(a1.dp*t1));
    }
    line closest(axis a0,line l1)
    {
    vec3 u=a0.dp;
    vec3 v=l1.dp;
    vec3 w=a0.p0-l1.p0;
    float a=dot(u,u); // always >= 0
    float b=dot(u,v);
    float c=dot(v,v); // always >= 0
    float d=dot(u,w);
    float e=dot(v,w);
    float D=a*c-b*b; // always >= 0
    float t0,t1;
    // compute the line parameters of the two closest points
    if (D<1e-6) // the lines are almost parallel
    {
    t0=0.0;
    t1=(b>c ? d/b : e/c); // use the largest denominator
    }
    else{
    t0=(b*e-c*d)/D;
    t1=(a*e-b*d)/D;
    }
    if (t1<0.0) t1=0.0;
    if (t1>1.0) t1=1.0;
    return line(a0.p0+(a0.dp*t0),l1.p0+(l1.dp*t1));
    }
    line closest(axis a0,triangle t0)
    {
    line cl,ll;
    cl=closest(a0,line(t0.p0,t0.p1));
    ll=closest(a0,line(t0.p1,t0.p2)); if (cl.l>ll.l) cl=ll;
    ll=closest(a0,line(t0.p2,t0.p0)); if (cl.l>ll.l) cl=ll;
    return cl;
    }
    line closest(axis a0,convex_mesh m0)
    {
    int i;
    line cl,ll;
    cl=line(vec3(0.0,0.0,0.0),vec3(0.0,0.0,0.0)); cl.l=1e300;
    for (i=0;i<m0.tri.num;i++)
    {
    ll=closest(a0,m0.tri.dat[i]);
    if (cl.l>ll.l) cl=ll;
    }
    return cl;
    }
    //---------------------------------------------------------------------------
    line closest(line l0,point p0){ line cl; cl=closest(p0,l0); cl.swap(); return cl; }
    line closest(line l0,axis a0) { line cl; cl=closest(a0,l0); cl.swap(); return cl; }
    line closest(line l0,line l1)
    {
    vec3 u=l0.p1-l0.p0;
    vec3 v=l1.p1-l1.p0;
    vec3 w=l0.p0-l1.p0;
    float a=dot(u,u); // always >= 0
    float b=dot(u,v);
    float c=dot(v,v); // always >= 0
    float d=dot(u,w);
    float e=dot(v,w);
    float D=a*c-b*b; // always >= 0
    float t0,t1;
    // compute the line parameters of the two closest points
    if (D<1e-6) // the lines are almost parallel
    {
    t0=0.0;
    t1=(b>c ? d/b : e/c); // use the largest denominator
    }
    else{
    t0=(b*e-c*d)/D;
    t1=(a*e-b*d)/D;
    }
    if (t0<0.0) t0=0.0;
    if (t0>1.0) t0=1.0;
    if (t1<0.0) t1=0.0;
    if (t1>1.0) t1=1.0;
    return line(l0.p0+(l0.dp*t0),l1.p0+(l1.dp*t1));
    }
    line closest(line l0,triangle t0)
    {
    float t;
    point p;
    line cl,ll;
    cl.l=1e300;
    t=dot(l0.p0-t0.p0,t0.n); p=l0.p0-t*t0.n; if ((fabs(t)>1e-6)&&(inside(p,t0))){ ll=line(l0.p0,p.p0); if (cl.l>ll.l) cl=ll; }
    t=dot(l0.p1-t0.p0,t0.n); p=l0.p1-t*t0.n; if ((fabs(t)>1e-6)&&(inside(p,t0))){ ll=line(l0.p1,p.p0); if (cl.l>ll.l) cl=ll; }
    ll=closest(l0,line(t0.p0,t0.p1)); if (cl.l>ll.l) cl=ll;
    ll=closest(l0,line(t0.p1,t0.p2)); if (cl.l>ll.l) cl=ll;
    ll=closest(l0,line(t0.p2,t0.p0)); if (cl.l>ll.l) cl=ll;
    return cl;
    }
    line closest(line l0,convex_mesh m0)
    {
    int i;
    line cl,ll;
    cl=line(vec3(0.0,0.0,0.0),vec3(0.0,0.0,0.0)); cl.l=1e300;
    for (i=0;i<m0.tri.num;i++)
    {
    ll=closest(l0,m0.tri.dat[i]);
    if (cl.l>ll.l) cl=ll;
    }
    return cl;
    }
    //---------------------------------------------------------------------------
    line closest(triangle t0,point p0){ line cl; cl=closest(p0,t0); cl.swap(); return cl; }
    line closest(triangle t0,axis a0) { line cl; cl=closest(a0,t0); cl.swap(); return cl; }
    line closest(triangle t0,line l0) { line cl; cl=closest(l0,t0); cl.swap(); return cl; }
    line closest(triangle t0,triangle t1)
    {
    float t;
    point p;
    line l0,l1,l2,l3,l4,l5,cl,ll;
    l0=line(t0.p0,t0.p1); l3=line(t1.p0,t1.p1);
    l1=line(t0.p1,t0.p2); l4=line(t1.p1,t1.p2);
    l2=line(t0.p2,t0.p0); l5=line(t1.p2,t1.p0);
    cl.l=1e300;
    t=dot(t0.p0-t1.p0,t1.n); p=t0.p0-t*t1.n; if ((fabs(t)>1e-6)&&(inside(p,t1))){ ll=line(t0.p0,p.p0); if (cl.l>ll.l) cl=ll; }
    t=dot(t0.p1-t1.p0,t1.n); p=t0.p1-t*t1.n; if ((fabs(t)>1e-6)&&(inside(p,t1))){ ll=line(t0.p1,p.p0); if (cl.l>ll.l) cl=ll; }
    t=dot(t0.p2-t1.p0,t1.n); p=t0.p2-t*t1.n; if ((fabs(t)>1e-6)&&(inside(p,t1))){ ll=line(t0.p2,p.p0); if (cl.l>ll.l) cl=ll; }
    t=dot(t1.p0-t0.p0,t0.n); p=t1.p0-t*t0.n; if ((fabs(t)>1e-6)&&(inside(p,t0))){ ll=line(p.p0,t1.p0); if (cl.l>ll.l) cl=ll; }
    t=dot(t1.p1-t0.p0,t0.n); p=t1.p1-t*t0.n; if ((fabs(t)>1e-6)&&(inside(p,t0))){ ll=line(p.p0,t1.p1); if (cl.l>ll.l) cl=ll; }
    t=dot(t1.p2-t0.p0,t0.n); p=t1.p2-t*t0.n; if ((fabs(t)>1e-6)&&(inside(p,t0))){ ll=line(p.p0,t1.p2); if (cl.l>ll.l) cl=ll; }
    ll=closest(l0,l3); if (cl.l>ll.l) cl=ll;
    ll=closest(l0,l4); if (cl.l>ll.l) cl=ll;
    ll=closest(l0,l5); if (cl.l>ll.l) cl=ll;
    ll=closest(l1,l3); if (cl.l>ll.l) cl=ll;
    ll=closest(l1,l4); if (cl.l>ll.l) cl=ll;
    ll=closest(l1,l5); if (cl.l>ll.l) cl=ll;
    ll=closest(l2,l3); if (cl.l>ll.l) cl=ll;
    ll=closest(l2,l4); if (cl.l>ll.l) cl=ll;
    ll=closest(l2,l5); if (cl.l>ll.l) cl=ll;
    return cl;
    }
    line closest(triangle t0,convex_mesh m0)
    {
    int i;
    line cl,ll;
    cl=line(vec3(0.0,0.0,0.0),vec3(0.0,0.0,0.0)); cl.l=1e300;
    for (i=0;i<m0.tri.num;i++)
    {
    ll=closest(m0.tri.dat[i],t0);
    if (cl.l>ll.l) cl=ll;
    }
    return cl;
    }
    //---------------------------------------------------------------------------
    line closest(convex_mesh m0,point p0) { line cl; cl=closest(p0,m0); cl.swap(); return cl; }
    line closest(convex_mesh m0,axis a0) { line cl; cl=closest(a0,m0); cl.swap(); return cl; }
    line closest(convex_mesh m0,line l0) { line cl; cl=closest(l0,m0); cl.swap(); return cl; }
    line closest(convex_mesh m0,triangle t0){ line cl; cl=closest(t0,m0); cl.swap(); return cl; }
    line closest(convex_mesh m0,convex_mesh m1)
    {
    int i0,i1;
    line cl,ll;
    cl=line(vec3(0.0,0.0,0.0),vec3(0.0,0.0,0.0)); cl.l=1e300;
    for (i0=0;i0<m0.tri.num;i0++)
    for (i1=0;i1<m1.tri.num;i1++)
    {
    ll=closest(m0.tri.dat[i0],m1.tri.dat[i1]);
    if (cl.l>ll.l) cl=ll;
    }
    return cl;
    }
    line closest(convex_mesh m0,spherical_sector s0)
    {
    int i,N=18;
    float a,da,ca,sa,cb,sb;
    vec3 u,v,w,q;
    line cl,ll;
    // cap
    ll=closest(m0,point(s0.p0)); // sphere
    if (dot(ll.dp,s0.dp)/(ll.l*s0.R)>=cos(s0.ang)) // cap
    ll=line(ll.p0,ll.p1+(ll.dp*s0.R/ll.l));
    cl=ll;
    // cone
    w=normalize(s0.dp); u=vec3(1.0,0.0,0.0);
    if (fabs(dot(u,w))>0.75) u=vec3(0.0,1.0,0.0);
    v=cross(u,w);
    u=cross(v,w);
    u=normalize(u)*s0.r;
    v=normalize(v)*s0.r;
    da=2.0*M_PI/float(N-1);
    cb=cos(s0.ang);
    sb=sin(s0.ang);
    for (a=0.0,i=0;i<N;i++)
    {
    ca=cos(a);
    sa=sin(a);
    q=vec3(ca*sb,sa*sb,cb);
    q=s0.p0+((q.x*u+q.y*v+q.z*w)*s0.R);
    ll=line(s0.p0,q);
    ll=closest(m0,ll);
    if (cl.l>ll.l) cl=ll;
    }
    return cl;
    }
    //---------------------------------------------------------------------------
    bool intersect(convex_mesh m0,spherical_sector s0)
    {
    line cl;
    cl=closest(m0,s0);
    if (cl.l<=1e-6) return true;
    if (inside(cl.p0,s0)) return true;
    return false;
    }
    //---------------------------------------------------------------------------
    #endif
    //---------------------------------------------------------------------------
    GLSL 数学可以由 this 创建或使用 GLM 或其他任何东西。
    我还使用了我的动态列表模板(只是将三角形列表存储在网格中),所以: List<double> xxx;double xxx[]; 相同 xxx.add(5);添加 5到列表末尾 xxx[7]访问数组元素(安全) xxx.dat[7]访问数组元素(不安全但快速的直接访问) xxx.num是数组的实际使用大小 xxx.reset()清除数组并设置 xxx.num=0 xxx.allocate(100)100 预分配空间项目
    您可以使用您可以使用的任何列表。
    在这里测试预览测试这个的正确性:
    preview
    锥体根据相交测试的结果旋转并改变颜色。黄线是最近的线结果。
    我在这个周末为了好玩而破坏了它,所以它还没有经过广泛的测试,并且可能仍然存在未处理的边缘情况。
    我希望代码尽可能可读,所以它根本没有优化。我也没有过多评论(因为低级原语和基本向量数学应该足够明显,如果不是你应该在实现这样的东西之前先学习)
    [编辑1]
    看来我搞砸了 closest测试忽略一些边缘情况..它需要重大返工(对所有相关功能应用修复)我现在没有足够的时间(一旦完成将更新代码)所以现在这里快速修复线与线仅最接近的测试:
    line3D closest(line3D l0,line3D l1)
    {
    vec3 u=l0.p1-l0.p0;
    vec3 v=l1.p1-l1.p0;
    vec3 w=l0.p0-l1.p0;
    float a=dot(u,u); // always >= 0
    float b=dot(u,v);
    float c=dot(v,v); // always >= 0
    float d=dot(u,w);
    float e=dot(v,w);
    float D=a*c-b*b; // always >= 0
    float t0,t1;
    point3D p;
    line3D r,rr;
    int f; // check distance perpendicular to: 1: l0, 2: l1
    f=0; r.l=-1.0;
    // compute the line3D parameters of the two closest points
    if (D<acc_dot) f=3; // the lines are almost parallel
    else{
    t0=(b*e-c*d)/D;
    t1=(a*e-b*d)/D;
    if (t0<0.0){ f|=1; t0=0.0; }
    if (t0>1.0){ f|=1; t0=1.0; }
    if (t1<0.0){ f|=2; t1=0.0; }
    if (t1>1.0){ f|=2; t1=1.0; }
    r=line3D(l0.p0+(l0.dp*t0),l1.p0+(l1.dp*t1));
    }
    // check perpendicular distance from each endpoint marked in f
    if (int(f&1))
    {
    t0=0.0;
    t1=divide(dot(l0.p0-l1.p0,l1.dp),l1.l*l1.l);
    if (t1<0.0) t1=0.0;
    if (t1>1.0) t1=1.0;
    rr=line3D(l0.p0+(l0.dp*t0),l1.p0+(l1.dp*t1));
    if ((r.l<0.0)||(r.l>rr.l)) r=rr;
    t0=1.0;
    t1=divide(dot(l0.p1-l1.p0,l1.dp),l1.l*l1.l);
    if (t1<0.0) t1=0.0;
    if (t1>1.0) t1=1.0;
    rr=line3D(l0.p0+(l0.dp*t0),l1.p0+(l1.dp*t1));
    if ((r.l<0.0)||(r.l>rr.l)) r=rr;
    }
    if (int(f&2))
    {
    t1=0.0;
    t0=divide(dot(l1.p0-l0.p0,l0.dp),l0.l*l0.l);
    if (t0<0.0) t0=0.0;
    if (t0>1.0) t0=1.0;
    rr=line3D(l0.p0+(l0.dp*t0),l1.p0+(l1.dp*t1));
    if ((r.l<0.0)||(r.l>rr.l)) r=rr;
    t1=1.0;
    t0=divide(dot(l1.p1-l0.p0,l0.dp),l0.l*l0.l);
    if (t0<0.0) t0=0.0;
    if (t0>1.0) t0=1.0;
    rr=line3D(l0.p0+(l0.dp*t0),l1.p0+(l1.dp*t1));
    if ((r.l<0.0)||(r.l>rr.l)) r=rr;
    }
    return r;
    }

    关于math - 锥盒碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62145967/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com