Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву
Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Метод построчной закраски треугольникаСодержание книги
Поиск на нашем сайте
Наиболее просто осуществляется построчная закраска треугольника (в 3D графике треугольник – это основной элемент аппроксимации криволинейных поверхностей): 1. сортируем вершины треугольника по высоте: ‑ верхняя (X1,Y1) ‑ средняя (X3,Y3) ‑ нижняя (X2,Y2) 2. разбиваем на 2 треугольника: ‑ выше средней вершины (1,3,4) ‑ ниже средней вершины (4,3,2) => вводится новая псевдовершина (X4,Y4) 3. сортируем среднюю и новую вершины по горизонтали: ‑ левая (X4,Y4) ‑ правая (X3,Y3) 4. строим уравнения прямой для левого и правого ребер: ‑ от (X1,Y1) до (X4,Y4) - левая прямая (идентична (X1,Y1)-(X2,Y2)) ‑ от (X1,Y1) до (X3,Y3) - правая прямая-ребро по формуле X=(Y-Yn)*(Xk-Xn)/(Yk-Yn)+Xn 5. построчная закраска треугольника горизонтальными прямыми: внешний цикл for Y:=Y1 to Y3 внутренний цикл for X:=Xл(Y) to Xп(Y) 6. повторяем 4)-5) для нижнего треугольника for Y:=Y3 to Y2
X4,Y4 X3,Y3
X2,Y2
Вместо одноцветного PutPixel (X, Y, C) можно использовать вывод точек, например, из картинки 32х32 пикселя: PutPixel (X, Y, sprite [ X mod 32, Y mod 32]). 5. Контрольные вопросы
1. Геометрические основы машинной графики. Основные понятия. 2. Представление объекта в виде каркаса. 3. Перенос и масштабирование объектов. 4. Поворот объекта вокруг осей координат. 5. Алгоритмы удаления скрытых линий и поверхностей. 6. Алгоритм художника. Неопределенности. Тесты. 7. Алгоритм с использованием Z-буфера. 8. Алгоритм трассировки лучей. 8. Модели освещения. Диффузное отражение. 9. Модели освещения. Зеркальное отражение. 10. Модели освещения. Общая формула интенсивности и значение 11. Закраска объекта, аппроксимированного полигональной сеткой. 12. Закраска объекта, аппроксимированного полигональной сеткой. 13. Закраска объекта, аппроксимированного полигональной сеткой. 6. Выбор варианта задания для студентов Лаб. раб. № 2 «3D-изображения: Лаб. раб. № 3 «3D-изображения: удаление невидимых граней» закраска видимых граней» Лаб. Раб. № 2 «Движение каркасных объектов с простой закраской» Лаб. Раб. № 3 «Движение закрашенного объекта с учетом освещения»
Модели объекта (-ов), их цвет и движение у всех должны отличаться.
Содержание общего отчета
1. Геометрическая модель сцены с указанием точки наблюдения и источников освещения. 2. Описание используемого алгоритма удаления невидимых поверхностей. 3. Описание используемого алгоритма закраски. 4. Исходный текст программы с комментариями. 5. Результат работы (скрин-шот). 6. Выводы с личными впечатлениями от работы. Пример программы на языке Delphi
Фон примера лаб.раб №2 черный, объект – четырехугольная звезда (шестеренка). В нормальном режиме (когда не выбран метод удаления невидимых ребер и граней) рисуется каркасный объект с ребрами разного цвета, в режиме «удаления» (которые необходимо реализовать самостоятельно) грани должны закрашиваться разным цветом. В режиме просмотра («демо») грани отображаются без сортировки (в порядке их описания). Возникающие артефакты удаления необходимо описать в выводах. Градиентную закраску Гуро или Фонга для лаб.раб №3 от направления освещения сделать самостоятельно на базе алгоритма построчной развертки треугольников согласно индивидуального задания (второй пример). Вектор освещения можно задать ткнувшись в изображение.
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls;
type TForm1 = class(TForm) Image1: TImage; CheckBox1: TCheckBox; Timer1: TTimer; Panel1: TPanel; RadioButton1: TRadioButton; RadioButton3: TRadioButton; RadioButton4: TRadioButton; RadioButton5: TRadioButton; RadioButton2: TRadioButton; Panel2: TPanel; RadioButton6: TRadioButton; RadioButton7: TRadioButton; RadioButton8: TRadioButton; RadioButton9: TRadioButton; procedure CheckBox1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.CheckBox1Click(Sender: TObject); begin Timer1.Enabled:=CheckBox1.Checked; end;
const k_v=24; { количество вершин } k_r=44; { количество ребер } k_g=22; { количество граней } d=-1000; { центр. проекция }
type m_v=array[1..k_v,1..3] of single; //массив вершин - XYZ m_r=array[1..k_r,1..2] of integer; //массив ребер - ном.вершин m_v2=array[1..k_v,1..3] of integer; m_g=array[1..k_g,1..5] of integer; //массив граней (до5ном.вершин)
var a:m_v; { массив вершин } b:m_r; { массив ребер } g:m_g; { массив граней } p,a1,a2:m_v; pr:m_v2; { массив вершин в проекции } q,w,e,kx,ky,kz,wx,wy,wz,rad:integer; x0,y0,z0,x,y,ugol,z1:single; f:boolean; xv1,yv1,xv2,yv2:integer; maxX, maxY:integer; VAR oX,oY,oZ:single; // вектор освещения
{----- Масштабирование -----} procedure MASH(var a,b:m_v; kx,ky,kz:integer); var q:integer; begin for q:=1 to k_v do begin b[q,1]:=a[q,1]*kx; b[q,2]:=a[q,2]*ky; b[q,3]:=a[q,3]*kz; end; end;
{----- Поворот фигуры -----} procedure POVOROT(var a,b:m_v; wx,wy,wz:integer); var q:integer; ug,co,si:single; c,c1:m_v; begin c:=a; c1:=c; if wx<>0 then begin ug:=wx*pi/180; for q:=1 to k_v do begin co:=cos(ug); si:=sin(ug); c[q,2]:=c1[q,2]*co-c1[q,3]*si; c[q,3]:=c1[q,2]*si+c1[q,3]*co; c[q,1]:=c1[q,1]; end; c1:=c; end; if wy<>0 then begin ug:=wy*pi/180; for q:=1 to k_v do begin co:=cos(ug); si:=sin(ug); c[q,1]:=c1[q,1]*co+c1[q,3]*si; c[q,3]:=-c1[q,1]*si+c1[q,3]*co; c[q,2]:=c1[q,2]; end; c1:=c; end; if wz<>0 then begin ug:=wz*pi/(180*0.5); for q:=1 to k_v do begin co:=cos(ug); si:=sin(ug); c[q,1]:=c1[q,1]*co-c1[q,2]*si; c[q,2]:=c1[q,1]*si+c1[q,2]*co; c[q,3]:=c1[q,3]; end; c1:=c; end; b:=c1; end;
{----- Перенос -----} procedure PERENOS(var a,b:m_v; var dx,dy,dz:single); var q:integer; begin for q:=1 to k_v do begin b[q,1]:=a[q,1]+dx; b[q,2]:=a[q,2]+dy; b[q,3]:=a[q,3]+dz; end; end;
{----- Проекция на плоскость экрана -----} procedure PROEK(var a:m_v; var b:m_v2); var q:integer; z,xx,yy:single; begin xx:=maxX/2; yy:=maxY/2; for q:=1 to k_v do begin z:=a[q,3]; b[q,1]:=round(a[q,1]*d/z+xx); b[q,2]:=round(a[q,2]*d/z+yy); b[q,3]:=round(a[q,3]*100); end; end;
procedure TForm1.FormCreate(Sender: TObject); begin {------ Задание вершин шестеренки с 4 зубцами ------} a[1,1]:=0.25;a[1,2]:=0;a[1,3]:=0; a[2,1]:=0.75;a[2,2]:=0;a[2,3]:=0; a[3,1]:=1;a[3,2]:=1;a[3,3]:=0; a[4,1]:=0;a[4,2]:=1;a[4,3]:=0; a[5,1]:=0.25;a[5,2]:=0;a[5,3]:=0.5; a[6,1]:=0.75;a[6,2]:=0;a[6,3]:=0.5; a[7,1]:=1;a[7,2]:=1;a[7,3]:=0.5; a[8,1]:=0;a[8,2]:=1;a[8,3]:=0.5; a[9,1]:=-1;a[9,2]:=1.25;a[9,3]:=0; a[10,1]:=-1;a[10,2]:=1.75;a[10,3]:=0; a[11,1]:=0;a[11,2]:=2;a[11,3]:=0; a[12,1]:=-1;a[12,2]:=1.25;a[12,3]:=0.5; a[13,1]:=-1;a[13,2]:=1.75;a[13,3]:=0.5; a[14,1]:=0;a[14,2]:=2;a[14,3]:=0.5; a[15,1]:=0.25;a[15,2]:=3;a[15,3]:=0; a[16,1]:=0.75;a[16,2]:=3;a[16,3]:=0; a[17,1]:=1;a[17,2]:=2;a[17,3]:=0; a[18,1]:=0.25;a[18,2]:=3;a[18,3]:=0.5; a[19,1]:=0.75;a[19,2]:=3;a[19,3]:=0.5; a[20,1]:=1;a[20,2]:=2;a[20,3]:=0.5; a[21,1]:=2;a[21,2]:=1.75;a[21,3]:=0; a[22,1]:=2;a[22,2]:=1.25;a[22,3]:=0; a[23,1]:=2;a[23,2]:=1.75;a[23,3]:=0.5; a[24,1]:=2;a[24,2]:=1.25;a[24,3]:=0.5; {-------- Задание граней -------------} g[1,1]:=1;g[1,2]:=2;g[1,3]:=3;g[1,4]:=4; g[2,1]:=5;g[2,2]:=8;g[2,3]:=7;g[2,4]:=6; g[3,1]:=1;g[3,2]:=5;g[3,3]:=6;g[3,4]:=2; g[4,1]:=3;g[4,2]:=2;g[4,3]:=6;g[4,4]:=7; g[5,1]:=1;g[5,2]:=4;g[5,3]:=8;g[5,4]:=5; g[6,1]:=7;g[6,2]:=8;g[6,3]:=14;g[6,4]:=20; g[7,1]:=4;g[7,2]:=9;g[7,3]:=12;g[7,4]:=8; g[8,1]:=8;g[8,2]:=12;g[8,3]:=13;g[8,4]:=14; g[9,1]:=9;g[9,2]:=10;g[9,3]:=13;g[9,4]:=12; g[10,1]:=10;g[10,2]:=11;g[10,3]:=14;g[10,4]:=13; g[11,1]:=9;g[11,2]:=4;g[11,3]:=11;g[11,4]:=10; g[12,1]:=3;g[12,2]:=17;g[12,3]:=11;g[12,4]:=4; g[13,1]:=11;g[13,2]:=15;g[13,3]:=18;g[13,4]:=14; g[14,1]:=15;g[14,2]:=16;g[14,3]:=19;g[14,4]:=18; g[15,1]:=16;g[15,2]:=17;g[15,3]:=20;g[15,4]:=19; g[16,1]:=14;g[16,2]:=18;g[16,3]:=19;g[16,4]:=20; g[17,1]:=11;g[17,2]:=17;g[17,3]:=16;g[17,4]:=15; g[18,1]:=17;g[18,2]:=21;g[18,3]:=23;g[18,4]:=20; g[19,1]:=21;g[19,2]:=22;g[19,3]:=24;g[19,4]:=23; g[20,1]:=22;g[20,2]:=3;g[20,3]:=7;g[20,4]:=24; g[21,1]:=20;g[21,2]:=23;g[21,3]:=24;g[21,4]:=7; g[22,1]:=3;g[22,2]:=22;g[22,3]:=21;g[22,4]:=17; {-------- Задание ребер -------------} b[1,1]:=1;b[1,2]:=2; b[2,1]:=2;b[2,2]:=3; b[3,1]:=3;b[3,2]:=4; b[4,1]:=4;b[4,2]:=1; b[5,1]:=5;b[5,2]:=6; b[6,1]:=6;b[6,2]:=7; b[7,1]:=7;b[7,2]:=8; b[8,1]:=8;b[8,2]:=5; b[9,1]:=1;b[9,2]:=5; b[10,1]:=2;b[10,2]:=6; b[11,1]:=3;b[11,2]:=7; b[12,1]:=4;b[12,2]:=8; b[13,1]:=4;b[13,2]:=9; b[14,1]:=9;b[14,2]:=10; b[15,1]:=10;b[15,2]:=11; b[16,1]:=4;b[16,2]:=11; b[17,1]:=8;b[17,2]:=12; b[18,1]:=12;b[18,2]:=13; b[19,1]:=13;b[19,2]:=14; b[20,1]:=14;b[20,2]:=8; b[21,1]:=9;b[21,2]:=12; b[22,1]:=10;b[22,2]:=13; b[23,1]:=11;b[23,2]:=14; b[24,1]:=11;b[24,2]:=15; b[25,1]:=15;b[25,2]:=16; b[26,1]:=16;b[26,2]:=17; b[27,1]:=17;b[27,2]:=11; b[28,1]:=14;b[28,2]:=18; b[29,1]:=18;b[29,2]:=19; b[30,1]:=19;b[30,2]:=20; b[31,1]:=20;b[31,2]:=14; b[32,1]:=15;b[32,2]:=18; b[33,1]:=16;b[33,2]:=19; b[34,1]:=17;b[34,2]:=20; b[35,1]:=17;b[35,2]:=21; b[36,1]:=21;b[36,2]:=22; b[37,1]:=22;b[37,2]:=3; b[38,1]:=3;b[38,2]:=17; b[39,1]:=20;b[39,2]:=23; b[40,1]:=23;b[40,2]:=24; b[41,1]:=24;b[41,2]:=7; b[42,1]:=23;b[42,2]:=21; b[43,1]:=22;b[43,2]:=24; b[44,1]:=7;b[44,2]:=20; {-----------------------} x0:=0; y0:=0; z0:=0; { начальные координаты } kx:=2; ky:=2; kz:=2; { коэффициенты масштабирования } wx:=1; wy:=1; wz:=0; { углы поворота шестеренки } MASH(a,a1, kx,ky,kz); ugol:=0; rad:=10; z1:=10; { движения шестеренки } oX:=1; oY:=1; oZ:=1; //нормированный вектор maxX:=Image1.Width; maxY:=Image1.Height; end; //============== процедура для 3 лаб.работы - закраска граней ================== procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); //задаем вектор освещения из мыши в центр var xx,yy,zz:integer; rr:single; begin xx:=X-maxX div 2; yy:=Y-maxY div 2; zz:=400-Round(sqrt(sqr(xx)+sqr(yy))); rr:=sqrt(sqr(xx)+sqr(yy)+sqr(zz)); oX:=xx/rr; oY:=yy/rr; oZ:=zz/rr; end; //замена Poligon(), но с другими параметрами procedure Polygon123(var aa:m_v2; gr:integer); //аa-массив спроецированных вершин 2D var q,i:integer; ver:array[1..4,1..3] of single; //массив нормалей 4 вершин грани gr begin //gr-номер грани из g[gr] With Form1,Form1.Image1.Canvas do begin if RadioButton6.Checked then begin //Гуро - например //на входе грань g[gr] с 4 вершинами - ищем соседние грани в g[] для каждой вершины //далее 4 раза:для соседних граней с вершинами из a2[] находим нормали и усредняем // по вектору освещения (oX,oY,oZ) и этой нормали определяем интенсивность в вершине // далее 2 раза: закрашиваем треугольники 123 и 341 из вершин грани с интерполяцией end; end; end;
{================= Рисование фигуры для 2 лабы ============================} procedure PRINT0(var a:m_v2; var b:m_r); //а-массив вершин, уже спроецированный, т.е.2D var q,i,v1,v2, x1,x2,y1,y2:integer; sort:boolean; //b-массив ребер, не изменяется poly:array[1..4] of Tpoint; // грань remas:array[1..k_g] of integer; //массив косвенной сортировки по Z begin xv1:=maxX-1; yv1:=maxY-1; xv2:=0; yv2:=0; // габариты грани for i:=1 to k_g do remas[i]:=i; {del unview} With Form1,Form1.Image1.Canvas do begin Brush.Color:=clWhite; Pen.Color:=clWhite; //доступ к графике if RadioButton5.Checked then for q:=1 to k_g do begin //demo Poly[1].X:=a[g[q,1],1]; Poly[1].Y:=a[g[q,1],2]; Poly[2].X:=a[g[q,2],1]; Poly[2].Y:=a[g[q,2],2]; Poly[3].X:=a[g[q,3],1]; Poly[3].Y:=a[g[q,3],2]; Poly[4].X:=a[g[q,4],1]; Poly[4].Y:=a[g[q,4],2]; Brush.Color:=Brush.Color-080808; Polygon(Poly); end; if RadioButton1.Checked then begin {sort of Zmax - Художника}
Repeat sort:=false; //сортировка граней, рекомендуется в отдельном массиве Until not sort; {sort of Zmax}(**) // рисуем грани for q:=1 to k_g do begin for i:=1 to 4 do begin poly[i].X:=000; poly[i].Y:=111; end; Brush.Color:=clGray; if false then Polygon(Poly); end; end; // можно свои цвета и разные if RadioButton2.Checked then begin Brush.Color:=clGreen; //ориентация граней по формуле for q:=1 to k_g do begin //poly[].X:=
Brush.Color:=clGreen; if false then Polygon(Poly); end; end; {only karkas} if RadioButton3.Checked then begin end; //трассировка лучей if RadioButton4.Checked then begin end; //Z-буфер if RadioButton9.Checked then for q:=1 to k_r do begin v1:=b[q,1]; v2:=b[q,2]; //рисуем ребра x1:=a[v1,1]; y1:=a[v1,2]; x2:=a[v2,1]; y2:=a[v2,2]; if x1<xv1 then xv1:=x1 else if x1>xv2 then xv2:=x1; // габариты if x2<xv1 then xv1:=x2 else if x2>xv2 then xv2:=x2; if y1<yv1 then yv1:=y1 else if y1>yv2 then yv2:=y1; if y2<yv1 then yv1:=y2 else if y2>yv2 then yv2:=y2; Pen.Color:=Pen.Color-080808; MoveTo(x1,y1); LineTo(x2,y2); end; if xv1<0 then xv1:=0; if xv2<0 then xv2:=0; if yv1<0 then yv1:=0; if yv2<0 then yv2:=0; end; end;
procedure TForm1.Timer1Timer(Sender: TObject); var i,j:integer; cc:tcolor; begin //рисование Image1.Canvas.Brush.Color:=clBlack; Image1.Canvas.FillRect(Rect(0,0,Image1.Width,Image1.Height)); //640x480 POVOROT(a1,a2, wx,wy,wz); a1:=a2; //вариант относительных поворотов //wx:=wx+1; wy:=wy+1; //wz:=wz+1; //вариант абсолютных поворотов x:=rad*sin(ugol); y:=rad*cos(ugol); ugol:=ugol+pi/180; if (z1<140)and(not(f)) then z1:=z1+1 else f:=true; if (z1>=40)and(f) then z1:=z1-1 else f:=false; PERENOS(a2,p, x,y,z1); PROEK(p,pr); // While (port[$3DA] and 8)<>0 do; { wait end sync } // While (port[$3DA] and 8)=0 do; { wait begin sync } PRINT0(pr, b); {paint} end;
end. { unit1.dfm } object Form1: TForm1 Left = 192 Top = 118 Width = 847 Height = 541 Caption = #1040#1085#1080#1084#1072#1090#1086#1088'3D' Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [] OldCreateOrder = False OnCreate = FormCreate PixelsPerInch = 96 TextHeight = 13 object Image1: TImage Left = 8 Top = 8 Width = 641 Height = 481 OnMouseDown = Image1MouseDown end object CheckBox1: TCheckBox Left = 680 Top = 48 Width = 97 Height = 33 Caption = #1076#1074#1080#1078#1077#1085#1080#1077 TabOrder = 0 OnClick = CheckBox1Click end object Panel1: TPanel Left = 664 Top = 120 Width = 153 Height = 161 Caption = #1052#1077#1090#1086#1076#1099' '#1091#1076#1072#1083#1077#1085#1080#1103':' Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [] ParentFont = False TabOrder = 1 object RadioButton1: TRadioButton Left = 16 Top = 24 Width = 113 Height = 17 Caption = #1061#1091#1076#1086#1078#1085#1080#1082#1072 TabOrder = 0 end object RadioButton3: TRadioButton Left = 16 Top = 96 Width = 121 Height = 17 Caption = #1090#1088#1072#1089#1089#1080#1088#1086#1074#1082#1072' '#1083#1091#1095#1077#1081 TabOrder = 1 end object RadioButton4: TRadioButton Left = 16 Top = 112 Width = 113 Height = 17 Caption = 'Z-'#1073#1091#1092#1077#1088 TabOrder = 2 end object RadioButton5: TRadioButton Left = 16 Top = 0 Width = 113 Height = 17 Caption = '-demo-' TabOrder = 3 end object RadioButton2: TRadioButton Left = 16 Top = 40 Width = 121 Height = 17 Caption = #1086#1088#1080#1077#1085#1090#1072#1094#1080#1103' '#1075#1088#1072#1085#1077#1081 TabOrder = 4 end object RadioButton9: TRadioButton Left = 16 Top = 136 Width = 113 Height = 17 Caption = #1090#1086#1083#1100#1082#1086' '#1082#1072#1088#1082#1072#1089 Checked = True TabOrder = 5 TabStop = True end end object Panel2: TPanel Left = 664 Top = 320 Width = 153 Height = 169 Caption = #1052#1077#1090#1086#1076#1099' '#1079#1072#1082#1088#1072#1089#1082#1080':' TabOrder = 2 object RadioButton6: TRadioButton Left = 32 Top = 24 Width = 89 Height = 17 Caption = #1052#1077#1090#1086#1076' '#1043#1091#1088#1086 TabOrder = 0 end object RadioButton7: TRadioButton Left = 32 Top = 48 Width = 105 Height = 17 Caption = #1052#1077#1090#1086#1076' '#1060#1086#1085#1075#1072 TabOrder = 1 end object RadioButton8: TRadioButton Left = 32 Top = 112 Width = 97 Height = 17 Caption = #1060#1086#1090#1086#1075#1088#1072#1092#1080#1103 TabOrder = 2 end end object Timer1: TTimer Enabled = False Interval = 100 OnTimer = Timer1Timer Left = 792 Top = 48 end end Выводы: 1. Самостоятельная программная реализация алгоритма движения трехмерного каркасного объекта и удаления его невидимых граней позволяет освоить преобразование координат и законы проекции. 2. Самостоятельная программная реализация алгоритма закраски видимых граней с учетом источника освещения позволяет изучить законы освещения и повысить реалистичность изображения.
Учебное издание
Составитель Егоров Станислав Феликсович
|
||||||||||
|
Последнее изменение этой страницы: 2020-10-24; просмотров: 271; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.217.21 (0.009 с.) |