1 #include "PolygonItem.h"
2 #include "IMapRender.h"
3 
IsPointInsidePolygon(const Array<Point> & p,Point s)4 bool IsPointInsidePolygon(const Array<Point>& p, Point s)
5 {
6 	int i, j;
7 	bool parity = false;
8 	for (i = 0, j = p.GetCount() - 1; i < p.GetCount(); j = i++)
9 	{
10 		if ( ( p[i].y < s.y && s.y <= p[j].y || p[j].y < s.y && s.y <= p[i].y )
11 			&& (s.x > (p[j].x - p[i].x) * (s.y - p[i].y) / (p[j].y - p[i].y) + p[i].x))
12 				parity = !parity;
13 	}
14 	return parity;
15 }
16 
RectOfFigure(const Array<Point> & p)17 Rect RectOfFigure(const Array<Point>& p)
18 {
19 	if (!p.GetCount())
20 		return Null;
21 
22 	Point s = Point(INT_MAX, INT_MAX);
23 	Point e = Point(-1, -1);
24 
25 	for (int i = 0; i < p.GetCount();  i++)
26 	{
27 		s.x = min(p[i].x, s.x);
28 		s.y = min(p[i].y, s.y);
29 
30 		e.x = max(p[i].x, e.x);
31 		e.y = max(p[i].y, e.y);
32 	}
33 
34 	return Rect(s, e);
35 }
36 
CenterOfFigure(const Array<Point> & p)37 Point CenterOfFigure(const Array<Point>& p)
38 {
39 	return RectOfFigure(p).CenterPoint();
40 }
41 
TopLeftOfFigure(const Array<Point> & p)42 Point TopLeftOfFigure(const Array<Point>& p)
43 {
44 	if (!p.GetCount())
45 		return Null;
46 
47 	Point s = p[0];
48 
49 	for (int i = 1; i < p.GetCount();  i++)
50 	{
51 		if (s.x > p[i].x && s.y > p[i].y)
52 			s = p[i];
53 	}
54 
55 	return s;
56 }
57 
PolygonItem(IMapRender * render)58 PolygonItem::PolygonItem(IMapRender* render)
59 	: IMapItem(render), _display(new PolygonItemDisplay()), _stdDisplay(true)
60 {
61 }
62 
63 Callback1<Ptr<PolygonItem> > PolygonItem::WhenClick;
64 
~PolygonItem()65 PolygonItem::~PolygonItem()
66 {
67 	if (_stdDisplay && _display)
68 		delete _display;
69 }
70 
SetDisplay(PolygonItemDisplay * disp)71 PolygonItem* PolygonItem::SetDisplay(PolygonItemDisplay* disp)
72 {
73 	if (_stdDisplay && _display)
74 		delete _display;
75 	_display = disp;
76 	return this;
77 }
78 
GetRect()79 Rect PolygonItem::GetRect()
80 {
81 	return RectOfFigure(GetVertices());
82 }
83 
GetCenter()84 Point PolygonItem::GetCenter()
85 {
86 	return CenterOfFigure(GetVertices());
87 }
88 
GetTopLeft()89 Point PolygonItem::GetTopLeft()
90 {
91 	return TopLeftOfFigure(GetVertices());
92 }
93 
Contains(const Point & p)94 bool PolygonItem::Contains(const Point& p)
95 {
96 	return IsPointInsidePolygon(GetVertices(), p);
97 }
98 
Render(Draw * w)99 void PolygonItem::Render(Draw* w)
100 {
101 	_display->Paint(w, this);
102 }
103 
Paint(Draw * w,PolygonItem * item) const104 void PolygonItemDisplay::Paint(Draw* w, PolygonItem* item) const
105 {
106 	if (!item->GetTopRender())
107 		return;
108 
109 	Vector<Point> points;
110 	for (int i = 0; i < item->GetVertices().GetCount(); ++i)
111 		points << item->GetTopRender()->ViewToScene(item->GetVertices()[i]);
112 
113 	if (item->IsFound())
114 	{
115 		w->DrawPolygon(points,
116 			item->IsSelected()
117 				? Yellow()
118 				: LtRed(), 1, Black());
119 	}
120 
121 	else if (item->IsSelected() && !item->IsFound())
122 		w->DrawPolygon(points, Yellow(), 1, Black());
123 
124 	else if (item->IsState(STATE_EDIT))
125 		w->DrawPolygon(points, Green(),  1, Black());
126 }
127