Я немного запутался в использовании многочлена третьей степени.
Да, он дает правильные значения в 0 и 1, но производные соседних ячеек не подходят, насколько я могу вычислить. Если данные сетки линейны, они даже не возвращают строку....
И это не точечная симметрия в x = 0,5
Многочлен, который соответствует 0 и 1 И также имеет те же производные для соседних ячеек и, следовательно, является гладким, (почти) так же легко вычисляется.
(и сводится к линейной форме, если это соответствует данным)
В маркировке p и m - это сокращение от плюса и минуса, например. vm1 это v(-1)
//Bicubic convolution algorithm, cubic Hermite spline
static double CubicPolateConv
(double vm1, double v0, double vp1, double vp2, double frac) {
//The polynomial of degree 3 where P(x)=f(x) for x in {0,1}
//and P'(1) in one cell matches P'(0) in the next, gives a continuous smooth curve.
//And we also wants it to reduce nicely to a line, if that matches the data
//P(x)=Dx³+Cx²+Bx+A=((Dx+C)x+B)x+A
//P'(x)=3Dx²+2Cx+B
//P(0)=A =v0
//P(1)=D+C+B+A =Vp1
//P'(0)=B =(vp1-vm1)/2
//P'(1)=3D+2C+B=(vp2-v0 )/2
//Subtracting expressions for A and B from D+C+B+A
//D+C =vp1-B-A = (vp1+vm1)/2 - v0
//Subtracting that twice and a B from the P'(1)
//D=(vp2-v0)/2 - 2(D+C) -B =(vp2-v0)/2 - (Vp1+vm1-2v0) - (vp1-vm1)/2
// = 3(v0-vp1)/2 + (vp2-vm1)/2
//C=(D+C)-D = (vp1+vm1)/2 - v0 - (3(v0-vp1)/2 + (vp2-vm1)/2)
// = vm1 + 2vp1 - (5v0+vp2)/2;
//It is quite easy to calculate P(½)
//P(½)=D/8+C/4+B/2+A = (9*(v0+vp1)-(vm1+vp2))/16
//i.e. symmetric in its uses, and a mean of closest adjusted by mean of next ones
double B = (vp1 - vm1) / 2;
double DpC =(vp1 -v0) -B; //D+C+B+A - A - B
double D = (vp2 - v0) / 2 - 2 * DpC - B;
double C = DpC - D;
//double C = vm1 + 2 * vp1 - (5 * v0 + vp2) / 2;
//double D = (3*(v0 - vp1) + (vp2 - vm1)) / 2;
return ((D * frac + C) * frac + B) * frac + A;
}
Вдохновленный комментарием ManuTOO ниже, я сделал это также как четвертый порядок, с необязательным параметром, который вы можете установить/вычислить по своему усмотрению, не нарушая плавность кривой. Это в основном то же самое с добавленным членом на всем протяжении расчетов. И если вы установите E на ноль, это будет идентично приведенному выше. (Очевидно, что если данные на самом деле находятся в строке, ваш расчет E должен гарантировать, что E равно нулю, чтобы получить линейный вывод)
//The polynomial of degree 4 where P(x)=f(x) for x in {0,1}
//and P'(1) in one cell matches P'(0) in the next, gives a continuous smooth curve.
//And we also wants the it to reduce nicely to a line, if that matches the data
//With high order quotient weight of your choice....
//P(x)=Ex⁴+Dx³+Cx²+Bx+A=((((Ex+D)x+C)x+B)x+A
//P'(x)=4Ex³+3Dx²+2Cx+B
//P(0)=A =v0
//P(1)=E+D+C+B+A =Vp1
//P'(0)=B =(vp1-vm1)/2
//P'(1)=4E+3D+2C+B=(vp2-v0 )/2
//Subtracting Expressions for A, B and E from the E+D+C+B+A
//D+C =vp1-B-A -E = (vp1+vm1)/2 - v0 -E
//Subtracting that twice, a B and 4E from the P'(1)
//D=(vp2-v0)/2 - 2(D+C) -B -4E =(vp2-v0)/2 - (Vp1+vm1-2v0-2E) - (vp1-vm1)/2 -4E
// = 3(v0-vp1)/2 + (vp2-vm1)/2 -2E
//C=(D+C)-(D) = (vp1+vm1)/2 - v0 -E - (3(v0-vp1)/2 + (vp2-vm1)/2 -2E)
// = vm1 + 2vp1 - (5v0+vp2)/2 +E;
double E = ????????; //Your feed.... If Zero, cubic, see below
double B = (vp1 - vm1) / 2;
double DpC =(vp1 -v0) -B -E; //E+D+C+B+A - A - B -E
double D = (vp2 - v0) / 2 - 2 * DpC - B - 4 * E;
double C = DpC - D;
return (((E * frac + D) * frac + C) * frac + B) * frac + v0;
ДОБАВИТЬ: Цитата из предложения @ManTOO ниже:
double E = (v0 - vm1 + vp1 - vp2) * m_BicubicSharpness;
При значении m_BicubicSharpness 1,5 это очень близко к Bicubic Sharper в Photoshop; лично я установил его на 1,75 для небольшого дополнительного удара.
Обратите внимание, что если данные находятся в строке, это предложение сводится к нулю.
person
Eske Rahn
schedule
12.02.2017