public override bool Equals(object obj) { if (obj is MultiColor) { MultiColor c = obj as MultiColor; if (data.Length != c.data.Length) { return(false); } for (int i = 0; i < data.Length; i++) { if (data[i] != c.data[i]) { return(false); } if (transp[i] != c.transp[i]) { return(false); } } return(true); } else { return(false); } }
//ALGORITHM CORE private byte closestMultiColor(MultiColor mc) { if (mc.allTransparent()) { return(0); } else { int best = -1; float bestd = float.PositiveInfinity; for (int i = 0; i < multiPalette.Length; i++) { if (multiPalette[i] == null) { continue; } float d = mc.diff(multiPalette[i]); if (d < bestd || best == -1) { best = i; bestd = d; } } return((byte)best); } }
/// <summary> /// Shades checker /// </summary> /// <param name="ray">ray</param> /// <param name="hit">hit</param> /// /// <param name="hitObject">hitObject</param> /// <param name="shapes">Primitive</param> /// <param name="color">color</param> public override void TestColor(ref Ray ray, ref HitInfo hit, ref Primitive hitObject, ref List <Primitive> shapes, ref MultiColor mcolor) { // color.diffuse.Show(); Vector3 fromMe2Pt = new Vector3(); bool inShadow = false; Ray r = new Ray(position, hit.point - position, hit.distance + 1); //Console.WriteLine(hit.normal.ToString()); inShadow = Ray.CastAtPrimitive(ref r, ref shapes) != (hitObject); //if (inShadow == false) //{ // color.diffuse.Show(); //} if (inShadow) { count++; mcolor.diffuse *= 0; mcolor.specular *= 0; } //if (!mcolor.specular.isZero()&& !mcolor.specular.isOne()) // mcolor.specular.Show(); // shading fromMe2Pt = (hit.point - position).GetNormalized(); Ray temp = ray; temp.Direction = -ray.Direction; Material material = hitObject.GetMaterial(); Phong(ref fromMe2Pt, ref temp.Direction, ref hit.normal, ref mcolor, material); }
/// <summary> /// Phong light model /// </summary> /// <param name="Lightdir">Lightdir</param> /// <param name="LookDir">LookDir</param> /// /// <param name="normal">normal</param> /// <param name="mcolor">mcolor</param> /// <param name="material">material</param> public virtual void Phong( ref Vector3 Lightdir, ref Vector3 LookDir, ref Vector3 normal, ref MultiColor mcolor, Material material) { double specForce = 0; // mcolor.specular.Show(); // this.color.Show(); double f = (-Lightdir).dot(normal); //diffuse mcolor.diffuse = mcolor.diffuse * material.diffuseColor * color * (-Lightdir).dot(normal); //specular specForce = (LookDir).dot(Lightdir.Reflect(normal)); if (specForce < 0) { specForce = 0; } // mcolor.specular.Show(); mcolor.specular *= material.specularColor * color * Math.Pow(specForce, material.shininess); }
public MultiColor center() { MultiColor res = new MultiColor(min.Length); for (int i = 0; i < min.Length; i++) { res.data[i] = (byte)((min[i] + max[i]) / 2); } return(res); }
public void merge(MultiColor b) { for (int i = 0; i < data.Length; i++) { if (transp[i]) { transp[i] = b.transp[i]; data[i] = b.data[i]; } } calcHash(); }
public float diff(MultiColor b) { float res = 0; for (int i = 0; i < data.Length; i++) { if (!transp[i] && !b.transp[i]) { float d = data[i] - b.data[i]; res += d * d; } } return(res); }
public bool inside(MultiColor c) { for (int i = 0; i < min.Length; i++) { if (c.transp[i]) { continue; } if (c.data[i] < min[i]) { return(false); } if (c.data[i] > max[i]) { return(false); } } return(true); }
public MultiColor center() { MultiColor res = new MultiColor(min.Length); for (int i = 0; i < min.Length; i++) res.data[i] = (byte)((min[i] + max[i]) / 2); return res; }
public ImageIndexer(List<Bitmap> bl, int paletteCount, bool useAlpha, int transpCol) { this.bl = bl; this.paletteCount = paletteCount; this.useAlpha = useAlpha; boxColorCount = bl.Count * 3; //COMPUTE FREQUENCY TABLE freqTable = new Dictionary<MultiColor,int>(); //Quick check just in case... width = bl[0].Width; height = bl[0].Height; foreach(Bitmap b in bl) { if (b.Width != width || b.Height != height) throw new Exception("Not all images have the same size!!"); } for (int x = 0; x < width; x++) for (int y = 0; y < height; y++) { MultiColor c = new MultiColor(boxColorCount); for(int i = 0; i < bl.Count; i++) c.setColor(i, bl[i].GetPixel(x, y)); c.calcHash(); if(!c.allTransparent()) if (freqTable.ContainsKey(c)) freqTable[c]++; else freqTable[c] = 1; } int ct = 0; foreach (MultiColor c in freqTable.Keys) if (c.someTransparent()) ct++; // Console.Out.WriteLine("Transparent: " + ct); Dictionary<MultiColor, int> newFreqTable = new Dictionary<MultiColor, int>(); foreach (MultiColor c in freqTable.Keys) { if (!c.deleteFlag) { int cnt = freqTable[c]; foreach(MultiColor c2 in freqTable.Keys) { if (c2 == null) continue; if (c2.deleteFlag) continue; if (c2 == c) continue; if (c.diff(c2) == 0) { cnt += freqTable[c2]; c.merge(c2); c2.deleteFlag = true; } } c.deleteFlag = true; c.removeAllTransparent(); newFreqTable.Add(c, cnt); } } freqTable = newFreqTable; ct = 0; foreach (MultiColor c in freqTable.Keys) if (c.someTransparent()) ct++; // Console.Out.WriteLine("Transparent2: " + ct); // NOW CREATE THE PALETTE ZONES Box startBox = shrinkBox(new Box(boxColorCount)); boxes = new List<Box>(); boxes.Add(startBox); while (boxes.Count < (useAlpha ? paletteCount - 1 : paletteCount)) { // Console.Out.WriteLine(boxes.Count); Box bo = getDominantBox(); if (bo == null) break; split(bo); } multiPalette = new MultiColor[paletteCount]; for (int j = useAlpha ? 1 : 0; j < paletteCount; j++) if ((useAlpha ? j : j + 1) <= boxes.Count) multiPalette[j] = boxes[useAlpha ? j - 1 : j].center(); //NOW CREATE THE PALETTE COLORS palettes = new Color[bl.Count][]; for (int i = 0; i < bl.Count; i++) { palettes[i] = new Color[paletteCount]; for (int j = useAlpha ? 1 : 0; j < paletteCount; j++) { if ((useAlpha ? j : j + 1) > boxes.Count) palettes[i][j] = Color.Fuchsia; else palettes[i][j] = boxes[useAlpha ? j - 1 : j].center().getColor(i); // Console.Out.WriteLine(i + ": " + boxes[i] + ": "+ palette[i]); } if (useAlpha) palettes[i][0] = Color.Transparent; } //NOW MAP ORIGINAL COLORS TO PALETTE ENTRIES colorTable = new Dictionary<MultiColor, byte>(); foreach (MultiColor c in freqTable.Keys) colorTable[c] = closestMultiColor(c); //NOW INDEX THE WHOLE IMAGES imageData = new byte[width, height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { MultiColor c = new MultiColor(boxColorCount); for (int i = 0; i < bl.Count; i++) c.setColor(i, bl[i].GetPixel(x, y)); c.calcHash(); if (c.allTransparent()) imageData[x, y] = (byte)transpCol; else imageData[x, y] = closestMultiColor(c); } } Console.Out.WriteLine("DONE"); /* }*/ }
public bool inside(MultiColor c) { for (int i = 0; i < min.Length; i++) { if (c.transp[i]) continue; if (c.data[i] < min[i]) return false; if (c.data[i] > max[i]) return false; } return true; }
public float diff(MultiColor b) { float res = 0; for(int i = 0; i < data.Length; i++) if (!transp[i] && !b.transp[i]) { float d = data[i] - b.data[i]; res += d * d; } return res; }
public void merge(MultiColor b) { for(int i = 0; i < data.Length; i++) if (transp[i]) { transp[i] = b.transp[i]; data[i] = b.data[i]; } calcHash(); }
//ALGORITHM CORE private byte closestMultiColor(MultiColor mc) { if (mc.allTransparent()) return 0; else { int best = -1; float bestd = float.PositiveInfinity; for (int i = 0; i < multiPalette.Length; i++) { if (multiPalette[i] == null) continue; float d = mc.diff(multiPalette[i]); if (d < bestd || best == -1) { best = i; bestd = d; } } return (byte)best; } }
public ImageIndexer(List <Bitmap> bl, int paletteCount, bool useAlpha, int transpCol) { this.bl = bl; this.paletteCount = paletteCount; this.useAlpha = useAlpha; boxColorCount = bl.Count * 3; //COMPUTE FREQUENCY TABLE freqTable = new Dictionary <MultiColor, int>(); //Quick check just in case... width = bl[0].Width; height = bl[0].Height; foreach (Bitmap b in bl) { if (b.Width != width || b.Height != height) { throw new Exception("Not all images have the same size!!"); } } for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { MultiColor c = new MultiColor(boxColorCount); for (int i = 0; i < bl.Count; i++) { c.setColor(i, bl[i].GetPixel(x, y)); } c.calcHash(); if (!c.allTransparent()) { if (freqTable.ContainsKey(c)) { freqTable[c]++; } else { freqTable[c] = 1; } } } } int ct = 0; foreach (MultiColor c in freqTable.Keys) { if (c.someTransparent()) { ct++; } } // Console.Out.WriteLine("Transparent: " + ct); Dictionary <MultiColor, int> newFreqTable = new Dictionary <MultiColor, int>(); foreach (MultiColor c in freqTable.Keys) { if (!c.deleteFlag) { int cnt = freqTable[c]; foreach (MultiColor c2 in freqTable.Keys) { if (c2 == null) { continue; } if (c2.deleteFlag) { continue; } if (c2 == c) { continue; } if (c.diff(c2) == 0) { cnt += freqTable[c2]; c.merge(c2); c2.deleteFlag = true; } } c.deleteFlag = true; c.removeAllTransparent(); newFreqTable.Add(c, cnt); } } freqTable = newFreqTable; ct = 0; foreach (MultiColor c in freqTable.Keys) { if (c.someTransparent()) { ct++; } } // Console.Out.WriteLine("Transparent2: " + ct); // NOW CREATE THE PALETTE ZONES Box startBox = shrinkBox(new Box(boxColorCount)); boxes = new List <Box>(); boxes.Add(startBox); while (boxes.Count < (useAlpha ? paletteCount - 1 : paletteCount)) { // Console.Out.WriteLine(boxes.Count); Box bo = getDominantBox(); if (bo == null) { break; } split(bo); } multiPalette = new MultiColor[paletteCount]; for (int j = useAlpha ? 1 : 0; j < paletteCount; j++) { if ((useAlpha ? j : j + 1) <= boxes.Count) { multiPalette[j] = boxes[useAlpha ? j - 1 : j].center(); } } //NOW CREATE THE PALETTE COLORS palettes = new Color[bl.Count][]; for (int i = 0; i < bl.Count; i++) { palettes[i] = new Color[paletteCount]; for (int j = useAlpha ? 1 : 0; j < paletteCount; j++) { if ((useAlpha ? j : j + 1) > boxes.Count) { palettes[i][j] = Color.Fuchsia; } else { palettes[i][j] = boxes[useAlpha ? j - 1 : j].center().getColor(i); } // Console.Out.WriteLine(i + ": " + boxes[i] + ": "+ palette[i]); } if (useAlpha) { palettes[i][0] = Color.Transparent; } } //NOW MAP ORIGINAL COLORS TO PALETTE ENTRIES colorTable = new Dictionary <MultiColor, byte>(); foreach (MultiColor c in freqTable.Keys) { colorTable[c] = closestMultiColor(c); } //NOW INDEX THE WHOLE IMAGES imageData = new byte[width, height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { MultiColor c = new MultiColor(boxColorCount); for (int i = 0; i < bl.Count; i++) { c.setColor(i, bl[i].GetPixel(x, y)); } c.calcHash(); if (c.allTransparent()) { imageData[x, y] = (byte)transpCol; } else { imageData[x, y] = closestMultiColor(c); } } } Console.Out.WriteLine("DONE"); /* * * }*/ }
public abstract void TestColor(ref Ray ray, ref HitInfo hit, ref Primitive hitObject, ref List <Primitive> shapes, ref MultiColor color);