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("}");
}
}
}