Сжать график по оси (Х)

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

Всем привет!

Вопрос к более опытным кодерам или к тем кто сталкивался с такой задачей!

Чтоб было понятней проиллюстрировал все на картинке ниже.

Есть дисплей для примера 80пикселей шириной, нужно на него вывести график шириной более чем 80.

Если просто выводить первые 80 значений массива данных графика тогда часть графика не влезет.

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

Кто подскажет как плавно сжимать график по оси(Х) используя только простые математические операции?

James
Offline
Зарегистрирован: 26.02.2016

f(x)=sin(2x)

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

James пишет:

f(x)=sin(2x)

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

James
Offline
Зарегистрирован: 26.02.2016

координаты по иксу сожмите в n-раз

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

James пишет:

координаты по иксу сожмите в n-раз

Как сжать?

(х1+х2)/2 -усреднением?

Весь вопрос в том как это сделать прмитивной математикой?

James
Offline
Зарегистрирован: 26.02.2016

ну если примитивной, то да. а почему не выводить последовательно?сдвигая на n-пикселей, типо как бегущая строка

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Надо было учить математику в школе ...

Чтобы сжать в 2 раза нужно уменьшить число значений в 2 раза - чем меньше будет значений тем меньше места они займут. Тоесть выводить каждое второе значение.

for(int i=0;i<count;i+=2){

}

а положение пикселя при этом равно i/2

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

NeiroN пишет:

Надо было учить математику в школе ...

Чтобы сжать в 2 раза нужно уменьшить число значений в 2 раза - чем меньше будет значений тем меньше места они займут. Тоесть выводить каждое второе значение.

for(int i=0;i<count;i+=2){

}

а положение пикселя при этом равно i/2

Мне матиматику а вам просто чтение, мой первый пост этот метод описывает, хотите поумничать делайте это по поводу!

fogary
Offline
Зарегистрирован: 05.03.2016

bodriy2014 пишет:

(х1+х2)/2 -усреднением?

Если исходная ширина графика известна, или ее можно узнать, то примерно так:

1. Находите коэффициент масштабирования. Пусть, X1 - исходная ширина, X2 - желеаемая, а K - коэф. масштабирования. Тогда K = X2 / X1.

2. Вывод графика. Xout = Round(X1[i] * K).

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

График функции построенной по точкам можно прировнять к набору отрезков соединяющих эти точки. Если значения нового массива попадают между точками старого - то можно расчитать новое значение не как усреднение а как точку на прямой - если значение нового массива не точно посередине между значениями старого - то это значение можно счтитать значением на прямой построенной по этим двум точкам. 

Это если значения в начальном меняются плавно, но если значения содержат экстреммумы в виде одного значения - то величина этого значения может потеряться.

// есть два массива
double values[120] = {};
double new_values[80] = {};

for(int i = 0;i < sizeof(new_values);i++){
  // вычисляем позицию в большем массиве относительно позиции в меньшем массиве 120/80 - размер одной единицы перемещения по побольшему массиву(масштабирование)
  int pos= floor((double)(120.0*i)/80.0);// целые
  double rpos = ((double)(120.0*i)/80.0)-pos;// дробные
  // зависимость между двумя соседними точками массива можно считать линейной
  // найдем значение на прямой построенной по этим двум точкам - которое будет между ними и будет характерным для меньшего массива.
  // для этого к опорной точке прибавим изменение величины Y пропорционально изменению величины X
  new_values[i] = values[pos]+(values[pos+1]-values[pos])*rpos;
}

 

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Откуда берётся функция? Считается или заранее задана массиво точек? От этого всё и зависит.

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

fogary, NeiroN Спасибо, все попробую в железе.

ЕвгенийП За ранее известен массим точек для графика 500 или более, на дисплей влазит всего 80. Я использовал сдвиг для прокрутки графика и перескакивание чтоб сжать график, теперь попробую методы предложенные выше.

MagicianT
Offline
Зарегистрирован: 03.10.2015

bodriy2014 пишет:

Как сжать?

(х1+х2)/2 -усреднением?

Весь вопрос в том как это сделать прмитивной математикой?

Нет там никакой хитрости, называется децимация, берётся среднее арифметическое 10 точек и выводится на экран как одна точка. Ну если 1:10, в другом масштабе пропорционально.