【问题标题】:Cubic bezier curve arc length is always zero三次贝塞尔曲线弧长始终为零
【发布时间】:2019-07-27 03:17:36
【问题描述】:

我编写了以下代码来计算三次贝塞尔曲线的长度。我从Calculate the arclength, curve length of a cubic bezier curve. Why is not working? 得到了这个想法。问题是它总是产生零长度。

public Vector2 SegmentAtPoint(int segmentIndex, float t)
{
    t = Mathf.Clamp01(t);
    float oneMinusT = 1f - t;

    return
        oneMinusT * oneMinusT * oneMinusT * points[segmentIndex * 3] + 
        3f * oneMinusT * oneMinusT * t * points[segmentIndex * 3 + 1] +
        3f * oneMinusT * t * t * points[segmentIndex * 3 + 2] +
        t * t * t * points[segmentIndex * 3 + 3];

}

public float SegmentLength(int segmentIndex)    {
    var steps = 10;
    var t = 1 / steps;
    var sumArc = 0.0f;
    var j = 0.0f;
    var a = new Vector2(0.0f, 0.0f);
    var b = points[segmentIndex * 3];

    var dX = 0.0f;
    var dY = 0.0f;
    var dS = 0.0f;

    for (int i = 0; i < steps; j = j + t)
    {
        a = SegmentAtPoint(segmentIndex, j);

        dX = a.x - b.x;
        dY = a.y - b.y;
        dS = Mathf.Sqrt((dX * dX) + (dY * dY));

        sumArc = sumArc + dS;
        b.x = a.x;
        b.y = a.y;
        i++;
    }

    return sumArc;

}

【问题讨论】:

  • 我的第一个猜测是 SegmentAtPoint 返回一个与 b 相同或非常接近的点。你测试过这个吗?
  • 你试过debugging了吗?

标签: c# unity3d math bezier


【解决方案1】:

代码var t = 1 / steps; 生成integer division, 所以结果t 为零

还要注意j = j + t在每个循环之后执行,所以在第一次迭代j==0

这个缺陷会导致这样的问题:ba 在第一次迭代时是相等的,因为 j 仍然是 =0。所以你计算区间的段长度:0-0, 0-0.1, 0.1-0.2...0.7-0.8,0.8-0.9 - 忽略0.9-1.0区间

【讨论】:

  • 非常感谢。在循环满足您解决方案的第二部分之前,我认为var j = 0.0f;。还是我错过了什么?
  • 没有。我添加了解释
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-10
  • 2018-12-03
  • 2012-07-27
  • 1970-01-01
  • 2016-10-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多