计算曲面的地平线? [英] Calculate the horizon of a curved face?

查看:33
本文介绍了计算曲面的地平线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要找到曲面的视觉水平的 2 个点.

I need to find the 2 points of the visual horizon, of a curved face.

我有:

  • 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.

将您的贝塞尔曲线从贝塞尔表示转换为形式的多项式

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.

现在您构建曲线的第一个导数(很容易,因为它是一个多项式).这会给你一个二次方程.为根求解这些并丢弃 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.

你怎么有一堆根.将所有这些重新插入原始的贝塞尔曲线,评估它们的位置,你会得到一堆点.极值 - 如果存在 - 将在这些点中.

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.

请注意,您可能根本不会得到极值.例如,如果您的贝塞尔曲线是一条直线,就会发生这种情况.在这些情况下,您可能还希望在极值搜索中包括第一个和最后一个贝塞尔控制点.

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 代码:

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;
}

这篇关于计算曲面的地平线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆