代码之家  ›  专栏  ›  技术社区  ›  gnp

通过与多个三维平面相交获得最小二乘调整后的单线

  •  0
  • gnp  · 技术社区  · 11 年前

    我正在处理许多3D平面,并为以下情况寻找最小二乘法解决方案。

    如果我有许多3D平面,只知道一个点 法向量(例如O1和N1),并且所有这些平面彼此相交 其他,并制作几乎非常接近的三维线,然后如何计算 最小二乘法调整了一条三维线来表示所有这些 十字路口。

    为了弄清楚,我插入了一个数字。

    • 已知:一个点和每个平面的法向量。
    • 查找:最小二乘拟合单线3d

    enter image description here

    由于我想用c++来做这件事,所以我也使用了c++标记。

    1 回复  |  直到 4 年前
        1
  •  1
  •   Tocs    11 年前

    完全未经测试。

    如果你从十字路口沿着线路的方向走 Principle Component

    这样可以得到它们的方向。然后使用该方向和任意点创建一个平面,将平面相交计算中的所有点投影到平面上,并找到这些投影点的平均点。

    使用这个平均点和主分量来定义你的线。

    有点像。。。

    class Plane
    {
    public:
        Vector3 Point;
        Vector3 Normal;
    
        Line Intersect (const Plane &other);
    
        Vector3 Project (const Vector3 &point);
    }
    
    class Line
    {
    public:
        Vector3 Point;
        Vector3 Direction;
    
        Line (Vector3 point, Vector3 dir);
    
    };
    
    Vector3 PrincipleComponent (const std::vector<Line> &lines)
    {
        //You could use the covariance matrix to get this but I will try the interative method on wikipedia.
        Vector3 p(1,2,3); //a random vector?
        static const int c = 10;
        for (int i = 0; i < c; ++i)
        {
            Vector3 t;
            for (auto i = lines.begin(); i != lines.end (); ++i)
            {
                t = t + ((*i).Direction.Dot (p)) * (*i).Direction;
            }
            t.Normalize();
            p = t;
        }
        return p;
    }
    
    int main ()
    {
        std::vector<Line> LinesFromPlaneIntersections;
    
    
        Vector3 direction = PrincipleComponent (LinesFromPlaneIntersections);
        Plane projplane;
        projplane.Normal = direction;
        projplane.Point = LinesFromPlaneIntersections[0].Point;
    
        Vector3 meanpoint;
        for (auto i = LinesFromPlaneIntersections.begin(); i != LinesFromPlaneIntersections.end (); ++i)
        {
            meanpoint += projplane.Project ((*i).Point);
        }
    
        meanpoint /= LinesFromPlaneIntersections.size ();
    
        Line result (meanpoint,direction);
    }