Delphi — Как оптимизировать отрисовку синусоидальной кривой с количеством сэмплов более 1.000.000?
Вообщем возникла следующая проблема: имеется в буфере более 1.000.000 точек, необходимо вывести график с наименьшими затратами на время. На данный момент использую MoveTo - LineTo, но как вы сами понимаете, это очень медленно. Пробовал использовать алгоритм Рамера-Дугласа-Пекера для уменьшения точек кривой, достаточно хорошо отрабатывает, но медленно. Так же рассчитывал попадание точек кривой в пиксель экрана и просто проводил сплошную линию, тем самым уменьшая количество вызовов метода LineTo. Результат так-же не впечатлил. Будут какие-либо предложения по оптимизации?
for SmplIdx := Samples[itStart] to Samples[itEnd] do
begin
Time := SmplIdx / ChannelRate + ChNum / (CV.DataBuf.FADCData.AdcRate * 1000);
Voltage := CV.DataBuf.Voltage[ChNum, SmplIdx];
Temp := MapVal2Range(VoltageValue, VScaleRange, RVRange(PaintArea));
Point.Y := PaintArea.Top - Temp + PaintArea.Bottom;
Point.X := MapVal2Range(Time, HScaleRange, RHRange(PaintArea));
if bFirstPoint then
begin
Canvas.MoveTo(Point.X, Point.Y);
bFirstPoint := false;
end
else
begin
Canvas.LineTo(Point.X, Point.Y);
end;
end;
где:
SmplIdx - индекс сэмпла
ChannelRate - частота дискретизации на канал
ChNum - номер канала
CV.DataBuf.FADCData.AdcRate - частота дискретизации
функция MapVal2Range - преобразование значения из одного диапазона в другой
PaintArea - область, куда выводится график
Не совсем понятно что именно у вас "тормозит". Вы пытаетесь нарисовать на канве 1 000 000-1 линий или это канва со скороллом? Сложно давать какие-то советы по оптимизации того, что трудно представить.
Как вариант, можно попробовать усреднить соседние значения, что уменьшит объем данных вдвое.