Interpolación lineal en puntos interiores a un triángulo en el espacio tridimensional: C/C++

La interpolación lineal en puntos interiores a un triángulo, en el espacio tridimensional, es la base de las transformaciones de los TIN en MDT raster. Dados tres puntos en el espacio, el primer paso es determinar la ecuación del plano que pasa por dichos puntos y luego, calcular la cota para las coordenadas del centro del triángulo. Los fundamentos de cálculo están bien detallados aquí:

MDT a partir de curvas de nivel y ecuación del plano

Con base en la información anterior, se desarrolló un programa para ejecutar dicho proceso en C++.

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

double determinante(int n, double **a);

int main() {

	system ("clear");

	ifstream label1 ("datos//datos.in"); // Abre el archivo de entrada de datos

	// Definición de variables y asignación dinámica de memoria	

	int i, j, k, n=3;

	double **a, **b, A[3], D;

	a = new double* [n], b = new double* [n];

	for(j=0; j<n; j++){

		a[j] = new double [n], b[j] = new double [n];

	}	

	// Lectura de la matriz (label1 apunta a datos.in en el subdirectorio datos del home de usuario)

	for(i=0; i<n; i++){

		for(j=0; j<n; j++){

			label1 >> a[i][j];

			b[i][j] = a[i][j];

  
		}

	}

	cout.setf(ios::fixed);

	cout.precision(2);

	cout << "Imprime la matriz de origen\n\n";

	// Matriz de origen; a

	for(i=0; i<n; i++){

		for(j=0; j<n; j++){

			cout <<  a[i][j] << " ";
  
		}

		cout << endl;

	}

	cout << endl;

	D = -determinante(n, a); 

	cout << "El determinante de la matriz anterior es = " << D << "\n\n";

	for (k = 0; k <n; k++){

		for(i=0; i<n; i++){

			for(j=0; j<n; j++){

				if(k == j) b[i][j] = 1;
 
			}


		}

		cout << "Imprime la matriz de origen\n\n";

		// Matriz de origen

		for(i=0; i<n; i++){

			for(j=0; j<n; j++){

				cout <<  b[i][j] << " ";

  
			}

			cout << endl;

		}

		cout << endl;

		A[k] = determinante(n, b); 

		cout << "El determinante de la matriz anterior es = " << A[k] << "\n\n";

		for(i=0; i<n; i++){

			for(j=0; j<n; j++){

				b[i][j] = a[i][j];

			}

		}



	}

	delete [] a;

	cout << "Coordenadas del punto\n\n";

	double X, Y, Z;

	cout << "X = ? ";

	cin >> X;	

	cout << "Y = ? ";

	cin >> Y;	

	Z = (-D - A[1]*Y - A[0]*X)/A[2];

	cout << "Z = " << Z << "\n";

	return 0;

}

double determinante(int n, double **a) {

// Algoritmo para la eliminación simple de Gauss

	int i, j, k;

	double **b;

	b = new double* [n];

	for(j=0; j<n; j++){

		b[j] = new double [n];

	}	

	for(i=0; i<n; i++){

		for(j=0; j<n; j++){

			b[i][j] = a[i][j];
          

		}

	}

	double factor;

	for (k = 0; k < n - 1; k++) {

		for (i = k+1; i < n;  i++) {

			factor = b[i][k]/b[k][k]; 

			for (j = k+1; j < n + 1; j++) {

				b[i][j] = b[i][j] - factor * b[k][j];

			}

		}

	}

// Cálculo del determinante

	double determ = 1.;

	for (i = 0; i < n; i++) {

		determ = determ * b[i][i];

	}

	delete [] b;

	return determ;

}

La salida, para el ejemplo de la referencia, es la siguiente:

Imprime la matriz de origen

434000.00 4812000.00 215.00 
437000.00 4813000.00 320.00 
435000.00 4814000.00 400.00 

El determinante de la matriz anterior es = 2175175000000.02

Imprime la matriz de origen

1.00 4812000.00 215.00 
1.00 4813000.00 320.00 
1.00 4814000.00 400.00 

El determinante de la matriz anterior es = -25000.00

Imprime la matriz de origen

434000.00 1.00 215.00 
437000.00 1.00 320.00 
435000.00 1.00 400.00 

El determinante de la matriz anterior es = -450000.00

Imprime la matriz de origen

434000.00 4812000.00 1.00 
437000.00 4813000.00 1.00 
435000.00 4814000.00 1.00 

El determinante de la matriz anterior es = 5000000.00

Coordenadas del punto

X = ? 434500
Y = ? 4812500
Z = 262.50

En realidad, la salida está muy detallada para mostrar las matrices y sus determinantes para cada uno de los pasos especificados en la referencia pero la base del cálculo es la obtención del determinante por la eliminación simple de Gauss. Este programa, con muy pocas modificaciones, puede ser usado también para interpolación lineal en el plano.

Por otra parte, para una salida sin adornos, es decir así:

Coordenadas del punto

X = ? 434500
Y = ? 4812500
Z = 262.50

y con parte del código imbuido en una función interpolar, éste queda así:

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

double determinante(int n, double **a);

void interpolar(int n, double **a, double A[3], double &D);


int main() {

    

	system ("clear");



	ifstream label1 ("datos//datos.in"); // Abre el archivo de entrada de datos



	// Definición de variables y asignación dinámica de memoria	



	int i, j, k, n=3;



	double **a, A[3], D;



	a = new double* [n];



	for(j=0; j<n; j++){



		a[j] = new double [n];

	

	}	



	// Lectura de la matriz (label1 apunta a datos.in en el subdirectorio datos del home de usuario)



	for(i=0; i<n; i++){



		for(j=0; j<n; j++){



			label1 >> a[i][j];

            

		}



	}



	interpolar(n, a, A, D);




	delete [] a;



	cout.setf(ios::fixed);

	cout.precision(2);



	cout << "Coordenadas del punto\n\n";



	double X, Y, Z;



	cout << "X = ? ";



	cin >> X;	



	cout << "Y = ? ";



	cin >> Y;	



	Z = (-D - A[1]*Y - A[0]*X)/A[2];



	cout << "Z = " << Z << "\n";



	return 0;



}







double determinante(int n, double **a) {





// Algoritmo para la eliminación simple de Gauss



	int i, j, k;



	double **b;



	b = new double* [n];



	for(j=0; j<n; j++){



		b[j] = new double [n];

	

	}	



	for(i=0; i<n; i++){



		for(j=0; j<n; j++){



			b[i][j] = a[i][j];

            

		}



	}



	double factor;



	for (k = 0; k < n - 1; k++) {

		

		for (i = k+1; i < n;  i++) {



			factor = b[i][k]/b[k][k]; 



			for (j = k+1; j < n + 1; j++) {



				b[i][j] = b[i][j] - factor * b[k][j];



			}

		





		}



	}



// Cálculo del determinante



	double determ = 1.;



	for (i = 0; i < n; i++) {



		determ = determ * b[i][i];



	}





	delete [] b;



	return determ;





}

void interpolar(int n, double **a, double A[3], double &D){
	
	int i, j, k;

	double **b;



	b = new double* [n];



	for(j=0; j<n; j++){



		b[j] = new double [n];

	

	}	





	for(i=0; i<n; i++){



		for(j=0; j<n; j++){



			b[i][j] = a[i][j];

            

		}



	}

	D = -determinante(n, a); 


	for (k = 0; k <n; k++){



		for(i=0; i<n; i++){



			for(j=0; j<n; j++){



				if(k == j) b[i][j] = 1;

            

			}



	

		}





		A[k] = determinante(n, b); 



		for(i=0; i<n; i++){



			for(j=0; j<n; j++){



				b[i][j] = a[i][j];

            

			}



		}





	}

	delete [] b;



}
Esta entrada fue publicada en Código C++. Guarda el enlace permanente.

3 respuestas a Interpolación lineal en puntos interiores a un triángulo en el espacio tridimensional: C/C++

  1. Alex dijo:

    Eres un crack!!!!. Lo voy a probar🙂. Feliz viaje otra vez😉

  2. Pingback: Interpolación lineal en el plano: C/C++ |

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s