mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 14:16:09 -06:00
126 lines
2.4 KiB
C++
126 lines
2.4 KiB
C++
#include "PolygonItem.h"
|
|
#include "IMapRender.h"
|
|
|
|
bool IsPointInsidePolygon(const Array<Point>& p, Point s)
|
|
{
|
|
int i, j;
|
|
bool parity = false;
|
|
for (i = 0, j = p.GetCount() - 1; i < p.GetCount(); j = i++)
|
|
{
|
|
if ( ( p[i].y < s.y && s.y <= p[j].y || p[j].y < s.y && s.y <= p[i].y )
|
|
&& (s.x > (p[j].x - p[i].x) * (s.y - p[i].y) / (p[j].y - p[i].y) + p[i].x))
|
|
parity = !parity;
|
|
}
|
|
return parity;
|
|
}
|
|
|
|
Rect RectOfFigure(const Array<Point>& p)
|
|
{
|
|
if (!p.GetCount())
|
|
return Null;
|
|
|
|
Point s = Point(INT_MAX, INT_MAX);
|
|
Point e = Point(-1, -1);
|
|
|
|
for (int i = 0; i < p.GetCount(); i++)
|
|
{
|
|
s.x = min(p[i].x, s.x);
|
|
s.y = min(p[i].y, s.y);
|
|
|
|
e.x = max(p[i].x, e.x);
|
|
e.y = max(p[i].y, e.y);
|
|
}
|
|
|
|
return Rect(s, e);
|
|
}
|
|
|
|
Point CenterOfFigure(const Array<Point>& p)
|
|
{
|
|
return RectOfFigure(p).CenterPoint();
|
|
}
|
|
|
|
Point TopLeftOfFigure(const Array<Point>& p)
|
|
{
|
|
if (!p.GetCount())
|
|
return Null;
|
|
|
|
Point s = p[0];
|
|
|
|
for (int i = 1; i < p.GetCount(); i++)
|
|
{
|
|
if (s.x > p[i].x && s.y > p[i].y)
|
|
s = p[i];
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
PolygonItem::PolygonItem(IMapRender* render)
|
|
: IMapItem(render), _display(new PolygonItemDisplay()), _stdDisplay(true)
|
|
{
|
|
}
|
|
|
|
Callback1<Ptr<PolygonItem> > PolygonItem::WhenClick;
|
|
|
|
PolygonItem::~PolygonItem()
|
|
{
|
|
if (_stdDisplay && _display)
|
|
delete _display;
|
|
}
|
|
|
|
PolygonItem* PolygonItem::SetDisplay(PolygonItemDisplay* disp)
|
|
{
|
|
if (_stdDisplay && _display)
|
|
delete _display;
|
|
_display = disp;
|
|
return this;
|
|
}
|
|
|
|
Rect PolygonItem::GetRect()
|
|
{
|
|
return RectOfFigure(GetVertices());
|
|
}
|
|
|
|
Point PolygonItem::GetCenter()
|
|
{
|
|
return CenterOfFigure(GetVertices());
|
|
}
|
|
|
|
Point PolygonItem::GetTopLeft()
|
|
{
|
|
return TopLeftOfFigure(GetVertices());
|
|
}
|
|
|
|
bool PolygonItem::Contains(const Point& p)
|
|
{
|
|
return IsPointInsidePolygon(GetVertices(), p);
|
|
}
|
|
|
|
void PolygonItem::Render(Draw* w)
|
|
{
|
|
_display->Paint(w, this);
|
|
}
|
|
|
|
void PolygonItemDisplay::Paint(Draw* w, PolygonItem* item) const
|
|
{
|
|
if (!item->GetTopRender())
|
|
return;
|
|
|
|
Vector<Point> points;
|
|
for (int i = 0; i < item->GetVertices().GetCount(); ++i)
|
|
points << item->GetTopRender()->ViewToScene(item->GetVertices()[i]);
|
|
|
|
if (item->IsFound())
|
|
{
|
|
w->DrawPolygon(points,
|
|
item->IsSelected()
|
|
? Yellow()
|
|
: LtRed(), 1, Black());
|
|
}
|
|
|
|
else if (item->IsSelected() && !item->IsFound())
|
|
w->DrawPolygon(points, Yellow(), 1, Black());
|
|
|
|
else if (item->IsState(STATE_EDIT))
|
|
w->DrawPolygon(points, Green(), 1, Black());
|
|
}
|