2using System.Collections.Generic;
6using System.Threading.Tasks;
19 List<Tuple<double, int>> m_rgQuads0 =
new List<Tuple<double, int>>();
20 List<Tuple<double, int>> m_rgQuads1 =
new List<Tuple<double, int>>();
22 List<KeyValuePair<Color, SizeF>> m_rgColorMappings =
new List<KeyValuePair<Color, SizeF>>();
24 List<List<double>> m_rgrgColors =
new List<List<double>>();
27 Color m_clrNoMinMax = Color.HotPink;
56 m_clrDefault = clrDefault;
57 m_clrError = clrError;
58 m_nResolution = nResolution;
64 m_rgrgColors.Add(
new List<double>() { 1, 0, 0 });
65 m_rgrgColors.Add(
new List<double>() { 0, 0, 0.5 });
66 m_rgrgColors.Add(
new List<double>() { 0, 1, 0 });
70 m_rgrgColors.Add(
new List<double>() { 0, 0, 0 });
71 m_rgrgColors.Add(
new List<double>() { 0, 0, 1 });
72 m_rgrgColors.Add(
new List<double>() { 0, 1, 0 });
73 m_rgrgColors.Add(
new List<double>() { 1, 0, 0 });
74 m_rgrgColors.Add(
new List<double>() { 1, 1, 0 });
78 double dfMin1 = dfMin;
79 double dfMax1 = dfMax;
81 double dfRange = dfMax - dfMin;
82 double dfInc = dfRange / m_nResolution;
84 dfMax = dfMin + dfInc;
86 while (dfMax < m_dfMax)
88 Color clr = calculate(dfMin);
89 m_rgColorMappings.Add(
new KeyValuePair<Color, SizeF>(clr,
new SizeF((
float)dfMin, (
float)dfMax)));
94 if (m_rgColorMappings.Count == 0)
95 m_rgColorMappings.Add(
new KeyValuePair<Color, SizeF>(Color.Black,
new SizeF((
float)dfMin1, (
float)dfMax1)));
97 m_dfMid = dfRange / 2;
98 m_nMidIdx = m_rgColorMappings.Count / 2;
99 m_rgQuads0 = createSearchQuads(0, 0, m_rgColorMappings.Count, dfRange);
100 m_rgQuads1 = createSearchQuads(m_dfMid, m_nMidIdx, m_rgColorMappings.Count, dfRange);
113 public ColorMapper(
double dfMin,
double dfMax, Color clrDefault, Color clrError, List<double> rgClrStart, List<double> rgClrEnd,
int nResolution = 160)
115 m_clrDefault = clrDefault;
116 m_clrError = clrError;
117 m_nResolution = nResolution;
121 m_rgrgColors.Add(rgClrStart);
122 m_rgrgColors.Add(rgClrEnd);
124 double dfRange = dfMax - dfMin;
125 double dfInc = dfRange / m_nResolution;
127 dfMax = dfMin + dfInc;
129 while (dfMax < m_dfMax)
131 Color clr = calculate(dfMin);
132 m_rgColorMappings.Add(
new KeyValuePair<Color, SizeF>(clr,
new SizeF((
float)dfMin, (
float)dfMax)));
137 m_dfMid = dfRange / 2;
138 m_nMidIdx = m_rgColorMappings.Count / 2;
139 m_rgQuads0 = createSearchQuads(0, 0, m_rgColorMappings.Count, dfRange);
140 m_rgQuads1 = createSearchQuads(m_dfMid, m_nMidIdx, m_rgColorMappings.Count, dfRange);
143 private List<Tuple<double, int>> createSearchQuads(
double dfStart,
int nIdxStart,
int nItemCount,
double dfRange)
145 List<Tuple<double, int>> rgQuads =
new List<Tuple<double, int>>();
146 int nCount = (nItemCount < 160) ? 2 : 4;
147 double dfStep = 0.5 / nCount;
148 double dfPortion = dfStep;
150 for (
int i = 1; i < nCount; i++)
152 double dfQuad = dfStart + dfRange * dfPortion;
153 int nIdx = nIdxStart + (int)(nItemCount * dfPortion);
154 rgQuads.Add(
new Tuple<double, int>(dfQuad, nIdx));
167 get {
return m_nResolution; }
175 get {
return m_clrNoMinMax; }
176 set { m_clrNoMinMax = value; }
186 if (
double.IsNaN(dfVal) ||
double.IsInfinity(dfVal))
189 if (dfVal >= m_dfMin || dfVal <= m_dfMax)
191 if (m_rgColorMappings.Count > 0)
194 int nEnd = m_rgColorMappings.Count;
195 List<Tuple<double, int>> rgQuads;
199 nEnd = m_nMidIdx + 1;
200 rgQuads = m_rgQuads0;
204 nStart = m_nMidIdx - 1;
205 rgQuads = m_rgQuads1;
208 for (
int i = 0; i < rgQuads.Count; i++)
210 if (dfVal < rgQuads[i].Item1)
213 nStart = rgQuads[i].Item2 - 1;
215 if (i < rgQuads.Count - 1)
216 nEnd = rgQuads[i].Item2 + 1;
225 if (nEnd > m_rgColorMappings.Count)
226 nEnd = m_rgColorMappings.Count;
228 for (
int i = nStart; i < nEnd; i++)
230 if (dfVal < m_rgColorMappings[i].Value.Height && dfVal >= m_rgColorMappings[i].Value.Width)
231 return m_rgColorMappings[i].Key;
234 if (dfVal == m_rgColorMappings[m_rgColorMappings.Count - 1].Value.Height)
235 return m_rgColorMappings[m_rgColorMappings.Count - 1].Key;
237 else if (m_dfMin == m_dfMax && m_dfMin == 0)
239 return m_clrNoMinMax;
253 List<KeyValuePair<Color, SizeF>> rgItems = m_rgColorMappings.ToList();
254 Color clr0 = Color.Black;
256 for (
int i = 0; i < rgItems.Count; i++)
258 Color clr1 = rgItems[i].Key;
259 double dfMin = rgItems[i].Value.Width;
260 double dfMax = rgItems[i].Value.Height;
264 if (clr.R <= clr1.R && clr.G <= clr1.G && clr.B <= clr1.B)
265 return dfMin + (dfMax - dfMin) / 2;
269 if (((clr1.R >= clr0.R && clr.R <= clr1.R) ||
270 (clr1.R < clr0.R && clr.R >= clr1.R)) &&
271 ((clr1.G >= clr0.G && clr.G <= clr1.G) ||
272 (clr1.G < clr0.G && clr.G >= clr1.G)) &&
273 ((clr1.B >= clr0.B && clr.B <= clr1.B) ||
274 (clr1.B < clr0.B && clr.B >= clr1.B)))
275 return dfMin + (dfMax - dfMin) / 2;
281 int nCount = rgItems.Count;
282 double dfMin1 = rgItems[nCount - 1].Value.Width;
283 double dfMax1 = rgItems[nCount - 1].Value.Height;
285 return dfMin1 + (dfMax1 - dfMin1) / 2;
297 private Color calculate(
double dfVal)
299 double dfMin = m_dfMin;
300 double dfMax = m_dfMax;
301 double dfRange = dfMax - dfMin;
304 dfVal = (dfVal - dfMin) / dfRange;
308 double dfFraction = 0;
317 nIdx1 = m_rgrgColors.Count - 1;
318 nIdx2 = m_rgrgColors.Count - 1;
322 dfVal *= (m_rgrgColors.Count - 1);
323 nIdx1 = (int)Math.Floor(dfVal);
325 dfFraction = dfVal - (double)nIdx1;
328 if (nIdx1 < 0 || nIdx2 < 0)
331 double dfR = (m_rgrgColors[nIdx2][0] - m_rgrgColors[nIdx1][0]) * dfFraction + m_rgrgColors[nIdx1][0];
332 double dfG = (m_rgrgColors[nIdx2][1] - m_rgrgColors[nIdx1][1]) * dfFraction + m_rgrgColors[nIdx1][1];
333 double dfB = (m_rgrgColors[nIdx2][2] - m_rgrgColors[nIdx1][2]) * dfFraction + m_rgrgColors[nIdx1][2];
335 int nR = (int)(dfR * 255);
336 int nG = (int)(dfG * 255);
337 int nB = (int)(dfB * 255);
339 return Color.FromArgb(nR, nG, nB);
352 KeyValuePair<Color, SizeF> item;
354 if (
double.IsNaN(dfVal) ||
double.IsInfinity(dfVal))
357 else if (m_dfMin == m_dfMax && m_dfMin == 0)
358 return m_clrNoMinMax;
362 if (m_nLastIdx >= 0 && m_nLastIdx < m_rgColorMappings.Count)
364 item = m_rgColorMappings[m_nLastIdx];
365 if (dfVal < item.Value.Height && dfVal >= item.Value.Width)
369 item = m_rgColorMappings[m_rgColorMappings.Count - 1];
370 if (dfVal >= item.Value.Width)
373 item = m_rgColorMappings[0];
374 if (dfVal < item.Value.Height)
379 int nMaxNum = m_rgColorMappings.Count - 1;
381 while (nMinNum <= nMaxNum)
383 int nMid = (nMinNum + nMaxNum) / 2;
384 item = m_rgColorMappings[nMid];
385 SizeF sz = item.Value;
387 if (dfVal < sz.Height && dfVal >= sz.Width)
393 else if (dfVal == sz.Height)
395 m_nLastIdx = nMid + 1;
396 return m_rgColorMappings[nMid + 1].Key;
399 else if (dfVal < sz.Width)
402 else if (dfVal >= sz.Height)
The ColorMapper maps a value within a number range, to a Color within a color scheme.
Color NoMinMaxColor
Get/set the color used when the Min and Max both equal 0.
double GetValue(Color clr)
Returns the value associated with the color.
Color GetColorLegacy(double dfVal)
Returns the color associated with the value.
Color GetColor(double dfVal)
Find the color using a binary search algorithm.
ColorMapper(double dfMin, double dfMax, Color clrDefault, Color clrError, COLORSCHEME clrScheme=COLORSCHEME.NORMAL, int nResolution=160)
The ColorMapper constructor.
ColorMapper(double dfMin, double dfMax, Color clrDefault, Color clrError, List< double > rgClrStart, List< double > rgClrEnd, int nResolution=160)
The ColorMapper constructor.
COLORSCHEME
Defines the color scheme to use.
int Resolution
Returns the color resolution used.
The MyCaffe.basecode contains all generic types used throughout MyCaffe.