Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2015.12.06;
Скачать: [xml.tar.bz2];

Вниз

Замена Chart - графика для слабых компьютеров?   Найти похожие ветки 

 
Who_are_you? ©   (2014-04-24 14:58) [0]

При запуске программы на старом компе Pentium II, Win 98, ОЗУ-128 MБ получил огромные тормоза.
Стал анализировать и выяснил - то что летало на новом компе.

Это Chart. Ждать приходится около 3 минут.
Заремил  с десяток строк, начинающиеся на  Chart, - выполнение 2 секунды.

Посоветуйте как быстро (в смысле времени выполнения компьютером и времени написания программы) сделать графическое представление (X,Y) цифровых данных?  Может у кого есть заготовки, Unit-ы ?


 
MBo ©   (2014-04-24 15:31) [1]

Выводить не все данные, а выборку из них

Если в чарт сто тысяч точек выводить, постоянно обновляя, то и новый комп будет тормозить


 
junglecat   (2014-04-24 16:18) [2]

а у чарта нет чего-нить типа beginupdate / endupdate на время обновления?


 
Who_are_you? ©   (2014-04-24 17:10) [3]

А выводить нужно 4 графика от 100 до 16 000 точек в секунду ( дискретизация 100Гц -16 кГц).


 
Ega23 ©   (2014-04-24 17:16) [4]

Зачем 16000 точек на графике? Нельзя упростить?


 
junglecat   (2014-04-24 17:31) [5]

а как вообще можно увидеть 16000 точек на одном экране?


 
Jeer ©   (2014-04-24 18:55) [6]

>А выводить нужно 4 графика от 100 до 16 000 точек в секунду ( >дискретизация 100Гц -16 кГц).

Интересно, как это Вы собираетесь выводить графики с частотой 16 кГц ?


 
Ega23 ©   (2014-04-24 18:59) [7]


> а как вообще можно увидеть 16000 точек на одном экране?


Ну, допустим, у меня на экране 2304000 точек. В принципе, влезет порядка 150 таких графиков.
Но зачем?


 
junglecat   (2014-04-24 19:20) [8]

даже если представить, что вдруг получилось вывести на монитор 16000 точек/сек, то каким зрением должен обладать смотрящий, чтобы хоть что-то осознать?


 
Ega23 ©   (2014-04-24 20:45) [9]


>  то каким зрением должен обладать смотрящий, чтобы хоть
> что-то осознать?


Дискретным.


 
Who_are_you? ©   (2014-04-25 09:36) [10]

C критикой согласен.
Цифру бросил необдуманно.
Посмотрел на график - больше 1000 на каждый график не нужно.
Значит до ~1000 выводим в реальном времени, а более 1кГц - фрагментально или с запоминанием и дальнейшем выводе.

Пока нашел в инете такое предложение:
(автор не известен, а автор комментария Алексей Легкунец, Королевство Delphi)

unit Graf;
interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs;
type
 TForm1 = class(TForm)
   procedure FormPaint(Sender: TObject);
   procedure FormResize(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;
var
 Form1: TForm1;

implementation

{$R *.dfm}
Function f(x:real):real;
begin
f:=2*Sin(x)*exp(x/5);
end;
// строит график функции
procedure GrOfFunc;
var
x1,x2:real; // границы изменения аргумента функции
y1,y2:real; // границы изменения значения функции
x:real; // аргумент функции
y:real; // значение функции в точке х
dx:real; // приращение аргумента

l,b:integer; // левый нижний угол области вывода графика
w,h:integer; // ширина и высота области вывода графика
mx,my:real; // масштаб по осям X и Y
x0,y0:integer; // точка - начало координат
begin                                           // область вывода графика
l:=10;                                          // X - координата левого верхнего угла
b:=Form1.ClientHeight-20;               //У - координата левого верхнего угла
h:=Form1.ClientHeight-40; // высота
w:=Form1.Width-40; // ширина
x1:=0; // нижняя граница диапазона аргумента
x2:=25; // верхняя граница диапазона аргумента
dx:=0.01; // шаг аргумента

// найдем максимальное и минимальное значения
// функции на отрезке [x1,x2]

y1:=f(x1); // минимум
y2:=f(x1); //максимум
x:=x1;
repeat
y := f (x);
if y < y1 then y1:=y;
if y > y2 then y2:=y;
x:=x+dx; until (x >= x2);
// вычислим масштаб
my:=h/abs(y2-y1); // масштаб по оси Y
mx:=w/abs(x2-x1); // масштаб по оси X
x0:=1;
y0:=b-Abs(Round(y1*my)) ;
with form1.Canvas do
begin              // оси
MoveTo(l,b);LineTo(l,b-h);
MoveTo(x0,y0);LineTo(x0+w,y0);
TextOut(l+5,b-h,FloatToStrF(y2,ffGeneral,6,3));
TextOut(l+5,b,FloatToStrF(y1,ffGeneral,6,3));
// построение графика
x:=x1; repeat
y:=f(x);
Pixels[x0+Round(x*mx),y0-Round(y*my)]:=clRed;
x:=x+dx;
until (x >= x2);
end;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
GrOfFunc; end;
// изменился размер окна программы

procedure TForm1.FormResize(Sender: TObject);
begin
// очистить форму
form1.Canvas.FillRect(Rect(0,0,ClientWidth,ClientHeight));
// построить график
GrOfFunc;
end;
end.


Продолжаю поиски. Что взять за основу или самому придумать - еще не решил.
Всем, кто уже отозвался - большое спасибо.


 
junglecat   (2014-04-25 09:50) [11]

как минимум, вывод графики надо буферизовать. Рисовать в Bitmap.Canvas, потом StretchDraw


 
kilkennycat ©   (2014-04-25 18:56) [12]


> у меня на экране 2304000 точек.

а матрица глаз?


 
Who_are_you? ©   (2014-06-04 19:44) [13]

junglecat   (25.04.14 09:50) [11]

как минимум, вывод графики надо буферизовать. Рисовать в Bitmap.Canvas, потом StretchDraw

Заменил в тексте, что выше with Canvas do
на
with Bitmap.Canvas do
и сделал вывод
Bitmap.Canvas.StretchDraw(Rect(0, 0, Bitmap.Width,
       Bitmap.Height), Bitmap);

- в результате форма белая: графика нет.

Пожалуйста, предложите 5 строчек рабочих рисования Bitmap.Canvas и отображения Bitmap.Canvas.StretchDraw


 
Who_are_you? ©   (2014-06-04 19:54) [14]

Где-то грабли?
Даю, на всякие пожарные, весь текст.


// &#234;&#224;&#234; &#236;&#232;&#237;&#232;&#236;&#243;&#236;, &#226;&#251;&#226;&#238;&#228; &#227;&#240;&#224;&#244;&#232;&#234;&#232; &#237;&#224;&#228;&#238; &#225;&#243;&#244;&#229;&#240;&#232;&#231;&#238;&#226;&#224;&#242;&#252;.
//  &#208;&#232;&#241;&#238;&#226;&#224;&#242;&#252; &#226; Bitmap.Canvas, &#239;&#238;&#242;&#238;&#236; StretchDraw

unit pas_Low_Graf;

interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
   Button1: TButton;
   procedure GrOfFunc;
   procedure FormPaint(Sender: TObject);
   procedure FormResize(Sender: TObject);
   procedure Button1Click(Sender: TObject);
   procedure FormCreate(Sender: TObject);

private
  { Private declarations }
public
  { Public declarations }
end;
var
Form1: TForm1;

implementation
var
 BitMap:TBitMap;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  BitMap:=TBitMap.Create;
//   GrOfFunc;
end;

//********************************************************
Function f(x:real):real;
begin
f:=2*Sin(x)*exp(x/5);
end;

//********************************************************
// &#241;&#242;&#240;&#238;&#232;&#242; &#227;&#240;&#224;&#244;&#232;&#234; &#244;&#243;&#237;&#234;&#246;&#232;&#232;
procedure TForm1.GrOfFunc;
var
x1,x2:real;       // &#227;&#240;&#224;&#237;&#232;&#246;&#251; &#232;&#231;&#236;&#229;&#237;&#229;&#237;&#232;&#255; &#224;&#240;&#227;&#243;&#236;&#229;&#237;&#242;&#224; &#244;&#243;&#237;&#234;&#246;&#232;&#232;
y1,y2:real;       // &#227;&#240;&#224;&#237;&#232;&#246;&#251; &#232;&#231;&#236;&#229;&#237;&#229;&#237;&#232;&#255; &#231;&#237;&#224;&#247;&#229;&#237;&#232;&#255; &#244;&#243;&#237;&#234;&#246;&#232;&#232;
x:real;           // &#224;&#240;&#227;&#243;&#236;&#229;&#237;&#242; &#244;&#243;&#237;&#234;&#246;&#232;&#232;
y:real;           // &#231;&#237;&#224;&#247;&#229;&#237;&#232;&#229; &#244;&#243;&#237;&#234;&#246;&#232;&#232; &#226; &#242;&#238;&#247;&#234;&#229; &#245;
dx:real;          // &#239;&#240;&#232;&#240;&#224;&#249;&#229;&#237;&#232;&#229; &#224;&#240;&#227;&#243;&#236;&#229;&#237;&#242;&#224;

l,b:integer;      // &#235;&#229;&#226;&#251;&#233; &#237;&#232;&#230;&#237;&#232;&#233; &#243;&#227;&#238;&#235; &#238;&#225;&#235;&#224;&#241;&#242;&#232; &#226;&#251;&#226;&#238;&#228;&#224; &#227;&#240;&#224;&#244;&#232;&#234;&#224;
w,h:integer;      // &#248;&#232;&#240;&#232;&#237;&#224; &#232; &#226;&#251;&#241;&#238;&#242;&#224; &#238;&#225;&#235;&#224;&#241;&#242;&#232; &#226;&#251;&#226;&#238;&#228;&#224; &#227;&#240;&#224;&#244;&#232;&#234;&#224;
mx,my:real;       // &#236;&#224;&#241;&#248;&#242;&#224;&#225; &#239;&#238; &#238;&#241;&#255;&#236; X &#232; Y
x0,y0:integer;    // &#242;&#238;&#247;&#234;&#224; - &#237;&#224;&#247;&#224;&#235;&#238; &#234;&#238;&#238;&#240;&#228;&#232;&#237;&#224;&#242;

begin                          // &#238;&#225;&#235;&#224;&#241;&#242;&#252; &#226;&#251;&#226;&#238;&#228;&#224; &#227;&#240;&#224;&#244;&#232;&#234;&#224;
l:=10;                         // X - &#234;&#238;&#238;&#240;&#228;&#232;&#237;&#224;&#242;&#224; &#235;&#229;&#226;&#238;&#227;&#238; &#226;&#229;&#240;&#245;&#237;&#229;&#227;&#238; &#243;&#227;&#235;&#224;
b:=Form1.ClientHeight-20;      // &#211; - &#234;&#238;&#238;&#240;&#228;&#232;&#237;&#224;&#242;&#224; &#235;&#229;&#226;&#238;&#227;&#238; &#226;&#229;&#240;&#245;&#237;&#229;&#227;&#238; &#243;&#227;&#235;&#224;
h:=Form1.ClientHeight-40;  // &#226;&#251;&#241;&#238;&#242;&#224;
w:=Form1.Width-40;         // &#248;&#232;&#240;&#232;&#237;&#224;
x1:=0;                        // &#237;&#232;&#230;&#237;&#255;&#255; &#227;&#240;&#224;&#237;&#232;&#246;&#224; &#228;&#232;&#224;&#239;&#224;&#231;&#238;&#237;&#224; &#224;&#240;&#227;&#243;&#236;&#229;&#237;&#242;&#224;
x2:=25;                       // &#226;&#229;&#240;&#245;&#237;&#255;&#255; &#227;&#240;&#224;&#237;&#232;&#246;&#224; &#228;&#232;&#224;&#239;&#224;&#231;&#238;&#237;&#224; &#224;&#240;&#227;&#243;&#236;&#229;&#237;&#242;&#224;
dx:=0.01;                     // &#248;&#224;&#227; &#224;&#240;&#227;&#243;&#236;&#229;&#237;&#242;&#224;

// &#237;&#224;&#233;&#228;&#229;&#236; &#236;&#224;&#234;&#241;&#232;&#236;&#224;&#235;&#252;&#237;&#238;&#229; &#232; &#236;&#232;&#237;&#232;&#236;&#224;&#235;&#252;&#237;&#238;&#229; &#231;&#237;&#224;&#247;&#229;&#237;&#232;&#255;
// &#244;&#243;&#237;&#234;&#246;&#232;&#232; &#237;&#224; &#238;&#242;&#240;&#229;&#231;&#234;&#229; [x1,x2]
y1:=f(x1); // &#236;&#232;&#237;&#232;&#236;&#243;&#236;
y2:=f(x1); //&#236;&#224;&#234;&#241;&#232;&#236;&#243;&#236;
x:=x1;
repeat
 y := f (x);
 if y < y1 then y1:=y;
 if y > y2 then y2:=y;
 x:=x+dx;
until (x >= x2);
// &#226;&#251;&#247;&#232;&#241;&#235;&#232;&#236; &#236;&#224;&#241;&#248;&#242;&#224;&#225;
my:=h/abs(y2-y1); // &#236;&#224;&#241;&#248;&#242;&#224;&#225; &#239;&#238; &#238;&#241;&#232; Y
mx:=w/abs(x2-x1); // &#236;&#224;&#241;&#248;&#242;&#224;&#225; &#239;&#238; &#238;&#241;&#232; X
x0:=1;
y0:=b-Abs(Round(y1*my)) ;
with Bitmap.Canvas do
//with Form1.Canvas do
begin              // &#238;&#241;&#232;
 MoveTo(l,b);LineTo(l,b-h);
 MoveTo(x0,y0);LineTo(x0+w,y0);
 TextOut(l+5,b-h,FloatToStrF(y2,ffGeneral,6,3));
 TextOut(l+5,b,FloatToStrF(y1,ffGeneral,6,3));
 // &#239;&#238;&#241;&#242;&#240;&#238;&#229;&#237;&#232;&#229; &#227;&#240;&#224;&#244;&#232;&#234;&#224;
 x:=x1;
 repeat
   y:=f(x);
   Pixels[x0+Round(x*mx),y0-Round(y*my)]:=clRed;
   x:=x+dx;
 until (x >= x2);
end;
end;

//********************************************************
procedure TForm1.FormPaint(Sender: TObject);
begin
GrOfFunc;
  Bitmap.Canvas.StretchDraw(Rect(0, 0, Bitmap.Width,
       Bitmap.Height), Bitmap);
end;

//********************************************************
// &#232;&#231;&#236;&#229;&#237;&#232;&#235;&#241;&#255; &#240;&#224;&#231;&#236;&#229;&#240; &#238;&#234;&#237;&#224; &#239;&#240;&#238;&#227;&#240;&#224;&#236;&#236;&#251;
procedure TForm1.FormResize(Sender: TObject);
begin
// &#238;&#247;&#232;&#241;&#242;&#232;&#242;&#252; &#244;&#238;&#240;&#236;&#243;
Bitmap.Canvas.FillRect(Rect(0,0,ClientWidth,ClientHeight));

// &#239;&#238;&#241;&#242;&#240;&#238;&#232;&#242;&#252; &#227;&#240;&#224;&#244;&#232;&#234;
GrOfFunc;
  Bitmap.Canvas.StretchDraw(Rect(0, 0, Bitmap.Width,
       Bitmap.Height), Bitmap);
end;

//********************************************************
procedure TForm1.Button1Click(Sender: TObject);
begin
  GrOfFunc;
  Bitmap.Canvas.StretchDraw(Rect(0, 0, Bitmap.Width,
       Bitmap.Height), Bitmap);
end;

end.


 
brother ©   (2014-06-04 20:22) [15]

вы "стретчити" на самого себя, а надо на канву формы (или еще куда)...


 
brother ©   (2014-06-04 20:28) [16]

И для начала добейтесь нормальной отрисовки по Button1Click, а уж потом всякие другие условия, ибо в FormResize например, не учитывается размер клиентской области формы...


 
Who_are_you? ©   (2014-06-04 21:50) [17]

Заменил  Bitmap.Canvas.StretchDraw
на
Canvas.draw(0,0,bitmap);  //отрисовываем сам bitmap

и все заработало.


 
Who_are_you? ©   (2014-06-04 21:55) [18]

Сделал так:
Canvas.StretchDraw(Rect(0, 0, Bitmap.Width,Bitmap.Height), Bitmap);

работает.

Спасибо brother!


 
brother ©   (2014-06-05 17:40) [19]

как всегда опять не совсем то)
если Bitmap.Width, Bitmap.Height будут больше размеров формы, то что мы получим? и смылсы отрисовывать через Stretch, если отрисовываемя область равна (?) размеру выводимой области (канва формы)


 
brother ©   (2014-06-05 17:42) [20]

поясню: Вы реализовали BitBlt через StretchDraw, но зачем?


 
Who_are_you? ©   (2014-06-06 12:22) [21]

Честно говоря,
так и не понял, чем лучше отображать на стареньком ноуте:
Canvas.draw
или
Canvas.StretchDraw(Rect


Bitmap.Width := ClientWidth;
Bitmap.Height:= ClientHeight;

// очистить форму
Bitmap.Canvas.FillRect(Rect(0,0,ClientWidth,ClientHeight));

// построить график
GrOfFunc;

// Canvas.draw(0,0,bitmap);  //отрисовываем сам bitmap
Canvas.StretchDraw(Rect(0, 0, Bitmap.Width,Bitmap.Height), Bitmap);


 
Who_are_you? ©   (2014-06-06 12:33) [22]

brother ©   (05.06.14 17:40) [19]
смысл отрисовывать через Stretch, если отрисовываемая область равна (?) размеру выводимой области (канва формы)

Вся канитель из-за пожелания:
(для быстроты выполнения)

junglecat   (25.04.14 09:50) [11]

как минимум, вывод графики надо буферизовать. Рисовать в Bitmap.Canvas, потом StretchDraw


 
MBo ©   (2014-06-06 12:47) [23]

А Вы понимаете, что такое Stretch?


 
Who_are_you? ©   (2014-06-06 12:55) [24]

MBo ©   (06.06.14 12:47) [23]

А Вы понимаете, что такое Stretch?

Согласно справочнику:
Методы для вывода картинок на канву - Draw и StretchDraw, В качестве параметров указываются прямоугольник и графический объект для вывода (это может быть TBitmap, TIcon или TMetafile). StretchDraw отличается тем, что растягивает или сжимает картинку так, чтобы она заполнила весь указанный прямоугольник


 
MBo ©   (2014-06-06 13:02) [25]

Так это самое растяжение требуется или нет?


 
Who_are_you? ©   (2014-06-06 14:44) [26]


MBo ©   (06.06.14 13:02) [25]

Так это самое растяжение требуется или нет?


В данный момент нет.
А а дальнейшем хочу использовать как масштабирование.


 
Who_are_you? ©   (2014-06-10 16:44) [27]

Отображаю:
Canvas.draw(0,0,bitmap);  //отрисовываем сам bitmap
А если так:
Image1.Canvas.StretchDraw(Rect(0, 0, Image1.Width,Image1.Height), Bitmap);
то теряется контрастность и пропадают точки.
Ширина и высота в обоих случаях одинаковая.

Может есть лучший вариант?
Я рисую 4-е графика, каждый имеет свой Bitmap, а потом нужно их разместить на форме в определенных местах.


 
brother ©   (2014-06-10 17:20) [28]

это стретч ужимая картинку выкидиывает пикселы...


 
brother ©   (2014-06-10 17:31) [29]

зы. скриншоты покажи, что происходит...


 
Who_are_you? ©   (2014-06-11 09:36) [30]

brother ©   (10.06.14 17:20) [28]

это стретч ужимая картинку выкидиывает пикселы...


Спасибо, да, стретч.
Удивительно, уменьшая размер через стретч, плотность должна увеличиваться, а на самом деле выбрасываются точки.

P.S.  Cкриншоты не знаю как на этом сайте выложить.


 
Inovet ©   (2014-06-11 10:00) [31]

> [30] Who_are_you? ©   (11.06.14 09:36)
> плотность должна увеличиваться, а на самом деле выбрасываются точки.

Откуда же он знает где там у тебя нужные точки, а где не нужные - для него все точки одинаковые.

А сразу выводить как надо почему не получается?


 
brother ©   (2014-06-11 11:56) [32]

> плотность должна увеличиваться

чего? как было 72dpi,так и остается!


 
MBo ©   (2014-06-11 19:43) [33]

SetStretchBltMode c HALFTONE поможет улучшить качество сжатого изображения


 
Who_are_you? ©   (2014-06-17 12:03) [34]

Продолжение: чтение с файла, обработка, замена Chart.

Всем большое спасибо за помощь по быстродействию при работе с файлами в теме Два байта в одно число

Получается, что не нужно читать фрагментами файл, а для быстродействия его нужно прочитать весь, запомнить в матрицу (у меня это n-кбайт строк по 10 байт), а потом делать математ. вычисления и отображать через BitMap.Canvas?


 
Styx   (2014-06-17 16:37) [35]

Вам виднее.


 
Who_are_you? ©   (2014-06-17 17:22) [36]

// 1
 Fail_rd :array[1..100,1..8] of byte;  
...
 Resul:=ReadFile(hInFile,Fail_rd,N_strok_File,Bytes,nil);

// 2
 Fail_rd :array of array of byte;  
...
 SetLength(Fail_rd, 100,8); //
 Resul:=ReadFile(hInFile,Fail_rd,N_strok_File,Bytes,nil);

Почему в 1 случае Fail_rd заполняется, а 2-ом Fail_rd заполнен нулями?
Как воспользоваться динам. матрицой?


 
Германн ©   (2014-06-17 17:30) [37]


>  2-ом Fail_rd заполнен нулями?

Потому что во втором случае ты считываешь по адресу переменной, которая содержит ссылку на область памяти.
Ну и кроме того ты не сможешь одним вызовом ReadFile считать данные в двумерный динамический массив.


 
turbouser ©   (2014-06-17 17:41) [38]


>  Fail_rd

Как вы яхту назовете, так она и поплывет =)


 
Who_are_you? ©   (2014-06-18 11:43) [39]

Согласен, хороший повод посмеяться.
Исправил на File_rd.

Изучаю, как вызовом ReadFile считать данные в двумерный динамический массив.
Если кто-нибудь предложит примеры текста программ, был бы весьма рад !!!


 
Jeer ©   (2014-06-18 14:32) [40]

Динамический N-мерный массив всегда можно логически представить одномерным.
Исходи из этого.



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2015.12.06;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.58 MB
Время: 0.003 c
2-1403357120
cr@nk
2014-06-21 17:25
2015.12.06
Консольное приложение и количество строк на экране


15-1429047002
Юрий
2015-04-15 00:30
2015.12.06
С днем рождения ! 15 апреля 2015 среда


15-1428355804
Юрий
2015-04-07 00:30
2015.12.06
С днем рождения ! 7 апреля 2015 вторник


15-1428960604
Юрий
2015-04-14 00:30
2015.12.06
С днем рождения ! 14 апреля 2015 вторник


2-1398337114
Who_are_you?
2014-04-24 14:58
2015.12.06
Замена Chart - графика для слабых компьютеров?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский