Created
August 24, 2023 05:50
-
-
Save arif-pandu/1e1888a6119eeeafbb5f39d3622b5cfe to your computer and use it in GitHub Desktop.
Combine 2 HSL Colors in C#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections.Generic; | |
public class ColorCombination : MonoBehaviour | |
{ | |
public Material newMaterial; | |
private void OnCollisionEnter(Collision collision) | |
{ | |
Renderer renderer = collision.gameObject.GetComponent<Renderer>(); | |
ClayObject clayObject = collision.gameObject.GetComponent<ClayObject>(); | |
if (renderer != null && newMaterial != null && !collision.gameObject.CompareTag("Ground") && clayObject != null) | |
{ | |
if (clayObject.objectColor != Color.clear) | |
{ | |
List<Color> listColors = new List<Color>(); | |
listColors.Add(clayObject.objectColor); | |
listColors.Add(newMaterial.color); | |
Color averageColor = CalculateAverageColor(listColors); | |
clayObject.objectColor = averageColor; | |
renderer.material.color = averageColor; | |
} | |
else | |
{ | |
clayObject.objectColor = newMaterial.color; | |
renderer.material.color = newMaterial.color; | |
} | |
} | |
Destroy(gameObject); | |
} | |
string ColorToHex(Color color) | |
{ | |
int r = Mathf.RoundToInt(color.r * 255); | |
int g = Mathf.RoundToInt(color.g * 255); | |
int b = Mathf.RoundToInt(color.b * 255); | |
int a = Mathf.RoundToInt(color.a * 255); | |
return string.Format("#{0:X2}{1:X2}{2:X2}{3:X2}", r, g, b, a); | |
} | |
public static Color CalculateAverageColor(List<Color> colors) | |
{ | |
if (colors == null || colors.Count == 0) | |
{ | |
return Color.black; | |
} | |
// Initialize total H, S, and L values | |
List<float> totalH = new List<float>(); | |
float totalS = 0f; | |
float totalL = 0f; | |
foreach (Color color in colors) | |
{ | |
// Convert RGB to HSL | |
RGBToHSL(color, out float h, out float s, out float l); | |
// Accumulate H, S, and L values | |
totalH.Add(h); | |
totalS += s; | |
totalL += l; | |
} | |
float averageH = CountHValue(totalH); | |
float averageS = totalS / 2; | |
float averageL = totalL / 2; | |
string hDebug = string.Join(", ", totalH); | |
Debug.Log("(" + hDebug + ") => " + averageH); | |
// Convert average HSL back to RGB | |
Color averageColor = HSLToRGB(averageH, averageS, averageL); | |
return averageColor; | |
} | |
// Helper function to convert RGB to HSL | |
public static void RGBToHSL(Color rgb, out float h, out float s, out float l) | |
{ | |
float r = rgb.r; | |
float g = rgb.g; | |
float b = rgb.b; | |
float max = Mathf.Max(r, Mathf.Max(g, b)); | |
float min = Mathf.Min(r, Mathf.Min(g, b)); | |
// Calculate lightness | |
l = (max + min) / 2; | |
if (max == min) | |
{ | |
// Grayscale | |
h = 0; | |
s = 0; | |
} | |
else | |
{ | |
// Calculate saturation | |
if (l < 0.5f) | |
{ | |
s = (max - min) / (max + min); | |
} | |
else | |
{ | |
s = (max - min) / (2.0f - max - min); | |
} | |
// Calculate hue | |
if (max == r) | |
{ | |
h = (g - b) / (max - min); | |
} | |
else if (max == g) | |
{ | |
h = 2.0f + (b - r) / (max - min); | |
} | |
else | |
{ | |
h = 4.0f + (r - g) / (max - min); | |
} | |
h *= 60; | |
if (h < 0) | |
{ | |
h += 360; | |
} | |
} | |
} | |
// Helper function to convert HSL to RGB | |
public static Color HSLToRGB(float h, float s, float l) | |
{ | |
float r, g, b; | |
if (s == 0) | |
{ | |
// Grayscale | |
r = g = b = l; | |
} | |
else | |
{ | |
float q = l < 0.5f ? l * (1.0f + s) : l + s - l * s; | |
float p = 2.0f * l - q; | |
r = HueToRGB(p, q, h + 120); | |
g = HueToRGB(p, q, h); | |
b = HueToRGB(p, q, h - 120); | |
} | |
return new Color(r, g, b); | |
} | |
private static float HueToRGB(float p, float q, float t) | |
{ | |
if (t < 0) t += 360; | |
if (t >= 360) t -= 360; | |
if (t < 60) return p + (q - p) * t / 60; | |
if (t < 180) return q; | |
if (t < 240) return p + (q - p) * (240 - t) / 60; | |
return p; | |
} | |
private static float CountHValue(List<float> doubleH) | |
{ | |
float smallestH = Mathf.Min(doubleH.ToArray()); | |
float highestH = Mathf.Max(doubleH.ToArray()); | |
float distanceA = Mathf.Abs(highestH - smallestH); | |
float distanceB = 360 - distanceA; | |
if (doubleH.Count == 2) | |
{ | |
if (distanceA <= distanceB) | |
{ | |
smallestH += (distanceA / 2); | |
return smallestH; | |
} | |
else | |
{ | |
highestH += (distanceB / 2); | |
return highestH; | |
} | |
} | |
return 0f; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment