| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 | using PaintDotNet.Annotation.Enum;using PaintDotNet.Base.CommTool;using System;using System.Collections.Generic;using System.Diagnostics;using System.Drawing;using System.Drawing.Drawing2D;using System.Globalization;using System.Runtime.Serialization;using System.Windows.Forms;namespace PaintDotNet.Annotation.FieldView{    /// <summary>    /// 椭圆形视场绘制    /// </summary>    public class ViewOval : ViewBase    {        #region Calculate        List<Func<PointF>> m_ovalTemple;        float _a;        float _b;        float _centerx;        float _centery;        float _angle = 0;        readonly float _sqrt2 = (float)Math.Sqrt(2);        public override double Width        {            get => _a * 2;            set            {                _a = (float)value / 2;                _centerx = Center.X;                _centery = Center.Y;                Points = CalculateCirclePoints();            }        }        public override double Height        {            get => _b * 2;            set            {                _b = (float)value / 2;                _centerx = Center.X;                _centery = Center.Y;                Points = CalculateCirclePoints();            }        }        void InitOvalTemplate()        {            m_ovalTemple = new List<Func<PointF>>();            m_ovalTemple.Add(                new Func<PointF>(() =>                { return new PointF(-(_a / _sqrt2), -(_b / _sqrt2)); }));            m_ovalTemple.Add(                new Func<PointF>(() =>                { return new PointF(0, -_b); }));            m_ovalTemple.Add(                new Func<PointF>(() =>                { return new PointF((_a / _sqrt2), -(_b / _sqrt2)); }));            m_ovalTemple.Add(                new Func<PointF>(() =>                { return new PointF(_a, 0); }));            m_ovalTemple.Add(                new Func<PointF>(() =>                { return new PointF((_a / _sqrt2), (_b / _sqrt2)); }));            m_ovalTemple.Add(                new Func<PointF>(() =>                { return new PointF(0, _b); }));            m_ovalTemple.Add(                new Func<PointF>(() =>                { return new PointF(-(_a / _sqrt2), (_b / _sqrt2)); }));            m_ovalTemple.Add(                new Func<PointF>(() =>                { return new PointF(-_a, 0); }));        }        List<PointF> CalculateCirclePoints()        {            List<PointF> points = new List<PointF>();            foreach (var func in m_ovalTemple)            {                var p = func.Invoke();                p = BasicCalculationHelper.GetAnglePoint(p, _lastCenter, _angle);                points.Add(new PointF(p.X + _centerx, p.Y + _centery));            }            return points;        }        /// <summary>        /// 当PointList被修改时,更新参数        /// </summary>        /// <param name="points"></param>        void ReverseBuild(List<PointF> points)        {            _b = (float)(BasicCalculationHelper.GetDistance(points[1], points[5]) / 2);            _a = (float)(BasicCalculationHelper.GetDistance(points[3], points[7]) / 2);            _centerx = (points[1].X + points[5].X) / 2;            _centery = (points[1].Y + points[5].Y) / 2;            _angle = (float)BasicCalculationHelper.CalculateAngle(new PointF(_centerx, _centery), new PointF(_centerx + 100, _centery), points[3]);        }        public override double Getacreage()        {            var b = BasicCalculationHelper.GetDistance(Points[1], Points[5]) / 2;            var a = BasicCalculationHelper.GetDistance(Points[3], Points[7]) / 2;            return Math.PI * a * b;        }        #endregion        #region Constructor        public ViewOval()        {            this.objectType = DrawClass.View;            this.drawToolType = DrawToolType.ViewOval;            Rotatable = true;            Initialize();            InitOvalTemplate();        }        public ViewOval(int x, int y) : this()        {            for (int i = 0; i < 8; i++) AddPoint(x, y);        }        public ViewOval(List<PointF> points) : this()        {            ReverseBuild(points);            Points = points;        }        #endregion        public override PointF Center        {            get            {                var x = (Points[1].X + Points[5].X) / 2;                var y = (Points[1].Y + Points[5].Y) / 2;                return new PointF(x, y);            }            set { }        }        #region Handle        public override int HandleCount => 9;        public override PointF GetHandle(int handleNumber)        {            if (handleNumber > Points.Count)            {                var x = (Center.X + Points[3].X) / 2;                var y = (Center.Y + Points[3].Y) / 2;                return new PointF(x, y);            }            else                return Points[handleNumber - 1];        }        public override Cursor GetHandleCursor(int handleNumber)        {            switch (handleNumber)            {                case 9:                    return m_rotateCursor;                default:                    return m_resizeCursor;            }        }        public override void MoveHandleTo(Point point, int handleNumber)        {            if (handleNumber == 9) MoveRotate(point);            else if (handleNumber % 2 != 0)                MoveCorner(point);            else                MoveEdage(point, handleNumber);            OnPropertyChanged();        }        private void MoveCorner(Point point)        {            _centerx = Center.X;            _centery = Center.Y;            var p = BasicCalculationHelper.GetAnglePoint(point, new PointF(_centerx, _centery), -_angle);            _a = Math.Abs(p.X - Center.X) * _sqrt2;            _b = Math.Abs(p.Y - Center.Y) * _sqrt2;            Points = CalculateCirclePoints();        }        protected override void MoveRotate(PointF point)        {            _centerx = Center.X;            _centery = Center.Y;            _angle = (float)BasicCalculationHelper.CalculateAngle(new PointF(_centerx, _centery), new PointF(_centerx + 100, _centery), point);            Points = CalculateCirclePoints();        }        private void MoveEdage(Point point, int i)        {            var o = Points[(i + 3) % 8];            var p = BasicCalculationHelper.GetAnglePoint(point, o, -_angle);            var c = BasicCalculationHelper.GetAnglePoint(Center, o, -_angle);            if (i % 4 == 0)            {                c.X = (p.X + o.X) / 2;                _a = Math.Abs(p.X - o.X) / 2;            }            else            {                c.Y = (p.Y + o.Y) / 2;                _b = Math.Abs(p.Y - o.Y) / 2;            }            c = BasicCalculationHelper.GetAnglePoint(c, o, _angle);            _centerx = c.X;            _centery = c.Y;            Points = CalculateCirclePoints();        }        #endregion         #region Clone        public override DrawObject Clone()        {            return Clone(ISurfaceBox);        }        public override DrawObject Clone(ISurfaceBox surfaceBox)        {            ViewOval drawRectangle = new ViewOval(Points);            drawRectangle.ISurfaceBox = surfaceBox;            drawRectangle.combineMode = this.combineMode;            drawRectangle.Color = Color;            drawRectangle.ID = ID;            FillDrawObjectFields(drawRectangle);            return drawRectangle;        }        #endregion    }}
 |