Задача
Найти площадь поверхности, которая является трёхмерным графиком функции [latex]f\left( x, y\right)[/latex], в пределах от [latex]a[/latex] до [latex]b[/latex] по оси [latex]x[/latex] и от [latex]c[/latex] до [latex]d[/latex] по оси [latex]y[/latex] c величиной шага [latex]h[/latex].
Входные данные:
Четыре целых числа: [latex]a[/latex], [latex]b[/latex], [latex]c[/latex], [latex]d[/latex].
Вещественное число: [latex]h[/latex].
Выходные данные:
Площадь поверхности [latex]S[/latex].
Тесты
№ | [latex]f\left( x, y\right)[/latex] | Входные данные | Выходные данные | ||||
[latex]a[/latex] | [latex]b[/latex] | [latex]c[/latex] | [latex]d[/latex] | [latex]h[/latex] | [latex]S[/latex] | ||
1 | [latex]x+y[/latex] | -10 | 10 | -10 | 10 | 0.001 | 692.82 |
2 | [latex]\left| x \right| +\left| y \right|[/latex] | -2 | 2 | -2 | 2 | 0.005 | 27.7128 |
3 | [latex]1[/latex] | 0 | 100 | 0 | 100 | 0.1 | 10000 |
4 | [latex]{x}^{2}+{y}^{2}[/latex] | -1 | 1 | -1 | 1 | 0.0005 | 7.44626 |
Код программы
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#include <iostream> #include <cmath> using namespace std; double z(double x, double y){ return abs(x)+abs(y);//<-- место для ввода функции z=f(x, y). } double dl(double x, double y, double z){ return sqrt(x*x+y*y+z*z);//Длина вектора. } double ras(double xi, double xj, double yi, double yj){ double zii, zjj, zij, zji, v1x=0, v1y=0, v1z=0, v2x=0, v2y=0, v2z=0; zii=z(xi, yi); //Найдём координату z каждой вершины треугольников. zjj=z(xj, yj); zij=z(xi, yj); zji=z(xj, yi); v1x=(yi-yj)*(zji-zii); //Вычислим векторное произведение векторов. v1y=(zii-zij)*(xj-xi); v1z=(yj-yi)*(xj-xi); v2x=(yj-yi)*(zji-zjj); v2y=(zjj-zij)*(xi-xj); v2z=(yi-yj)*(xi-xj); return (dl(v1x, v1y, v1z)+dl(v2x, v2y, v2z))/2;//Найдём площадь треугольников. } int main(){ double xi, xj, yi, yj, s=0, h; int a, b, c, d; cin >> a >> b >> c >> d >> h; xi = a; while(xi<=(b-h)){ yi=c; xj=xi+h; while(yi<(d-h)){ yj=yi+h; s+=ras(xi,xj,yi,yj); yi=yj; } xi=xj; } cout<<s; return 0; } |
Решение
Представим поверхность в виде множества геометрических фигур. Тогда её площадь будет суммой площадей этих фигур. В качестве фигур, покрывающих данную поверхность, возьмём треугольники, поскольку через любые [latex]3[/latex] точки в пространстве можно провести плоскость и только одну (а значит и треугольник). Координатную плоскость [latex]xy[/latex] условно поделим на квадраты, где сторона квадрата будет равняться заданному шагу [latex]h[/latex]. Будем рассматривать только квадраты, что лежат в заданных пределах. Условно проведём одну из диагоналей у каждого квадрата — получим треугольники на плоскости. Поочередно будем искать координату [latex]z[/latex] вершин каждой пары треугольников, подставляя уже известные координаты [latex]x[/latex] и [latex]y[/latex] в указанную формулу. Зная координаты треугольников в пространстве, найдём площадь каждого, сумма данных площадей и будет площадью поверхности. Чтоб найти площадь треугольника, зная координаты его вершин, найдем векторное произведение его координат. Возьмем треугольник с координатами вершин [latex]\left( x_i,y_i,z_{ii} \right) [/latex], [latex]\left( x_i, y_j, z_{ij} \right) [/latex] и [latex]\left( x_j, y_i, z_{ji} \right) [/latex], возьмём произвольные два вектора, которые образуют данный треугольник — [latex]\overrightarrow { a } =\left ( x_i-x_i, y_j-y_i, z_{ij}-z_{ii} \right)[/latex], [latex]\overrightarrow { b } =\left ( x_j-x_i, y_i-y_i, z_{ji}-z_{ii} \right)[/latex].
[latex]\overrightarrow { a } =\left ( 0, y_j-y_i, z_{ij}-z_{ii} \right)[/latex], [latex]\overrightarrow { b } =\left ( x_j-x_i, 0, z_{ji}-z_{ii} \right)[/latex].
Тогда векторное произведение [latex]\left [ \overrightarrow { a }, \overrightarrow { b } \right] =\left ( (y_i-y_j)( z_{ji}-z_{ii}), (z_{ii}-z_{ij})(z_{ji}-z_{ii} ), ( y_j-y_i)(x_j-x_i) \right)[/latex].
Поскольку длина вектора равного векторному произведения двух векторов в пространстве равна площади параллелограмма, образованного исходными векторами — найдём его длину и разделим пополам, чтоб получить площадь треугольника, образованного исходными векторами. Значит площадь каждого треугольника можно вычислить по формуле:
[latex]s =\frac { 1 }{ 2 } \sqrt{({(y_i-y_j)}^{2}{( z_{ji}-z_{ii})}^{2}+{(z_{ii}-z_{ij})}^{2}{(z_{ji}-z_{ii} )}^{2}+{( y_j-y_i)}^{2}{(x_j-x_i)}^{2})}[/latex]
Тогда площадь поверхности в пределах заданных точек можно вычислить, сложив площади этих треугольников.
Модификация
Модифицируем данную программу для нахождения приблизительной площади поверхности, заданной функцией с корнем чётной степени.
Тесты
№ | [latex]f\left( x, y\right)[/latex] | [latex]z_0[/latex] | Входные данные | Выходные данные | ||||
[latex]a[/latex] | [latex]b[/latex] | [latex]c[/latex] | [latex]d[/latex] | [latex]h[/latex] | [latex]S[/latex] | |||
1 | [latex]\sqrt { 1-{ x }^{ 2 }-{ y }^{ 2 } }[/latex] | [latex]1[/latex] | -1 | 1 | -1 | 1 | 0.00011 | 6.28734 |
2 | [latex]\sqrt { 1-{ x }^{ 2 }-{ y }^{ 2 } }[/latex] | [latex]7y[/latex] | -1 | 1 | -1 | 1 | 0.00011 | 23.0803 |
3 | [latex]\sqrt { 1-{ x }^{ 2 }-\frac{ { y }^{ 2 }}{ 2 } }[/latex] | [latex]0[/latex] | -1 | 1 | -2 | 2 | 0.00015 | 8.08214 |
4 | [latex]\sqrt { 2-{ x }^{ 2 }-{ y }^{ 2 } }[/latex] | [latex]-1[/latex] | -2 | 2 | -2 | 2 | 0.0005 | 12.5835 |
Код программы
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
#include <iostream> #include <cmath> using namespace std; double z(double x, double y, double &z0){ z0=7*y; //<-- место для ввода слагаемых функции f(x, y) не под корнем чётной степени. return (1-x*x-y*y)<0? z0:sqrt(1-x*x-y*y)+z0;//<-- место для ввода функции z=f(x, y). } long double dl(double x, double y, double z){ return sqrt(x*x+y*y+z*z);//Длина вектора. } double ras(double xi, double xj, double yi, double yj){ double zii, zjj, zij, zji, v1x=0, v1y=0, v1z=0, v2x=0, v2y=0, v2z=0, z0=0; zii=z(xi, yi, z0); //Найдём координату z каждой вершины треугольников. zjj=z(xj, yj, z0); zij=z(xi, yj, z0); zji=z(xj, yi, z0); if(z(xi, yi, z0)!=z0||z(xi, yj, z0)!=z0||z(xj, yi, z0)!=z0){//Используем функцию z(), потому что z0 может оказаться переменной. v1x=(yj-yi)*(zji-zii); //Вычислим векторное произведение векторов. v1y=(zij-zii)*(xj-xi); v1z=(yi-yj)*(xj-xi); } if(z(xj, yj, z0)!=z0||z(xi, yj, z0)!=z0||z(xj, yi, z0)!=z0){ v2x=(yi-yj)*(zji-zjj); v2y=(zij-zjj)*(xi-xj); v2z=(yj-yi)*(xi-xj); } return (dl(v1x, v1y, v1z)+dl(v2x, v2y, v2z))/2;//Найдём площадь треугольников. } int main(){ double xi, xj, yi, yj, s=0, h, z0=0; int a, b, c, d; cin >> a >> b >> c >> d >> h; xi = a; while(xi<=(b-h)){ yi=c; xj=xi+h; while(yi<=(d-h)){ yj=yi+h; s+=ras(xi, xj, yi, yj); yi=yj; } xi=xj; } cout<<s; return 0; } |
Условно отделим от функцию [latex]f\left( x, y\right)[/latex] слагаемые, что не под корнем, если такие имеются. Тогда [latex]z_0[/latex] равно части функции, что не под корнем. Для того, чтоб рассматривать площади треугольников, вершины которых выходят за область определения функции, доопределим их в [latex]z_0[/latex] по оси [latex]z[/latex]. Затем вычислим площадь треугольников, у которых как минимум одна вершина не лежит на [latex]z=z_0[/latex] .