2D のベジエ曲線 (P0、P1、P2、P3) のポイントが与えられた場合、特定の x 座標の y 座標を見つけたいと思います。この問題は、次の制限により明確に定義されています。
- P0 = (0,0)、P3 = (1,1)
- P1 = (t, 1-t) for t for 0, 1
- P2 = 1 - P1 (x と y)
上記のすべての制限をベジエ曲線の式CubicBezier.htmlに入れて、答えを計算する次の関数があります。私は Newton-Raphson を使用して、必要なポイントのパラメーターを計算しています。(定義された許容範囲内で) 終了するまでループを終了させないため、これが機能することがわかっています。
この関数を使用して、画像にコントラスト フィルターを適用しています。この 0.5 では同じ画像が返され、0.0 ではコントラストが最大に減少し、1.0 では最大に増加します。
編集次の関数は修正され、完全に機能するようになりました。
/*
* Parameters: p - x co-ord of P1,
* x - x we want to find y for
*
* This method is unstable for p ~= 0.5, maybe needs refinement.
*/
#include <iostream>
#include <math.h>
#define ITER_TOL 0.00001
float maths::bezier(float p, float x)
{
if(p < 0.f || p > 1.f || x < 0.f || x > 1.f)
{
std::cerr << "Both parameters must be between 0 and 1, returning dummy value" << std::endl;
return 0.f;
}
//First guess for u
float u = x;
//Coefficients of curve (for x and y co-ord)
float x3 = 6 * p - 2;
float x2 = 3 - 9 * p;
float x1 = 3 * p;
float x0 = -x;
float y3 = 6 * (1-p) - 2;
float y2 = 3 - 9 * (1-p);
float y1 = 3 * (1-p);
//Newton-Raphson refinement
for(int i=0; fabs(x3*u*u*u + x2*u*u + x1*u + x0) > ITER_TOL && i<1000; i++)
{
u = u - (x3*u*u*u + x2*u*u + x1*u + x0) /
(3*x3*u*u + 2*x2*u + x1);
//std::cout << i << ": " << u << std::endl;
//Deal with non-convergence
if(i==999)
{
std::cerr << "Warning, Newton-Raphson method did not converge in Maths.cpp, returning dummy" << std::endl;
return 0.f;
}
}
//Calculate y co-ord
return y3*u*u*u + y2*u*u + y1*u;
}
p = 0.5 に設定すると、直線が得られるはずですが、linspace に対してこれを行って点をプロットすると、0.5 と 1.0 の間で曲がります。なぜこれが起こっているのか、誰にもわかりますか?何かできることがあれば教えてください。