rendered paste bodyusing System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
namespace ESoft.CaptchaSolver
{
public class Histogram
{
public static double MeaningCircle = 0.75;
int[,] hist = new int[0, 0];
public int rlength
{
get { return hist.GetLength(0); }
}
public int plength
{
get { return hist.GetLength(1); }
}
double radius = 0;
public int this[int i, int j]
{
get { return _ijok(i, j) ? hist[i, j] : 0; }
set { if (_ijok(i, j)) hist[i, j] = value; }
}
public bool _ijok(int i, int j)
{
return i >= 0 && i < rlength && j >= 0 && j < plength;
}
public Histogram(int r, int rseg, int pseg)
{
hist = new int[rseg, pseg];
}
int total = 0;
public int Total
{
get { return total; }
}
private void Normalize(int maximum)
{
total = 0;
for (int i = 0; i < rlength; i++)
for (int j = 0; j < plength; j++)
{
if (maximum > 0)
hist[i, j] = (int)Math.Floor(255.0 * (double)hist[i, j] / (double)maximum);
else
hist[i, j] = 0;
total += hist[i, j];
}
}
public Histogram MakeCopy()
{
Histogram ret = new Histogram(10, this.rlength, this.plength);
for (int i = 0; i < rlength; i++)
for (int j = 0; j < plength; j++)
{
ret.hist[i, j] = this.hist[i, j];
}
ret.radius = this.radius;
ret.total = this.total;
return ret;
}
public void Divide(int othertotal)
{
/*double rate = (double)(othertotal - this.total) / (double)Math.Max(this.total, othertotal);
if (othertotal > 0 && rate > 0.75 && false)
{
int subtotal = 0;
int maximum = 0;
for (int i = 0; i < rlength; i++)
for (int j = 0; j < plength; j++)
{
hist[i, j] = (int)((double)(hist[i, j]) / (double)othertotal * (double)total);
maximum = Math.Max(hist[i, j], maximum);
subtotal += hist[i, j];
}
if (othertotal < total)
Normalize(maximum);
else
total = subtotal;
}*/
}
public void CountBitImagePart(BitImage image, int x, int y, int r)
{
hist = new int[rlength, plength]; //clear histogram
int maximum = 0;
this.radius = Math.Sqrt(2) * r;
for (int i = x - r; i < x + r + 1; i++)
for (int j = y - r; j < y + r + 1; j++)
{
if (image[i, j])
{
double phi = 0.0;
double rad = Math.Sqrt(Math.Pow((double)(i - x), 2.0) + Math.Pow((double)(j - y), 2.0));
if ((i - x) == 0)
{
phi = (j - y) < 0 ? Math.PI / 2.0 : Math.PI + Math.PI / 2.0;
}
else if ((i - x) < 0)
{
phi = Math.PI + Math.Atan((double)(j - y) / (double)(i - x));
}
else
{
phi = Math.Atan((double)(j - y) / (double)(i - x));
if (phi < 0) phi += Math.PI * 2.0;
if (phi > Math.PI * 2.0) phi -= Math.PI * 2.0;
}
double rsegd = (rad / radius) * (double)rlength;
double psegd = (phi / 2.0 / Math.PI) * (double)plength;
int rseg = rsegd < 0 ? 0 : rsegd > rlength - 1 ? rlength - 1 : (int)Math.Floor(rsegd);
int pseg = psegd < 0 ? 0 : psegd > plength - 1 ? plength - 1 : (int)Math.Floor(psegd);
hist[rseg, pseg]++;
maximum = Math.Max(hist[rseg, pseg], maximum);
}
}
Normalize(maximum);
}
public void Draw(Graphics g, int x, int y, int r, bool drawlines)
{
for (int i = 0; i < rlength; i++)
for (int j = 0; j < plength; j++)
{
GraphicsPath p = new GraphicsPath();
int inradius = (int)((double)i / (double)rlength * (double)r);
int outradius = (int)((double)(i + 1) / (double)rlength * (double)r);
int startangle = (int)((double)j / (double)plength * 360.0);
int endangle = (int)((double)(j + 1) / (double)plength * 360.0);
int sweepangle = (int)(360.0 / (double)plength);
double startangled = (double)j / (double)plength * Math.PI * 2.0;
double endangled = (double)(j + 1) / (double)plength * Math.PI * 2.0;
Point outstart = new Point(x + (int)((double)outradius * Math.Cos(startangled)),
y + (int)((double)outradius * Math.Sin(startangled)));
Point instart = new Point(x + (int)((double)inradius * Math.Cos(startangled)),
y + (int)((double)inradius * Math.Sin(startangled)));
Point outend = new Point(x + (int)((double)outradius * Math.Cos(endangled)),
y + (int)((double)outradius * Math.Sin(endangled)));
Point inend = new Point(x + (int)((double)inradius * Math.Cos(endangled)),
y + (int)((double)inradius * Math.Sin(endangled)));
if (sweepangle >= 360)
{
p.AddEllipse(new Rectangle(x - outradius, y - outradius, outradius * 2, outradius * 2));
p.Reverse();
p.AddEllipse(new Rectangle(x - inradius, y - inradius, inradius * 2, inradius * 2));
}
else
{
p.AddArc(new Rectangle(x - outradius, y - outradius, outradius * 2, outradius * 2), startangle, sweepangle);
if (inradius > 0)
{
p.AddLine(outend, inend);
p.AddArc(new Rectangle(x - inradius, y - inradius, inradius * 2, inradius * 2), endangle, -sweepangle);
p.AddLine(instart, outstart);
}
else
{
p.AddLine(outend, new Point(x, y));
p.AddLine(new Point(x, y), outstart);
}
}
Color c = Color.FromArgb(255 - hist[i, j], 255 - hist[i, j], 255 - hist[i, j]);
g.FillPath(new SolidBrush(c), p);
if(drawlines)
g.DrawPath(new Pen(i < (rlength * MeaningCircle) ? Color.Black : Color.DarkGray), p);
}
g.DrawEllipse(new Pen(Color.Black), x - r, y - r, r * 2, r * 2);
}
}
}