微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

NURBS 曲线点评估中的奇点

如何解决NURBS 曲线点评估中的奇点

为了了解 NURBS 曲线的工作原理,我决定在 C# 中实现一个 NURBS 类。根据几个不同的在线资源,我创建了一个基本类。我已经测试并验证了它的大部分功能。然而,在评估曲线上的点时,我发现自己陷入了在 NURBS 基函数中出现奇点的情况。我已经按照下面的算法实现了基函数

enter image description here

我在 C# 中实现了这个函数

    // i is the knot index,filled by iterating over control points which are less than the number of knots
    // p is the degree
    // x is the position to evaluate at
    private double N (int i,int p,double x) {
        double ti0 = knotVector[i];     //u_{i}
        double ti1 = knotVector[i+1];   //u_{i+1}

        double tip = knotVector[i+p];   // u_{i+p}
        double tip1 = knotVector[i+p+1];// u_{i+p+1}

        if (p == 0) {
            if (ti0 <= x && x < ti1) {
                return 1;
            } else {
                return 0;
            }
        }

        double fi0 = (x - ti0) / (tip - ti0);
        double gi1 = (tip1 - x) / (tip1 - ti1);

        return fi0 * N(i,p-1,x) 
             + gi1 * N(i+1,x);
    }

在下面的属性中使用此基函数来评估点在 3d 空间中的坐标。

public Vec3 this[double t] {
        get {
            double x = 0,y = 0,z = 0;
            double rationalWeight = 0;
            double[] ns = new double[this.ControlPoints.Length];

            for (int i = 0; i < this.ControlPoints.Length; i++) {
                double n = N(i,this.Degree,t);
                ns[i] = n;
                double temp = n * this.ControlPoints[i].Weight;
                rationalWeight += temp;
            }

            for (int i = 0; i < this.ControlPoints.Length; i++) {
                double temp = ns[i];
                x += this.ControlPoints[i].X * this.ControlPoints[i].Weight * temp / rationalWeight;
                y += this.ControlPoints[i].Y * this.ControlPoints[i].Weight * temp / rationalWeight;
                z += this.ControlPoints[i].Z * this.ControlPoints[i].Weight * temp / rationalWeight;
            }
            return new Vec3(x,y,z);
        }
    }

例如,对于这个 curve

  • 3 级
  • 点 [(-4,-4,0),(-2,4,(2,(4,0)]
  • 权重 [1,1,1]
  • 结 [0,1]

我最终得到了一个案例,例如在 x = 0.5 处,其中 (tip - ti0)(tip1 - ti1) 为 0,导致除以 0 和 NaN 问题。我没有获得正确的值(如之前从曲线链接中验证的那样),而是从函数中获得“非数字”。从我目前的阅读来看,我没有发现任何可以描述处理奇点的东西。这向我表明我在我的实施中遗漏了一些东西,或者误解了它的某些部分是如何工作的。

有没有人知道我在这个基函数的实现上哪里出了问题?

解决方法

问题是你没有理解插值函数背后的数学原理。假设您有坐标为 x 和 y 的二维点。那么N就是一个将参数u映射到点(x,y)的函数。

但是您所做的是将 N 解释为将 x 映射到 y 的函数,这是不正确的。 u 不是 x 坐标,它只是一个参数。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。