Pergunta

Eu preciso encontrar os 2 pontos do horizonte visual , de uma face curva.

Eu tenho:

  • XYZ dos 4 pontos de canto
  • XYZ da borda curvada 2 Bezier pontos

E eu preciso calcular quer:

  • XY dos pontos horizonte
  • XYZ dos pontos horizonte
Foi útil?

Solução

Em primeiro lugar você tem que converter seus 3D Beziers para 2D. Se bem me lembro, é suficiente para projetar as curvas como você projetar em 3D pontos para renderização.

Depois você tem que encontrar os extremos das curvas.

Uma pequena HowTo:

Converter seu bezier-curve da representação bezier a um polyonomial da forma

  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.

Agora você construir a primeira derivação da curva (fácil como é um polynomail). Isto lhe dará uma equação quadrática. Resolvê-los para as raízes e descartar todas as raízes que estão fora do intervalo 0..1. Novamente encontrar as raízes é fácil, pois é apenas um polinômio quadrático.

Você como ter um monte de raízes. Ligue todos estes de volta para a curva de bezier original, avaliar a sua posição e você terá um monte de pontos. A extrema - se existir - estará entre esses pontos.

Agora tudo que você tem a fazer é procurar um com o mais elevado. (Ou menor - não sei como seu coordenar aparência do sistema, como) coordenada y

Note que você não pode ter uma extrema a todos. Este happends se o seu bezier é por exemplo uma linha reta. Nestes casos, você pode querer incluir o primeiro eo último ponto de controle bezier em sua busca extrema também.


EDIT:

Você perguntou como transformar o bezier em um polinômio. Bem, você começa com a equação normal de curva bezier:

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

(x0 a X3 são os valores de x dos quatro controlo-pontos da curva).

Então você multiplicar a todos os termos um após o outro e classificá-los por os poderes de t. Infelizmente eu não tenho o meu pacote de matemática em execução no computador que estou escrevendo, e eu sou preguiçoso :-) Então, para fazê-lo em papel, se alguém tiver running MATHLAB, você poderia editar esta resposta e adicione o expandida versão?

De qualquer forma, desde que você não está realmente interessado no polinômio mas apenas o derivado de TI coisas são um pouco mais fácil. Você pode obter os coeficientes diretamente (aqui mostrado para x apenas):

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]);

Usando estes três valores (A, B, C) o polinomial dos primeiros aparência derivados como este:

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

Agora ligue A, B e C em um solucionador de raiz para polinômios quadráticos e está feito. Para referência eu uso o C-código solver abaixo:

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;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top