All pastes #814185 Raw Edit

Someone

public text v1 · immutable
·published 2007-12-13 01:40 UTC
rendered paste body
using 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);
		}
	}
}