/// <summary> /// We want to minimize the sum of the variances of two sub-boxes. /// The sum(c^2) terms can be ignored since their sum over both sub-boxes /// is the same (the sum for the whole box) no matter where we split. /// The remaining terms have a minus sign in the variance formula, /// so we drop the minus sign and maximize the sum of the two terms. /// </summary> /// <param name="c">The cube.</param> /// <param name="direction">The direction.</param> /// <param name="first">The first position.</param> /// <param name="last">The last position.</param> /// <param name="cut">The cutting point.</param> /// <param name="wholeR">The whole red.</param> /// <param name="wholeG">The whole green.</param> /// <param name="wholeB">The whole blue.</param> /// <param name="wholeA">The whole alpha.</param> /// <param name="wholeW">The whole weight.</param> /// <returns>The result.</returns> private float Maximize(ref Box c, int direction, int first, int last, out int cut, float wholeR, float wholeG, float wholeB, float wholeA, float wholeW) { int baseR = Bottom(ref c, direction, this.vmr); int baseG = WuAlphaColorQuantizer.Bottom(ref c, direction, this.vmg); int baseB = WuAlphaColorQuantizer.Bottom(ref c, direction, this.vmb); int baseA = WuAlphaColorQuantizer.Bottom(ref c, direction, this.vma); int baseW = WuAlphaColorQuantizer.Bottom(ref c, direction, this.vwt); float max = 0.0f; cut = -1; for (int i = first; i < last; i++) { float halfR = baseR + WuAlphaColorQuantizer.Top(ref c, direction, i, this.vmr); float halfG = baseG + WuAlphaColorQuantizer.Top(ref c, direction, i, this.vmg); float halfB = baseB + WuAlphaColorQuantizer.Top(ref c, direction, i, this.vmb); float halfA = baseA + WuAlphaColorQuantizer.Top(ref c, direction, i, this.vma); float halfW = baseW + WuAlphaColorQuantizer.Top(ref c, direction, i, this.vwt); if (halfW == 0) { continue; } float temp = ((halfR * halfR) + (halfG * halfG) + (halfB * halfB) + (halfA * halfA)) / halfW; halfR = wholeR - halfR; halfG = wholeG - halfG; halfB = wholeB - halfB; halfA = wholeA - halfA; halfW = wholeW - halfW; if (halfW == 0) { continue; } temp += ((halfR * halfR) + (halfG * halfG) + (halfB * halfB) + (halfA * halfA)) / halfW; if (temp > max) { max = temp; cut = i; } } return(max); }
/// <summary> /// We want to minimize the sum of the variances of two sub-boxes. /// The sum(c^2) terms can be ignored since their sum over both sub-boxes /// is the same (the sum for the whole box) no matter where we split. /// The remaining terms have a minus sign in the variance formula, /// so we drop the minus sign and maximize the sum of the two terms. /// </summary> /// <param name="cube">The cube.</param> /// <param name="direction">The direction.</param> /// <param name="first">The first position.</param> /// <param name="last">The last position.</param> /// <param name="cut">The cutting point.</param> /// <param name="wholeR">The whole red.</param> /// <param name="wholeG">The whole green.</param> /// <param name="wholeB">The whole blue.</param> /// <param name="wholeA">The whole alpha.</param> /// <param name="wholeW">The whole weight.</param> /// <returns>The result.</returns> private double Maximize(Box cube, int direction, int first, int last, out int cut, double wholeR, double wholeG, double wholeB, double wholeA, double wholeW) { long baseR = WuAlphaColorQuantizer.Bottom(cube, direction, this.vmr); long baseG = WuAlphaColorQuantizer.Bottom(cube, direction, this.vmg); long baseB = WuAlphaColorQuantizer.Bottom(cube, direction, this.vmb); long baseA = WuAlphaColorQuantizer.Bottom(cube, direction, this.vma); long baseW = WuAlphaColorQuantizer.Bottom(cube, direction, this.vwt); double max = 0.0; cut = -1; for (int i = first; i < last; i++) { double halfR = baseR + WuAlphaColorQuantizer.Top(cube, direction, i, this.vmr); double halfG = baseG + WuAlphaColorQuantizer.Top(cube, direction, i, this.vmg); double halfB = baseB + WuAlphaColorQuantizer.Top(cube, direction, i, this.vmb); double halfA = baseA + WuAlphaColorQuantizer.Top(cube, direction, i, this.vma); double halfW = baseW + WuAlphaColorQuantizer.Top(cube, direction, i, this.vwt); if (halfW == 0) { continue; } double temp = ((halfR * halfR) + (halfG * halfG) + (halfB * halfB) + (halfA * halfA)) / halfW; halfR = wholeR - halfR; halfG = wholeG - halfG; halfB = wholeB - halfB; halfA = wholeA - halfA; halfW = wholeW - halfW; if (halfW == 0) { continue; } temp += ((halfR * halfR) + (halfG * halfG) + (halfB * halfB) + (halfA * halfA)) / halfW; if (temp > max) { max = temp; cut = i; } } return(max); }