| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416 | using System;using System.Collections.Generic;using System.Drawing;using System.Drawing.Drawing2D;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace OTSIncAReportGraph{    #region 基类,抽像类    /// <summary>    /// 绘制的基本类,下面的画布,多边形,线都要从这里派生    /// </summary>    public abstract class BaseObject : ICloneable    {        //自动生成的ID        public abstract string ID { get; set; }        //画布的坐标        public abstract RectangleF Rect { get; set; }                //OTS的坐标        public abstract PointF OTSPointF { get; set; }        //画布是否被选择        public abstract bool IsSelect { get; set; }        //画布是否被拖动        public abstract bool IsDragging { get; set; }        //画布被拖动到的位置        public abstract PointF DraggingPoint { get; set; }        //线的颜色        public abstract Color Color { get; set; }        //画布的背景色        public abstract Color BackColor { get; set; }        //绘制函数        public abstract void OnPaint(PaintEventArgs e);        //多边形路径        public abstract GraphicsPath GPath { get; set; }        //克隆        public virtual object Clone()        {            return null;        }    }    #endregion    #region 历史操作记录类    ///历史操作记录类,记录颗粒被操作的记录    public class HistoryApolygon    {        //自增长,操作id,增长在程序中自己写代码控制        private int m_id;        //所操作的颗粒的id        private string m_apolygonid;        //操作类型        private ParticleOperator m_operator;        //原先的操作状态类型        private ParticleOperator m_oldoperator;        /// <summary>        /// 操作类ID        /// </summary>        public int ID        {            get { return m_id; }            set { m_id = value; }        }        /// <summary>        /// 颗粒类ID        /// </summary>        public string APolygonID        {            get { return m_apolygonid; }            set { m_apolygonid = value; }        }        /// <summary>        /// 操作类型        /// </summary>        public ParticleOperator Operator        {            get { return m_operator; }            set { m_operator = value; }        }        /// <summary>        /// 原先的操作类型        /// </summary>        public ParticleOperator OldOperator        {            get { return m_oldoperator; }            set { m_oldoperator = value; }        }    }    #endregion    #region 颗粒分布图,排序图统一使用类    /// <summary>    /// 颗粒排序,能对颗粒进行分栏的类    /// </summary>    public class SortParticleDistribution : ICloneable    {        private List<DParticle> list_dparticle = new List<DParticle>();        private RectangleF m_rectf;        private string m_showstr = "";        private float m_size_min = 0;        private float m_size_max = 0;        public SortParticleDistribution()        { }        //构造函数        SortParticleDistribution(List<DParticle> inlist_dparticle, SortParticleDistribution in_spd)        {            m_rectf = in_spd.m_rectf;            m_showstr = in_spd.m_showstr;            m_size_min = in_spd.m_size_min;            m_size_max = in_spd.m_size_max;            foreach (DParticle e in inlist_dparticle)            {                list_dparticle.Add(e.Clone() as DParticle);            }        }        /// <summary>        /// 克隆方法        /// </summary>        /// <returns></returns>        public object Clone()        {            return new SortParticleDistribution(this.list_dparticle, this);        }        /// <summary>        /// 多边形图数组        /// </summary>        public List<DParticle> List_DParticle        {            get { return list_dparticle; }            set { list_dparticle = value; }        }        /// <summary>        /// 整个分类Grid的位置        /// </summary>        public RectangleF RectF        {            get { return m_rectf; }            set { m_rectf = value; }        }        /// <summary>        /// 该分类Grid显示的文字         /// </summary>        public string ShowStr        {            get { return m_showstr; }            set { m_showstr = value; }        }        /// <summary>        /// 该Grid保存多边形范围的最小值        /// </summary>        public float Size_Min        {            get { return m_size_min; }            set { m_size_min = value; }        }        /// <summary>        /// 该Grid保存多边形范围的最大值        /// </summary>        public float Size_Max        {            get { return m_size_max; }            set { m_size_max = value; }        }        /// <summary>        /// 获取多边形Grid内,所有多边形所占有的行数,用于其它计算使用        /// </summary>        /// <returns></returns>        public int GetDParticleRowNumber()        {            int RowsNumber = 0;            //首先获取所有多边形的宽度之和            float f_all_dparticle_widthsum = 0;            foreach (DParticle dp in this.list_dparticle)            {                f_all_dparticle_widthsum = f_all_dparticle_widthsum + dp.Rect.Width;            }            //然后除以自身的宽度+1,就是所有的行数了            float f_rowsnumber = f_all_dparticle_widthsum / this.RectF.Width + 1;            RowsNumber = Convert.ToInt32(f_rowsnumber);            return RowsNumber;        }        /// <summary>        /// 获取多边形分栏,分栏的高度        /// </summary>        /// <returns></returns>        public float GetSortGridHeight()        {            float i_SortGridHeight = 0;            int i_RowNumber = GetDParticleRowNumber();            //再获取所有的颗粒中,最长的            float i_heightmax = 0;            float i_ls_height = 0;            foreach (DParticle dp in this.list_dparticle)            {                float ls_y = 0;//用来判断y坐标是否有变化,好用来计算长度                foreach (DSegment ds in dp.DSegments)                {                    if (ds.Rect.Y != ls_y)                    {                        //i_ls_height++;                        ls_y = ds.Rect.Y;                        //如果需要考虑笔宽缩放的话,目前这样写,效果还没有出现问题                        i_ls_height = i_ls_height + ds.Rect.Height * ds.PenWidthAndHeight;                    }                    if (i_heightmax < i_ls_height)                    {                        i_heightmax = i_ls_height;                    }                }                i_ls_height = 0;            }            //用最高的颗粒*行数,来计算整个grid的高度            i_SortGridHeight = i_RowNumber * (i_heightmax + 10) + 20;//因为每行都额外增加了10点的高度            //应该当grid最小大于=50            if (i_SortGridHeight < 50)            {                i_SortGridHeight = 50;            }            return i_SortGridHeight;        }        /// <summary>        /// 根据传入的2个多边形list,从大到小进行排序,两个多边形list通过guid保持一致        /// 主要用于计算list与old_list能进行相同顺序的排序        /// </summary>        /// <param name="list_dparticle"></param>        /// <param name="old_list_dparticle"></param>        public void SortDParticleBySizeFromBigToSmall(List<DParticle> list_dparticle, List<DParticle> old_list_dparticle)        {            //首先分别将两个多边形list保存起来            List<DParticle> list_dp1 = new List<DParticle>();            List<DParticle> list_dp2 = new List<DParticle>();            foreach (DParticle ls_dp in list_dparticle)            {                DParticle dp1 = ls_dp.Clone() as DParticle;                list_dp1.Add(dp1);            }            foreach (DParticle ls_dp in old_list_dparticle)            {                DParticle dp2 = ls_dp.Clone() as DParticle;                list_dp2.Add(dp2);            }            //清除原先的两个多边形list            list_dparticle.Clear();            old_list_dparticle.Clear();            //嵌套2次循环            int icount = list_dp1.Count();            for (int i = 0; i < icount; i++)            {                //找出最大的                float f_max_size = 0;                string str_jlguid = "";                DParticle ls_dp = new DParticle();                foreach (DParticle ls_del_dp in list_dp1)                {                    //通过包含的线,获取多边形的尺寸大小                    ls_del_dp.FSize = ls_del_dp.GetSizeFormSegmentsAllWidth();                    if (f_max_size < ls_del_dp.FSize)                    {                        f_max_size = ls_del_dp.FSize;                        str_jlguid = ls_del_dp.ID;                        ls_dp = ls_del_dp;                    }                }                //然后分别将两个该guid的多边形从list1,2中删除                list_dp1.Remove(ls_dp);                //再分别插入到原先的list,和old_list中                ls_dp.Rect = ls_dp.GetRectFromDSegment();                list_dparticle.Add(ls_dp);            }            //换种方法,按Guid将list2中对应的再添加到old_list中            foreach (DParticle ls_dp in list_dparticle)            {                foreach (DParticle ls_dp2 in list_dp2)                {                    if (ls_dp2.ID == ls_dp.ID)                    {                        ls_dp2.Rect = ls_dp2.GetRectFromDSegment();                        old_list_dparticle.Add(ls_dp2);                    }                }            }        }        /// <summary>        /// 根据传入的2个多边形list,从小到大进行排序,两个多边形list通过guid保持一致        /// 主要用于计算list与old_list能进行相同顺序的排序        /// </summary>        /// <param name="list_dparticle"></param>        /// <param name="old_list_dparticle"></param>        public void SortDParticlesBySizeFromSmallToBig(List<DParticle> list_dparticle, List<DParticle> old_list_dparticles)        {            //首先分别将两个多边形list保存起来            List<DParticle> list_dp1 = new List<DParticle>();            List<DParticle> list_dp2 = new List<DParticle>();            foreach (DParticle ls_dp in list_dparticle)            {                DParticle dp1 = ls_dp.Clone() as DParticle;                list_dp1.Add(dp1);            }            foreach (DParticle ls_dp in old_list_dparticles)            {                DParticle dp2 = ls_dp.Clone() as DParticle;                list_dp2.Add(dp2);            }            //清除原先的两个多边形list            list_dparticle.Clear();            old_list_dparticles.Clear();            //嵌套2次循环            int icount = list_dparticle.Count();            for (int i = 0; i < icount; i++)            {                //找出最小的                float f_min_size = 10000000;                string str_jlguid = "";                DParticle ls_dp = new DParticle();                foreach (DParticle ls_del_dp in list_dp1)                {                    //通过包含的线,获取多边形的尺寸大小                    ls_del_dp.FSize = ls_del_dp.GetSizeFormSegmentsAllWidth();                    if (f_min_size > ls_del_dp.FSize)                    {                        f_min_size = ls_del_dp.FSize;                        str_jlguid = ls_del_dp.ID;                        ls_dp = ls_del_dp;                    }                }                //然后分别将两个该guid的多边形从list1,2中删除                list_dp1.Remove(ls_dp);                //再分别插入到原先的list,和old_list中                list_dparticle.Add(ls_dp);            }            //换种方法,按Guid将list2中对应的再添加到old_list中            foreach (DParticle ls_dp in list_dparticle)            {                foreach (DParticle ls_dp2 in list_dp2)                {                    if (ls_dp2.ID == ls_dp.ID)                    {                        old_list_dparticles.Add(ls_dp2);                    }                }            }        }                /// <summary>        /// 颗粒排序方法2        /// </summary>        /// <param name="in_f_zoom_record"></param>        public void SortParticle222(float in_f_zoom_record)        {            float f_ls_x = this.m_rectf.X + 3 * in_f_zoom_record;            float f_ls_y = this.m_rectf.Y + 3 * in_f_zoom_record;            foreach (DParticle dp in this.list_dparticle)            {                dp.Rect = dp.GetRectFromDSegment();                if ((f_ls_x + dp.Rect.Width + 6) > this.m_rectf.Width + this.m_rectf.X)                {                    f_ls_x = this.m_rectf.X + 3 * in_f_zoom_record;                    f_ls_y = f_ls_y + this.GetSortGridHeight() / this.GetDParticleRowNumber() - 5;                }                float f_cz_x = f_ls_x - dp.Rect.X;                float f_cz_y = f_ls_y - dp.Rect.Y;                foreach (DSegment ds in dp.DSegments)                {                    ds.Rect = new RectangleF(ds.Rect.X + f_cz_x, ds.Rect.Y + f_cz_y, ds.Rect.Width, ds.Rect.Height);                }                f_ls_x = f_ls_x + dp.Rect.Width + 3 * in_f_zoom_record;                dp.Rect = dp.GetRectFromDSegment();                dp.GPath = dp.GetRegionFromDSegments();                dp.SmallRect = dp.GetSmallRectangleFromRect();            }        }        /// <summary>        /// 对已经存入的颗粒信息,按定位好的rect位置,重新给line和各参数,重新进行计算        /// 就是在分栏的Grid中对多边形进行摆放        /// </summary>        public void SortDParticle(float in_f_zoom_record)        {            //设置增长的x,y轴值,+3是跳过边框的位置, 可能有个别情况,会在右侧突出占到边框的位置上            float f_ls_x = this.m_rectf.X + 3 * in_f_zoom_record;            float f_ls_y = this.m_rectf.Y + 3 * in_f_zoom_record;            foreach (DParticle dp in this.list_dparticle)            {                //这里要对不显示的颗粒进行屏蔽,也就是进行不计算位置,不知道会不会有其它的影响                if (dp.Operator !=ParticleOperator.NODISPLAY)                {                    //首先确定各多边形的矩形位置                    dp.Rect = dp.GetRectFromDSegment();                    //判断是否已经达到了x的边缘,是的话,那么y轴进行增长,判断x轴+颗粒的宽度+6的相当于边框宽度的差值补值,大于grid宽度时                    //在增长前就判断宽度,防止部份多边形突出到分栏外                    if ((f_ls_x + dp.Rect.Width + 6) > this.m_rectf.Width + this.m_rectf.X)                    {                        //还原x到该分栏Grid的左边框+3的位置,并且将y轴定位到下一高度的y轴位置                        f_ls_x = this.m_rectf.X + 3 * in_f_zoom_record;                        f_ls_y = f_ls_y + this.GetSortGridHeight() / this.GetDParticleRowNumber() - 5;//在获取高度时,已经+10,所以这里再-5,颗粒近一些                    }                    //计算出与定位的Grid的差值,然后重新排序线,用分栏Grid-颗粒的外Rect,取到x,y的差值                    float f_cz_x = f_ls_x - dp.Rect.X;                    float f_cz_y = f_ls_y - dp.Rect.Y;                    //获取到差值后,再对该多边形下面的所有线进行调整                    foreach (DSegment ds in dp.DSegments)                    {                        ds.Rect = new RectangleF(ds.Rect.X + f_cz_x, ds.Rect.Y + f_cz_y, ds.Rect.Width, ds.Rect.Height);                    }                    //定位好该多边形后,对x轴进行增长,为下一个多边形定位好位置                    f_ls_x = f_ls_x + dp.Rect.Width + 3 * in_f_zoom_record;                    //重新计算sort_ap的                    dp.Rect = dp.GetRectFromDSegment();                    //通过line获取路径边缘                    dp.GPath = dp.GetRegionFromDSegments();                    //重新计算小矩形边框                    dp.SmallRect = dp.GetSmallRectangleFromRect();                }            }        }    }    /// <summary>    /// 包含DParticle类的field类,目前只用于绘制背景色,按理说应该有更多的作用,比如做多线程分式运算    /// </summary>    public class DField:BaseObject    {        string m_id;        string m_tagid;        string m_fieldid;        bool m_IsDragging;        Color m_backcolor;        List<DParticle> m_list_dparticle;        RectangleF m_ots_rect;  //按底层设计结构,底层返回的物理坐标位置及大小,OTS坐标大小        RectangleF m_pix_rect; //与底层返回物理坐标及位置大小对应转换成,pixel像素分率下的坐标位置大小        RectangleF m_show_rect;//最后换算到在显示器上显示的坐标位置大小        RectangleF m_current_rect;//当前field在显示器上显示的坐标位置大小        PointF m_dragingpoint;//鼠标拖动的位置        private string m_GBContent;        private PointF m_OTSPointF;        private bool m_IsSelect;        private Color m_color;        private GraphicsPath m_GPath;        /// <summary>        /// 构造函数        /// </summary>        public DField()        {            m_id = System.Guid.NewGuid().ToString();        }                public DField(List<DParticle> in_list_dparticle)        {            m_list_dparticle = in_list_dparticle;        }        /// <summary>        /// ID        /// </summary>        //public string ID        //{        //    get { return m_id; }        //    set { m_id = value; }        //}        public override string ID { get =>  m_id; set => m_id=value; }        /// <summary>        /// 记录与底层对应的TagID        /// </summary>        public string TagID        {            get { return m_tagid; }            set { m_tagid = value; }        }        /// <summary>        /// 是否被拖动标识        /// </summary>        //public  bool IsDragging        //{        //    get { return m_IsDragging; }        //    set { m_IsDragging = value; }        //}        public override bool IsDragging { get => m_IsDragging; set => m_IsDragging=value; }        /// <summary>        /// 被拖动到的位置坐标        /// </summary>        //public PointF DraggingPoint        //{        //    get { return m_dragingpoint; }        //    set { m_dragingpoint = value; }        //}        public override PointF DraggingPoint { get => m_dragingpoint; set => m_dragingpoint=value; }        /// <summary>        /// 与底层对应的ID,这里叫成FieldID        /// </summary>        public string FieldID        {            get { return m_fieldid; }            set { m_fieldid = value; }        }        public override Color BackColor { get => m_backcolor; set => m_backcolor=value; }        /// <summary>        /// 包含的Particle列表        /// </summary>        public List<DParticle> List_DParticle        {            get { return m_list_dparticle; }            set { m_list_dparticle = value; }        }        /// <summary>        /// 该Field的OTS坐标及大小        /// </summary>        public RectangleF OTS_RECT        {            get { return m_ots_rect; }            set { m_ots_rect = value; }        }        /// <summary>        /// 该Field物理坐标大小转换出,对应的像素坐标及大小        /// </summary>        public RectangleF Pix_Rect        {            get { return m_pix_rect; }            set { m_pix_rect = value; }        }        /// <summary>        /// 该Field最后在屏幕上显示的坐标及大小        /// </summary>        public RectangleF Show_Rect        {            get { return m_show_rect; }            set { m_show_rect = value; }        }        /// <summary>        /// Field当前在屏幕上显示的坐标及大小        /// </summary>        public RectangleF Current_Rect        {            get { return m_current_rect; }            set { m_current_rect = value; }        }        public override RectangleF Rect { get => m_ots_rect; set => m_ots_rect=value; }        public override PointF OTSPointF { get => m_OTSPointF; set => m_OTSPointF=value; }        public override bool IsSelect { get => m_IsSelect; set => m_IsSelect=value; }        public override Color Color { get => m_color; set => m_color=value; }        public override GraphicsPath GPath { get => m_GPath; set =>m_GPath=value; }        public override void OnPaint(PaintEventArgs e)        {            throw new NotImplementedException();        }    }    /// <summary>    /// Particle对象上操作状态的枚举,显示,不显示,已删除,已选择    /// </summary>    public enum ParticleOperator    {        DISPLAY = 0,        NODISPLAY = 1,        DELETED = 2,        SELECTED =3,    }    /// <summary>    /// Particle对象上操作xray的枚举状态,显示xray数据,不显示    /// </summary>    public enum ParticleOperatorShowXray    {        SELECTANDDISPLAYXRAY = 0,        NODISPLAY = 1,    }    /// <summary>    /// Segment对象绘制的枚举,以点绘制,还是以线绘制    /// </summary>    public enum SegmentShowMode    {        DRAWPOINT = 0,        DRAWLINE = 1,    }    /// <summary>    /// 颗粒类    /// </summary>    public class DParticle : BaseObject, ICloneable, IComparable<DParticle>    {        private string m_id;        private RectangleF m_rect;        private PointF m_OTSPointF;        private RectangleF m_small_rect;        private bool m_isselected_smallrect;        private bool m_showsmallx;        private bool m_isselect;        private ParticleOperator m_operator = ParticleOperator.DISPLAY;//显示,不显示,删除,选择,默认应为(不显示)        private ParticleOperatorShowXray m_operator_showxray = ParticleOperatorShowXray.NODISPLAY;//选定显示XRAY,不显示XRAY,默认应为(不显示XRAY)        private bool m_isdragging;        private PointF m_dragingpoint;        private Color m_color;        private Color m_backcolor;        private GraphicsPath m_gpath;        private List<DSegment> m_listdsegment = new List<DSegment>();        private bool m_IsMouseMove;        private float m_zoom_displaymultiplier = 1;        private bool m_zoom_display;        private string m_sort_type = "从大到小";        private float m_f_size = 0;        private string m_str_lj = "颗粒粒级";        private string m_str_klzl = "颗粒种类";        private string m_str_klfl = "颗粒分类";        private int m_clrfieldid = 0;        private int m_clrtagid = 0;        private int m_stdtypeid = 0;//表示这个颗粒分析出来后的类型        //TypeId        public int TypeId { set; get; }        //TypeName        public string TypeName { set; get; }        //XRayId        public int XRayId { set; get; }        public int SEMPosX { set; get; }        public int SEMPosY { set; get; }        //国标内容        private string m_GBContent = "";        public DParticle()        {            m_id = System.Guid.NewGuid().ToString();        }        public DParticle(List<DSegment> in_list_segment, DParticle in_particle)        {            // m_id = System.Guid.NewGuid().ToString();            m_id = in_particle.m_id;            m_zoom_display = in_particle.m_zoom_display;            m_zoom_displaymultiplier = in_particle.m_zoom_displaymultiplier;            m_clrfieldid = in_particle.m_clrfieldid;            m_clrtagid = in_particle.m_clrtagid;            m_operator = in_particle.m_operator;            m_operator_showxray = in_particle.m_operator_showxray;            m_stdtypeid = in_particle.m_stdtypeid;            SEMPosX = in_particle.SEMPosX;            SEMPosY = in_particle.SEMPosY;            foreach (DSegment e in in_list_segment)            {                m_listdsegment.Add(e.Clone() as DSegment);            }        }        /// <summary>        /// [目前也不使用该方法了,因为该方法每次排序都有不同的结果]多边形排序,按传入的sort_type的排序类型行排序,但需要两个list做一致性排序        /// </summary>        /// <param name="in_ap"></param>        /// <returns></returns>        public int CompareTo(DParticle in_particle)        {            int r_b = 0;//排序返回值            switch (m_sort_type)            {                case "从大到小":                    r_b = in_particle.m_f_size.CompareTo(this.m_f_size);                    break;                case "从小到大":                    //与上面的从大到小正好相反即可                    r_b = in_particle.m_f_size.CompareTo(this.m_f_size);                    if (r_b == 1)                        r_b = -1;                    else                        r_b = 1;                    break;                default:                    break;            }            return r_b;        }        /// <summary>        /// 克隆方法        /// </summary>        /// <returns></returns>        public override object Clone()        {            return new DParticle(this.m_listdsegment, this);        }        /// <summary>        /// ID        /// </summary>        public override string ID        {            get { return m_id; }            set { m_id = value; }        }        /// <summary>        /// 颗粒的外边框大小        /// </summary>        public override RectangleF Rect        {            get { return m_rect; }            set { m_rect = value; }        }        /// <summary>        /// OTSPointF        /// </summary>        public override PointF OTSPointF        {            get { return m_OTSPointF; }            set { m_OTSPointF = value; }        }        /// <summary>        /// 颗粒里+号位置的外边框大小        /// </summary>        public RectangleF SmallRect        {            get { return m_small_rect; }            set { m_small_rect = value; }        }        /// <summary>        /// 颗粒是否被选择        /// </summary>        public override bool IsSelect        {            get { return m_isselect; }            set { m_isselect = value; }        }        /// <summary>        /// 该颗粒是否被设置成,选中状态        /// </summary>        public ParticleOperator Operator        {            get { return m_operator; }            set { m_operator = value; }        }        /// <summary>        /// 是否对该颗粒选定显示X-Ray能谱图        /// </summary>        public ParticleOperatorShowXray Operator_ShowXRay        {            get { return m_operator_showxray; }            set { m_operator_showxray = value; }        }        /// <summary>        /// 鼠标是否在该矩形上        /// </summary>        public bool IsMouseMove        {            get { return m_IsMouseMove; }            set { m_IsMouseMove = value; }        }        /// <summary>        /// 是否显示x号        /// </summary>        public bool IsShowSmallX        {            get { return m_showsmallx; }            set { m_showsmallx = value; }        }        /// <summary>        /// 颗粒的x-ray的点,是否被选择上了        /// </summary>        public bool IsSelectedSmallRect        {            get { return m_isselected_smallrect; }            set { m_isselected_smallrect = value; }        }        /// <summary>        /// 是否在被拖动        /// </summary>        public override bool IsDragging        {            get { return m_isdragging; }            set { m_isdragging = value; }        }        /// <summary>        /// 被拖动到的位置坐标        /// </summary>        public override PointF DraggingPoint        {            get { return m_dragingpoint; }            set { m_dragingpoint = value; }        }        /// <summary>        /// 线的颜色        /// </summary>        public override Color Color        {            get { return m_color; }            set { m_color = value; }        }        /// <summary>        /// 背景色        /// </summary>        public override Color BackColor        {            get { return m_backcolor; }            set { m_backcolor = value; }        }        /// <summary>        /// 多边形的图形路径边缘        /// </summary>        public override GraphicsPath GPath        {            get { return m_gpath; }            set { m_gpath = value; }        }        /// <summary>        /// 里面包含的多个线的集合        /// </summary>        public List<DSegment> DSegments        {            get { return m_listdsegment; }            set { m_listdsegment = value; }        }        /// <summary>        /// 控制多边形在进行缩放到多少倍时进行显示        /// </summary>        public float Zoom_DisPlayMultiplier        {            get { return m_zoom_displaymultiplier; }            set { m_zoom_displaymultiplier = value; }        }        /// <summary>        /// 临时的变量,控制进行缩放时,是显示+号,还是显示多边形        /// </summary>        public bool Zoom_DisPlay        {            get { return m_zoom_display; }            set { m_zoom_display = value; }        }        /// <summary>        /// 设置排序的类型        /// </summary>        public string SortType        {            get { return m_sort_type; }            set { m_sort_type = value; }        }        /// <summary>        /// 设置该多边形的尺寸大小        /// </summary>        public float FSize        {            get { return m_f_size; }            set { m_f_size = value; }        }        /// <summary>        /// 设置粒级        /// </summary>        public string ParticleLJ        {            get { return m_str_lj; }            set { m_str_lj = value; }        }        /// <summary>        /// 设置种类        /// </summary>        public string ParticleZL        {            get { return m_str_klzl; }            set { m_str_klzl = value; }        }        /// <summary>        /// 设置分类        /// </summary>        public string ParticleFL        {            get { return m_str_klfl; }            set { m_str_klfl = value; }        }        /// <summary>        /// 获取或设置该Particle对应底层的FieldID值        /// </summary>        public int CLRFieldID        {            get { return m_clrfieldid; }            set { m_clrfieldid = value; }        }        /// <summary>        /// 获取或设置该Particle对应底层的ParticleID值        /// </summary>        public int CLRTagID        {            get { return m_clrtagid; }            set { m_clrtagid = value; }        }        /// <summary>        /// 获取或设置STD分析物的ID        /// </summary>        public int STDTypeID        {            get { return m_stdtypeid; }            set { m_stdtypeid = value; }        }                /// <summary>        /// 绘制函数        /// </summary>        /// <param name="e"></param>        public override void OnPaint(PaintEventArgs e)        {            Graphics g = e.Graphics;            //绘制鼠标移动到颗粒上时的边框,需要判断当前鼠标在颗粒上,及颗粒的操作为正常显示            if (true == m_IsMouseMove && m_operator == ParticleOperator.DISPLAY)            {                //如果有鼠标在该矩形上,那么进行描边                ControlPaint.DrawBorder(g,                                    Rectangle.Round(this.Rect),                                    Color.Lime,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.Lime,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.Lime,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.Lime,                                    1,                                    ButtonBorderStyle.Solid);            }            else            {                //应该是什么都不做就可以了,就刷新掉了            }            if (ParticleOperator.SELECTED == m_operator)            {                //如果説该矩形被选择上了的话,那么也显示边框                ControlPaint.DrawBorder(g,                                    Rectangle.Round(this.Rect),                                    Color.Blue,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.Blue,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.Blue,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.Blue,                                    1,                                    ButtonBorderStyle.Solid);            }                        if (ParticleOperatorShowXray.SELECTANDDISPLAYXRAY == m_operator_showxray && ParticleOperator.NODISPLAY != m_operator)            {                //当鼠标在该颗粒上进行点击,则对颗粒状态更改为选定状态,用来显示X-ray能谱表                ControlPaint.DrawBorder(g,                                    Rectangle.Round(this.Rect),                                    Color.DeepSkyBlue,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.DeepSkyBlue,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.DeepSkyBlue,                                    1,                                    ButtonBorderStyle.Solid,                                    Color.DeepSkyBlue,                                    1,                                    ButtonBorderStyle.Solid);            }            //只有正常和选择中的颗粒才进行绘制显示            if (m_operator == ParticleOperator.DISPLAY || m_operator == ParticleOperator.SELECTED)            {                if (m_zoom_display == true)                {                    //调用绘制基本线                    foreach (DSegment item in m_listdsegment)                    {                        item.OnPaint(e);                    }                }                else                {                    g.DrawString("+", new Font("黑体", 6), new SolidBrush(Color.DarkSlateBlue), new PointF(m_small_rect.X, m_small_rect.Y));                }            }        }        /// <summary>        /// 从Line中获取矩形的边缘闭合路径        /// </summary>        /// <returns></returns>        public GraphicsPath GetRegionFromDSegments()        {            GraphicsPath gpath = new GraphicsPath();            List<PointF> list_leftpointf = new List<PointF>();            List<PointF> list_rightpointf = new List<PointF>();            //从y循环,这里假设y轴会按lines集合来计算,然后将所有的左x,和右x取出排成两个队列            foreach (DSegment ds in this.m_listdsegment)            {                list_leftpointf.Add(new PointF(ds.Rect.X, ds.Rect.Y));                list_rightpointf.Add(new PointF(ds.Rect.X + ds.Rect.Width, ds.Rect.Y));            }            PointF[] lsp = new PointF[list_leftpointf.Count + list_rightpointf.Count];            //再将两个x,y点依次添加到闭合路径中            for (int i = 0; i < list_leftpointf.Count(); i++)            {                lsp[i] = list_leftpointf[i];            }            //右节点            for (int i = 0; i < list_rightpointf.Count(); i++)            {                //这边倒着存入                lsp[list_rightpointf.Count() + i] = list_rightpointf[list_rightpointf.Count() - i - 1];            }            //防止从低层拿到无数据的外边路径,在我的程序里却需要计算,而防止程序报死,这里做一下特殊处理。            if (lsp.Count() >= 3)            {                gpath.AddPolygon(lsp);            }            else            {                //有时居然有颗粒,有没有segment的时候,防止报错                if (this.DSegments.Count == 0)                {                    lsp = new PointF[3] { new PointF(0, 0), new PointF(0, 0), new PointF(0, 0) };                    gpath.AddPolygon(lsp);                    return gpath;                }                //有2条数据                if (lsp[1].X != 0 && lsp[1].Y != 0)                {                    lsp = new PointF[3] { new PointF(lsp[0].X, lsp[0].Y), new PointF(lsp[1].X, lsp[1].Y), new PointF(lsp[1].X, lsp[1].Y) };                }                //有1条数据                else if (lsp[0].X != 0 && lsp[0].Y != 0)                {                    lsp = new PointF[3] { new PointF(lsp[0].X, lsp[0].Y), new PointF(lsp[0].X, lsp[0].Y), new PointF(lsp[0].X, lsp[0].Y) };                }                //剩下的情况                 else                {                    lsp = new PointF[3] { new PointF(0, 0), new PointF(0, 0), new PointF(0,0) };                }                gpath.AddPolygon(lsp);            }            return gpath;        }        /// <summary>        /// 从已经确定的外边框来计算出里面的+号小框位置        /// </summary>        /// <returns></returns>        public RectangleF GetSmallRectangleFromRect()        {            RectangleF rect = new RectangleF();            //用外边框的坐标,除2获得中心点,然后再分别+,- 4            float x = 0, y = 0;            x = m_rect.X + (m_rect.Width / 2);            y = m_rect.Y + (m_rect.Height / 2);            rect.X = x - 4;            rect.Y = y - 4;            rect.Width = 8;            rect.Height = 4;            return rect;        }        /// <summary>        /// 根据该多边形所有包含的线长度,计算出,该多边形的面积大小        /// </summary>        /// <returns></returns>        public float GetSizeFormSegmentsAllWidth()        {            float f_size_sum = 0;            foreach (DSegment ls_ds in this.m_listdsegment)            {                f_size_sum = f_size_sum + ls_ds.Rect.Width;            }            return f_size_sum;        }        /// <summary>        /// 从基本线中获取整个矩形的Rectangle        /// </summary>        /// <returns></returns>        public RectangleF GetRectFromDSegment()        {            RectangleF rect = new RectangleF();            float x1 = 0, y1 = 0;            float i_width = 0, i_height = 0;            //先从自身中初始化x,y,和宽,高            if (this.m_listdsegment.Count > 0)            {                x1 = this.m_listdsegment[0].Rect.X;                y1 = this.m_listdsegment[0].Rect.Y;                i_width = x1 + this.m_listdsegment[0].Rect.Width;                i_height = this.m_listdsegment[0].Rect.Y;            }            foreach (DSegment ds in this.m_listdsegment)            {                //分别取出,最小的x,y,                if (ds.Rect.X < x1)                {                    x1 = ds.Rect.X;                }                if (ds.Rect.Y < y1)                {                    y1 = ds.Rect.Y;                }                //最大的x,y                if (ds.Rect.X + ds.Rect.Width > i_width)                {                    i_width = ds.Rect.X + ds.Rect.Width;                }                if (ds.Rect.Y > i_height)                {                    i_height = ds.Rect.Y;                }            }            //对矩形Rect大小位置进行修补,因为画线是内边框,并且计算出来的位置也是向内占用一像素的,            //正常应该是 +2,但实际效果,+3也才勉强够用,因为放大缩小画笔宽度影响的            rect.X = x1 - 2;            rect.Y = y1 - 3;            rect.Width = i_width - rect.X + 2;            rect.Height = i_height - rect.Y + 3;            //判断如果太小,就给个最小值吧            if (rect.Width < 8)                rect.Width = 8;            if (rect.Height < 8)                rect.Height = 8;            return rect;        }    }    /// <summary>    /// 基本线类    /// </summary>    public class DSegment : BaseObject, ICloneable    {        private string m_id;        private RectangleF m_region;        private PointF m_OTSPointF;        private bool m_isselect;        private bool m_isdragging;        private PointF m_dragingpoint;        private Color m_color;        private Color m_backcolor;        private GraphicsPath m_gpath;        private float m_PenWidthAndHeight = 1;        private SegmentShowMode show_mode = SegmentShowMode.DRAWPOINT;//绘线,绘点,默认绘点,意思为默认显示BSE原图像        private List<Color> m_list_colors;        /// <summary>        /// 克隆基本线        /// </summary>        /// <returns></returns>        public override object Clone()        {            return MemberwiseClone();        }        public DSegment()        {            m_id = System.Guid.NewGuid().ToString();        }        /// <summary>        /// ID        /// </summary>        public override string ID        {            get { return m_id; }            set { m_id = value; }        }        /// <summary>        /// 画面的大小        /// </summary>        public override RectangleF Rect        {            get { return m_region; }            set { m_region = value; }        }        /// <summary>        /// OTSField        /// </summary>        public override PointF OTSPointF        {            get { return m_OTSPointF; }            set { m_OTSPointF = value; }        }        /// <summary>        /// 画布是否被选择        /// </summary>        public override bool IsSelect        {            get { return m_isselect; }            set { m_isselect = value; }        }        /// <summary>        /// 是否在被拖动        /// </summary>        public override bool IsDragging        {            get { return m_isdragging; }            set { m_isdragging = value; }        }        /// <summary>        /// 被拖动到的位置坐标        /// </summary>        public override PointF DraggingPoint        {            get { return m_dragingpoint; }            set { m_dragingpoint = value; }        }        /// <summary>        /// 线的颜色        /// </summary>        public override Color Color        {            get { return m_color; }            set { m_color = value; }        }        /// <summary>        /// 背景色        /// </summary>        public override Color BackColor        {            get { return m_backcolor; }            set { m_backcolor = value; }        }        /// <summary>        /// 多边形的图形路径边缘        /// </summary>        public override GraphicsPath GPath        {            get { return m_gpath; }            set { m_gpath = value; }        }        /// <summary>        /// 设置画笔的笔宽度        /// </summary>        public float PenWidthAndHeight        {            get { return m_PenWidthAndHeight; }            set { m_PenWidthAndHeight = value; }        }        /// <summary>        /// 设置显示的方式,可以用,绘线显示查看标准库颜色的,也可以用绘点,查看BSE原图颗粒图色的        /// </summary>        public SegmentShowMode ShowMode        {            get { return show_mode; }            set { show_mode = value; }        }        /// <summary>        /// 保存BSE标准库文件的颗粒点的颜色信息        /// </summary>        public List<Color> List_Colors        {            get { return m_list_colors; }            set { m_list_colors = value; }        }        /// <summary>        /// 绘制函数        /// </summary>        /// <param name="e"></param>        public override void OnPaint(PaintEventArgs e)        {            //两种绘制模式的选择,绘线还是缓点            if (show_mode == SegmentShowMode.DRAWLINE)            {                //表示显示的是带有标准库的图像                Pen p = new Pen(m_color, m_PenWidthAndHeight + 1f);//这里加1f的宽度后,用线组成多边形不会分散,效果正常,原因不知,但目前没有遇到问题                e.Graphics.DrawLine(p, Rect.X, Rect.Y, Rect.X + Rect.Width, Rect.Y);            }            else if (show_mode == SegmentShowMode.DRAWPOINT)            {                //根据color的序列,显示绘制的原像素的图像。                for (int i = 0; i < m_list_colors.Count(); i++)                {                    e.Graphics.FillRectangle(new SolidBrush(m_list_colors[i]),                                            this.Rect.X + (i * m_PenWidthAndHeight) + 1f,                            this.Rect.Y,                            m_PenWidthAndHeight,                            m_PenWidthAndHeight);                }            }        }    }    #endregion}
 |