<bdo id='FDeVp'></bdo><ul id='FDeVp'></ul>

      <small id='FDeVp'></small><noframes id='FDeVp'>

      <legend id='FDeVp'><style id='FDeVp'><dir id='FDeVp'><q id='FDeVp'></q></dir></style></legend>
    1. <tfoot id='FDeVp'></tfoot>

    2. <i id='FDeVp'><tr id='FDeVp'><dt id='FDeVp'><q id='FDeVp'><span id='FDeVp'><b id='FDeVp'><form id='FDeVp'><ins id='FDeVp'></ins><ul id='FDeVp'></ul><sub id='FDeVp'></sub></form><legend id='FDeVp'></legend><bdo id='FDeVp'><pre id='FDeVp'><center id='FDeVp'></center></pre></bdo></b><th id='FDeVp'></th></span></q></dt></tr></i><div id='FDeVp'><tfoot id='FDeVp'></tfoot><dl id='FDeVp'><fieldset id='FDeVp'></fieldset></dl></div>
    3. C# 中的高效 AABB/三角形相交

      时间:2023-07-25
            <bdo id='A3OCU'></bdo><ul id='A3OCU'></ul>

            <small id='A3OCU'></small><noframes id='A3OCU'>

            1. <i id='A3OCU'><tr id='A3OCU'><dt id='A3OCU'><q id='A3OCU'><span id='A3OCU'><b id='A3OCU'><form id='A3OCU'><ins id='A3OCU'></ins><ul id='A3OCU'></ul><sub id='A3OCU'></sub></form><legend id='A3OCU'></legend><bdo id='A3OCU'><pre id='A3OCU'><center id='A3OCU'></center></pre></bdo></b><th id='A3OCU'></th></span></q></dt></tr></i><div id='A3OCU'><tfoot id='A3OCU'></tfoot><dl id='A3OCU'><fieldset id='A3OCU'></fieldset></dl></div>
              <legend id='A3OCU'><style id='A3OCU'><dir id='A3OCU'><q id='A3OCU'></q></dir></style></legend>
                <tbody id='A3OCU'></tbody>
            2. <tfoot id='A3OCU'></tfoot>

              • 本文介绍了C# 中的高效 AABB/三角形相交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

                任何人都可以向 CSharp 推荐任何公共 AABB/三角形相交算法的有效端口.

                Can anyone recommend an efficient port to CSharp of any of the public AABB/triangle intersection algorithms.

                我一直在研究 Moller 的方法,抽象地描述了 这里,如果我要移植它,我可能会从 这个 C++ 版本.这个由 Mike Vandelay 编写的 C++ 库 似乎这也是一个很好的起点.

                I've been looking at Moller's approach, described abstractly here, and if I were to port it, I would probably start from this C++ version. This C++ library by Mike Vandelay seems like it could also be a great starting point.

                ...或...任何其他轮子",可以采用 Vector3 的三角形并告诉我它是否与 AABB 相交),相对有效.

                ...or... any other "wheel" that can take a triangle of Vector3's and tell me if it intersects with an AABB), relatively efficiently.

                似乎有各种各样的算法,但大多数似乎都是用 c++ 编写的,或者只是在白皮书中抽象地描述了,我需要为我们的应用程序提供一个特定于 c# 的实现.效率不是关键,但 c# 是.(虽然效率当然也很不错;p)

                There seem to be a variety of algorithms, but most seem to be written in c++, or just described abstractly in white papers and I need a c# specific implementation for our application. Efficiency is not key, but c# is. (though efficiency is obviously nice too of course ;p )

                任何 C# 选项,在我涉足数学"端口之前 ;) 将不胜感激!谢谢.

                Any C# options, before I wade through a "math" port ;) would be greatly appreciated! Thanks.

                推荐答案

                对于任意两个凸网格,要判断它们是否相交,需要检查是否存在分离平面.如果是这样,它们就不会相交.可以从任意形状的任何面或边缘叉积中拾取平面.

                For any two convex meshes, to find whether they intersect, you need to check if there exist a separating plane. If it does, they do not intersect. The plane can be picked from any face of either shape, or the edge cross-products.

                平面被定义为法线和从 Origo 的偏移.因此,您只需检查 AABB 的三个面和三角形的一个面.

                The plane is defined as a normal and an offset from Origo. So, you only have to check three faces of the AABB, and one face of the triangle.

                bool IsIntersecting(IAABox box, ITriangle triangle)
                {
                    double triangleMin, triangleMax;
                    double boxMin, boxMax;
                
                    // Test the box normals (x-, y- and z-axes)
                    var boxNormals = new IVector[] {
                        new Vector(1,0,0),
                        new Vector(0,1,0),
                        new Vector(0,0,1)
                    };
                    for (int i = 0; i < 3; i++)
                    {
                        IVector n = boxNormals[i];
                        Project(triangle.Vertices, boxNormals[i], out triangleMin, out triangleMax);
                        if (triangleMax < box.Start.Coords[i] || triangleMin > box.End.Coords[i])
                            return false; // No intersection possible.
                    }
                
                    // Test the triangle normal
                    double triangleOffset = triangle.Normal.Dot(triangle.A);
                    Project(box.Vertices, triangle.Normal, out boxMin, out boxMax);
                    if (boxMax < triangleOffset || boxMin > triangleOffset)
                        return false; // No intersection possible.
                
                    // Test the nine edge cross-products
                    IVector[] triangleEdges = new IVector[] {
                        triangle.A.Minus(triangle.B),
                        triangle.B.Minus(triangle.C),
                        triangle.C.Minus(triangle.A)
                    };
                    for (int i = 0; i < 3; i++)
                    for (int j = 0; j < 3; j++)
                    {
                        // The box normals are the same as it's edge tangents
                        IVector axis = triangleEdges[i].Cross(boxNormals[j]);
                        Project(box.Vertices, axis, out boxMin, out boxMax);
                        Project(triangle.Vertices, axis, out triangleMin, out triangleMax);
                        if (boxMax <= triangleMin || boxMin >= triangleMax)
                            return false; // No intersection possible
                    }
                
                    // No separating axis found.
                    return true;
                }
                
                void Project(IEnumerable<IVector> points, IVector axis,
                        out double min, out double max)
                {
                    double min = double.PositiveInfinity;
                    double max = double.NegativeInfinity;
                    foreach (var p in points)
                    {
                        double val = axis.Dot(p);
                        if (val < min) min = val;
                        if (val > max) max = val;
                    }
                }
                
                interface IVector
                {
                    double X { get; }
                    double Y { get; }
                    double Z { get; }
                    double[] Coords { get; }
                    double Dot(IVector other);
                    IVector Minus(IVector other);
                    IVector Cross(IVector other);
                }
                
                interface IShape
                {
                    IEnumerable<IVector> Vertices { get; }
                }
                
                interface IAABox : IShape
                {
                    IVector Start { get; }
                    IVector End { get; }
                }
                
                interface ITriangle : IShape {
                    IVector Normal { get; }
                    IVector A { get; }
                    IVector B { get; }
                    IVector C { get; }
                }
                

                <小时>

                一个很好的例子是方框 (±10, ±10, ±10) 和三角形 (12,9,9),(9,12,9),(19,19,20).没有一个面可以用作分离平面,但它们不相交.分离轴为<1,1,0>,由<1,0,0>和<-3,3,0>的叉积得到.


                A good example is the box (±10, ±10, ±10) and the triangle (12,9,9),(9,12,9),(19,19,20). None of the faces can be used as a separating plane, yet they do not intersect. The separating axis is <1,1,0>, which is obtained from the cross product between <1,0,0> and <-3,3,0>.

                这篇关于C# 中的高效 AABB/三角形相交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                上一篇:查找圆边上的坐标 下一篇:数学问题:根据外角半径/厚度确定内边界的角半径

                相关文章

                  <bdo id='6HhzX'></bdo><ul id='6HhzX'></ul>
                1. <i id='6HhzX'><tr id='6HhzX'><dt id='6HhzX'><q id='6HhzX'><span id='6HhzX'><b id='6HhzX'><form id='6HhzX'><ins id='6HhzX'></ins><ul id='6HhzX'></ul><sub id='6HhzX'></sub></form><legend id='6HhzX'></legend><bdo id='6HhzX'><pre id='6HhzX'><center id='6HhzX'></center></pre></bdo></b><th id='6HhzX'></th></span></q></dt></tr></i><div id='6HhzX'><tfoot id='6HhzX'></tfoot><dl id='6HhzX'><fieldset id='6HhzX'></fieldset></dl></div>

                  <small id='6HhzX'></small><noframes id='6HhzX'>

                  <legend id='6HhzX'><style id='6HhzX'><dir id='6HhzX'><q id='6HhzX'></q></dir></style></legend>
                2. <tfoot id='6HhzX'></tfoot>