Possible to create min(x,y,z) and max(x,y,z)???
Moderator: DosItHelp
-
- Posts: 175
- Joined: 17 Jan 2016 23:55
Possible to create min(x,y,z) and max(x,y,z)???
Hello everyone ^-^
I would like to create some sort of math function that can compare 3 integers and determine the MIN or MAX of the 3.
My only problem is that I'm clueless on how this would work in a mathematical sense, but I'm desperate to learn how to do it!
My current project is working on an RGB to HSL convert algorithm, but I need a MIN(x,y,z) or... MIN(r,g,b) and MAX(r,g,b)
Is it possible to do this with just math? I would really like to not use and IF's if I could.
I would like to create some sort of math function that can compare 3 integers and determine the MIN or MAX of the 3.
My only problem is that I'm clueless on how this would work in a mathematical sense, but I'm desperate to learn how to do it!
My current project is working on an RGB to HSL convert algorithm, but I need a MIN(x,y,z) or... MIN(r,g,b) and MAX(r,g,b)
Is it possible to do this with just math? I would really like to not use and IF's if I could.
Re: Possible to create min(x,y,z) and max(x,y,z)???
You can do that with bitwise operations.
Source:
Bit Twiddling Hacks
This technique is risky with big positive or negative numbers because of possible type overflows. Even though I'm sure you won't get any trouble with RGB values.
Steffen
Source:
Bit Twiddling Hacks
Code: Select all
@echo off &setlocal
set /a "x=-55, y=99, z=11"
set /a "min= y + ((x - y) & ((x - y) >> 31)), min= z + ((min - z) & ((min - z) >> 31))"
set /a "max= x - ((x - y) & ((x - y) >> 31)), max= max - ((max - z) & ((max - z) >> 31))"
echo %min%
echo %max%
pause
This technique is risky with big positive or negative numbers because of possible type overflows. Even though I'm sure you won't get any trouble with RGB values.
Steffen
-
- Posts: 175
- Joined: 17 Jan 2016 23:55
Re: Possible to create min(x,y,z) and max(x,y,z)???
Aha! This is perfect! This is exactly what I needed! And thanks for the link you provided as well!
EDIT:
For my own purposes I changed out the variables.
I also have one more question!
Is it possible to know the value AND the name of the variable of MIN and MAX?
For example...
How would I go about doing that..?
EDIT:
For my own purposes I changed out the variables.
Code: Select all
set /a "min= g + ((r - g) & ((r - g) >> 31)), min= b + ((min - b) & ((min - b) >> 31))"
set /a "max= r - ((r - g) & ((r - g) >> 31)), max= max - ((max - b) & ((max - b) >> 31))"
I also have one more question!
Is it possible to know the value AND the name of the variable of MIN and MAX?
For example...
Code: Select all
set /a "r=131", "g=34", "b=190"
set /a "max= r - ((r - g) & ((r - g) >> 31)), max= max - ((max - b) & ((max - b) >> 31))"
echo %MAX% = 190
But I would also like to know that it was b - BLUE
How would I go about doing that..?
Re: Possible to create min(x,y,z) and max(x,y,z)???
You can't return any string (variable name) using SET /A.
Right now I had a look at my C++ code for this kind of conversion. I don't see any reason why you would need it. You would rather need floating point calculation which isn't supported using Batch.
Steffen
Right now I had a look at my C++ code for this kind of conversion. I don't see any reason why you would need it. You would rather need floating point calculation which isn't supported using Batch.
Steffen
-
- Posts: 175
- Joined: 17 Jan 2016 23:55
Re: Possible to create min(x,y,z) and max(x,y,z)???
I was trying to follow a Javascript code, and I found it used this.
And I assumed this meant that it new not only the max value, but the name as well, which would be how it's choosing what to do..?
Perhaps I am wrong! I guess I will need to keep looking v.v
Code: Select all
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
And I assumed this meant that it new not only the max value, but the name as well, which would be how it's choosing what to do..?
Perhaps I am wrong! I guess I will need to keep looking v.v
Re: Possible to create min(x,y,z) and max(x,y,z)???
No it doesn't know the name.
You can use IF-ELSE instead of switch-case in the Java code
Steffen
You can use IF-ELSE instead of switch-case in the Java code
Code: Select all
if %max%==%r% (
...
) else if %max%==%g% (
...
) else ( REM only %b% is left here
...
)
Steffen
-
- Posts: 175
- Joined: 17 Jan 2016 23:55
Re: Possible to create min(x,y,z) and max(x,y,z)???
Oooh that works as well! Thank you so much for your help
Re: Possible to create min(x,y,z) and max(x,y,z)???
You may also use this slightly different approach:
Antonio
Code: Select all
@echo off
setlocal EnableDelayedExpansion
:loop
set /P "rgb=Enter R,G,B values: "
if errorlevel 1 goto :EOF
for /F "tokens=1-3 delims=, " %%a in ("%rgb%") do set /A r=%%a, g=%%b, b=%%c
echo r=%r%, g=%g%, b=%b%
set "var[%r%]=r" & set "var[%g%]=g" & set "var[%b%]=b"
set /A "a=((r-g)>>31)+1, max=a*r+^!a*g, a=((max-b)>>31)+1, max=a*max+^!a*b"
set /A "a=((g-r)>>31)+1, min=a*r+^!a*g, a=((b-min)>>31)+1, min=a*min+^!a*b"
echo The max is: !var[%max%]!=%max%. The min is: !var[%min%]!=%min%.
goto loop
Antonio
Re: Possible to create min(x,y,z) and max(x,y,z)???
I took a few minutes to "translate" the C++ code I have.
Values in the sub routine are calculated with 1/100 of degrees or percent in order to minimize rounding errors (although you can't avoid them).
Calculations using (... + 50) / 100 are there for rounding half up.
Steffen
Code: Select all
@echo off &setlocal
set /a "r= 65, g= 105, b= 225"
echo Red: %r%, Green: %g%, Blue: %b%
call :rgb2hsv %r% %g% %b%
echo Hue: %h% deg., Saturation: %s%%%, Value: %v%%%
pause
exit /b
:rgb2hsv
setlocal DisableDelayedExpansion
set /a "r= %~1 * 10000 / 255, g= %~2 * 10000 / 255, b= %~3 * 10000 / 255, h= 0, s= 0"
set /a "min= g + ((r - g) & ((r - g) >> 31)), min= b + ((min - b) & ((min - b) >> 31))"
set /a "v= r - ((r - g) & ((r - g) >> 31)), v= v - ((v - b) & ((v - b) >> 31)), d= v - min"
if %d% gtr 0 (
set /a "s= ((10000 * d / v) + 50) / 100"
if %v%==%r% (
set /a "h= ((6000 * (g - b) / d) + 50) / 100"
) else if %v%==%g% (
set /a "h= ((12000 + 6000 * (b - r) / d) + 50) / 100"
) else (
set /a "h= ((24000 + 6000 * (r - g) / d) + 50) / 100"
)
)
set /a "v= (v + 50) / 100, h= (h + 360) %% 360"
endlocal &set "h=%h%" &set "s=%s%" &set "v=%v%" &exit /b
Values in the sub routine are calculated with 1/100 of degrees or percent in order to minimize rounding errors (although you can't avoid them).
Calculations using (... + 50) / 100 are there for rounding half up.
Steffen
-
- Posts: 175
- Joined: 17 Jan 2016 23:55
Re: Possible to create min(x,y,z) and max(x,y,z)???
aGerman wrote:I took a few minutes to "translate" the C++ code I have.Code: Select all
@echo off &setlocal
set /a "r= 65, g= 105, b= 225"
echo Red: %r%, Green: %g%, Blue: %b%
call :rgb2hsv %r% %g% %b%
echo Hue: %h% deg., Saturation: %s%%%, Value: %v%%%
pause
exit /b
:rgb2hsv
setlocal DisableDelayedExpansion
set /a "r= %~1 * 10000 / 255, g= %~2 * 10000 / 255, b= %~3 * 10000 / 255, h= 0, s= 0"
set /a "min= g + ((r - g) & ((r - g) >> 31)), min= b + ((min - b) & ((min - b) >> 31))"
set /a "v= r - ((r - g) & ((r - g) >> 31)), v= v - ((v - b) & ((v - b) >> 31)), d= v - min"
if %d% gtr 0 (
set /a "s= ((10000 * d / v) + 50) / 100"
if %v%==%r% (
set /a "h= ((6000 * (g - b) / d) + 50) / 100"
) else if %v%==%g% (
set /a "h= ((12000 + 6000 * (b - r) / d) + 50) / 100"
) else (
set /a "h= ((24000 + 6000 * (r - g) / d) + 50) / 100"
)
)
set /a "v= (v + 50) / 100, h= (h + 360) %% 360"
endlocal &set "h=%h%" &set "s=%s%" &set "v=%v%" &exit /b
Values in the sub routine are calculated with 1/100 of degrees or percent in order to minimize rounding errors (although you can't avoid them).
Calculations using (... + 50) / 100 are there for rounding half up.
Steffen
Please excuse me absence the past few days.
Thank you very much for your help. My RGB2HSL was very similar to yours, but I can see the obvious mistakes I was making now.