【问题标题】:Sphere-Sphere intersection c#, 3D coordinates of collision pointsSphere-Sphere相交c#,碰撞点的3D坐标
【发布时间】:2013-11-11 22:05:18
【问题描述】:

我查看了许多 3D 球体-球体相交问题,不幸的是,它们要么超出我的理解能力,要么不适合我正在寻找的内容。

这是在 Unity 游戏引擎中并使用 c#

我已经设法让这段代码工作了:

public void calculatePoints_H(Vector3 c1p, Vector3 c2p, float c1r, float c2r, out Vector3 startLine, out Vector3 endLine)
{
    //c1p = circle one position
    //c1r = circle one radius

    Vector3 P0 = c1p;
    Vector3 P1 = c2p;

    float d,a,h;


    d = Vector3.Distance(P0,P1);

    a = (c1r*c1r - c2r*c2r + d*d)/(2*d);

    h = Mathf.Sqrt(c1r*c1r - a*a);


    Vector3 P2 = (P1 - P0);
            P2 = (P2 * (a/d));
            P2 = (P2 + P0);

    float x3,y3,x4,y4 = 0;

    x3 = P2.x + h*(P1.y - P0.y)/d;
    y3 = P2.y - h*(P1.x - P0.x)/d;

    x4 = P2.x - h*(P1.y - P0.y)/d;
    y4 = P2.y + h*(P1.x - P0.x)/d;;

    //draw visual to screen (unity 3D engine)
    Debug.DrawLine(new Vector3(x3,0,y3), new Vector3(x4,0,y4),Color.green);

    //out parameters for a line renderer
    startLine = new Vector3(x3,0,y3);
    endLine = new Vector3(x4,0,y4);


}

目前这段代码允许我计算两个球体相交的 x 轴和 z 轴上的两个点,然后画一条线。

我想要实现的是一个 xyz 交点,因此我还可以在方法中添加高度(y 向量 3 值),这样我就可以让一个球体从任何方向/高度与另一个球体相交

有人可以帮我理解如何解决这个问题吗,我的大脑有点炸了,我担心我缺少一个简单的解决方案?

【问题讨论】:

    标签: unity3d geometry coordinates collision-detection intersection


    【解决方案1】:

    球体很好,因为您知道交点(如果它们相接触)是沿矢量 ABSphereA 中心到 SphereB 的一段距离> 中心。该距离是球体半径的函数:

    float dA = SphereA.radius / AB.magnitude // % distance along AB starting from SphereA
    

    从那里您可以计算出您的交点沿 AB 的距离:

    Vector3 p = SphereA.position + AB * dA; // eq: p`= p + direction * time
    

    示例(使用 Unity 的内置球体预制件):

    bool Intersect(out Vector3 ip, float threshold=0.1f){
        // vector from sphere 1 -> sphere 2
        Vector3 ab = Sphere2.transform.position - Sphere1.transform.position;
    
        // Calculate radius from Unity built-in sphere.
        // Unity spheres are unit spheres (diameter = 1)
        // So diameter = scale, thus radius = scale / 2.0f.
        // **Presumes uniform scaling.
        float r1 = Sphere1.transform.localScale.x / 2.0f;
        float r2 = Sphere2.transform.localScale.x / 2.0f;
    
        // When spheres are too close or too far apart, ignore intersection.
        float diff = Mathf.Abs(r2 + r1 - ab.magnitude);
        if( diff >= threshold) {
            ip = Vector3.zero;
            return false;
        }
        // Intersection is the distance along the vector between
        // the 2 spheres as a function of the sphere's radius.
        ip = Sphere1.transform.position + ab * r1/ab.magnitude;
        return true;
    }
    

    示例用法:

    void FixedUpdate(){
        Vector3 p; //will hold intersection point if one is found
        if(Intersect(out p,0.1f)){
            IntersectionPoint.transform.position = p;
            IntersectionPoint.renderer.enabled = true;
        } else {
            IntersectionPoint.renderer.enabled = false;
        }
    }
    

    这只会返回一个交点。多个交点(例如球体重叠时)是需要解决的不同问题。

    【讨论】:

    • 谢谢你。修改示例以使其利用三角剖分和 3 个球体的交点会有多大问题?
    • @Sean "...利用三角测量" 你的意思是网格碰撞上的网格吗?至于 3 个领域,它可以适应,但并非微不足道。我会尝试找到一个旧的 sn-p 就足够了。
    • 现在我有一些代码可以在两个或三个球体相互交叉时显示。但是,这只发生在 X 和 Z 平面中。我真正想要的,以及你让我用​​一个球体做的事情,也是锻炼每个球体彼此相交的高度。
    猜你喜欢
    • 1970-01-01
    • 2011-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多