C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
бегущий график на Canvas
khan
Отправлено: 13.02.2007, 10:52


Ученик-кочегар

Группа: Участник
Сообщений: 19



Итак рисую график на Canvas код таков:
CODE

void Graph::SlideGraph(unsigned int slide_step)
{
 TRect Dest,Src;
 Dest=Rect(1,1,gwidth-(1+slide_step),gheight-1);//vis dest
 Src=Rect(1+slide_step,1,gwidth-1,gheight-1);//unvis src
 BackImage->Canvas->CopyRect(Src,Image->Canvas,Src);
 Image->Canvas->Pen->Color=clBlack;
 Image->Canvas->Rectangle(0,0,gwidth,gheight);
 Image->Canvas->Pen->Color=clGreen;
 Image->Canvas->CopyRect(Dest,BackImage->Canvas,Src);
}
//---------------------------------------------------------------------------
void Graph::AddPoint(double data, unsigned int step_point)
{
 curr_y=(gheight/2)-data;
 if(curr_x==(gwidth-step_point))
 {
   SlideGraph(step_point);
 }
 else
 {
   last_x=curr_x;
   curr_x=curr_x+step_point;
 }
 Image->Canvas->MoveTo(last_x,last_y);
 Image->Canvas->LineTo(curr_x,curr_y);
 last_y=curr_y;
}


При сдвиге затирается пиксель в чем дело не могу никак разобраться. Кто поможет?
nawok78
Отправлено: 13.02.2007, 11:51


Станционный диспетчер

Группа: Участник
Сообщений: 115



какой именно?
khan
Отправлено: 13.02.2007, 14:40


Ученик-кочегар

Группа: Участник
Сообщений: 19



последний
khan
Отправлено: 13.02.2007, 17:37


Ученик-кочегар

Группа: Участник
Сообщений: 19



Ошибка была в этом месте:
вместо
CODE
 if(curr_x==(gwidth-step_point))

надо было написать
CODE
 if(curr_x==(gwidth-(step_point+1)))

Всем спасибо!

Отредактировано khan — 13.02.2007, 18:23
khan
Отправлено: 13.02.2007, 18:26


Ученик-кочегар

Группа: Участник
Сообщений: 19



Новый вопрос: Как создать Сетку на таком графике и быстро ее перерисовывать?
Zor
Отправлено: 13.02.2007, 21:45


Ученик-кочегар

Группа: Участник
Сообщений: 4



рисуйте на Graphics::TBitmap, затем родным BitBlt (Copyxxx тормозит) кидайте на видимый контрол
и вообще, рисовать напрямую на экранный Canvas это ОЧЕНЬ медленно.

Отредактировано Zor — 13.02.2007, 22:01
khan
Отправлено: 14.02.2007, 10:46


Ученик-кочегар

Группа: Участник
Сообщений: 19



Тогда нужен пример как оптимальным образом использовать BitBlt.
Поскольку я себе это представляю так:
Я рисую график копирую его в для сдвига затем копирую его снова чтоб нанести сверху сетку затем снова копирую его на видимый экран.

Отредактировано khan — 14.02.2007, 19:39
Zor
Отправлено: 14.02.2007, 21:15


Ученик-кочегар

Группа: Участник
Сообщений: 4



Неправильно smile.gif слишком много пустых операций

модель 1: отрисовка всего в динамике:

// создаете в OnPaint буфер и чистите его — создание можно кинуть в OnCreate
Graphics::TBitmap Bitmap = new Graphics::TBitmap();
Bitmap->PixelFormat = pf8bit; // самый быстрый режим
Bitmap->Width = W; // ваш размер картинки
Bitmap->Height = H;

TCanvas* BC = Bitmap->Canvas;

BC->Brush->Color = clWhite; // залили фоном
BC->FillRect(0,0,W,H);

/* тут рисуете график */
/* тут сетку (или наоборот) */

BitBlt(PaintBox1->Canvas->Handle, 0,0,W,H, BC->Handle, 0,0,SCRCOPY);

delete Bitmap; // если создавали в OnCreate — удаляем в OnDestroy
//=====================================================


модель 2: отрисовка кое-чего заранее:

// пустышку графика с сеткой (Frame) делаем заранее
// в OnPaint остается:

BitBlt(BC->Handle, 0,0,W,H, Frame->Canvas->Handle, 0,0,SCRCOPY); // копируем пустышку
/* тут рисуете график */ // рисуем на ней график
BitBlt(PaintBox1->Canvas->Handle, 0,0,W,H, BC->Handle, 0,0,SCRCOPY); // кидаем на экран

//=====================================================

+для бегущих графиков лучше использовать кольцевой буфер данных — это еще немного ускоряет процесс
khan
Отправлено: 15.02.2007, 10:15


Ученик-кочегар

Группа: Участник
Сообщений: 19



Сделал почти по второму, только сетку и отрисовку местами поменял сетку рисую поверх графика используя SRCAND.
Кольцевой буфер используется при добавлении точек, т.е. за раз несколько точек отрисовываю.

Отредактировано khan — 15.02.2007, 10:19

Вернуться в Вопросы программирования в C++Builder