计算曲面的视野?曲面、视野

2023-09-08 01:06:41 作者:5.伊人回眸泪倾城

我需要找到2点的视觉地平线曲面的的。

我有:

的4个角点的XYZ 2弧形边缘贝塞尔点的XYZ

和我需要计算两种:

地平线点XY 地平线分XYZ

推荐答案

首先,你必须将你的3D济耶转换为2D。如果我没记错的话就足够就像你预测3D点进行渲染到项目的曲线。

First off you have to convert your 3D beziers to 2D. If I remember right it's sufficient to project the curves just like you project 3D points for rendering.

之后,你必须找到曲线的极值。

Afterwards you have to find the extrema of the curves.

将您的贝塞尔曲线从贝塞尔重新presentation到窗体的polyonomial

Convert your bezier-curve from bezier representation to a polyonomial of the form

  x(t) = a*t^3 + b*t^2 + c*t + d
  y(t) = e*t^3 + f*t^2 + g*t + g

  Here t is your interpolation variable that goes from 0 to 1.
  a to d are the coefficients for the curve along the x-axis
  e to g are the coefficients for the curve along the y-axis.

现在你打造曲线的一阶导数(简单,因为它是一个polynomail)。 这会给你一个二次方程。解决这些为根,丢弃以外的0..1范围内的所有根源。再次找到根源是容易,因为它只是一个二次多项式。

Now you build the first derivation of the curve (easy as it's a polynomail). This will give you a quadratic equation. Solve these for the roots and discard all roots that are outside the 0..1 range. Again finding the roots is easy as it's just a quadratic polynomial.

您如何有一堆的根。堵上所有这些放回原Bezier曲线,评估他们的位置,你会得到一堆点。极值 - 如果存在 - 将这些点之间。

You how have a bunch of roots. Plug all these back into the original bezier curve, evaluate their position and you get a bunch of points. The extrema - if exist - will be among these points.

现在你需要做的是寻找一个具有最高(或最低 - 不知道你是如何坐标系的样子)。y坐标

Now all you have to do is to search for the one with the highest (or lowest - dunno how your coordinate system looks like) y-coordinate.

请注意,你可能不会得到极值的。这happends如果您的贝塞尔是例如一个直线。在这些情况下,您可能希望在您的极值搜索的第一个和最后贝塞尔控制点为好。

Note that you may not get an extrema at all. This happends if your bezier is for example a straight line. In these cases you may want to include the first and last bezier control point in your extrema search as well.

编辑:

您已经询问如何将贝塞尔成多项式。好了,你开始正常的贝塞尔曲线方程:

You've asked how to turn the bezier into a polynomial. Well, you start with the normal bezier curve equation:

 x(t) = x0 * (1-t)³ + 3*x1*(1-t)²*t + 3*x2*(1-t)*t² +x3*t³

(X0至X3是四个控制点的曲线的x值)。

(x0 to x3 are the x-values of the four control-points of the curve).

然后你乘的所有方面一个又一个由T的权力排序。不幸的是我没有我的,我写在计算机上运行的数学包,我懒做在纸上:-)因此,如果任何人有mathlab运行,你能请编辑这个答案并添加扩展版本?

Then you multiply out all terms one after another and sort them by the powers of t. Unfortunately I don't have my math package running on the computer I'm writing on, and I'm to lazy to do it on paper :-) So if anyone has mathlab running, could you please edit this answer and add the expanded version?

不管怎样,因为你不是在多项式,但它的东西只是衍生真正感兴趣的是一个更容易一些。您可以直接获得系数(此处显示为X只):

Anyway, since you're not really interested in the polynomial but just the derivate of it things are a bit easier. You can get the coefficients directly (here shown for x only):

A = 3.0f*(x[1] - x[0]);
B = 6.0f*(x[2] - 2.0f*x[1] + x[0]);
C = 3.0f*(x[3] - 3.0f*x[2] + 3.0f *x[1] - x[0]);

使用这三个值(A,B,C)的一阶导数的多项式看起来是这样的:

Using these three values (A,B,C) the polynomial of the first derivate looks like this:

  x(t) = A*t^2 + B*t + C

现在插上A,B和C到根求解器的二次多项式就大功告成了。供参考我用的是求解C- $ C $低于C:

Now plug A,B and C into a root solver for quadratic polynomials and you're done. For reference I use the solver C-code below:

int GetQuadraticRoots (float A, float B, float C, float *roots)
{
  if ((C < -FLT_EPSILON) || (C > FLT_EPSILON))
  {
    float d,p;
    // it is a cubic:
    p = B*B - 4.0f * C*A;
    d = 0.5f / C;
    if (p>=0)
    {
      p = (float) sqrt(p);
      if ((p < -FLT_EPSILON) || (p > FLT_EPSILON))
      {
        // two single roots:
        roots[0] = (-B + p)*d;
        roots[1] = (-B - p)*d;
        return 2;
      } 
      // one double root:
      roots[0] = -B*d;
      return 1;
    } else {
      // no roots:
      return 0;
    }
  } 
  // it is linear:
  if ((B < -FLT_EPSILON) || (B > FLT_EPSILON))
  {
    // one single root:
    roots[0] = -A/B;
    return 1;
  }
  // it is constant, so .. no roots.
  return 0;
}