Subversion Repositories AndroidProjects

Rev

Rev 1422 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Windows.Forms;
using System.ComponentModel;
using System.Threading;
using System.Globalization;


using BauzoidNET.graphics;
using BauzoidNET.graphics.sprite;
using BauzoidNET.math;

using OrderedPropertyGrid;

namespace ShapeEditor.file.shapes
{
    [TypeConverter(typeof(PropertySorter))]
    public class PolygonElement : BaseShapeElement
    {
        private List<Vector2> mVertices = new List<Vector2>();

        public List<Vector2> Vertices
        {
            get { return mVertices; }
        }
       
        public PolygonElement(Document doc, string name, List<Vector2> vertices)
            : base(doc, name)
        {
            for (int i = 0; i < vertices.Count; i++)
            {
                mVertices.Add(new Vector2(vertices[i]));
            }
        }

        public override void Render(SpriteTransform transform)
        {
            float z = mDocument.Owner.ZoomFactor;

            for (int i = 0; i < mVertices.Count; i++)
            {
                int j = (i + 1) % mVertices.Count;

                float x1 = mVertices.ElementAt(i).x * z;
                float y1 = mVertices.ElementAt(i).y * z;
                float x2 = mVertices.ElementAt(j).x * z;
                float y2 = mVertices.ElementAt(j).y * z;

                RenderUtil.drawLine(MainForm.App.getGraphics(), x1, y1, x2, y2, transform, Document.SHAPE_COLOR);
            }

            /*float z = mDocument.Owner.ZoomFactor;
           
            float x1 = centerX - radiusX;
            float y1 = centerY - radiusY;
            float x2 = centerX + radiusX;
            float y2 = centerY + radiusY;

            x1 *= z;
            y1 *= z;
            x2 *= z;
            y2 *= z;
            RenderUtil.drawEllipse(MainForm.App.getGraphics(), x1, y1, x2, y2, transform, Document.SHAPE_COLOR);*/

        }

        public override void RenderSelected(SpriteTransform transform, bool drawHandles = true)
        {
            float z = mDocument.Owner.ZoomFactor;

            for (int i = 0; i < mVertices.Count; i++)
            {
                int j = (i + 1) % mVertices.Count;

                float x1 = mVertices.ElementAt(i).x * z;
                float y1 = mVertices.ElementAt(i).y * z;
                float x2 = mVertices.ElementAt(j).x * z;
                float y2 = mVertices.ElementAt(j).y * z;

                RenderUtil.drawLine(MainForm.App.getGraphics(), x1, y1, x2, y2, transform, Document.SHAPE_COLOR_SELECTED);
            }

            if (drawHandles)
            {
                for (int i = 0; i < mVertices.Count; i++)
                    mDocument.RenderHandle(mVertices[i].x, mVertices[i].y, transform);
            }

            /*float z = mDocument.Owner.ZoomFactor;

            float x1 = centerX - radiusX;
            float y1 = centerY - radiusY;
            float x2 = centerX + radiusX;
            float y2 = centerY + radiusY;

            x1 *= z;
            y1 *= z;
            x2 *= z;
            y2 *= z;

            RenderUtil.drawEllipse(MainForm.App.getGraphics(), x1, y1, x2, y2, transform, Document.SHAPE_COLOR_SELECTED);

            if (drawHandles)
            {
                for (int i = 0; i < NUM_HANDLES; i++)
                    mDocument.RenderHandle(mHandles[i].x, mHandles[i].y, transform);
            }*/

        }

        public override int GetNumHandles() { return mVertices.Count; }

        public override int FindHandleAt(float px, float py)
        {
            //UpdateHandles();

            for (int i = 0; i < mVertices.Count; i++)
            {
                if (IsInsideHandle(px, py, mVertices[i].x, mVertices[i].y))
                    return i;
            }

            return -1;
        }

        public override bool IsInside(float px, float py)
        {
            px -= mDocument.Sprite.transform.x;
            py -= mDocument.Sprite.transform.y;

            px /= mDocument.Owner.ZoomFactor;
            py /= mDocument.Owner.ZoomFactor;

            bool negativeSide = false;

            for (int i = 0; i < mVertices.Count; i++)
            {
                //position = sign( (Bx-Ax)*(Y-Ay) - (By-Ay)*(X-Ax) )

                int j = (i + 1) % mVertices.Count;

                Vector2 a = mVertices[i];
                Vector2 b = mVertices[j];

                float side = (b.x - a.x) * (py - a.y) - (b.y - a.y) * (px - a.x);

                if (i == 0)
                {
                    if (side < 0)
                        negativeSide = true;
                    else
                        negativeSide = false;
                }
                else
                {
                    if ((side < 0) && (!negativeSide))
                        return false;
                    if ((side > 0) && (negativeSide))
                        return false;
                }

            }

            return true;       

            /*
            if (radiusX == 0)
                return false;
            if (radiusY == 0)
                return false;

            float dx = (px - centerX);
            float dy = (py - centerY);

            if (((dx * dx) / (radiusX * radiusX) + (dy * dy) / (radiusY * radiusY)) <= 1)
                return true;

            return false;*/

        }

        /*public void UpdateHandles()
        {
            mHandles[0].set(centerX - radiusX, centerY - radiusY);
            mHandles[1].set(centerX + radiusX, centerY - radiusY);
            mHandles[2].set(centerX - radiusX, centerY + radiusY);
            mHandles[3].set(centerX + radiusX, centerY + radiusY);
        }*/


        public override Cursor GetCursor(int handle)
        {
            if ((handle >= 0) && (handle < mVertices.Count))
                return Cursors.SizeAll;
            return Cursors.Arrow;
        }

        public bool IsInsideHandle(float px, float py, float handleX, float handleY)
        {
            px -= mDocument.Sprite.transform.x;
            py -= mDocument.Sprite.transform.y;

            px /= mDocument.Owner.ZoomFactor;
            py /= mDocument.Owner.ZoomFactor;

            if ((Math.Abs(handleX - px) < Document.HANDLE_SIZE / 2) && (Math.Abs(handleY - py) < Document.HANDLE_SIZE / 2))
                return true;

            return false;
        }

        public override void DragHandle(int handle, float dx, float dy)
        {
            //UpdateHandles();

            dx /= mDocument.Owner.ZoomFactor;
            dy /= mDocument.Owner.ZoomFactor;

            if (handle == -1)
                return;

            if (handle >= mVertices.Count)
                return;

            mVertices[handle].x += dx;
            mVertices[handle].y += dy;

            /*if (handle == 0)
            {
                // upper left
                centerX += dx/2; radiusX -= dx/2;
                centerY += dy/2; radiusY -= dy/2;
            }
            else if (handle == 1)
            {
                // upper right
                centerX += dx/2; radiusX += dx/2;
                centerY += dy/2; radiusY -= dy/2;
            }
            else if (handle == 2)
            {
                // lower left
                centerX += dx/2; radiusX -= dx/2;
                centerY += dy/2;  radiusY += dy/2;
            }
            else if (handle == 3)
            {
                // lower right
                centerX += dx/2; radiusX += dx/2;
                centerY += dy/2; radiusY += dy/2;
            }*/


            mDocument.SetDirty();

            //UpdateHandles();

            UpdateName();
        }

        public override void DragMove(float dx, float dy)
        {
            //centerX += dx / mDocument.Owner.ZoomFactor;
            //centerY += dy / mDocument.Owner.ZoomFactor;

            for (int i = 0; i < mVertices.Count; i++)
            {
                mVertices[i].x += dx;
                mVertices[i].y += dy;
            }

            mDocument.SetDirty();

            //UpdateHandles();

            UpdateName();
        }

        public void UpdateName()
        {
            //ShapeName = "rect " + Math.Min(centerX, centerX + radiusX) + ", " + Math.Min(centerY, centerY + radiusY) + ", " + Math.Abs(radiusX) + ", " + Math.Abs(radiusY);
            ShapeName = "polygon " + mVertices[0].x + ", " + mVertices[0].y + " -->";
            typeof(ListBox).InvokeMember("RefreshItems", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, mDocument.Owner.ElementsListBox, new object[] { });
        }

        public override void FixCoordinates()
        {
            /*if (radiusX < 0)
            {
                radiusX = -radiusX;
            }
            if (radiusY < 0)
            {
                radiusY = -radiusY;
            }*/

        }

        public override void WriteFile(System.IO.TextWriter tw)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
            //tw.WriteLine("ellipse " + centerX + ", " + centerY + ", " + radiusX + ", " + radiusY + ";");

            tw.WriteLine("polygon");
            tw.WriteLine("{");

            for (int i = 0; i < mVertices.Count; i++)
            {
                tw.WriteLine("    p " + mVertices[i].x + ", " + mVertices[i].y + ";");
            }
           
            tw.WriteLine("}");
        }

    }
}