Russian Qt Forum
Ноябрь 23, 2024, 08:29 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 [3] 4 5   Вниз
  Печать  
Автор Тема: операторы для ARGB  (Прочитано 32674 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #30 : Сентябрь 04, 2010, 16:26 »

Ладненько, тогда следуя Вашей логике, можно оставить только лишь один оператор "+" определённый след. образом:
Код
C++ (Qt)
inline const ARGB operator+(const ARGB &c1, const ARGB &c2)
{
   ARGB  res;
   float x = 0.5f * (1.0 - c1.alpha + c2.alpha);
 
   res.alpha = 0.5f * (c1.alpha + c2.alpha);
   res.r = c1.r * (1.0f - x) + x * c2.r;
   res.g = c1.g * (1.0f - x) + x * c2.g;
   res.b = c1.b * (1.0f - x) + x * c2.b;
   return res;
}
 

Очевидно как получается эта формула?
Проверим

С1: (1, 0, 0, 0)   // видимый RGB (0, 0, 0)  
С2: (0.5, 1, 0, 0)  // видимый RGB (0.5, 0, 0)
------------ (x = 0.25)
result:  (0.75, 0.25, 0, 0)  // видимый RGB (0.1875, 0, 0)
Неверно, видимый RGB должен быть (0.25, 0, 0)  

Кроме того, такой оператор дает неверную альфу при сложении 3 или более ARGB, напр
c1 + c2 + c3 + ..

Немного опечатался: нужно писать
Код
C++ (Qt)
inline const ARGB operator+(const ARGB &c1, const ARGB &c2)
{
   ARGB  res;
   float x = 0.5f * (1.0 - c1.alpha + c2.alpha);
 
   res.alpha = c1.alpha * (1.0f - x) + x * c2.alpha; // <--- вот здесь))
   res.r = c1.r * (1.0f - x) + x * c2.r;
   res.g = c1.g * (1.0f - x) + x * c2.g;
   res.b = c1.b * (1.0f - x) + x * c2.b;
   return res;
}
 
Проверяем

С1: (1, 0, 0, 0)   // видимый RGB (0, 0, 0) 
С2: (0.5, 1, 0, 0)  // видимый RGB (0.5, 0, 0)
------------
result:  (0.875, 0.25, 0, 0)  // видимый RGB (0.21875, 0, 0)
Увы  Плачущий
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #31 : Сентябрь 04, 2010, 16:35 »

Цитировать
Проверяем

С1: (1, 0, 0, 0)   // видимый RGB (0, 0, 0) 
С2: (0.5, 1, 0, 0)  // видимый RGB (0.5, 0, 0)
------------
result:  (0.875, 0.25, 0, 0)  // видимый RGB (0.21875, 0, 0)
Увы

А какой результат вы ожидали? Вы смешиваете чёрный с полупрозрачным красным и получаете (видимый) затемнённый (тёмный) красный. Не логично?
 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #32 : Сентябрь 04, 2010, 16:54 »

А какой результат вы ожидали? Вы смешиваете чёрный с полупрозрачным красным и получаете (видимый) затемнённый (тёмный) красный. Не логично?
Вполне, вот только числа неверны  Улыбающийся
Аналогия с красками. Было 0.5 литра красной краски разведенной в  0.5 литре воды. Добавили 1 литр черной краски.  Общее кол-во краски 1.5/2 = 0.75 (альфа 75%). Цвет краски без воды RGB(0.333(3). 0, 0). Разведенная краска бледнее: 0.3333 * 0.75 = 0.25 (Red)
Записан
spectre71
Гость
« Ответ #33 : Сентябрь 04, 2010, 17:24 »

Объясните, какой смысл в использовании оператора +
Не вдаваясь в формулы сложения двух цветов. Единственно что может иметь смысл это получение некоторой усредненной точки. И это все! При этом стоит заметить, что имея 3 разных точки не лежащих на одной прямой(что является общим случаем) вы получите:
С123 = С1+С2+С3;
С231 = С2+С3+С1;
С132 = С1+С3+С2;

С123 != С231;
С123 != С132;
С231 != С132;

Отсутствует ассоциативность! Какой для вас в этом смысл?

Имеет смысл 3-нарная операция вернее метод F(C1, C2, Mid = 0.5)
Кстати, F(C1, C2, Mid) != F(C2, C1, Mid) в общем случае, но всегда F(C1, C2, 0.5) == F(C2, C1, 0.5)
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #34 : Сентябрь 04, 2010, 17:38 »

Объясните, какой смысл в использовании оператора +
Не вдаваясь в формулы сложения двух цветов.
Для 2-х я бы просто использовал ф-цию - и все дела. Но различные методы разбиения поверхности требуют различных взвешиваний, в общем виде

Код:
new_value = (value1 * k1 + value2 * k2 + value3 * k3 + ...) / (k1 +  k2 + k3 + ..);    
От 2 до 8 "k". А "value" могут быть (атрибуты точки)

- float числа
- тройки чисел (x, y, z)
- RGB
- ARGB

Я могу сделать напр такую ф-цию
Код:
ARGB Interpolate( const ARGB * src, float * k, int count );
Но пользоваться ей неудобно (надо все время заряжать 2 массива) и в template она не ложится

Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #35 : Сентябрь 04, 2010, 17:57 »

Цитировать
Вполне, вот только числа неверны 
Аналогия с красками. Было 0.5 литра красной краски разведенной в  0.5 литре воды. Добавили 1 литр черной краски.  Общее кол-во краски 1.5/2 = 0.75 (альфа 75%). Цвет краски без воды RGB(0.333(3). 0, 0). Разведенная краска бледнее: 0.3333 * 0.75 = 0.25 (Red)
Неверны относительно модели с вёдрами?))
Замечу, что эта аналогия здесь в данном случае - некорректна. Если альфа - канал у вас нуль, но тем не менее отличны от нуля компоненты RGB то сразу получаем противоречие.

Цитировать
Объясните, какой смысл в использовании оператора +
Не вдаваясь в формулы сложения двух цветов. Единственно что может иметь смысл это получение некоторой усредненной точки.
Вот мы и получаем некоторую среднюю точку.

И кстати
Цитировать
Имеет смысл 3-нарная операция вернее метод F(C1, C2, Mid = 0.5)
Кстати, F(C1, C2, Mid) != F(C2, C1, Mid) в общем случае, но всегда F(C1, C2, 0.5) == F(C2, C1, 0.5)
не совсем верно. В последнем варианте, что я привёл, аналог Вашего Mid - есть x. И он равен 0.5 только в случае одинаковых прозрачностей у складываемых цветов, тем не менее свойство ассоциативности всегда выполняется:
с1 + с2 = с2 + с1 
 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
spectre71
Гость
« Ответ #36 : Сентябрь 04, 2010, 18:00 »

Я понимаю что не удобно. Но нельзя муху превратить в слона.
Пример я привел выше. Он математически обоснован.

С123 = С1+С2+С3;
С231 = С2+С3+С1;
С132 = С1+С3+С2;

С123 != С231;
С123 != С132;
С231 != С132;

Если они не лежат на оной прямой вы никак не заставите их быть равными, как ни старайтесь.

Но так иамем точку центра тяжести треугольника:
F(F(С1+С2)+С3, 3) == F(F(С2+С3)+С1, 3) == F(F(С1+С3)+С2, 3);

Записан
spectre71
Гость
« Ответ #37 : Сентябрь 04, 2010, 18:03 »

тем не менее свойство ассоциативности всегда выполняется:
с1 + с2 = с2 + с1 

Это Коммутативность, а не Aссоциативность

Aссоциативность:
(x+y)+ z=x+(y+z)
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #38 : Сентябрь 04, 2010, 18:19 »

Цитировать
тем не менее свойство ассоциативности всегда выполняется:
с1 + с2 = с2 + с1 

Это Коммутативность, а не Aссоциативность

Коммутативность это когда AB=BA
Коммутатор это: [A, B] = AB - BA. Говорят, если A и B коммутируют, то [A, B] = 0
А есть ещё антикоммутатор [A, B]+=AB+BA. И говорят, если A и B антикоммутируют, то AB + BA = 0

А вот A+B = B+A - это как рас ассоциативность  Крутой
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
spectre71
Гость
« Ответ #39 : Сентябрь 04, 2010, 18:41 »

Коммутативность это когда AB=BA
Коммутатор это: [A, B] = AB - BA. Говорят, если A и B коммутируют, то [A, B] = 0
А есть ещё антикоммутатор [A, B]+=AB+BA. И говорят, если A и B антикоммутируют, то AB + BA = 0

А вот A+B = B+A - это как рас ассоциативность  Крутой

Не надо путать "Коммутатор операторов" и "коммутативность" !

http://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D1%83%D1%82%D0%B0%D1%82%D0%BE%D1%80_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BE%D0%B2

http://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D1%83%D1%82%D0%B0%D1%82%D0%B8%D0%B2%D0%BD%D0%B0%D1%8F_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F

http://ru.wikipedia.org/wiki/%D0%90%D1%81%D1%81%D0%BE%D1%86%D0%B8%D0%B0%D1%82%D0%B8%D0%B2%D0%BD%D0%B0%D1%8F_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #40 : Сентябрь 04, 2010, 18:48 »

Я понимаю что не удобно. Но нельзя муху превратить в слона.
Пример я привел выше. Он математически обоснован.

С123 = С1+С2+С3;
С231 = С2+С3+С1;
С132 = С1+С3+С2;

С123 != С231;
С123 != С132;
С231 != С132;

Если они не лежат на оной прямой вы никак не заставите их быть равными, как ни старайтесь
В операторе предложенном m_ax - согласен, не равны. Но не вижу почему они не равны для операторов предложенных в посте #21. Заметим что каждое слагаемое должно сначала на что-то множиться (premultiply alpha)

Неверны относительно модели с вёдрами?))
Замечу, что эта аналогия здесь в данном случае - некорректна. Если альфа - канал у вас нуль, но тем не менее отличны от нуля компоненты RGB то сразу получаем противоречие.
А что такого плохого (непристойного  Улыбающийся) в модели с ведрами? Противоречие уже обсуждалось в посте #18 и любой практический расчет такие противоречия имеет: напр как взвесить если оба веса = 0? Результат ноль независимо от исходных значений,  это нормально и не есть проблема
« Последнее редактирование: Сентябрь 04, 2010, 18:56 от Igors » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #41 : Сентябрь 04, 2010, 19:00 »

Цитировать
Не надо путать "Коммутатор операторов" и "коммутативность" !
Согласен)) Извиняйте)

Цитировать
В операторе предложенном m_ax - согласен, не равны. Но не вижу почему они не равны для операторов предложенных в посте #21
Почему эт не равны? Всегда с1+с2=с2+с1.

А, у вас тут три точки)) Ясненько)
« Последнее редактирование: Сентябрь 04, 2010, 19:13 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #42 : Сентябрь 04, 2010, 19:06 »

Цитировать
А что такого плохого (непристойного  ) в модели с ведрами? Противоречие уже обсуждалось в посте #18 и любой практический расчет такие противоречия имеет: напр как взвесить если оба веса = 0? Результат ноль независимо от исходных значений,  это нормально и не есть проблема
Хорошо, давайте так: Первый вариант, который я привёл:
Код
C++ (Qt)
inline const ARGB operator+(const ARGB &c1, const ARGB &c2)
{
   ARGB  res;
   float x = 0.5f * (1.0f - c1.alpha + c2.alpha);
 
   res.alpha = 0.5f * (c1.alpha + c2.alpha);
   res.r = c1.r * (1.0f - x) + x * c2.r;
   res.g = c1.g * (1.0f - x) + x * c2.g;
   res.b = c1.b * (1.0f - x) + x * c2.b;
   return res;
}
 
Даёт для компонент RGB правильные доли этих цветов, если A = 1. Более того, он даёт правильный ответ для A.
А теперь вопрос: что нужно там изменить, чтоб получилась модель с ведром?

ЗЫ
Я при получении этого соотношения исходил совсем из других соображений. К вёдрам оно отношения не имело)) 
« Последнее редактирование: Сентябрь 04, 2010, 19:09 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
spectre71
Гость
« Ответ #43 : Сентябрь 04, 2010, 19:14 »

Почему эт не равны? Всегда с1+с2=с2+с1.

А, у вас тут три точки)) Ясненько)


Отсутствует Ассоциативность, а не Коммутативность
С1+С2+С3 != С2+С3+С1
Но поскольку имеем Ассоциативность, то
С1+С2 == C2+C1 =>                               
(С1+С2)+С3 == (C2+C1)+C3 равносильно такой записи С1+С2+С3 == C2+C1+C3
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #44 : Сентябрь 04, 2010, 19:21 »

Цитировать
Отсутствует Ассоциативность, а не Коммутативность
С1+С2+С3 != С2+С3+С1
Но поскольку имеем Ассоциативность, то
С1+С2 == C2+C1 =>                               
(С1+С2)+С3 == (C2+C1)+C3 равносильно такой записи С1+С2+С3 == C2+C1+C3
И в чём тогда проблема? Или я чего-то не вкуриваю.. 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Страниц: 1 2 [3] 4 5   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.229 секунд. Запросов: 23.