Как связать две переменных как в фотошопе

Daminski

✩✩✩✩✩✩✩
26 Май 2021
23
1
Доброго времени суток. Никак не могу понять как сделать взаимосвязь между двумя переменными, на подобии как в фотошопе при задании размеров изображения.
1640562813542.png
На картинке мы видим, что параметр Ширина и Высота связаны между собой и когда меняешь один из параметров, второй меняется автоматически, когда нажата кнопка с изображением скрепки. Благодаря этой связи формат изображения остаётся прежним, меняется лишь только разрешение.

Как в ардуино запрограммировать такую взаимосвязь? Только есть один нюанс, сейчас опишу что конкретнее я хочу сделать:
Для примера я буду использовать два светодиода. они будут объявлены через переменную типа unsigned char и у них максимальная яркость достигается при значении 255. У первого светодиода по умолчанию яркость будет настроена на 60, у второго на 85. Разница яркости между ними 40%. И нужно чтобы по мере увеличения яркости на одном из светодиодов при условии связанности параметров яркости обоих светодиодов, увеличивалась яркость у обоих, но разница в процентном соотношении уменьшалась чем больше добавлена яркость. Т.е. в финале если один светодиод достигнет яркости в 255, то второй должен светить максимум на значении 240. Тут разница составляет уже 6%. И соответственно наоборот, если я уменьшаю яркость, чтобы разница по яркости в процентах уже увеличивалась. Например если значение более яркого светодиода сделать 50, то второй, менее яркий должен светить уже на 20, где разница составит уже 60%.

Предполагаю, что нужно использовать map, но не могу понять как это всё оформить в код.
 

Lumenjer

★★★✩✩✩✩
10 Дек 2020
220
112
@Daminski, Что-то непонятное вы тут изобретаете) Зачем map?
Никто вам не мешает перевести яркости светодиодов в % и отнимать по 1%. Это и будет связь
255 = 100%, значит 1% это 2.55, во втором 240 = 100%, 1% = 2.4, и от каждого отнимаете по 1% когда надо, т.е. по 2,55 и 2,4

Но если разрыв между ними должен увеличиваться, то чет это слабо похоже на связь как в фотошопе.
А то, что вы хотите, можно реализовать еще проще, на каждый -1 от максимального значения отнимать от второго диода -1.1, например
Т.е. у первого макс значение 255, у второго ограничите до 240, уже разница в 15 и с каждым -1 разница будет увеличиваться, т.е. при минус -100, разница будет уже 25 (15+10), при , при -200 разница уже будет в 35 (что схоже с вашим примером)
При яркости 50 первого будет ~15 второго

И да, это не противоречит вашей задаче, т.к. сами переменные вы сможете без проблем хранить в unsigned char и даже все выше описанные операции проводить без float, я описал для наглядности
 
Изменено:

Daminski

✩✩✩✩✩✩✩
26 Май 2021
23
1
Никто вам не мешает перевести яркости светодиодов в % и отнимать по 1%. Это и будет связь
255 = 100%, значит 1% это 2.55, во втором 240 = 100%, 1% = 2.4, и от каждого отнимаете по 1% когда надо, т.е. по 2,55 и 2,4
Ну как минимум для этого можно использовать map :)
Но если разрыв между ними должен увеличиваться, то чет это слабо похоже на связь как в фотошопе.
Фотошоп это всего лишь аналогия. В нём частично похожая функция реализована, на ту, которую я хочу сделать.
А то, что вы хотите, можно реализовать еще проще, на каждый -1 от максимального значения отнимать от второго диода -1.1, например
Т.е. у первого макс значение 255, у второго ограничите до 240, уже разница в 15 и с каждым -1 разница будет увеличиваться, т.е. при минус -100, разница будет уже 25 (15+10), при , при -200 разница уже будет в 35 (что схоже с вашим примером)
При яркости 50 первого будет ~15 второго
А как сделать чтобы этот коэффициент разницы значений изменялся динамино, при изменении одного из значений?
 

Lumenjer

★★★✩✩✩✩
10 Дек 2020
220
112
Ну как минимум для этого можно использовать map :)
А еще есть алгебра)

А как сделать чтобы этот коэффициент разницы значений изменялся динамино, при изменении одного из значений?
Эм, найти разницу между текущим изменяемым значением и его максимальным значением, умножить ее на нужный множитель и отнять от максимального значения второго значения)
Например первое значение макс 255, второе макс 240
Выставили первое на 150, разница между 255 и 150 = 105, а что это значит? Что нам надо к 105 добавить еще 10%, например (т.к. на каждый пункт мы отнимали от второго 1.1 (т.е. на 10% больше))
105 + 10% =~115, и теперь 240 - 115 = 125
Также со вторым на 50, разница 205 + 10% = ~225, и теперь 240 - 225 = 15

***
Вот вам в коде для наглядности
C++:
const uint8_t LED_2MAX = 240;

led2 = LED_2MAX - ((255 - led1)+(255 - led1)/10);
Если вопрос стоит именно в множителе, то добавляете условия к (255 - led1)/10, но я хз, каких значений вы добиваетесь и поэтому хз, какую формулу для этого выводить

***
Интересно еще, как вы собирались map использовать? Надеюсь, не держать в памяти каждое значение led1 как ключ и к нему значение led2?
 
Изменено:
  • Лойс +1
Реакции: Daminski

Wan-Derer

★★★★★✩✩
Команда форума
31 Июл 2018
2,059
406
Москва
wan-derer.ru
@Daminski, используй математику:
Если:
rate = a / b,
То:
a = rate * b,
b = a / rate
Чтобы избежать использования типов с плавающей точкой, можно предварительно умножить a и b, например, на 100 (или на что-то чтобы они хорошо помещались в беззнаковый int) и использовать целочисленную арифметику. Перед выводом числа в порт, его надо поделить на тот же коэффициент.
 

Daminski

✩✩✩✩✩✩✩
26 Май 2021
23
1
Избыточное цитирование. Отредактируй или сообщение будет удалено
Например первое значение макс 255, второе макс 240
Выставили первое на 150, разница между 255 и 150 = 105, а что это значит? Что нам надо к 105 добавить еще 10%, например (т.к. на каждый пункт мы отнимали от второго 1.1 (т.е. на 10% больше))
105 + 10% =~115, и теперь 240 - 115 = 125
Также со вторым на 50, разница 205 + 10% = ~225, и теперь 240 - 225 = 15
Да, это похоже на то что я хотел, спасибо. Только нужно чтобы ещё этот коэффициент (который 1.1 или 10%) мог также меняться в зависимости от значения максимально яркого светодиода. Чтобы при значении максимально яркого в 85, яркость менее яркого была 60, а не 53, как получается по вашей формуле


Если:
rate = a / b,
То:
a = rate * b,
b = a / rate
Чтобы избежать использования типов с плавающей точкой, можно предварительно умножить a и b, например, на 100 (или на что-то чтобы они хорошо помещались в беззнаковый int) и использовать целочисленную арифметику. Перед выводом числа в порт, его надо поделить на тот же коэффициент.
Здесь не совсем понял. Я использую unsigned char чтобы значение можно было задать от 0 до 255. И насколько я понимаю, дробные значения например, такие как 52.4, будут округляться до 52, а значение 67.8 округлится до 68. Не понял логику вашего кода.
 

Wan-Derer

★★★★★✩✩
Команда форума
31 Июл 2018
2,059
406
Москва
wan-derer.ru
дробные значения например, такие как 52.4, будут округляться до 52, а значение 67.8 округлится до 68
Чтобы уменьшить ошибки округления, я предлагаю умножить rate на 100 (или больше).
 

Lumenjer

★★★✩✩✩✩
10 Дек 2020
220
112
олько нужно чтобы ещё этот коэффициент (который 1.1 или 10%) мог также меняться в зависимости от значения максимально яркого светодиода.
led2 = LED_2MAX - ((255 - led1)+(255 - led1)/10);
Берите во внимание часть +(255 - led1)/X
Это и есть %, который добавляется, чем меньше число "X", тем больше будет %. Берем пример 100%/10 = 10%, 100%/9 = 11.11%, 100%/5 = 20%
Значит, что и Х сделать зависимым от значения led1
при значении максимально яркого в 85, яркость менее яркого была 60
Чтобы получилось 60, то при led1 = 85 значение Х должно быть 17, при этом, чем больше значение led1, тем меньше должно быть Х
led2 = LED_2MAX - ((255 - led1)+(255 - led1)/(20 - led1*10/255));