/* 3d.c * * Benötigt eine int[][][]-Initialisierung aus 3dgen.cpp * * gcc -Wall -Wextra -std=c11 3d.c -o 3d && ./3d */ #define ZWISCHENWERTE_AUSGEBEN #include #include #include #include // willkürliche Anzahl Stützstellen: #define dimX (10) #define dimY (15) #define dimZ (12) // Definitionsbereich uC-freundlich in Festkommazahlen (skaliert mit 100): const int minX_scaledX = 0; const int maxX_scaledX = 200; const int minY_scaledY = 0; const int maxY_scaledY = 200; const int minZ_scaledZ = 0; const int maxZ_scaledZ = 400; const double scaleX = 100; const double scaleY = 100; const double scaleZ = 100; const double scaleF = 100; // Gitterabstand in jede Richtung: const int griddistX_scaledX = ( maxX_scaledX - minX_scaledX )/( dimX - 1 ); const int griddistY_scaledY = ( maxY_scaledY - minY_scaledY )/( dimY - 1 ); const int griddistZ_scaledZ = ( maxZ_scaledZ - minZ_scaledZ )/( dimZ - 1 ); int f_array_scaledF[dimX][dimY][dimZ] = #include "3dvalues.inc" ; // interpoliert das skalierte f(x,y,z) für ein skaliertes Tripel x,y,z: int f_scaledF( int x_scaledX, int y_scaledY, int z_scaledZ ) { // linke + rechte Stuetzstelle in x-Richtung: int indexXl = ( x_scaledX - minX_scaledX )*( dimX - 1 )/( maxX_scaledX - minX_scaledX ); if( indexXl<0 ) { indexXl = 0; } if( indexXl>dimX-2 ) { indexXl = dimX-2; } int indexXr = indexXl + 1; // zugehörige Abszisse: int x_scaledX_l = minX_scaledX + indexXl*( maxX_scaledX - minX_scaledX )/( dimX - 1 ); int x_scaledX_r = x_scaledX_l + griddistX_scaledX; #ifdef ZWISCHENWERTE_AUSGEBEN printf( "x l = [%2d] %3d/%g = %8.4f, x r [%2d] %3d/%g = %8.4f\n", indexXl, x_scaledX_l, scaleX, (double)x_scaledX_l/scaleX, indexXr, x_scaledX_r, scaleX, (double)x_scaledX_r/scaleX ); #endif /* ifdef ZWISCHENWERTE_AUSGEBEN */ // linke + rechte Stuetzstelle in y-Richtung: int indexYl = ( y_scaledY - minY_scaledY )*( dimY - 1 )/( maxY_scaledY - minY_scaledY ); if( indexYl<0 ) { indexYl = 0; } if( indexYl>dimY-2 ) { indexYl = dimY-2; } int indexYr = indexYl + 1; // zugehörige Abszisse: int y_scaledY_l = minY_scaledY + indexYl*( maxY_scaledY - minY_scaledY )/( dimY - 1 ); int y_scaledY_r = y_scaledY_l + griddistY_scaledY; #ifdef ZWISCHENWERTE_AUSGEBEN printf( "y l = [%2d] %3d/%g = %8.4f, y r [%2d] %3d/%g = %8.4f\n", indexYl, y_scaledY_l, scaleY, (double)y_scaledY_l/scaleY, indexYr, y_scaledY_r, scaleY, (double)y_scaledY_r/scaleY ); #endif /* ifdef ZWISCHENWERTE_AUSGEBEN */ // linke + rechte Stuetzstelle in z-Richtung: int indexZl = ( z_scaledZ - minZ_scaledZ )*( dimZ - 1 )/( maxZ_scaledZ - minZ_scaledZ ); if( indexZl<0 ) { indexZl = 0; } if( indexZl>dimZ-2 ) { indexZl = dimZ-2; } int indexZr = indexZl + 1; // zugehörige Abszisse: int z_scaledZ_l = minZ_scaledZ + indexZl*( maxZ_scaledZ - minZ_scaledZ )/( dimZ - 1 ); int z_scaledZ_r = z_scaledZ_l + griddistZ_scaledZ; #ifdef ZWISCHENWERTE_AUSGEBEN printf( "z l = [%2d] %3d/%g = %8.4f, z r [%2d] %3d/%g = %8.4f\n", indexZl, z_scaledZ_l, scaleZ, (double)z_scaledZ_l/scaleZ, indexZr, z_scaledZ_r, scaleZ, (double)z_scaledZ_r/scaleZ ); #endif /* ifdef ZWISCHENWERTE_AUSGEBEN */ return ( f_array_scaledF[indexXl][indexYl][indexZl] // Stützstelle jeweils links in jeder Dimension // Lineare Interpolation in x-Richtung mit y=y_l und z=z_l + ( ( f_array_scaledF[indexXr][indexYl][indexZl] - f_array_scaledF[indexXl][indexYl][indexZl] ) *( x_scaledX - x_scaledX_l ) /( griddistX_scaledX ) ) // Lineare Interpolation in y-Richtung mit x=x_l und z=z_l + ( ( f_array_scaledF[indexXl][indexYr][indexZl] - f_array_scaledF[indexXl][indexYl][indexZl] ) *( y_scaledY - y_scaledY_l ) /( griddistY_scaledY ) ) // Lineare Interpolation in z-Richtung mit x=x_l und y=y_l + ( ( f_array_scaledF[indexXl][indexYl][indexZr] - f_array_scaledF[indexXl][indexYl][indexZl] ) *( z_scaledZ - z_scaledZ_l ) /( griddistZ_scaledZ ) ) ); } void teste_f( int x_scaledX, int y_scaledY, int z_scaledZ ) { printf( "f( %4d/%g, %4d/%g, %4d/%g ) = %4d/%g\n", x_scaledX, scaleX, y_scaledY, scaleY, z_scaledZ, scaleZ, f_scaledF( x_scaledX, y_scaledY, z_scaledZ ), scaleF ); } int main() { printf( "Gitterabstand skaliert x %d, y %d, z %d\n", griddistX_scaledX, griddistY_scaledY, griddistZ_scaledZ ); teste_f( 0, 0, 0 ); teste_f( 200, 200, 384 ); teste_f( 200, 135, 180 ); teste_f( 100, 200, 400 ); teste_f( 200, 200, 400 ); return 0; }