graphics - essential - title templates premiere
Calcule el horizonte de una cara curva? (1)
Necesito encontrar los 2 puntos del horizonte visual , de una cara curva.
Yo tengo:
- XYZ de los 4 puntos de esquina
- XYZ de los 2 puntos bezier de borde curvo
Y necesito calcular cualquiera:
- XY de los puntos del horizonte
- XYZ de los puntos del horizonte
Primero, debes convertir tus beziers 3D a 2D. Si recuerdo bien, es suficiente proyectar las curvas como si proyectas puntos 3D para renderizar.
Luego debes encontrar los extremos de las curvas.
Un pequeño HowTo:
Convierta su curva bezier de representación bezier a un polinomio de la 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.
Ahora construyes la primera derivación de la curva (es fácil ya que es un polinomail). Esto te dará una ecuación cuadrática. Resuelve estos para las raíces y descarta todas las raíces que están fuera del rango de 0..1. Nuevamente, encontrar las raíces es fácil, ya que es solo un polinomio cuadrático.
Tu tienes un montón de raíces. Vuelva a conectar todo esto en la curva original de bezier, evalúe su posición y obtendrá un montón de puntos. Los extremos, si existen, estarán entre estos puntos.
Ahora todo lo que tiene que hacer es buscar el que tenga la coordenada y más alta (o la más baja, no sé cómo se ve su sistema de coordenadas).
Tenga en cuenta que no puede obtener un extremo en absoluto. Esto sucede si tu bezier es, por ejemplo, una línea recta. En estos casos, es posible que desee incluir también el primer y último punto de control bezier en su búsqueda extrema.
EDITAR:
Has preguntado cómo convertir el bezier en un polinomio. Bueno, empiezas con la ecuación de curva de bezier normal:
x(t) = x0 * (1-t)³ + 3*x1*(1-t)²*t + 3*x2*(1-t)*t² +x3*t³
(x0 a x3 son los valores x de los cuatro puntos de control de la curva).
Luego, multiplicas todos los términos uno tras otro y los clasificas por los poderes de t. Lamentablemente, no tengo mi paquete de matemática ejecutándose en la computadora en la que estoy escribiendo, y soy perezoso para hacerlo en papel :-) Entonces, si alguien tiene mathlab ejecutándose, ¿podría editar esta respuesta y agregar la versión ampliada? ¿versión?
De todos modos, ya que no estás realmente interesado en el polinomio, sino solo el derivado de él, las cosas son un poco más fáciles. Puede obtener los coeficientes directamente (aquí se muestra solo para x):
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 estos tres valores (A, B, C) el polinomio de la primera derivada se ve así:
x(t) = A*t^2 + B*t + C
Ahora conecte A, B y C en un solucionador de raíz para polinomios cuadráticos y listo. Como referencia, uso el código C del solucionador a continuación:
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;
}