Что не так с моим кодом, чтобы получить правильный градиент? - PullRequest
0 голосов
/ 23 мая 2019

У меня проблема с результатами округления.У меня есть матрица градиента, мои результаты почти такие же, как предполагалось.ПОЧТИ.

Я пытаюсь использовать FLOOR / ROUND / CEIL, но это ничего не улучшает.

uint16_t t1=0,t2=0,t3=0;
float a,b,c;
uint16_t value=0;
for (int j = 0; j < count; j++) {
    t1 = ceil(rgbLeft->r +(floor((rgbRight->r - rgbLeft->r) * j) / (count-1)));
    t2 = ceil(rgbLeft->g +(floor((rgbRight->g - rgbLeft->g) * j) / (count-1)));
    t3 = ceil(rgbLeft->b + (floor(rgbRight->b - rgbLeft->b) * j) / (count-1));

    value = (t1 << 11) | (t2 << 5) | (t3);
    vec.push_back(value);
}

INPUT

всегда равно 16. Это размер матрицы 16x8.Я помещаю структуру как:

   typedef struct{
       unsigned int r:5;
       unsigned int g:6;
       unsigned int b:5;
   }RGB;

rgbLeft И rgbRight - это структура RGB.Входные данные для примера - 1 и 16. И я получаю строку:

0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F 0010

ВХОД ДЛЯ ЭТОГО примера - 1 16 161. (начало сверху, конец сверху, начало снизу, конец снизу).

Сначала я создаю struct rgbLeft и rgbRight из входа (1,16,16,1) (val - начало начала (rgbLeft), конецстоп (rgbRight)

rgb->r = (val >> 11);
rgb->g = (val >> 5);
rgb->b = (val);

после этого я использую

uint16_t t1=0,t2=0,t3=0;
float a,b,c;
uint16_t value=0;
for (int j = 0; j < count; j++) {
    t1 = ceil(rgbLeft->r +(floor((rgbRight->r - rgbLeft->r) * j) / (count-1)));
    t2 = ceil(rgbLeft->g +(floor((rgbRight->g - rgbLeft->g) * j) / (count-1)));
    t3 = ceil(rgbLeft->b + (floor(rgbRight->b - rgbLeft->b) * j) / (count-1));

    value = (t1 << 11) | (t2 << 5) | (t3);
    vec.push_back(value);
}

Наконец я получаю:

0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E000F 0010

0002 0002 0003 0004 0005 0006 0006 0007 0008 0009 000A 000A 000B 000C 000D 000E

0004 0004 0005 0005 0006 0006 0007 0007 0008 0008 0009 0009 000A 000A 000B 000C

0006 0006 0006 0006 0007 0007 0007 0007 0008 0008 0008 0008 0009 0009 0009 000A

0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008

000A 0009 0009 0009 0008 0008 0008 0008 0007 0007 0007 0007 0006 0006 0006 0006

000C 000B 000A 000A 0009 0009 0008 0008 0007 0007 0006 0006 0005 0005 0004 0004

000E 000D 000C 000B 000A 000A 0009 0008 0007 0006 00060005 0004 0003 0002 0002

0010 000F 000E 000D 000C 000B 000A 0009 0008 0007 0006 0005 0004 0003 0002 0001

Но я думаю (??) у меня должно быть что-токак это:

0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F 0010

0002 0003 0004 0005 0005 0006 0007 0008 0008 0009 000A 000B 000B 000C 000D 000E

0004 0005 0005 0006 0006 0007 0007 0008 0008 0009 0009 000A 000A 000B 000B 000C

0006 0006 0007 0007 0007 0007 0008 0008 0008 0008 0009 0009 0009 0009 000A 000A

0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008

000A 000A 0009 0009 00090009 0008 0008 0008 0008 0007 0007 0007 0007 0006 0006

000C 000B 000B 000A 000A 0009 0009 0008 0008 0007 0007 0006 0006 0005 0005 0004

000E 000D 000C 000B 000B 000B 000A 0009 0008 0008 0007 0006 0005 0005 0004 0003 0002

0010 000F 000E 000D 000C 000B 000A 0009 0008 0007 0006 0005 0004 00030002 0001

например, ввод 0 0 3200 1800 в порядке ...

Вот пример кода для проверки каждой линии:

https://wandbox.org/permlink/bdkxrjxYtq6LHhMg

РЕДАКТИРОВАТЬ.

Я немного изменить код:

uint8_t t1=0,t2=0,t3=0;
int a=0,b=0,c=0;
uint16_t value=0;
for (int j = 0; j < count; j++) {
    t1 =round(rgbLeft->r + (((floor(rgbRight->r - rgbLeft->r) * j) / (count-1))));
    t2 =round(rgbLeft->g + (((floor(rgbRight->g - rgbLeft->g) * j) / (count-1))));
    t3 =round(rgbLeft->b + (((floor(rgbRight->b - rgbLeft->b) * j) / (count-1))));


    value = (t1 << 11) | (t2 << 5) | (t3);
    vec.push_back(value);
}

и я получаю

0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F 0010

0002 0003 0004 0004 00050006 0007 0008 0008 0009 000A 000B 000C 000C 000D 000E

0004 0005 0005 0006 0006 0007 0007 0008 0008 0009 0009 000A 000A 000B 000B 000C

0006 0006 0007 0007 00070007 0008 0008 0008 0008 0009 0009 0009 0009 000A 000A

0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008 0008

000A 000A 0009 0009 0009 0009 0008 0008 0008 0008 0007 0007 0007 0007 0006 0006

000C 000B 000B 000A 000A 0009 0009 0008 0008 0007 0007 0006 0006 0005 0005 0004

000E 000D 000C 000C 000B 000A 0009 0008 0008 0007 0006 0005 0004 0004 0003 0002

0010 000F 000E 000D 000C 000B 000A 0009 0008 0007 0006 0005 0004 0003 0002 0001

ТОЛЬКО 4 ТОЧКИ ОТ РАЗУМЛЕННЫХ!

РЕДАКТИРОВАТЬ:

ТЛ: 1

tr 16

bl 16

br 1

 RGB RGBtl, RGBtr, RGBbl, RGBbr;
        std::vector<uint16_t> firstColumn,lastColumn;

   valueToColorRGB(&RGBtl,tl);
   valueToColorRGB(&RGBtr,tr);
   valueToColorRGB(&RGBbl,bl);
   valueToColorRGB(&RGBbr,br);
   colorRGBtoVector(firstColumn,&RGBtl,&RGBbl,size.height);
   colorRGBtoVector(lastColumn,&RGBtr,&RGBbr,size.height);
    for (int j = 0; j < size.height; j++) {
        tl = firstColumn[j];
        tr = lastColumn[j];

        valueToColorRGB(&RGBtl,tl);
        valueToColorRGB(&RGBtr,tr);
        colorRGBtoVector2(vec3,&RGBtl,&RGBtr,size.width);
    }

valueToColorRGB(RGB *rgb, const uint16_t &val){
    rgb->r = (val >> 11);
    rgb->g = (val >> 5);
    rgb->b = (val);
}
colorRGBtoVector2(std::vector<uint16_t> &vec, RGB *rgbLeft, RGB *rgbRight, const uint16_t &count){
    uint8_t t1=0,t2=0,t3=0;
    int a=0,b=0,c=0;
    uint16_t value=0;
    for (int j = 0; j < count; j++) {
        t1 =(rgbLeft->r + ((floor(rgbRight->r - rgbLeft->r) * j) / (count-1)));
        t2 =(rgbLeft->g + ((floor(rgbRight->g - rgbLeft->g) * j) / (count-1)));
        t3 =(rgbLeft->b + ((floor(rgbRight->b - rgbLeft->b) * j) / (count-1)));


        value = (t1 << 11) | (t2 << 5) | (t3);
        vec.push_back(value);
    }
}

1 Ответ

0 голосов
/ 23 мая 2019

Ваш фактический вопрос , кажется, сводится к:

IDK почему (14-2) * 1/15 + 2 = 2

Это взято из производных значений от того, что у вас будет:

  • rgbRight: 14U
  • rgbLeft: 2U
  • count: 16
  • j: 1

Ваше уравнение в вопросе: t3 = ceil(rgbLeft->b + (floor(rgbRight->b - rgbLeft->b) * j) / (count-1)) будет воспроизводиться в следующем порядке:

  1. rgbRight->b - rgbLeft->b: 12U
  2. floor(rgbRight->b - rgbLeft->b): 12,0
  3. floor(rgbRight->b - rgbLeft->b) * j: 12,0
  4. count - 1: 15
  5. (floor(rgbRight->b - rgbLeft->b) * j) / (count-1): 0,8
  6. rgbLeft->b + (floor(rgbRight->b - rgbLeft->b) * j) / (count-1): 2,8
  7. ceil(rgbLeft->b + (floor(rgbRight->b - rgbLeft->b) * j) / (count-1)): 3,0

Наконец, назначение back to t3 приведет с игнорируемым предупреждением обратно к 3U not 2U .

Я думаю, что вас смущает то, что ваш связанный тестер не использует double s : (unsigned int)start.b + (((stop.b - start.b) * i) / (elems - 1)), который будет воспроизводиться в следующем порядке:

  1. (unsigned int)start.b: 2U
  2. stop.b - start.b: 12U
  3. (stop.b - start.b) * i: 12
  4. elems - 1: 15
  5. ((stop.b - start.b) * i) / (elems - 1): 0
  6. (unsigned int)start.b + (((stop.b - start.b) * i) / (elems - 1)): 2U

Важно отметить, что 5 в этом списке выполняет целочисленное деление и, таким образом, возвращает 0 , тогда как 5 из предыдущего списка выполняет деление с плавающей запятой и возвращает 0,8 * +1097 *. * * тысяча девяносто-восемь

...