Контур рисования контура графического контура - PullRequest
0 голосов
/ 06 ноября 2019

Я хочу создать Области ограничивающего круга для моих двух фигур, Камня и Треугольника. Когда они близки, я хочу выполнить тест пересечения и удалить оба из формы.

Я создал связанный список областей, но когда я рендерил их, он оставляет путь моей фигуры, проходя черезформа. Я хочу, чтобы вокруг точек фигур был кружок, который будет отображаться, если пересечение вот-вот произойдет.

abstract class ShapeBase
    {
        double min = -3.00;
        double max = 3.00;
        double minX = -2.5;
        double maxX = 2.5;

        public double m_fRot;
        public double m_fRotInc;

        //x velocity
        public double m_fXSpeed;

        //y velocity
        public double m_fYSpeed;
        public static Random s_rnd;

        //size
        public const int TILESIZE = 100;

        bool IsMarkedForDeath
        {
            get { return IsMarkedForDeath; }
            set {IsMarkedForDeath = value; }
        }

        public PointF Pos
        {
            get;
            private set;
        }

        //contructor should accept a PointF for position
        public ShapeBase(PointF p)
        {
            s_rnd = new Random();
            Pos = p; //position as the  provided position
            m_fRot = 0; //current rotation as 0
            m_fRotInc = s_rnd.NextDouble() * (max - min) + min; //rotation increment from -3.00 to 3.00
            m_fXSpeed = s_rnd.NextDouble() * (maxX - minX) + minX;//x/y speed values fro -2.5 to 2.5
            m_fYSpeed = s_rnd.NextDouble() * (maxX - minX) + minX;

        }

        //makes original graphicspath
        static public GraphicsPath GenModel(int vertices, float variance)
        {
            double dAngle = 0;

            PointF[] triPoints = new PointF[vertices];
            Random rnd = new Random();

            //rock
            if (variance > 1)
            {
                for (int i = 0; i < vertices; ++i, dAngle += (2 * Math.PI) / vertices)
                {
                    triPoints[i] = new PointF((float)Math.Cos(dAngle) * TILESIZE * (float)(rnd.NextDouble() * 0.5 + 0.1), (float)Math.Sin(dAngle) * TILESIZE * (float)(rnd.NextDouble() * 0.5 + 0.1));
                }
            }

            //triangle
            else
            {
                for (int i = 0; i < vertices; ++i, dAngle += (2 * Math.PI) / vertices)
                {
                    triPoints[i] = new PointF((float)Math.Cos(dAngle) * TILESIZE, (float)Math.Sin(dAngle) * TILESIZE);
                }
            }


            GraphicsPath ModelPath = new GraphicsPath();

            ModelPath.AddPolygon(triPoints);

            ModelPath.CloseFigure();



            return ModelPath;


        }

        //produce graphics path for rendering
        //clone genmodel path
        virtual public GraphicsPath GetPath()
        {
            ////srt in here

            GraphicsPath _Path = new GraphicsPath();

            //matrix is used to apply a transformation
            //SRT - scale rotate transform

            //Matrix m = new Matrix();
            //m.Rotate(m_fRot);
            //_Path.Transform(new Matrix());


            return _Path;
        }


        //render method will fill getpath return value with a provided colour
        public void Render(Graphics g, Color colour)
        {
            g.FillPath(new SolidBrush(colour), GetPath());

        }


        //accept a size and move the shape according to current speed values
        //for any violation of bounds, speed value will flip
        public void Tick(Size _size)
        {
            m_fRot += m_fRotInc;

            Pos = new PointF((float)(Pos.X + m_fXSpeed), (float)(Pos.Y + m_fYSpeed));

            if (Pos.X + TILESIZE > _size.Width || Pos.X + TILESIZE < 0)
            {
                m_fXSpeed *= -1;
                m_fYSpeed *= -1;

            }

            if (Pos.Y + TILESIZE > _size.Height || Pos.Y + TILESIZE < 0)
            {
                m_fXSpeed *= -1;
                m_fYSpeed *= -1;
            }

        }


        public static double Distance(ShapeBase shape1, ShapeBase shape2)
        {
            double a = (shape2.Pos.X - shape1.Pos.X);
            double b = (shape2.Pos.Y - shape1.Pos.Y);
            double c = Math.Pow(a, 2) + Math.Pow(b, 2);

            return Math.Sqrt(c); //c= √a^2+b^2


        }



    }

    class Triangle : ShapeBase
    {

        static readonly GraphicsPath s_model; //hold model for triangle shape

        static Triangle()
        {
            //generate model
            s_model = GenModel(3, 0);

        }

        //set the position to the provided pointf
        public Triangle(PointF position) : base(position)
        {


        }

        public override GraphicsPath GetPath()
        {

            GraphicsPath workingCopy = (GraphicsPath)s_model.Clone();
            Matrix mat = new Matrix();
            mat.Reset();
            mat.Translate(Pos.X, Pos.Y);
            mat.Rotate((float)m_fRot);
            workingCopy.Transform(mat);


            return workingCopy;

        }
    }

    class Rock : ShapeBase
    {
        public GraphicsPath _model;

        //send in location to base class (ShapeBase)
        public Rock(PointF location): base(location)
        {
            _model = GenModel(s_rnd.Next(4,13),2);
        }

        public override GraphicsPath GetPath()
        {
            GraphicsPath wCopy = (GraphicsPath)_model.Clone();
            Matrix mat = new Matrix();
            mat.Reset();
            mat.Translate(Pos.X, Pos.Y);
            mat.Rotate((float)m_fRot);
            wCopy.Transform(mat); 

            return wCopy;

        }

    }

}```

```    public partial class Form1 : Form
    {
        int count = 1000;
        LinkedList<Region> Regions = new LinkedList<Region>();
        List<ShapeBase> ShapeList = new List<ShapeBase>();//collection of your choosing 
        LinkedList<Region> Intersections = new LinkedList<Region>(); //hold all intersections 
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            Random random = new Random();

            PointF coordinates = Form.MousePosition;

            if (e.Button == MouseButtons.Left)
            {
                //if shift key pressed, create a Rock
                if (ModifierKeys == Keys.Shift)
                {
                    Rock r = new Rock(coordinates);
                    if (!ShapeList.Contains(r))
                    {
                        ShapeList.Add(r);
                    }
                }

                //otherwise, create a Triangle
                else
                {
                    ShapeList.Add(new Triangle(coordinates));
                }
            }

            if (e.Button == MouseButtons.Right)
            {
                    //if shift key pressed, create a Rock
                if (ModifierKeys == Keys.Shift)
                {
                    Rock r = new Rock(new PointF(random.Next(ClientRectangle.Width), random.Next(ClientRectangle.Height)));
                    if (!ShapeList.Contains(r))
                    {
                        while (count > 0)
                        {

                            ShapeList.Add(r);
                            count--;
                        }
                    }
                }

                //otherwise, create a Triangle
                else
                {
                    ShapeList.Add(new Triangle(coordinates));
                }
            }

        }

        private void Timer1_Tick(object sender, EventArgs e)
        {
            Graphics gr = CreateGraphics();
            using (BufferedGraphicsContext bgc = new BufferedGraphicsContext())
            {
                // bind a back-buffer to the primary surface, spec size to create as client size
                using (BufferedGraphics bg = bgc.Allocate(gr, this.DisplayRectangle))
                {
                    //clear the back buffer
                    bg.Graphics.Clear(Color.Black);

                    // render all previous intersections between shapes in dark blue

                    //tick each shape
                    //render the shapes
                    foreach(ShapeBase shape in ShapeList)
                    {
                        shape.Tick(ClientRectangle.Size);

                        //triangle is aqua
                        if (shape is Triangle)
                        {
                            shape.Render(bg.Graphics, Color.Aqua);
                        }

                        //rock is green
                        if (shape is Rock)
                        {
                            shape.Render(bg.Graphics, Color.Green);
                        }

                        Regions.AddFirst(new Region(shape.GetPath()).Clone());

                        if (ShapeBase.Distance(shape, ShapeList.ne)
                        Text = $"{shape.Pos.X} , {shape.Pos.Y}";

                    }

                    //perform intersection test for each shape against every other shape
                    //make region for shape from getpath

                    // flip back-buffer to front buffer
                    bg.Render();


                    //remove all shapes that have been marked for removal with a lambda


                }
            }


        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {

        }
    }```
...