From 28afbba0cac27a9ff08fc50e7c2ecdcf625455f1 Mon Sep 17 00:00:00 2001 From: liteng <930372551@qq.com> Date: Sun, 9 Dec 2018 12:24:50 +0800 Subject: [PATCH] =?UTF-8?q?Color=E7=B1=BB=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- THREE/Math/Color.cs | 1019 ++++++++++++++++++------------------------- THREE/Math/Math.cs | 26 +- 2 files changed, 443 insertions(+), 602 deletions(-) diff --git a/THREE/Math/Color.cs b/THREE/Math/Color.cs index af31c625..ed607f30 100644 --- a/THREE/Math/Color.cs +++ b/THREE/Math/Color.cs @@ -2,7 +2,10 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; +using System.Reflection; +using _Math = System.Math; namespace THREE { @@ -12,666 +15,504 @@ namespace THREE /// public class Color { - public string[] ColorKeywords = new string[] { "aliceblue", "0xF0F8FF", "antiquewhite", "0xFAEBD7", "aqua", "0x00FFFF", "aquamarine", "0x7FFFD4", "azure", "0xF0FFFF", "beige", "0xF5F5DC", "bisque", "0xFFE4C4", "black", "0x000000", "blanchedalmond", "0xFFEBCD", "blue", "0x0000FF", "blueviolet", "0x8A2BE2", "brown", "0xA52A2A", "burlywood", "0xDEB887", "cadetblue", "0x5F9EA0", "chartreuse", "0x7FFF00", "chocolate", "0xD2691E", "coral", "0xFF7F50","cornflowerblue", "0x6495ED", "cornsilk", "0xFFF8DC", "crimson", "0xDC143C", "cyan", "0x00FFFF", "darkblue", "0x00008B", "darkcyan", "0x008B8B", "darkgoldenrod", "0xB8860B", "darkgray", "0xA9A9A9", "darkgreen", "0x006400", "darkgrey", "0xA9A9A9", "darkkhaki", "0xBDB76B", "darkmagenta", "0x8B008B", "darkolivegreen", "0x556B2F", "darkorange": 0xFF8C00, "darkorchid": 0x9932CC, "darkred": 0x8B0000, "darksalmon": 0xE9967A, "darkseagreen": 0x8FBC8F, - "darkslateblue": 0x483D8B, "darkslategray": 0x2F4F4F, "darkslategrey": 0x2F4F4F, "darkturquoise": 0x00CED1, "darkviolet": 0x9400D3, - "deeppink": 0xFF1493, "deepskyblue": 0x00BFFF, "dimgray": 0x696969, "dimgrey": 0x696969, "dodgerblue": 0x1E90FF, "firebrick": 0xB22222, - "floralwhite": 0xFFFAF0, "forestgreen": 0x228B22, "fuchsia": 0xFF00FF, "gainsboro": 0xDCDCDC, "ghostwhite": 0xF8F8FF, "gold": 0xFFD700, - "goldenrod": 0xDAA520, "gray": 0x808080, "green": 0x008000, "greenyellow": 0xADFF2F, "grey": 0x808080, "honeydew": 0xF0FFF0, "hotpink": 0xFF69B4, - "indianred": 0xCD5C5C, "indigo": 0x4B0082, "ivory": 0xFFFFF0, "khaki": 0xF0E68C, "lavender": 0xE6E6FA, "lavenderblush": 0xFFF0F5, "lawngreen": 0x7CFC00, - "lemonchiffon": 0xFFFACD, "lightblue": 0xADD8E6, "lightcoral": 0xF08080, "lightcyan": 0xE0FFFF, "lightgoldenrodyellow": 0xFAFAD2, "lightgray": 0xD3D3D3, - "lightgreen": 0x90EE90, "lightgrey": 0xD3D3D3, "lightpink": 0xFFB6C1, "lightsalmon": 0xFFA07A, "lightseagreen": 0x20B2AA, "lightskyblue": 0x87CEFA, - "lightslategray": 0x778899, "lightslategrey": 0x778899, "lightsteelblue": 0xB0C4DE, "lightyellow": 0xFFFFE0, "lime": 0x00FF00, "limegreen": 0x32CD32, - "linen": 0xFAF0E6, "magenta": 0xFF00FF, "maroon": 0x800000, "mediumaquamarine": 0x66CDAA, "mediumblue": 0x0000CD, "mediumorchid": 0xBA55D3, - "mediumpurple": 0x9370DB, "mediumseagreen": 0x3CB371, "mediumslateblue": 0x7B68EE, "mediumspringgreen": 0x00FA9A, "mediumturquoise": 0x48D1CC, - "mediumvioletred": 0xC71585, "midnightblue": 0x191970, "mintcream": 0xF5FFFA, "mistyrose": 0xFFE4E1, "moccasin": 0xFFE4B5, "navajowhite": 0xFFDEAD, - "navy": 0x000080, "oldlace": 0xFDF5E6, "olive": 0x808000, "olivedrab": 0x6B8E23, "orange": 0xFFA500, "orangered": 0xFF4500, "orchid": 0xDA70D6, - "palegoldenrod": 0xEEE8AA, "palegreen": 0x98FB98, "paleturquoise": 0xAFEEEE, "palevioletred": 0xDB7093, "papayawhip": 0xFFEFD5, "peachpuff": 0xFFDAB9, - "peru": 0xCD853F, "pink": 0xFFC0CB, "plum": 0xDDA0DD, "powderblue": 0xB0E0E6, "purple": 0x800080, "rebeccapurple": 0x663399, "red": 0xFF0000, "rosybrown": 0xBC8F8F, - "royalblue": 0x4169E1, "saddlebrown": 0x8B4513, "salmon": 0xFA8072, "sandybrown": 0xF4A460, "seagreen": 0x2E8B57, "seashell": 0xFFF5EE, - "sienna": 0xA0522D, "silver": 0xC0C0C0, "skyblue": 0x87CEEB, "slateblue": 0x6A5ACD, "slategray": 0x708090, "slategrey": 0x708090, "snow": 0xFFFAFA, - "springgreen": 0x00FF7F, "steelblue": 0x4682B4, "tan": 0xD2B48C, "teal": 0x008080, "thistle": 0xD8BFD8, "tomato": 0xFF6347, "turquoise": 0x40E0D0, - "violet": 0xEE82EE, "wheat": 0xF5DEB3, "white": 0xFFFFFF, "whitesmoke": 0xF5F5F5, "yellow": 0xFFFF00, "yellowgreen": 0x9ACD32 }; + public double r = 1.0; + public double g = 1.0; + public double b = 1.0; - public Color(int r, int g, int b ) + public Color(double r, double g, double b) { - - if (g === undefined && b === undefined) - { - - // r is THREE.Color, hex or string - return this.set(r); - - } - - return this.setRGB(r, g, b); - + this.SetRGB(r, g, b); } - isColor: true, - - r: 1, g: 1, b: 1, - - set: function(value ) + public Color(int color) { + this.Set(color); + } - if (value && value.isColor) - { + public Color(string color) + { + this.Set(color); + } - this.copy(value); + public const bool isColor = true; - } - else if (typeof value === "number") - { - - this.setHex(value); - - } - else if (typeof value === "string") - { - - this.setStyle(value); - - } + public Color Set(Color value) + { + this.Copy(value); return this; + } - }, - - setScalar: function(scalar ) + public Color Set(int value) { + this.SetHex(value); + return this; + } + + public Color Set(string value) + { + this.SetStyle(value); + + return this; + } + + public Color SetScalar(double scalar) + { this.r = scalar; this.g = scalar; this.b = scalar; return this; + } - }, - - setHex: function(hex ) + public Color SetHex(int hex) { - - hex = Math.floor(hex); - this.r = (hex >> 16 & 255) / 255; this.g = (hex >> 8 & 255) / 255; this.b = (hex & 255) / 255; return this; + } - }, - - setRGB: function(r, g, b ) + public Color SetRGB(double r, double g, double b) { - this.r = r; this.g = g; this.b = b; return this; - - }, - - setHSL: function() - { - - function hue2rgb(p, q, t ) - { - - if (t < 0) t += 1; - if (t > 1) t -= 1; - if (t < 1 / 6) return p + (q - p) * 6 * t; - if (t < 1 / 2) return q; - if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t); - return p; - - } - - return function setHSL(h, s, l) { - - // h,s,l ranges are in 0.0 - 1.0 - h = _Math.euclideanModulo(h, 1); - s = _Math.clamp(s, 0, 1); - l = _Math.clamp(l, 0, 1); - - if (s === 0) - { - - this.r = this.g = this.b = l; - - } - else - { - - var p = l <= 0.5 ? l * (1 + s) : l + s - (l * s); - var q = (2 * l) - p; - - this.r = hue2rgb(q, p, h + 1 / 3); - this.g = hue2rgb(q, p, h); - this.b = hue2rgb(q, p, h - 1 / 3); - - } - - return this; - - }; - } - (), - setStyle: function(style ) + private double Hue2rgb(double p, double q, double t) { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1 / 6) return p + (q - p) * 6 * t; + if (t < 1 / 2) return q; + if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t); + return p; + } - function handleAlpha(string ) + public Color SetHSL(double h, double s, double l) + { + // h,s,l ranges are in 0.0 - 1.0 + h = Math.EuclideanModulo(h, 1); + s = Math.Clamp(s, 0, 1); + l = Math.Clamp(l, 0, 1); + + if (s == 0) { + this.r = this.g = this.b = l; + } + else + { + var p = l <= 0.5 ? l * (1 + s) : l + s - (l * s); + var q = (2 * l) - p; - if (string === undefined) return; - - if (parseFloat(string) < 1) - { - - console.warn("THREE.Color: Alpha component of " + style + " will be ignored."); - - } - + this.r = Hue2rgb(q, p, h + 1 / 3); + this.g = Hue2rgb(q, p, h); + this.b = Hue2rgb(q, p, h - 1 / 3); } + return this; + } - var m; + private void HandleAlpha(string str, string style) + { + if (str == null) return; - if (m = /^ ((?: rgb | hsl)a ?)\(\s * ([^\)]*)\)/.exec(style) ) { + if (double.Parse(str) < 1) + { + Console.WriteLine("THREE.Color: Alpha component of " + style + " will be ignored."); + } + } + public Color SetStyle(string style) + { + Match m; + + if ((m = new Regex(@"^((?:rgb|hsl)a?)\(\s*([^\)]*)\)", RegexOptions.ECMAScript).Match(style)).Success) + { // rgb / hsl - - var color; - var name = m[1]; - var components = m[2]; + Match color; + var name = m.Groups[1].Value; + var components = m.Groups[2].Value; switch (name) { - case "rgb": case "rgba": + if ((color = new Regex(@"^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$", + RegexOptions.ECMAScript).Match(components)).Success) + { + // rgb(255,0,0) rgba(255,0,0,0.5) + this.r = _Math.Min(255, Convert.ToInt32(color.Groups[1].Value, 10)) / 255; + this.g = _Math.Min(255, Convert.ToInt32(color.Groups[2].Value, 10)) / 255; + this.b = _Math.Min(255, Convert.ToInt32(color.Groups[3].Value, 10)) / 255; - if (color = /^ (\d +)\s *,\s * (\d +)\s *,\s * (\d +)\s * (,\s * ([0 - 9] *\.?[0-9]+)\s*)?$/.exec(components ) ) { + this.HandleAlpha(color.Groups[5].Value, style); - // rgb(255,0,0) rgba(255,0,0,0.5) - this.r = Math.min( 255, parseInt(color[1], 10 ) ) / 255; - this.g = Math.min( 255, parseInt(color[2], 10 ) ) / 255; - this.b = Math.min( 255, parseInt(color[3], 10 ) ) / 255; + return this; + } - handleAlpha(color[5] ); + if ((color = new Regex(@"^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$", + RegexOptions.ECMAScript).Match(components)).Success) + { + // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) + this.r = _Math.Min(100, Convert.ToInt32(color.Groups[1].Value, 10)) / 100; + this.g = _Math.Min(100, Convert.ToInt32(color.Groups[2].Value, 10)) / 100; + this.b = _Math.Min(100, Convert.ToInt32(color.Groups[3].Value, 10)) / 100; - return this; + this.HandleAlpha(color.Groups[5].Value, style); - } + return this; + } + break; + case "hsl": + case "hsla": + if ((color = new Regex(@"^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$", + RegexOptions.ECMAScript).Match(components)).Success) + { + // hsl(120,50%,50%) hsla(120,50%,50%,0.5) + var h = Convert.ToDouble(color.Groups[1].Value) / 360; + var s = Convert.ToInt32(color.Groups[2].Value, 10) / 100; + var l = Convert.ToInt32(color.Groups[3].Value, 10) / 100; - if (color = /^(\d+)\%\s*,\s* (\d+)\%\s*,\s* (\d+)\%\s* (,\s* ([0 - 9]*\.?[0 - 9]+)\s*)?$/.exec(components ) ) { + this.HandleAlpha(color.Groups[5].Value, style); - // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) - this.r = Math.min(100, parseInt(color[1], 10)) / 100; - - this.g = Math.min(100, parseInt(color[2], 10)) / 100; - - this.b = Math.min(100, parseInt(color[3], 10)) / 100; - - - handleAlpha(color[5] ); - - return this; - - - } - - break; - - case "hsl": - case "hsla": - - if (color = /^([0 - 9]*\.?[0 - 9]+)\s*,\s* (\d+)\%\s*,\s* (\d+)\%\s* (,\s* ([0 - 9]*\.?[0 - 9]+)\s*)?$/.exec(components ) ) { - - // hsl(120,50%,50%) hsla(120,50%,50%,0.5) - var h = parseFloat(color[1]) / 360; - var s = parseInt(color[2], 10) / 100; - var l = parseInt(color[3], 10) / 100; - - handleAlpha(color[5] ); - - return this.setHSL(h, s, l); - - - } - - break; - - } - - } else if (m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) { - - // hex color - - var hex = m[1]; -var size = hex.length; - - if (size === 3 ) { - - // #ff0 - this.r = parseInt(hex.charAt(0) + hex.charAt(0), 16) / 255; - - this.g = parseInt(hex.charAt(1) + hex.charAt(1), 16) / 255; - - this.b = parseInt(hex.charAt(2) + hex.charAt(2), 16) / 255; - - return this; - - - } else if (size === 6 ) { - - // #ff0000 - this.r = parseInt(hex.charAt(0) + hex.charAt(1), 16) / 255; - - this.g = parseInt(hex.charAt(2) + hex.charAt(3), 16) / 255; - - this.b = parseInt(hex.charAt(4) + hex.charAt(5), 16) / 255; - - return this; + return this.SetHSL(h, s, l); + } + break; + } + } + else if ((m = new Regex(@"^\#([A-Fa-f0-9]+)$", RegexOptions.ECMAScript).Match(style)).Success) + { + // hex color + var hex = m.Groups[1].Value; + var size = hex.Length; + if (size == 3) + { + // #ff0 + this.r = Convert.ToInt32((hex[0] + hex[0]).ToString(), 16) / 255; + this.g = Convert.ToInt32((hex[1] + hex[1]).ToString(), 16) / 255; + this.b = Convert.ToInt32((hex[2] + hex[2]).ToString(), 16) / 255; + return this; + } + else if (size == 6) + { + // #ff0000 + this.r = Convert.ToInt32((hex[0] + hex[1]).ToString(), 16) / 255; + this.g = Convert.ToInt32((hex[2] + hex[3]).ToString(), 16) / 255; + this.b = Convert.ToInt32((hex[4] + hex[5]).ToString(), 16) / 255; + return this; + } } - } - - if (style && style.length > 0 ) { - - // color keywords - var hex = ColorKeywords[style]; - - if (hex !== undefined ) { - - // red - this.setHex(hex ); - - - } else { - - // unknown color - console.warn( "THREE.Color: Unknown color " + style ); - - } - - } - - return this; - - - }, - - clone: function() -{ - - return new this.constructor(this.r, this.g, this.b); - -}, - - copy: function(color ) -{ - - this.r = color.r; - this.g = color.g; - this.b = color.b; - - return this; - -}, - - copyGammaToLinear: function(color, gammaFactor ) -{ - - if (gammaFactor === undefined) gammaFactor = 2.0; - - this.r = Math.pow(color.r, gammaFactor); - this.g = Math.pow(color.g, gammaFactor); - this.b = Math.pow(color.b, gammaFactor); - - return this; - -}, - - copyLinearToGamma: function(color, gammaFactor ) -{ - - if (gammaFactor === undefined) gammaFactor = 2.0; - - var safeInverse = (gammaFactor > 0) ? (1.0 / gammaFactor) : 1.0; - - this.r = Math.pow(color.r, safeInverse); - this.g = Math.pow(color.g, safeInverse); - this.b = Math.pow(color.b, safeInverse); - - return this; - -}, - - convertGammaToLinear: function(gammaFactor ) -{ - - this.copyGammaToLinear(this, gammaFactor); - - return this; - -}, - - convertLinearToGamma: function(gammaFactor ) -{ - - this.copyLinearToGamma(this, gammaFactor); - - return this; - -}, - - copySRGBToLinear: function() -{ - - function SRGBToLinear(c ) - { - - return (c < 0.04045) ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4); - - } - - return function copySRGBToLinear(color) { - - this.r = SRGBToLinear(color.r); - this.g = SRGBToLinear(color.g); - this.b = SRGBToLinear(color.b); - - return this; - - }; - -} -(), - - copyLinearToSRGB: function() -{ - - function LinearToSRGB(c ) - { - - return (c < 0.0031308) ? c * 12.92 : 1.055 * (Math.pow(c, 0.41666)) - 0.055; - - } - - return function copyLinearToSRGB(color) { - - this.r = LinearToSRGB(color.r); - this.g = LinearToSRGB(color.g); - this.b = LinearToSRGB(color.b); - - return this; - - }; - -} -(), - - convertSRGBToLinear: function() -{ - - this.copySRGBToLinear(this); - - return this; - -}, - - convertLinearToSRGB: function() -{ - - this.copyLinearToSRGB(this); - - return this; - -}, - - getHex: function() -{ - - return (this.r * 255) << 16 ^ (this.g * 255) << 8 ^ (this.b * 255) << 0; - -}, - - getHexString: function() -{ - - return ("000000" + this.getHex().toString(16)).slice(-6); - -}, - - getHSL: function(target ) -{ - - // h,s,l ranges are in 0.0 - 1.0 - - if (target === undefined) - { - - console.warn("THREE.Color: .getHSL() target is now required"); - target = { h: 0, s: 0, l: 0 }; - - } - - var r = this.r, g = this.g, b = this.b; - - var max = Math.max(r, g, b); - var min = Math.min(r, g, b); - - var hue, saturation; - var lightness = (min + max) / 2.0; - - if (min === max) - { - - hue = 0; - saturation = 0; - - } - else - { - - var delta = max - min; - - saturation = lightness <= 0.5 ? delta / (max + min) : delta / (2 - max - min); - - switch (max) - { - - case r: hue = (g - b) / delta + (g < b ? 6 : 0); break; - case g: hue = (b - r) / delta + 2; break; - case b: hue = (r - g) / delta + 4; break; - + if (style != null && style.Length > 0) + { + // color keywords + var field = typeof(ColorKeywords).GetField(style); + + if (field != null) + { + var hex = Convert.ToInt32(field.GetValue(null).ToString()); + + // red + this.SetHex(hex); + } + else + { + // unknown color + Console.WriteLine("THREE.Color: Unknown color " + style); + } + } + + return this; } - hue /= 6; + public Color Clone() + { + return new Color(this.r, this.g, this.b); + } + + public Color Copy(Color color) + { + this.r = color.r; + this.g = color.g; + this.b = color.b; + + return this; + } + + public Color CopyGammaToLinear(Color color, double gammaFactor = 2.0) + { + this.r = _Math.Pow(color.r, gammaFactor); + this.g = _Math.Pow(color.g, gammaFactor); + this.b = _Math.Pow(color.b, gammaFactor); + + return this; + } + + public Color CopyLinearToGamma(Color color, double gammaFactor = 2.0) + { + var safeInverse = (gammaFactor > 0) ? (1.0 / gammaFactor) : 1.0; + + this.r = _Math.Pow(color.r, safeInverse); + this.g = _Math.Pow(color.g, safeInverse); + this.b = _Math.Pow(color.b, safeInverse); + + return this; + } + + public Color ConvertGammaToLinear(double gammaFactor) + { + this.CopyGammaToLinear(this, gammaFactor); + + return this; + } + + public Color ConvertLinearToGamma(double gammaFactor) + { + this.CopyLinearToGamma(this, gammaFactor); + + return this; + } + + private double SRGBToLinear(double c) + { + return (c < 0.04045) ? c * 0.0773993808 : _Math.Pow(c * 0.9478672986 + 0.0521327014, 2.4); + } + + public Color CopySRGBToLinear(Color color) + { + this.r = SRGBToLinear(color.r); + this.g = SRGBToLinear(color.g); + this.b = SRGBToLinear(color.b); + + return this; + } + + private double LinearToSRGB(double c) + { + return (c < 0.0031308) ? c * 12.92 : 1.055 * (_Math.Pow(c, 0.41666)) - 0.055; + } + + public Color CopyLinearToSRGB(Color color) + { + this.r = LinearToSRGB(color.r); + this.g = LinearToSRGB(color.g); + this.b = LinearToSRGB(color.b); + + return this; + } + + public Color ConvertSRGBToLinear() + { + this.CopySRGBToLinear(this); + + return this; + } + + public Color ConvertLinearToSRGB() + { + this.CopyLinearToSRGB(this); + + return this; + } + + public double GetHex() + { + return Convert.ToInt32(this.r * 255) << 16 ^ Convert.ToInt32(this.g * 255) << 8 ^ Convert.ToInt32(this.b * 255) << 0; + } + + public string GetHexString() + { + var hex = ("000000" + this.GetHex().ToString("{0:X}")); + return hex.Substring(hex.Length - 6, 6); + } + + public double[] GetHSL(double[] target = null) // [h, s, l] + { + // h,s,l ranges are in 0.0 - 1.0 + + if (target == null) + { + Console.WriteLine("THREE.Color: .getHSL() target is now required"); + target = new double[] { 0, 0, 0 }; + } + + double r = this.r, g = this.g, b = this.b; + + var max = _Math.Max(_Math.Max(r, g), b); + var min = _Math.Min(_Math.Max(r, g), b); + + double hue = 0, saturation; + var lightness = (min + max) / 2.0; + + if (min == max) + { + hue = 0; + saturation = 0; + } + else + { + var delta = max - min; + + saturation = lightness <= 0.5 ? delta / (max + min) : delta / (2 - max - min); + + if (max == r) + { + hue = (g - b) / delta + (g < b ? 6 : 0); + } + else if (max == g) + { + hue = (b - r) / delta + 2; + } + else if (max == b) + { + hue = (r - g) / delta + 4; + } + + hue /= 6; + } + + target = new double[] { hue, saturation, lightness }; + + return target; + } + + public string GetStyle() + { + return "rgb(" + _Math.Floor(this.r * 255) + "," + _Math.Floor(this.g * 255) + "," + _Math.Floor(this.b * 255) + ")"; + } + + public Color OffsetHSL(double h, double s, double l) + { + var hsl = new double[3]; + + this.GetHSL(hsl); + + hsl[0] += h; + hsl[1] += s; + hsl[2] += l; + + this.SetHSL(hsl[0], hsl[1], hsl[2]); + + return this; + } + + public Color Add(Color color) + { + this.r += color.r; + this.g += color.g; + this.b += color.b; + + return this; + } + + public Color AddColors(Color color1, Color color2) + { + this.r = color1.r + color2.r; + this.g = color1.g + color2.g; + this.b = color1.b + color2.b; + + return this; + } + + public Color AddScalar(double s) + { + this.r += s; + this.g += s; + this.b += s; + + return this; + } + + public Color Sub(Color color) + { + this.r = _Math.Max(0, this.r - color.r); + this.g = _Math.Max(0, this.g - color.g); + this.b = _Math.Max(0, this.b - color.b); + + return this; + } + + public Color Multiply(Color color) + { + this.r *= color.r; + this.g *= color.g; + this.b *= color.b; + + return this; + } + + public Color MultiplyScalar(double s) + { + this.r *= s; + this.g *= s; + this.b *= s; + + return this; + } + + public Color Lerp(Color color, double alpha) + { + this.r += (color.r - this.r) * alpha; + this.g += (color.g - this.g) * alpha; + this.b += (color.b - this.b) * alpha; + + return this; + } + + public Color LerpHSL(Color color, double alpha) + { - } + var hslA = new double[] { 0, 0, 0 }; + var hslB = new double[] { 0, 0, 0 }; - target.h = hue; - target.s = saturation; - target.l = lightness; + this.GetHSL(hslA); + color.GetHSL(hslB); - return target; + var h = Math.Lerp(hslA[0], hslB[0], alpha); + var s = Math.Lerp(hslA[1], hslB[1], alpha); + var l = Math.Lerp(hslA[2], hslB[2], alpha); -}, + this.SetHSL(h, s, l); - getStyle: function() -{ + return this; + } - return "rgb(" + ((this.r * 255) | 0) + "," + ((this.g * 255) | 0) + "," + ((this.b * 255) | 0) + ")"; + public bool Equals(Color c) + { + return (c.r == this.r) && (c.g == this.g) && (c.b == this.b); + } -}, + public Color FromArray(double[] array, int offset = 0) + { + this.r = array[offset]; + this.g = array[offset + 1]; + this.b = array[offset + 2]; - offsetHSL: function() -{ + return this; + } - var hsl = { }; - - return function(h, s, l) { - - this.getHSL(hsl); - - hsl.h += h; hsl.s += s; hsl.l += l; - - this.setHSL(hsl.h, hsl.s, hsl.l); - - return this; - - }; - -} -(), - - add: function(color ) -{ - - this.r += color.r; - this.g += color.g; - this.b += color.b; - - return this; - -}, - - addColors: function(color1, color2 ) -{ - - this.r = color1.r + color2.r; - this.g = color1.g + color2.g; - this.b = color1.b + color2.b; - - return this; - -}, - - addScalar: function(s ) -{ - - this.r += s; - this.g += s; - this.b += s; - - return this; - -}, - - sub: function(color ) -{ - - this.r = Math.max(0, this.r - color.r); - this.g = Math.max(0, this.g - color.g); - this.b = Math.max(0, this.b - color.b); - - return this; - -}, - - multiply: function(color ) -{ - - this.r *= color.r; - this.g *= color.g; - this.b *= color.b; - - return this; - -}, - - multiplyScalar: function(s ) -{ - - this.r *= s; - this.g *= s; - this.b *= s; - - return this; - -}, - - lerp: function(color, alpha ) -{ - - this.r += (color.r - this.r) * alpha; - this.g += (color.g - this.g) * alpha; - this.b += (color.b - this.b) * alpha; - - return this; - -}, - - lerpHSL: function() -{ - - var hslA = { h: 0, s: 0, l: 0 }; -var hslB = { h: 0, s: 0, l: 0 }; - - return function lerpHSL(color, alpha ) -{ - - this.getHSL(hslA); - color.getHSL(hslB); - - var h = _Math.lerp(hslA.h, hslB.h, alpha); - var s = _Math.lerp(hslA.s, hslB.s, alpha); - var l = _Math.lerp(hslA.l, hslB.l, alpha); - - this.setHSL(h, s, l); - - return this; - -}; - - }(), - - equals: function(c ) -{ - - return (c.r === this.r) && (c.g === this.g) && (c.b === this.b); - -}, - - fromArray: function(array, offset ) -{ - - if (offset === undefined) offset = 0; - - this.r = array[offset]; - this.g = array[offset + 1]; - this.b = array[offset + 2]; - - return this; - -}, - - toArray: function(array, offset ) -{ - - if (array === undefined) array = []; - if (offset === undefined) offset = 0; - - array[offset] = this.r; - array[offset + 1] = this.g; - array[offset + 2] = this.b; - - return array; - -}, - - toJSON: function() -{ - - return this.getHex(); - -} + public double[] ToArray(double[] array = null, int offset = 0) + { + if (array == null) array = new double[3]; + + array[offset] = this.r; + array[offset + 1] = this.g; + array[offset + 2] = this.b; + + return array; + } + public double ToJSON() + { + return this.GetHex(); + } } } diff --git a/THREE/Math/Math.cs b/THREE/Math/Math.cs index 39a99e98..138434ec 100644 --- a/THREE/Math/Math.cs +++ b/THREE/Math/Math.cs @@ -48,7 +48,7 @@ namespace THREE return uuid.ToUpper(); } - public double Clamp(double value, double min, double max) + public static double Clamp(double value, double min, double max) { return _Math.Max(min, _Math.Min(max, value)); } @@ -56,27 +56,27 @@ namespace THREE // compute euclidian modulo of m % n // https://en.wikipedia.org/wiki/Modulo_operation - public double EuclideanModulo(double n, double m) + public static double EuclideanModulo(double n, double m) { return ((n % m) + m) % m; } // Linear mapping from range to range - public double MapLinear(double x, double a1, double a2, double b1, double b2) + public static double MapLinear(double x, double a1, double a2, double b1, double b2) { return b1 + (x - a1) * (b2 - b1) / (a2 - a1); } // https://en.wikipedia.org/wiki/Linear_interpolation - public double Lerp(double x, double y, double t) + public static double Lerp(double x, double y, double t) { return (1 - t) * x + t * y; } // http://en.wikipedia.org/wiki/Smoothstep - public double Smoothstep(double x, double min, double max) + public static double Smoothstep(double x, double min, double max) { if (x <= min) return 0; if (x >= max) return 1; @@ -97,47 +97,47 @@ namespace THREE } // Random integer from interval - public double RandInt(double low, double high) + public static double RandInt(double low, double high) { var ran = new Random(); return low + _Math.Floor(ran.NextDouble() * (high - low + 1)); } // Random float from interval - public double RandFloat(double low, double high) + public static double RandFloat(double low, double high) { var ran = new Random(); return low + ran.NextDouble() * (high - low); } // Random float from <-range/2, range/2> interval - public double RandFloatSpread(double range) + public static double RandFloatSpread(double range) { var ran = new Random(); return range * (0.5 - ran.NextDouble()); } - public double DegToRad(double degrees) + public static double DegToRad(double degrees) { return degrees * Math.DEG2RAD; } - public double RadToDeg(double radians) + public static double RadToDeg(double radians) { return radians * Math.RAD2DEG; } - public bool IsPowerOfTwo(int value) + public static bool IsPowerOfTwo(int value) { return (value & (value - 1)) == 0 && value != 0; } - public double CeilPowerOfTwo(double value) + public static double CeilPowerOfTwo(double value) { return _Math.Pow(2, _Math.Ceiling(_Math.Log(value) / _Math.Log(2))); } - public double FloorPowerOfTwo(double value) + public static double FloorPowerOfTwo(double value) { return _Math.Pow(2, _Math.Floor(_Math.Log(value) / _Math.Log(2))); }