ما هي الرياضيات وراء عجلة الألوان
-
26-09-2019 - |
سؤال
أريد إنشاء فطيرة مع 12 شريحة ، مع كل شريحة لون مختلف.
إلى حد كبير ، يبدو أن كل عجلة ملونة تتبع نفس التنسيق ؛ على سبيل المثال: http://www.tigercolor.com/color-lab/color-heory/color-heory-intro.htm .
ولكن ما الخوارزميات الموجودة لتوليد الألوان؟ ما هي الرياضيات وراء RGB (ثيتا)؟ من المؤكد أنه يجب أن يكون هناك بعض العلوم الراسخة في هذا الأمر ، لكن Google لا تعطيني أي أدلة.
المحلول
القي نظرة على http://www.easyrgb.com لديها الخوارزميات وراء العديد من تحويلات الألوان. إليك RGB -> HSV One.
var_R = ( R / 255 ) //RGB from 0 to 255
var_G = ( G / 255 )
var_B = ( B / 255 )
var_Min = min( var_R, var_G, var_B ) //Min. value of RGB
var_Max = max( var_R, var_G, var_B ) //Max. value of RGB
del_Max = var_Max - var_Min //Delta RGB value
V = var_Max
if ( del_Max == 0 ) //This is a gray, no chroma...
{
H = 0 //HSV results from 0 to 1
S = 0
}
else //Chromatic data...
{
S = del_Max / var_Max
del_R = ( ( ( var_Max - var_R ) / 6 ) + ( del_Max / 2 ) ) / del_Max
del_G = ( ( ( var_Max - var_G ) / 6 ) + ( del_Max / 2 ) ) / del_Max
del_B = ( ( ( var_Max - var_B ) / 6 ) + ( del_Max / 2 ) ) / del_Max
if ( var_R == var_Max ) H = del_B - del_G
else if ( var_G == var_Max ) H = ( 1 / 3 ) + del_R - del_B
else if ( var_B == var_Max ) H = ( 2 / 3 ) + del_G - del_R
if ( H < 0 ) H += 1
if ( H > 1 ) H -= 1
}
نصائح أخرى
عجلة الألوان (مثل Mac OS X Color Pancer ، في الصورة أدناه) تعرض مسحة و التشبع (اثنان من المكونات الثلاثة من مساحة اللون HSV). يختلف اللون مع الزاوية ، ويختلف التشبع مع نصف القطر. عادة ما يكون هناك شريط منزلق منفصل ل القيمة (ويعرف أيضا باسم السطوع).
انظر ويكيبيديا لكيفية تحويل ذهابًا وإيابًا بين HSV و RGB. أو قد يكون هناك واجهة برمجة تطبيقات للغة البرمجة المفضلة لديك. على سبيل المثال ، بيثون لديه colorsys
مكتبة.
كنت ألعب مع صنع عجلة ملونة تستند إلى HSL في Excel VBA ، باستخدام خلايا صغيرة مثل "وحدات البكسل" ، واتضح أنها بشكل جيد ، لذلك اعتقدت أنني سأشارك.
هذا يدل على التحويل بين HSL و RGB وكذلك كيفية برمجة ارسم الخطوط/الدوائر على أي شبكة - حتى خلايا جدول البيانات.
الكود جاهز لتشغيل كما هو:
Option Explicit
Const colorSheetName = "COLORS"
Const pi = 3.14159265358979
Const squareSize = 3.75 'cell square size (pts)
Const cDiameter = 80# 'circle diameter (cells)
Const numAngles = 360# 'number of angles (lines to draw)
Sub CalculateColorWheel()
Dim ws As Worksheet, radsPerAngle As Double, radius As Long, xStop As Double, _
yStop As Double, z As Integer, xyLength As Double, lineDot As Long, _
lineLength As Long, h As Byte, s As Byte, v As Byte, r As Byte, g As Byte, b As Byte
Set ws = ThisWorkbook.Sheets.Add 'create new worksheet
On Error Resume Next 'ignore error
Application.DisplayAlerts = False 'ignore warning
ThisWorkbook.Sheets(colorSheetName).Delete 'delete worksheet (if exists)
Application.DisplayAlerts = True 'stop ignoring warnings
On Error GoTo 0 'stop ignoring errors
With ws
.Name = colorSheetName 'name the new sheet
.Rows.RowHeight = squareSize 'set rowheight
.Columns.ColumnWidth=widthToColumnWidth(squareSize) 'match columnwidth to row
ActiveWindow.DisplayGridlines = False 'hide gridlines
ActiveWindow.DisplayHeadings = False 'hide row/col headings
radius = cDiameter / 2 'centre point
lineLength = radius * 1.5 'dots per angle (line)
radsPerAngle = (360 / numAngles) * pi / 180 'radians=a(degrees)×pi÷180°
Debug.Print "Grid size=" & .[a1].Height & "×" & .[a1].Width _
& ", Diameter:" & cDiameter _
& ", Area=" & Round(pi * radius ^ 2, 0) _
& ", Circumference=" & Round(2 * pi * radius, 0) _
& ", Radians per Angle=" & Round(radsPerAngle, 3) _
& " × " & numAngles & " angles" 'stats
For z = 0 To numAngles - 1 'loop through each angle
For lineDot = 1 To lineLength 'loop thru length of line
xyLength = radius * (lineDot / lineLength) 'calc dot xy& offset top-left
xStop = Int(Cos(radsPerAngle * z) * xyLength) + radius + 2 'x (column)
yStop = Int(Sin(radsPerAngle * z) * xyLength) + radius + 2 'y (row)
If .Cells(yStop, xStop).Interior.Pattern=xlNone Then 'skip colored cells
h = ((z + 1) / numAngles) * 255 'hue=angle
s = (lineDot / lineLength) * 255 'saturation=radius
v = 255 'maximum brightness. (Adjustable)
HSVtoRGB h, s, v, r, g, b 'convert HSV to RGB
.Cells(yStop, xStop).Interior.Color=rgb(r,g,b) 'color the cell
dots = dots + 1
End If
Next lineDot
Application.StatusBar = Format(z / (numAngles - 1), "0%")
DoEvents 'don't lag
Next z
End With
Beep
Application.StatusBar = "Finished drawing color circle (" & dots & " colors)"
End Sub
Public Function widthToColumnWidth(pts As Double) As Double
'convert desired column width (points) to Excel "ColWidthUnits"
'12pts and under is a 1:12 ratio of (colWidthUnits:Pts).
' Over 12pts: 1:12 for 1st unit, then 1:(75/11) for remainder
Select Case pts
Case Is <= 0: widthToColumnWidth = 0
Case Is <= 12: widthToColumnWidth = pts / 12
Case Else: widthToColumnWidth = 1 + (pts - 12) / (75 / 11) '
End Select
End Function
Public Sub HSVtoRGB(h As Byte, s As Byte, v As Byte, r As Byte, g As Byte, b As Byte)
Dim minV As Byte, maxV As Byte, Chroma As Byte, tempH As Double
If v = 0 Then
r = 0: g = 0: b = 0
Else
If s = 0 Then
r = v: g = v: b = v:
Else
maxV = v: Chroma = s / 255 * maxV: minV = maxV - Chroma
Select Case h
Case Is >= 170: tempH = (h - 170) / 43: g = 0
If tempH < 1 Then
b = maxV: r = maxV * tempH
Else: r = maxV: b = maxV * (2 - tempH): End If
Case Is >= 85: tempH = (h - 85) / 43: r = 0
If tempH < 1 Then
g = maxV: b = maxV * tempH
Else: b = maxV: g = maxV * (2 - tempH): End If
Case Else: tempH = h / 43: b = 0
If tempH < 1 Then
r = maxV: g = maxV * tempH
Else: g = maxV: r = maxV * (2 - tempH): End If
End Select
r = r / maxV * (maxV - minV) + minV
g = g / maxV * (maxV - minV) + minV
b = b / maxV * (maxV - minV) + minV
End If
End If
End Sub
كيفية تشغيل هذا في Excel: الصق الكود أعلاه ولصقه في وحدة منتظمة. (حدد الرمز ، كنترول+ج لنسخ ، ثم في Excel ، امسك البديل وضرب F11+أنا+م وثم كنترول+الخامس للصق ، و F5 لتشغيل.) 🤓
معلومات اكثر:
- ويكيبيديا: HSL و HSV
- ويكيبيديا: عجلة الألوان - HSL
- colormatters.com: نظرية اللون الأساسية
- ويكيبيديا: خوارزمية دائرة نقطة الوسط
إذا كنت تريد عجلة لونية مثل المثال الذي قدمته (ومثل معظم العجلات الملونة ، فستجد في قسم الطلاء المتجر الحرفي) ، حيث يكون اللون الأحمر معاكسًا للأخضر والأزرق معاكسًا للأصفر البرتقالي ، والأرجواني المقابل الأصفر ، وما إلى ذلك ، أنت ، أنت يمكن ببساطة القيام بالرياضيات التالية لتعديل Hue of HSL أو HSV للحصول على اللون القديم ...
double ToLegacyHue(double modernHue) {
modernHue = ((modernHue % 360) + 360) % 360; // normalize 360 > modernHue >= 0
double ret = 0;
if(modernHue < 60) {
ret = modernHue * 2;
} else if(modernHue < 120) {
ret = modernHue + 60;
} else {
ret = (modernHue - 120) * 0.75 + 180;
}
return ret;
}
double FromLegacyHue(double legacyHue) {
legacyHue = ((legacyHue % 360) + 360) % 360; // normalize 360 > legacyHue >= 0
double ret = 0;
if(legacyHue < 120) {
ret = legacyHue / 2;
} else if(legacyHue < 180) {
ret = legacyHue - 60;
} else {
ret = (legacyHue - 180) / 0.75 + 120;
}
return ret;
}