Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.08.05;
Скачать: CL | DM;

Вниз

В реальном времени нужно рисовать график(и) данных.   Найти похожие ветки 

 
SergeyG ©   (2007-05-24 12:46) [0]

Пакеты данных приходят каждые 50 мс (через СОМ-порт). После некоторой обработки на Image1 (расположенной на Form1) нужно поставить точку, соответстующую значению параметра. Размер Image - 500х320. График рисуется так: сначала он "ползет" в правой половине, доходит до конца, изображение правой половины переносится в левую половину, и снова ползет в правой половине. Для рисования использую Bitmap, который заполняется с помощью ScanLine[y], а вывод на Image - Image1.Picture.Graphic:=Bitmap. Ну, еще вывод делаю после прихода четырех пакетов.
Все хорошо, но проблема в том, что при выводе на Image дергается фон изображения.

Как это победить?

Приведу кусочек кода формирования изображения:


//ввод в Битмап черной точки, соотв. параметру Ang2
 p:=Bitmap.ScanLine[(Bh div 2)-(Ang2 div 4)];
 p[(CntRun+Cnt4)*3]:=0;
 p[(CntRun+Cnt4)*3+1]:=0;
 p[(CntRun+Cnt4)*3+2]:=0;
 inc(Cnt4);
 if Cnt4=4 then
//ввели 4 столбика в Битмап - выводим на экран
  begin
   Cnt4:=0;
   Image1.Picture.Graphic:=Bitmap;
   inc(CntRun,4);
   if CntRun>=Bw then
//закончились полэкрана
    begin
     CntRun:=Bw div 2;
     for h1:=0 to (Bh-1) do
      begin
       p:=Bitmap.ScanLine[h1];
       for w:=0 to ((Bw div 2)-1) do
        begin
//перезапись второго полэкрана в первый
//и очистка второго полэкрана
         R1:=p[(w+(Bw div 2))*3];
         p[(w+(Bw div 2))*3]:=$A0;          //цвет фона
         G:=p[(w+(Bw div 2))*3+1];
         p[(w+(Bw div 2))*3+1]:=$A0;;     //цвет фона
         B:=p[(w+(Bw div 2))*3+2];
         p[(w+(Bw div 2))*3+2]:=$A0;;     //цвет фона
         p[w*3]:=R1;
         p[w*3+1]:=G;
         p[w*3+2]:=B;
        end;
      end;
    end;
  end;

Application.ProcessMessages



Bh и Bw - высота и ширина Битмапа и Имиджа,
CntRun - счетчик полэкрана,
Cnt4 - счетчик 4 столбиков.

Где-то раньше:

procedure TForm1.FormCreate(Sender: TObject);
begin
Bitmap:=TBitmap.create;
Bitmap.PixelFormat:=pf24bit;
Bitmap.Height:=Bh;
Bitmap.Width:=Bw;
end;



 
S@shka ©   (2007-05-24 13:09) [1]

Не в тему но почему ж для графиков не юзать мощный TChart? ))


 
SergeyG ©   (2007-05-24 13:47) [2]

нам один программер пытался помочь, тоже использовал TChart, но захлебнулся (и тот и другой :)). Не успевает отработать за около 50 мс.


 
Германн ©   (2007-05-24 13:53) [3]


> В реальном времени нужно рисовать график(и) данных.

В "реальном времени" нужно только принимать данные с целью их последующего сохранения, например в файл. А рисовать их все вовсе не обязательно.


 
SergeyG ©   (2007-05-24 14:07) [4]

50 мс это не так мало, поэтому рисовать надо все.
Вам бы быть моим начальником, который говорил бы, что делать ничего не надо :-).


 
ANB ©   (2007-05-24 14:38) [5]


> SergeyG ©   (24.05.07 12:46)

Буферизацию надо включить. Или самому ее организовать - т.е. рисовать кусок изображения в памяти и за раз (BitBlt вроде как) выводить на экран.


 
ANB ©   (2007-05-24 14:40) [6]

Однако все равно рисование можеть "захлебнуться", посему лучше разнести процесс чтения данных и собственно рисование графика, продумав вопрос - чего делать, если пришедшие данные таки не успевают отображаться.


 
Jeer ©   (2007-05-24 14:45) [7]

Очистить точку по старым координатам
Нарисовать по новым

и все


 
SergeyG ©   (2007-05-24 14:59) [8]

на ABN:
я как раз и рисую в памяти (в Bitmap). А захлебывания вроде нет, т.к. график ползет равномерно, без рывков. Вот только дергание фона Имиджа.

на Jeer:
но это же рисование с помощью MoveTo, LineTo ?. Но у меня может быть рисование до десятка параметров. Может тоже не успеть. Да еще с учетом сетки.


 
Kolan ©   (2007-05-24 15:13) [9]

> тоже использовал TChart

TFastLine? Кроме того есть на сайте раздел форума(кажется) RealTimeCharting


 
MBo ©   (2007-05-24 15:21) [10]

>Вот только дергание фона Имиджа
может помочь установка DobleBuffered для родителя TImage (формы, видимо)


 
Darvin ©   (2007-05-24 15:25) [11]

Все должно успевать за 50 мс. У меня подобная проблема, но 20 мс и все успевает и даже проц не грузит. Я рисую не на битмапе, а на канве TPaintBox, что вообщем-то неважно.
НО! В каждый момент времени (дискретно 20 / 50 мс) нужно рисовать не весь битмап, а только измененную часть. Тогда никаких тормозов не будет.
Лучше это сделать в своем компоненте - наследнике, например того-же TPaintBox. В нем нужно организовать метод GetData (CurValue), в котором:
а) Рисовать отсчет
б) Запоминать его во внутреннем буфере.
Также в компоненте стоит переопределить метод Paint, в котором выполнять перерисовку всех данных из внутреннего буфера. Метод Paint будет вызываться тогда, когда компоненту будут приходить события WM_PAINT, например при сворачивании окна, перекрывающего твой компонент, намного реже, чем 20 мс.



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

Текущий архив: 2007.08.05;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.03 c
15-1183719967
nord489
2007-07-06 15:06
2007.08.05
Работа с 3D


2-1184052074
AZIZE
2007-07-10 11:21
2007.08.05
несовместимость типов


2-1184046719
gass
2007-07-10 09:51
2007.08.05
Как создать ветвь в реестре и записать в нее к.-л. значение типа


15-1183705117
DelphiN!
2007-07-06 10:58
2007.08.05
Разрешить учетной записи пользователя устанавливать программы


2-1184057982
click
2007-07-10 12:59
2007.08.05
Нарисовать тень...