本程序包含了c++读入TXT文档 及 输出TXT文档的方法;
并且对不规则二维图像的目标区域进行了拉格朗日插值。
//注释: 王磊
//用途: 二元图像插值
//取代 natual neighbourhood interpolation
// 19:45 2018/9/12
//邮箱: 1021516702@qq.com
//5LAGR2.CPP
//二元Lagrange插值
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
class lagr2
{
private:
int n, m;
double *x, *y, **z, u, v, f;
public:
lagr2(int nn, int mm) //声明构造函数
{
int k;
n = nn; m = mm;
x = new double[n]; //动态分配内存
y = new double[m];
z = new double*[n]; //z是个二维数组指针
for (k = 0; k < n; k++) { z[k] = new double[m]; }
}
void input(); //由文件读入n*m个数据点(x, y, z)
double interp(double, double); //执行二元Lagrange插值
void output(); //输出插值点u,v处的近似值f到文件
~lagr2() //这是析构函数
{
int i;
for (i = 0; i < n; i++) { delete[] z[i]; }
delete[] z;
delete[] x, y;
}
};
//class lagr2 的成员函数
void lagr2::input() //由文件读入n*m个数据点(x, y, z)
{
int k, j;
char str1[20];
cout << "\n输入文件名: ";
cin >> str1;
ifstream fin(str1); ////ifstream fin("c:\\x.123");//以输入的方式打开文件
//由于返回0代表程序正常退出,返回1等其他数字通常代表异常终止,在这里表示以输入的方式打开文档fin异常,所以终止
if (!fin)
{
cout << "\n不能打开这个文件 " << str1 << endl; exit(1);
}
//如果打开fin正常,那么读入文件
for (k = 0; k < n; k++) { fin >> x[k]; } //把数读入 x[k]
for (k = 0; k < m; k++) { fin >> y[k]; } //把数读入 y[k]
for (k = 0; k < n; k++) //读入n*m个数据点
for (j = 0; j < m; j++) { fin >> z[k][j]; } //把二维数读入 z[k][j]
fin.close();
}
//class lagr2 的成员函数
double lagr2::interp(double uu, double vv) //构造函数的定义
{
int ip, ipp, i, j, kk, iq, iqq, k;
double h, b[10];
u = uu; v = vv;
if (u <= x[0]) { ip = 1; ipp = 4; }
else if (u >= x[n - 1]) { ip = n - 3; ipp = n; }
else
{
i = 1; j = n;
while (((i - j) != 1) && ((i - j) != -1))
{
kk = (i + j) / 2;
if (u < x[kk - 1]) j = kk;
else i = kk;
}
ip = i - 3; ipp = i + 4;
}
if (ip < 1) ip = 1;
if (ipp > n) ipp = n;
if (v <= y[0]) { iq = 1; iqq = 4; }
else if (v >= y[m - 1]) { iq = m - 3; iqq = m; }
else
{
i = 1; j = m;
while (((i - j) != 1) && ((i - j) != -1))
{
kk = (i + j) / 2;
if (v < y[kk - 1]) j = kk;
else i = kk;
}
iq = i - 3; iqq = i + 4;
}
if (iq < 1) iq = 1;
if (iqq > m) iqq = m;
for (i = ip - 1; i <= ipp - 1; i++)
{
b[i - ip + 1] = 0.0;
for (j = iq - 1; j <= iqq - 1; j++)
{
h = z[i][j];
for (k = iq - 1; k <= iqq - 1; k++)
if (k != j) h = h*(v - y[k]) / (y[j] - y[k]);
b[i - ip + 1] = b[i - ip + 1] + h;
}
}
f = 0.0;
for (i = ip - 1; i <= ipp - 1; i++)
{
h = b[i - ip + 1];
for (j = ip - 1; j <= ipp - 1; j++)
if (j != i) h = h*(u - x[j]) / (x[i] - x[j]);
f = f + h;
}
return f; //返回f值
}
//class lagr2 的成员函数
void lagr2::output() //输出插值点u,v处的近似值f到文件
{
char str2[20];
cout << "\n输出文件名: ";
cin >> str2;
ofstream fout(str2, ios::app);
if (!fout)
{
cout << "\n不能打开这个文件 " << str2 << endl; exit(1);
}
fout << endl << u << " " << v << " " << f << endl; //上面空一行,下面空一行,非常聪明的做法
fout.close();
}
void main() //主函数
{
int i, j;
lagr2 solution(11, 11); //这是用到了lagr2 类 的构造函数
ofstream ft("lagr2.txt"); //ofstream file3("c:\\x.123");//以输出方式打开文件
if (!ft)
{
cout << "\n不能打开文件lagr2.txt " << endl; exit(1);
}
for (i = 0; i < 11; i++) ft << 0.1*i << " ";
ft << endl;
for (i = 0; i < 11; i++) ft << 0.1*i << " ";
ft << endl;
for (i = 0; i < 11; i++)
{
for (j = 0; j < 11; j++)
ft << exp(-(0.1*i - 0.1*j)) << " ";
ft << endl;
}
ft << endl;
ft.close(); //就把ft相连的文件关闭。
//输入文件结束,如果硬盘里没有 lagr2.txt 就创建一个
solution.input(); //由文件读入n*m个数据点(x, y, z)
cout << "x = 0.350, y = 0.650, z(x, y) = ";
cout << solution.interp(0.350, 0.650) << endl; //执行二元Lagrange插值
solution.output(); //输出插值点u,v处的近似值f到文件
cout << "x = 0.450, y = 0.550, z(x, y) = ";
cout << solution.interp(0.450, 0.550) << endl; //执行二元Lagrange插值
solution.output(); //输出插值点u,v处的近似值f到文件
}