matrix-multiplication - 双重轮廓和二次误差函数

标签 matrix-multiplication least-squares quadratic marching-cubes

我已经在 C# 中实现了行进立方体、双行进立方体和自适应行进立方体,结果发现我需要双重轮廓来实现我的目的。
我已经阅读了所有关于双等高线的作品,除了双等高线本身的核心之外,我获得了所有内容:最小化二次误差函数 (QEF)。

现在,我只是通过找到共享该单个顶点(3 到 6 个边)的所有边点之间的平均值来计算内部体素的顶点位置,并且效果很好,但显然它没有在正确的位置创建内部顶点。

这是我正在尝试创建的一段代码。任何帮助将不胜感激

/// <summary>
    /// ORIGINAL WORK: Dual Contouring of Hermite Data by Tao Ju (remember me of a MechCommander 2 character)
    /// 2.3 Representing and minimizing QEFs
    /// The function E[x] can be expressed as the inner
    /// product (Ax-b)T (Ax-b) where A is a matrix whose rows are the
    /// normals ni and b is a vector whose entries are ni*pi.  <------------ (dot product?)>
    /// Typically, the quadratic function E[x] is expanded into the form
    /// E[x] = xT AT Ax - 2xT AT b + bT b (2)
    /// where the matrix AT A is a symmetric 3x3 matrix, AT b is a column
    /// vector of length three and bT b is a scalar. The advantage of this expansion
    /// is that only the matrices AT A, AT b and bT b need be stored
    /// (10 floats), as opposed to storing the matrices A and b. Furthermore,
    /// a minimizing value ˆ x for E[x] can be computed by solving
    /// the normal equations AT Aˆ x = AT b.
    /// </summary>
    public Vector3 GetMinimumError(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 n0, Vector3 n1, Vector3 n2)
    {
        //so, here we are. I'm creating a vector to store the final value.
        Vector3 position = Vector3.Zero;

        //Values of b are supposed to b (:P) three floats. The only way i know to find a float value
        //by multiplying 2 vectors is to use dot product.
        Vector3 b = new Vector3(
               Vector3.Dot(p0, n0),
               Vector3.Dot(p1, n1),
               Vector3.Dot(p2, n2));

        //What the transpose of a vector is supposed to be?
        //I don't know, but i think should be the vector itself :)
        float bTb = Vector3.Dot(b, b); 

        //i create a square matrix 3x3, so i can use c# matrix transformation libraries.
        //i know i will probably have to build bigger matrix later on, but it should fit for now
        Matrix A = new Matrix(
            n0.X, n0.Y, n0.Z, 0,
            n1.X, n1.Y, n1.Z, 0,
            n2.X, n2.Y, n2.Z, 0,
            0, 0, 0, 0);

        //easy
        Matrix AT = Matrix.Transpose(A);

        //EASY
        Matrix ATA = Matrix.Multiply(AT, A);

        //Another intuition. Hope makes sense...
        Vector3 ATb = Vector3.Transform(b, AT);

        //...
        // some cool stuff about solving
        // the normal equations AT Aˆ x = AT b
        //...

        return position; //profit!
    }

最佳答案

QEF 比较难理解。希望我能帮上忙。双轮廓法计算每个交叉点处的“Hermite”数据,或者换句话说,在体素边缘上创建的每个点处,表面的法线是已知的。用一个点和一个法线可以计算平面的方程。

QEF 是从体素的内部点到与体素相关联的每个平面的距离的平方和。下面是一些用于计算 QEF 的伪代码。

double get_QEF(Point3d point, Voxel3d voxel) 
{ 
    double QEF = 0.0; 
    foreach(plane in voxel.planes) 
    { 
        double dist_to_plane = plane.distance(point); 
        QEF += dist_to_plane*dist_to_plane; 
    } 
    return(QEF); 
}

然后目标是在体素内选择最小化 QEF 的点。文献建议使用 Grahm-Schmidt 过程来定位最佳点,但这可能很复杂,也可能导致点位于体素之外。

另一种选择(hack-ish)是在体素内创建一个点网格并计算每个点的 QEF 并选择最低的点,网格越细越接近最佳点,但时间越长计算。

关于matrix-multiplication - 双重轮廓和二次误差函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16734792/

相关文章:

c++ - 为什么我使用 STL sort() 获得二次时间排序?

java - 当 A > 1 时,二次公式失败?

numpy - 点积之和

python - Pytorch 广播两个张量的乘积

multithreading - 使用 MKL BLAS 时,scipy 是否支持稀疏矩阵乘法的多线程?

c++ - 拟合反抛物线。无法达到最小二乘解析表达式

matlab - MATLAB 中阈值内的最小二乘最小化

c++ - 图像曲线拟合的多项式最小二乘法

python - 为什么 Python 中不使用 double ?

r - 在ggplot中拟合二次曲线